GPS Widget voor FrSky Horus

Discussie in 'Model elektronica' gestart door toostbeek, 12 apr 2019.

  1. N.P.S.

    N.P.S. Forum veteraan

    Lid geworden:
    17 jun 2007
    Berichten:
    9.093
    Heb de afbeelding van het vliegtuig een paar pixels groter gemaakt en en een cirkel omheen geplaatst. Nu valt het veel meer op.
     
  2. Hobby4Life

    Hobby4Life

    Lid geworden:
    20 nov 2009
    Berichten:
    1.329
    Locatie:
    Avenhorn, NL
    Ik heb geprobeerd ook een cirkeltje eromheen te tekenen.
    Dat werkt ook prima..

    Alleen ik krijg ik de kleur gewoon niet mee.. geen idee wat ik verkeerd doe.. het blijft een zwart cirkeltje.

    Code:
          lcd.setColor(CUSTOM_COLOR, WHITE)     
        for i = 1, 360 do
          local angle = i * math.pi / 180
          local ptx, pty = x + 10 * math.cos( angle ), y + 10 * math.sin( angle )
         lcd.drawPoint( ptx, pty, CUSTOM_COLOR )
        end
     
  3. N.P.S.

    N.P.S. Forum veteraan

    Lid geworden:
    17 jun 2007
    Berichten:
    9.093
    Mijn programma is gemaakt met Lua dat hoort bij een Jeti zender. De implementatie daarvan is nogal anders dan bij FRSKY. Een cirkel tekenen gaat heel eenvoudig:

    lcd.drawCircle(xas,yas,18)

    waarbij xas en yas de schermcoordinaten zijn en 18 de straal van de cirkel. Kan je helaas niet verder helpen.
     
  4. Hobby4Life

    Hobby4Life

    Lid geworden:
    20 nov 2009
    Berichten:
    1.329
    Locatie:
    Avenhorn, NL
    lcd.drawCircle lijkt op een of andere manier van de aardbodem verdwenen te zijn. lk kom dat ook niet meer tegen in de manual.. en krijg er ook een compile error op. vandaar de omweg die ik er voor gebruik.
     
  5. Hobby4Life

    Hobby4Life

    Lid geworden:
    20 nov 2009
    Berichten:
    1.329
    Locatie:
    Avenhorn, NL
    Opgelost door een line te tekenen van 1px, daar aan kan ik wel flags mee geven.

    Code:
        lcd.setColor(CUSTOM_COLOR, WHITE)    
        for i = 1, 360 do
          local angle = i * math.pi / 180
          local ptx, pty = x + 10 * math.cos( angle ), y + 10 * math.sin( angle )
         lcd.drawLine( ptx, pty, ptx, pty, SOLID, CUSTOM_COLOR )
        end
     
    N.P.S. en toostbeek vinden dit leuk.
  6. toostbeek

    toostbeek

    Lid geworden:
    6 dec 2014
    Berichten:
    1.403
    Zo ziet mijn huidige versie eruit. Deze versie staat intussen ook op Github.

    Code:
    ---- #########################################################################
    ---- #                                                                       #
    ---- # GPS Widget for FrSky Horus                                                  #
    -----#                                                                       #
    ---- # License GPLv3: http://www.gnu.org/licenses/gpl-3.0.html               #
    ---- #                                                                       #
    ---- # This program is free software; you can redistribute it and/or modify  #
    ---- # it under the terms of the GNU General Public License version 3 as     #
    ---- # published by the Free Software Foundation.                            #
    ---- #                                                                       #
    ---- # Rev 0.1                                                                                         #
    ---- # Tonnie Oostbeek                                                                                  #
    ---- #                                                                       #
    ---- #########################################################################
    
    
    local options = {
      { "TextColor", COLOR, Black }
    }
    
    
    -- in the create function you add all shared variables to the array containing the widget data ('thisWidget')
    local function create(zone, options)
      local thisWidget  = { zone=zone, options=options}
     
      --create array containing all sensor ID's used for quicker retrieval
      local ID = {}
      ID.GPS = getFieldInfo("GPS") and getFieldInfo("GPS").id    or 0
      ID.Hdg = getFieldInfo("Hdg") and getFieldInfo("Hdg").id or 0
      ID.GSpd = getFieldInfo("GSpd") and getFieldInfo("GSpd").id or 0
     
      --add ID to thisWidget
      thisWidget.ID = ID   
    
      --create array containing all map info per map size
      local map = {North={},South={},West={},East={},wx={},wy={},zx={},zy={}}
            
      -- coordinates for the small map.
      map.North.small = 52.559801
      map.South.small = 52.554921
      map.West.small = 5.867646
      map.East.small = 5.879677
      map.wx.small = 320
      map.wy.small = 0
      map.zx.small = 479
      map.zy.small = 210
    
      -- coordinates for the medium map.
      map.North.medium = 52.561551
      map.South.medium = 52.554211
      map.West.medium = 5.864698
      map.East.medium = 5.882574
      map.wx.medium = 246
      map.wy.medium = 0
      map.zx.medium = 443
      map.zy.medium = 271
    
      --coordinates for the largest map.
      map.North.large = 52.564116
      map.South.large = 52.553043
      map.West.large = 5.859864
      map.East.large = 5.887011
      map.wx.large = 197
      map.wy.large = 0
      map.zx.large = 410
      map.zy.large = 271
            
      --add one bitmap per map size and set current map size
      map.bmp={}
      map.bmp.small = Bitmap.open("/Widgets/Image1/map.png")
      map.bmp.medium = Bitmap.open("/Widgets/Image1/map1.png")
      map.bmp.large = Bitmap.open("/Widgets/Image1/map2.png")
     
      --set current size
      map.current = "large"
    
      --add the map array to thisWidget
      thisWidget.map = map   
     
      --return the thisWidget array to the opentx API, containing all data to be shared across functions
      return thisWidget
    end
    
    local function background(thisWidget)
     
      thisWidget.gpsLatLong = getValue(thisWidget.ID.GPS)
      if  (type(thisWidget.gpsLatLong) ~= "table") then
        thisWidget.ID.GPS = getFieldInfo("GPS") and getFieldInfo("GPS").id    or 0
        thisWidget.ID.Hdg = getFieldInfo("Hdg") and getFieldInfo("Hdg").id or 0
        thisWidget.ID.GSpd = getFieldInfo("GSpd") and getFieldInfo("GSpd").id or 0
        model.setGlobalVariable(8,0,0)
        return
      end
     
      thisWidget.headingDeg= getValue(thisWidget.ID.Hdg) 
      thisWidget.gpsLat = thisWidget.gpsLatLong.lat
      thisWidget.gpsLong = thisWidget.gpsLatLong.lon
      thisWidget.GSpd = getValue(thisWidget.ID.GSpd)
     
    -- Part for loading the correct zoomlevel of the map
    
    -- coordinates for the smallest map. These can be found by placing the image back into Google Earth and looking at the overlay
    -- parameters
    
      local North = thisWidget.map.North
      local South = thisWidget.map.South
      local East = thisWidget.map.East
      local West = thisWidget.map.West
        
      if thisWidget.gpsLat < North.small and thisWidget.gpsLat > South.small and thisWidget.gpsLong < East.small and thisWidget.gpsLong > West.small then   
        thisWidget.map.current = "small"
      elseif thisWidget.gpsLat < North.medium and thisWidget.gpsLat > South.medium and thisWidget.gpsLong < East.medium and thisWidget.gpsLong > West.medium then   
        thisWidget.map.current = "medium"
      else   
        thisWidget.map.current = "large"
      end
    
    -- Part for setting the correct zoomlevel ends here.
    
    -- Calculate Position in relation to map.
    
      North = North[thisWidget.map.current]
      South = South[thisWidget.map.current]
      East = East[thisWidget.map.current]
      West = West[thisWidget.map.current]
      local wx = thisWidget.map.wx[thisWidget.map.current]
      local wy = thisWidget.map.wy[thisWidget.map.current]
      local zx = thisWidget.map.zx[thisWidget.map.current]
      local zy = thisWidget.map.zy[thisWidget.map.current]
    
    
      thisWidget.x = math.floor(480*((thisWidget.gpsLong - West)/(East - West)))
      thisWidget.y = math.floor(272*((North - thisWidget.gpsLat)/(North - South)))
    
      thisWidget.x=math.max(10,thisWidget.x)
      thisWidget.x=math.min(thisWidget.x,470)
    
      thisWidget.y=math.max(10,thisWidget.y)
      thisWidget.y=math.min(thisWidget.y,262)
    
      if ((thisWidget.x - wx)*(zy-wy))-((thisWidget.y - wy)*(zx-wx)) < 0 then
        model.setGlobalVariable(8,0,0)
      else
        model.setGlobalVariable(8,0,1)
      end
    
    end
    
    local function update(thisWidget, options)
      thisWidget.options = options
    end
    
    local function refresh(thisWidget)
      background(thisWidget)
    
      if  (type(thisWidget.gpsLatLong) ~= "table") then
        lcd.drawBitmap(thisWidget.map.bmp.large, thisWidget.zone.x -10, thisWidget.zone.y -10)
        lcd.setColor(CUSTOM_COLOR, RED)
        lcd.drawText( 20, 130, "No GPS SIGNAL !!!", DBLSIZE + CUSTOM_COLOR)
        return
      end
    
      local xvalues = { }
      local yvalues = { }
      local headingDeg = thisWidget.headingDeg
      local x = thisWidget.x
      local y = thisWidget.y
    --                     A
    --                     |
    --                     |
    -- C   _________________|___________________  D
    --                     |
    --                     |
    --                     |
    --                     |
    --                     |
    --                     |
    --                     |
    --                E ---|--- F
    --                     B
    
    
      xvalues.ax = x + (4 * math.sin(math.rad(headingDeg)))                             -- front of fuselage x position
      yvalues.ay = y - (4 * math.cos(math.rad(headingDeg)))                             -- front of fuselage y position
      xvalues.bx = x - (7 * math.sin(math.rad(headingDeg)))                             -- rear of fuselage x position
      yvalues.by = y + (7 * math.cos(math.rad(headingDeg)))                             -- rear of fuselage y position
      xvalues.cx = x + (10 * math.cos(math.rad(headingDeg)))                             -- left wingtip x position
      yvalues.cy = y + (10 * math.sin(math.rad(headingDeg)))                            -- left wingtip y position
      xvalues.dx = x - (10 * math.cos(math.rad(headingDeg)))                            -- right wingtip x position
      yvalues.dy = y - (10 * math.sin(math.rad(headingDeg)))                            -- right wingtip y position
      xvalues.ex = x - ((7 * math.sin(math.rad(headingDeg))) + (3 * math.cos(math.rad(headingDeg))))    -- left tailwing tip x position
      yvalues.ey = y + ((7 * math.cos(math.rad(headingDeg))) - (3 * math.sin(math.rad(headingDeg))))    -- left tailwing tip y position
      xvalues.fx = x - ((7 * math.sin(math.rad(headingDeg))) - (3 * math.cos(math.rad(headingDeg))))    -- right tailwing tip x position
      yvalues.fy = y + ((7 * math.cos(math.rad(headingDeg))) + (3 * math.sin(math.rad(headingDeg))))    -- right tailwing tip y position
     
     
    --draw background 
      lcd.drawBitmap(thisWidget.map.bmp[thisWidget.map.current], thisWidget.zone.x -10, thisWidget.zone.y -10)
    
    --draw info
      lcd.setColor(CUSTOM_COLOR, WHITE)
      lcd.drawText(360, 20, math.floor(thisWidget.GSpd) .. "Km/h", DBLSIZE + CUSTOM_COLOR)
    --  lcd.setColor(CUSTOM_COLOR, WHITE)
    --  lcd.drawText(40, 60, thisWidget.gpsLong , CUSTOM_COLOR)
    --  lcd.setColor(CUSTOM_COLOR, BLUE)
    --  lcd.drawText(40, 80, math.floor(thisWidget.headingDeg) , CUSTOM_COLOR)
    --  lcd.drawText(40, 100, thisWidget.x , CUSTOM_COLOR)
    --  lcd.drawText(40, 120, thisWidget.y , CUSTOM_COLOR)
     
    --draw plane 
      lcd.setColor(CUSTOM_COLOR, lcd.RGB(255,255,255))
      lcd.drawLine(xvalues.ax, yvalues.ay, xvalues.bx, yvalues.by, SOLID, CUSTOM_COLOR)
      lcd.drawLine(xvalues.cx, yvalues.cy, xvalues.dx, yvalues.dy, SOLID, CUSTOM_COLOR)
      lcd.drawLine(xvalues.ex, yvalues.ey, xvalues.fx, yvalues.fy, SOLID, CUSTOM_COLOR)
    
    --draw noflightzone
      lcd.setColor(CUSTOM_COLOR, lcd.RGB(255,0,0))
      lcd.drawLine(thisWidget.map.wx[thisWidget.map.current], thisWidget.map.wy[thisWidget.map.current], thisWidget.map.zx[thisWidget.map.current], thisWidget.map.zy[thisWidget.map.current], SOLID, CUSTOM_COLOR)
    
    end
    return { name="Map", options=options, create=create, update=update, background=background, refresh=refresh }
     
    Hobby4Life vindt dit leuk.
  7. Hobby4Life

    Hobby4Life

    Lid geworden:
    20 nov 2009
    Berichten:
    1.329
    Locatie:
    Avenhorn, NL
    Ik heb trouwens nog even iets toegevoegd cq aangepast.

    Ik had met de Noflyzone global variabele, dat als ik het toestel uitzette, de global variable toggelde en de zender weer begon te bliepsen.
    Wat ik nu heb gedaan is dat als de RSSI > 0 is deze Noflyzone check pas actief is.

    Dus als het toestel nu uitgezet wordt, is de RSSI 0, en is de check uit.

    Code:
      if (((thisWidget.x - wx)*(zy-wy))-((thisWidget.y - wy)*(zx-wx)) < 0) and (thisWidget.Rssi > 10 )then
        model.setGlobalVariable(8,0,0)
      else
        model.setGlobalVariable(8,0,1)
      end
    P.s. RSSI wel overal weer even defineren.
     
  8. Hobby4Life

    Hobby4Life

    Lid geworden:
    20 nov 2009
    Berichten:
    1.329
    Locatie:
    Avenhorn, NL
    Zojuist ook de mogelijkheid toegevoegd om mappen te kiezen.

    Ik wil dit eigenlijk doen via de widget instellings pagina, alleen kreeg ik dat (nog) niet voor elkaar.


    Voorlopig gebruik ik nu een Global Variable om een map te kiezen. dit gaat prima :)
    In dit geval GV8.

    Bij de functie create widget heb ik het volgende gedaan:
    Code:
    -- in the create function you add all shared variables to the array containing the widget data ('thisWidget')
    local function create(zone, options)
      local thisWidget  = { zone=zone, options=options}
     
      local LoadMap = model.getGlobalVariable(7,0)
    
    
    Daarna verderop bij alle map parameters.

    Code:
    if LoadMap == 0 then
      -- Avenhorn ---
      -- coordinates for the small map.
      map.North.small = 52.633785
      map.South.small = 52.614104
      map.West.small = 4.930978
      map.East.small = 4.988488
    en bij de map files inladen:

    Code:
        --add one bitmap per map size and set current map size
      map.bmp={}
      map.bmp.small = Bitmap.open("/Widgets/GPSMap/map"..LoadMap.."a.png")
      map.bmp.medium = Bitmap.open("/Widgets/GPSMap/map"..LoadMap.."b.png")
      map.bmp.large = Bitmap.open("/Widgets/GPSMap/map"..LoadMap.."c.png")
    etc.. dit gaat uitstekend :)
     
    Laatst bewerkt: 16 sep 2019
    toostbeek vindt dit leuk.
  9. Hobby4Life

    Hobby4Life

    Lid geworden:
    20 nov 2009
    Berichten:
    1.329
    Locatie:
    Avenhorn, NL
    Iemand trouwens een idee hoe je kan uitlezen in lua wanneer een Flight wordt gereset? dit wil ik gebruiken om alle Max waardes weer op 0 te zetten.
     
  10. l shems

    l shems

    Lid geworden:
    27 jan 2015
    Berichten:
    1.045
    Niet direct. Een timer is wellicht de beste indicatie, of de max en Mon en actual rssi vergelijken. Zouden na een reset eventjes gelijk moeten zijn.
     
  11. Hobby4Life

    Hobby4Life

    Lid geworden:
    20 nov 2009
    Berichten:
    1.329
    Locatie:
    Avenhorn, NL
  12. Hobby4Life

    Hobby4Life

    Lid geworden:
    20 nov 2009
    Berichten:
    1.329
    Locatie:
    Avenhorn, NL

    Bijgevoegde bestanden:

    Laatst bewerkt: 2 okt 2019
    Helikapoter vindt dit leuk.
  13. Hobby4Life

    Hobby4Life

    Lid geworden:
    20 nov 2009
    Berichten:
    1.329
    Locatie:
    Avenhorn, NL
    Ik heb niet stil gezeten de laatste weken na de laatste update..

    Inmiddels heb ik de layout van het scherm aangepast..
    Tevens gebruik ik nu 5 ipv 3 maps.

    Om het nog leuker te maken, heb ik op mijn site een Map generator gemaakt waar je heel gemakkelijk 5 maps kunt genereren.
    De lastigste dingen zijn nu volledig verleden tijd :)

    https://hobby4life.nl/mapgen

    Het enige wat er moet gebeuren is de 5 plaatjes opslaan zoals aangegeven op de site, en het stuk lua code wat gegenereerd wordt kopieren en plakken in je lua script.
     
    Laatst bewerkt: 18 okt 2019
    toostbeek vindt dit leuk.
  14. l shems

    l shems

    Lid geworden:
    27 jan 2015
    Berichten:
    1.045
    Fun.

    Waarom genereer je geen setting.lua script, dat je met de plaatjes enkel op de goede plek hoeft te zetten op je zender?

    Gewoon een zipje met alles erin.

    Als je die settings.lua laat beginnen met

    local map = {North={},South={}, West={},East={}}

    En laat eindigen met

    return map

    Dan kan je in je hoofdscript gewoon het volgende opnemen om de settings te laden:

    Local maps=loadfile('settings.lua')()

    Nog makkelijker voor de gebruiker.
     
    Hobby4Life vindt dit leuk.
  15. Hobby4Life

    Hobby4Life

    Lid geworden:
    20 nov 2009
    Berichten:
    1.329
    Locatie:
    Avenhorn, NL
    Hoi, bedankt voor je berichtje.. ik had al aan zoiets zitten denken.
    Alleen was dat nog even een stap te ver qua kennis van Java/php en Lua :)

    Het probleem waar ik mee zit op de website is het opslaan van het gegenereerde static plaatje.
    En al helemaal om het boeltje te zippen.

    Maar dit is eigenlijk wel waar we heen willen.
    Ik moet het even laten inwerken hoe ik dit moet doen.





    Ik zit alleen nog met een ander dingetje, en denk dat jij mij daar goed mee kan helpen.

    Ik heb nu alles aangepast zodat er nu gewerkt wordt met 5 png files.

    Alleen gaat het inladen van de map files (png) niet goed.
    Dit gebeurd alleen als ik tussen modellen switch..

    Als ik een power cycle doe met de zender dan worden ze wel goed ingeladen..

    Ik heb geen enkele clue waar ik dit zou moeten zoeken.
     
  16. l shems

    l shems

    Lid geworden:
    27 jan 2015
    Berichten:
    1.045
    Ik begrijp niet goed wanneer precies het laden niet goed gaat?
     
  17. Hobby4Life

    Hobby4Life

    Lid geworden:
    20 nov 2009
    Berichten:
    1.329
    Locatie:
    Avenhorn, NL
    Heb even een filmpje gemaakt:

     
  18. l shems

    l shems

    Lid geworden:
    27 jan 2015
    Berichten:
    1.045
    Ok, helder.

    Zal eens kijken. Is het script op GitHub?
    Zet misschien voor de zekerheid hier nog een linkje.
     
  19. Hobby4Life

    Hobby4Life

    Lid geworden:
    20 nov 2009
    Berichten:
    1.329
    Locatie:
    Avenhorn, NL
  20. toostbeek

    toostbeek

    Lid geworden:
    6 dec 2014
    Berichten:
    1.403
    Moet je niet bij update ook de andere routines laten uitvoeren?

    Hier bedoel ik.
    local function update(thisWidget, options) thisWidget.options = optionsend
     
    Laatst bewerkt: 20 okt 2019

Deel Deze Pagina