GPS Widget voor FrSky Horus

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

  1. gie

    gie

    Lid geworden:
    17 apr 2017
    Berichten:
    25
    Locatie:
    Belgie
    Graag wat hulp van het forum.
    Heb een Horus X12S. Opentx 2.2.4. Wil de lua gebruiken in een zwever met een werkende FrSky GPS module.
    Heb de lua script van Phaedra geplaatst op de SD kaart in SCRIPTS/TELEMETRY/GPSmap.lua
    De maps gegenereerd met MapGen (superding) en ze in WIDGETS/GPSMAP/maps/... geplaatst.
    En dan ging het licht uit bij mij...
    Volgens de Hobby4life/Lua-GPS-Widget instructies zou ik nu een fullscreen widget page moeten maken en dat zie ik niet hoe het moet.
    Ik kan wel een Main view aanmaken maar dat zal het wel niet zijn veronderstel ik.

    Alvast bedankt.
     
  2. l shems

    l shems

    Lid geworden:
    27 jan 2015
    Berichten:
    1.045
    Druk op telemetrie, en kies een nieuwe pagina.

    Zou zichzelf moeten wijzen.
     
  3. gie

    gie

    Lid geworden:
    17 apr 2017
    Berichten:
    25
    Locatie:
    Belgie
    Bedankt voor je snel antwoord.
    Daar zit het hem juist. Ik druk op telemetrie, kies een nieuwe pagina maar kom er niet uit hoe het verder moet.
    Ik probeer een paar shotscreens door te sturen.
    Druk op Telemetry.
    Nieuwe pagina 'main view 4'. Ik selecteer geen 'topbar' en geen 'sliders + Trims'. Foto Gie1.
    Dan selecteer ik 'Setup Widget'. Ik krijg een volledig scherm te zien. Foto Gie2
    daar kan ik alleen de standaard opties selecteren maar niets dat verwijst naar de GPS lua. Vb foto Gie3.

    Ik zie dat de foto's op de topic allemaal met een Horus10 zijn gemaakt. Heeft dat er iets met te maken?
    Gie1.jpg Gie2.jpg Gie3.jpg
     
  4. gie

    gie

    Lid geworden:
    17 apr 2017
    Berichten:
    25
    Locatie:
    Belgie
    OK, probleem opgelost na wat zoeken samen met clublid na eindejaar.
    Had niet door dat de lua naam altijd main.lua moest zijn.
    Bij het selecteren van de widget op de Horus12 moesten we een tijdje lang wachten tot de widget 'map' te selecteren was.
    Nu nog een andere GPS sensor aanschaffen/bouwen om de trage FrSky te vervangen...
    In elk geval een mooie realisatie!
     
    toostbeek vindt dit leuk.
  5. Phaedra

    Phaedra

    Lid geworden:
    20 aug 2011
    Berichten:
    502
    Locatie:
    omgeving Antwerpen
    Vorige week kreeg ik eindelijk de kans om dit script eens te testen in een reeële vlucht (ipv in een simulatie).
    Het eerste dat me opviel was de regelmatige melding van "no fly zone", terwijl ik netjes binnen de toegelaten zone aan het vliegen was. Omdat ik niet tegelijkertijd kon vliegen en het scherm van de zender in het oog houden besloot ik om de vlucht "na te spelen" in de OpenTX simulator met de opgeslagen telemetrie data.
    De fout werd snel duidelijk: de onderkant van mijn "toegelaten zone" polygoon reikte niet tot aan de onderkant van het scherm, maar slechts tot aan de bovenkant van de grijze rechthoek met de telemetrie data:
    gpsmap screenshot 3.png

    Telkens het vliegtuig onder de polygoon terechtkwam, kreeg ik de melding.
    Ik heb de polygoon gewijzigd om tot aan de onderkant van het scherm te komen; telkens het vliegtuig onder de polygoon komt, zoomt de kaart automatisch uit, en krijg ik de melding niet meer onterecht.
    Voor de rest bleek de app overigens prima te werken, een zeer handig hulpmiddel.
     
  6. gie

    gie

    Lid geworden:
    17 apr 2017
    Berichten:
    25
    Locatie:
    Belgie
    Phaedra, wil je die laatste versie eens op het forum plaatsen?
    Alvast bedankt.
    Gie.
     
  7. Phaedra

    Phaedra

    Lid geworden:
    20 aug 2011
    Berichten:
    502
    Locatie:
    omgeving Antwerpen
    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.                                                             #
    ---- #                                                                                                        #
    ---- # Original idea and credits goes to Tonnie Oostbeek (Tonnie78)                                             #
    ---- #                                                                                                        #
    ---- # Revised by Björn Pasteuning / Hobby4life 2019                                                          #
    ---- #                                                                                                        #
    ---- # Changelog:                                                                                             #
    ---- #                                                                                                        #
    ---- # v1.6 - Added RSSI detect for noFlyzone alarm function                                                  #
    ---- # v1.7 - Added posibility to select maps with GV8                                                        #
    ---- # v1.8 - Added posibolity to select Heading/Bearing input with GV7                                       #
    ---- #        0 = Calculate, 1 = Use Sensor input                                                             #
    ---- # v1.9 - Added Reset function from a Source to reset all max values                                      #
    ---- # v1.9a- Small fix in reset function                                                                     #
    ---- # v2.0 - Added Satellite indicator                                                                       #
    ---- # v2.1 - 1) HomePoint indicator / will show after a sat fix...                                           #
    ---- #        2) Line of sight line added, can be turned on and off in widget settings                        #
    ---- #        3) NoFlyZone line color is fixed to RED                                                         #
    ---- #        4) PlaneColor is fixed to YELLOW                                                                #
    ---- #        5) Map now selectable from Widget Settings page                                                 #
    ---- # v2.3 - Cleaned up code, fixed NIL issue in LCD draw routines                                           #
    ---- # v2.4 - Added LoS distance in middle of LoSLine, and added bearing indicator from home to plane         #
    ---- # v2.5 - Distance is now calculated from 2 coordinates                                                   #
    ---- # v2.6 - Heading is now only calculated from 2 upfollowing coordinates                                   #
    ---- # v2.7 - Automatic detection of Altitude sensor, Vario Altimeter or GPS Altimeter                        #
    ---- #        Vario Altimeter has priority over GPS Altimeter                                                 #
    ---- # v2.8 - 1) If Plane is outside view of maps, "OUT OF RANGE" Message will appear                         #
    ---- #        2) If HomePoint is outside zoom level, HomePoint is not visible (fix)                           #
    ---- # v2.9   Changed Layout and masked bottom area due new map download function                             #
    ---- #        Maps can now be generated and downloaded from: https://www.hobby4life.nl/mapgen.htm             #
    ---- # v3.0   Now creating maps is much easier, 5 maps are now used                                           #
    ---- #        File structure changed!, remove GPSmap widget, and reinstall widget..                           #
    ---- #        Sometimes it looks like no map is loaded.                                                       #
    ---- #        Go to widget settings -> MapSelect and toggle between 0 and another map and back to 0           #
    ---- #        then close widget and restart radio to take effect.                                             #
    ---- # v3.1   Added a no-fly zone polygon                                                                     #
    ---- ##########################################################################################################
    
    Version     = "v3.1"  -- Current version
     
    TotalMaps   = 0       -- Enter the amount of maps loaded, starts with 0 !!!!
    
    
    local options = {
      { "ResetAll"  , SOURCE  , 1     },  --Define a source for trigger a reset of al max values
      { "Imperial"  , VALUE   , 0,0,1 },  --Toggle between Metric or Imperial notation, note that correct settings have to be set on the sensor page too!
      { "LosLine"   , VALUE   , 0,0,1 },  --Enable / Disable line of sight line between Home point and plane. 0 = off, 1 = on
      { "MapSelect" , VALUE   , 0,0,TotalMaps },  --Selects Map to load, needs model change or power cycle to take effect, 0 correnspondents to map0small.png, map0medium.png and map0large.png etc...
    }
    
    
    -- 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     = thisWidget.options.MapSelect or 0
    
    -- Declaration and preset of Global Widget Variables used in the entire scope --
      HomeLat     = 0
      HomeLong    = 0
      HomeSet     = 1
      DrawSock    = 0
      MaxDistance = 0
      MaxSpeed    = 0
      MaxAltitude = 0
      LoSDistance = 0
      MaxLoS      = 0
      TempLat     = 0
      TempLong    = 0
      HomePosx    = 0
      HomePosy    = 0
      HomeVisible = 1
     
      PlaneVisible= 0
     
      --create array containing all sensor ID's used for quicker retrieval
      local ID = {}
      ID.GPS        = getFieldInfo("GPS")  and getFieldInfo("GPS").id     or 0
      ID.GSpd       = getFieldInfo("GSpd") and getFieldInfo("GSpd").id or 0
      ID.Altimeter  = (getFieldInfo("Alt") and getFieldInfo("Alt").id) or (getFieldInfo("GAlt") and getFieldInfo("GAlt").id) or 0  -- Vario Altimeter has priority over GPS Altimeter
      ID.RSSI       = getFieldInfo("RSSI") and getFieldInfo("RSSI").id or 0
      ID.Tmp1       = getFieldInfo("Tmp1") and getFieldInfo("Tmp1").id or 0 -- used with OpenXsenor or sallites in view indicator
    
     
      --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={}, poly={}}
    
    if LoadMap == 0 then
     
    -- LAC Lier
    
    -- coordinates for the extra small map.
    map.North.xsmall = 51.114654
    map.South.xsmall = 51.113738
    map.West.xsmall = 4.561133
    map.East.xsmall = 4.563707
    -- No Fly Zone screen coordinates for extra small map--
    map.wx.xsmall = 0
    map.wy.xsmall = 100
    map.zx.xsmall = 90
    map.zy.xsmall = 0
    
    map.poly.xsmall = {{90,0}, {479,0}, {479,272}, {250,272}, {20,70}}
    
    -- coordinates for the small map.
    map.North.small = 51.115112
    map.South.small = 51.11328
    map.West.small = 4.559845
    map.East.small = 4.564995
    -- No Fly Zone screen coordinates for small map--
    map.wx.small = 0
    map.wy.small = 230
    map.zx.small = 270
    map.zy.small = 0
    
    map.poly.small = {{250,0}, {479,0}, {479,272}, {320,272}, {150,110}}
    
    -- coordinates for the medium map.
    map.North.medium = 51.116028
    map.South.medium = 51.112364
    map.West.medium = 4.55727
    map.East.medium = 4.56757
    -- No Fly Zone screen coordinates for medium map--
    map.wx.medium = 40
    map.wy.medium = 240
    map.zx.medium = 330
    map.zy.medium = 0
    
    map.poly.medium = {{280,0}, {479,0}, {479,272}, {360,272}, {195,125}}
    
    -- coordinates for the large map.
    map.North.large = 51.11786
    map.South.large = 51.110532
    map.West.large = 4.55212
    map.East.large = 4.57272
    -- No Fly Zone screen coordinates for large map--
    map.wx.large = 20
    map.wy.large = 240
    map.zx.large = 420
    map.zy.large = 0
    
    map.poly.large = {{300,0}, {479,0}, {479,272}, {380,272}, {210,120}}
    
    
    -- coordinates for the extra large map.
    map.North.xlarge = 51.121524
    map.South.xlarge = 51.106868
    map.West.xlarge = 4.541821
    map.East.xlarge = 4.583019
    -- No Fly Zone screen coordinates for extra large map--
    map.wx.xlarge = 20
    map.wy.xlarge = 240
    map.zx.xlarge = 420
    map.zy.xlarge = 0
    
    map.poly.xlarge = {{300,0}, {479,0}, {479,235}, {345,235}, {225,130}}
    
    
    end
    
        --add one bitmap per map size and set current map size
      map.bmp={}
      map.bmp.xsmall  = Bitmap.open("/widgets/GPSMap/maps/map"..LoadMap.."xsmall.png")
      map.bmp.small   = Bitmap.open("/widgets/GPSMap/maps/map"..LoadMap.."small.png")
      map.bmp.medium  = Bitmap.open("/widgets/GPSMap/maps/map"..LoadMap.."medium.png")
      map.bmp.large   = Bitmap.open("/widgets/GPSMap/maps/map"..LoadMap.."large.png")
      map.bmp.xlarge  = Bitmap.open("/widgets/GPSMap/maps/map"..LoadMap.."xlarge.png")
    
      WindSock = Bitmap.open("/widgets/GPSMap/icons/windsock.png")
      --HomeIcon = Bitmap.open("/widgets/GPSMap/home.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
    
    
    --***********************************************************************
    --*                           NO-FLY DETECTION FUNCTION                          *
    --***********************************************************************
    local function insidePolygon(polygon, planex, planey)
    --  local polygon = thisWidget.map.poly[thisWidget.map.current]
        local oddNodes = false
        local j = #polygon
        for i = 1, #polygon do
            if (polygon[i][2] < planey and polygon[j][2] >= planey or polygon[j][2] < planey and polygon[i][2] >= planey) then
                if (polygon[i][1] + ( planey - polygon[i][2] ) / (polygon[j][2] - polygon[i][2]) * (polygon[j][1] - polygon[i][1]) < planex) then
                    oddNodes = not oddNodes;
                end
            end
            j = i;
        end
        
        if (oddNodes) then
            lcd.drawText( 20, 136, "is inside", SMLSIZE + CUSTOM_COLOR)
        else
            lcd.drawText( 20, 136, "NOT inside", SMLSIZE + CUSTOM_COLOR)
        end
       return oddNodes
    end
    
    
    
    
    
    --***********************************************************************
    --*                        BACKGROUND FUNCTION                          *
    --***********************************************************************
    local function background(thisWidget)
     
      ImperialSet = thisWidget.options.Imperial or 0
      --ExtHeadingSensor = thisWidget.options.ExtHdg or 0
      LosLineSet = thisWidget.options.LosLine or 0
    
     
      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.GSpd      = getFieldInfo("GSpd") and getFieldInfo("GSpd").id or 0
        thisWidget.ID.Altimeter = (getFieldInfo("Alt") and getFieldInfo("Alt").id) or (getFieldInfo("GAlt") and getFieldInfo("GAlt").id) or 0
        thisWidget.ID.RSSI      = getFieldInfo("RSSI") and getFieldInfo("RSSI").id or 0
        thisWidget.ID.Tmp1      = getFieldInfo("Tmp1") and getFieldInfo("Tmp1").id or 0
        model.setGlobalVariable(8,0,0)
        return
      end
     
      thisWidget.Speed      = getValue(thisWidget.ID.GSpd)
      thisWidget.Altitude   = getValue(thisWidget.ID.Altimeter)
      thisWidget.Rssi       = getValue(thisWidget.ID.RSSI)
      thisWidget.Sats       = getValue(thisWidget.ID.Tmp1)
    
     
      thisWidget.gpsLat     = thisWidget.gpsLatLong.lat
      thisWidget.gpsLong    = thisWidget.gpsLatLong.lon
     
      -- 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
        
      ------ Checks if Plane is visible in any map, otherwise disable plane view ------
      if thisWidget.gpsLat < North.xsmall and thisWidget.gpsLat > South.xsmall and thisWidget.gpsLong < East.xsmall and thisWidget.gpsLong > West.xsmall then
        thisWidget.map.current = "xsmall"
        PlaneVisible = 1
      elseif thisWidget.gpsLat < North.small and thisWidget.gpsLat > South.small and thisWidget.gpsLong < East.small and thisWidget.gpsLong > West.small then
        thisWidget.map.current = "small"
        PlaneVisible = 1
      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"
        PlaneVisible = 1
      elseif thisWidget.gpsLat < North.large and thisWidget.gpsLat > South.large and thisWidget.gpsLong < East.large and thisWidget.gpsLong > West.large then   
        thisWidget.map.current = "large"
        PlaneVisible = 1
      elseif thisWidget.gpsLat < North.xlarge and thisWidget.gpsLat > South.xlarge and thisWidget.gpsLong < East.xlarge and thisWidget.gpsLong > West.xlarge then   
        thisWidget.map.current = "xlarge"
        PlaneVisible = 1   
      else
        thisWidget.map.current = "large"
        PlaneVisible = 0 
      end
    
    -- Part for setting the correct zoomlevel ends here.
      North = North[thisWidget.map.current]
      South = South[thisWidget.map.current]
      East  = East[thisWidget.map.current]
      West  = West[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)
    
    -- Calculate  home position in relation to map. 
     
      if thisWidget.gpsLat ~= 0 and thisWidget.gpsLong ~= 0 then
        if HomeSet == 1 then
            HomeLat = thisWidget.gpsLat
            HomeLong = thisWidget.gpsLong
            HomeSet = 0
            DrawSock = 1
        end
          HomePosx = math.floor(480*((HomeLong - West)/(East - West)))
          HomePosy = math.floor(272*((North - HomeLat)/(North - South)))
          HomePosx = math.max(10,HomePosx)
          HomePosx = math.min(HomePosx,470)
          HomePosy = math.max(10,HomePosy)
          HomePosy = math.min(HomePosy,262)   
      end   
    
    ------ Checks if Homepoint is visible on the map otherwise disable view -------
      if HomeLat < North and HomeLat > South and HomeLong < East and HomeLong > West then
        HomeVisible = 1
      else
        HomeVisible = 0 
      end
    
    -------------------- Checks if plane crossed the nofly zone line and toggles GV9 Variable --------------
      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]
    
      local testpolygon = thisWidget.map.poly[thisWidget.map.current]
    
      if (insidePolygon(testpolygon,thisWidget.x,thisWidget.y) and (thisWidget.Rssi > 0)) then
        model.setGlobalVariable(8,0,0)
      else
        model.setGlobalVariable(8,0,1)
      end
    
    
    end
    ---------------------------------------------------------------------------------------------------------
    
    --***********************************************************************
    --*                          SPECIAL FUNCTIONS                          *
    --***********************************************************************
    
    ----------------------- Function to calculated bearing angle between 2 coordinates ----------------------
    function CalcBearing(PrevLat,PrevLong,NewLat,NewLong)
      local yCalc = math.sin(math.rad(NewLong)-math.rad(PrevLong)) * math.cos(math.rad(NewLat))
      local xCalc = math.cos(math.rad(PrevLat)) * math.sin(math.rad(NewLat)) - math.sin(math.rad(PrevLat)) * math.cos(math.rad(NewLat)) * math.cos(math.rad(NewLat) - math.rad(PrevLat))
      local Bearing = math.deg(math.atan2(yCalc,xCalc))
      if Bearing < 0 then
        Bearing = 360 + Bearing
      end 
      return Bearing
    end
    
    ----------------------- Function to calculate distance between 2 coordinates -----------------------------
    function CalcDistance(PrevLat,PrevLong,NewLat,NewLong)
      local earthRadius = 0
      if ImperialSet == 1 then
        earthRadius = 20902000  --feet  --3958.8 miles
      else
        earthRadius = 6371000   --meters
      end
      local dLat = math.rad(NewLat-PrevLat)
      local dLon = math.rad(NewLong-PrevLong)
      PrevLat = math.rad(PrevLat)
      NewLat = math.rad(NewLat)
      local a = math.sin(dLat/2) * math.sin(dLat/2) + math.sin(dLon/2) * math.sin(dLon/2) * math.cos(PrevLat) * math.cos(NewLat)
      local c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
      return (earthRadius * c)
    end   
    
    --***********************************************************************
    --*                            UPDATE FUNCTION                          *
    --***********************************************************************
    local function update(thisWidget, options)
      thisWidget.options = options
    end
    
    
    
    
    --***********************************************************************
    --*                           REFRESH FUNCTION                          *
    --***********************************************************************
    local function refresh(thisWidget)
     
      local NS        = ""
      local EW        = ""
      local FM        = ""
      local SPD       = ""
      local LCD_Lat   = thisWidget.gpsLat or 0
      local LCD_Long  = thisWidget.gpsLong or 0
      local LCD_Speed = thisWidget.Speed or 0
      local LCD_Alt   = thisWidget.Altitude or 0
      local LCD_Sats  = thisWidget.Sats or 0 
      local xvalues   = { }
      local yvalues   = { }
      local x         = thisWidget.x or 0
      local y         = thisWidget.y or 0
     
        background(thisWidget)
     
      ------------------------------------------------------------------------------------------------------------
      RstAll = getValue(thisWidget.options.ResetAll) or 0
        
      if RstAll > 1000 then
        MaxDistance   = 0
        MaxSpeed      = 0
        MaxAltitude   = 0
        MaxLoS        = 0
        HomeSet       = 1
        DrawSock      = 0
        HomeLat       = thisWidget.gpsLat or 0
        HomeLong      = thisWidget.gpsLong or 0
      end 
     
       ------------ Calculates Heading and Distance from Home to Plane position -------------------------------------------
      local HomeToPlaneBearing = CalcBearing(HomeLat,HomeLong,LCD_Lat,LCD_Long) or 0
      local HomeToPlaneDistance = CalcDistance(HomeLat,HomeLong,LCD_Lat,LCD_Long) or 0
      --- Temporary fix for overflow HomeToPlaneDistance variable.. on Reset it sometimes overflows
      if HomeToPlaneDistance > 100000 then -- When overflowing with 100
        HomeToPlaneDistance = 0
      end
    ----------------------------------------- Calculates max Ground Distance ----------------------------------
        if (HomeToPlaneDistance > MaxDistance) then
                MaxDistance = HomeToPlaneDistance
      end
    -----------------------------------------------------------------------------------------------------------
    
    ------------------------------------------- Calculates max Speed ------------------------------------------
        if (LCD_Speed > MaxSpeed) then
            MaxSpeed = LCD_Speed
        end
    ----------------------------------------------------------------------------------------------------------
    
    ---------------------------------------- Calculates max Altitude -----------------------------------------
        if (LCD_Alt > MaxAltitude) then
            MaxAltitude = LCD_Alt
        end
    -------------------------------------------------------------------------------------------------------------
    
    -------------------------------- Calculates (max) Line Of Sight Distance ---------------------------------
        local a = math.floor(LCD_Alt)
        local b = math.floor(HomeToPlaneDistance)
        LoSDistance = math.floor(math.sqrt((a * a) + (b * b)))
        if LoSDistance > MaxLoS then
            MaxLoS = LoSDistance
        end
    
    ------------------------------ Checks if valid GPS data is received ------------------------------------- 
     if  (type(thisWidget.gpsLatLong) ~= "table") then
            lcd.drawBitmap(thisWidget.map.bmp.xlarge, thisWidget.zone.x -10, thisWidget.zone.y -10)
            lcd.setColor(CUSTOM_COLOR, lcd.RGB(255,0,0))
        lcd.drawFilledRectangle(0, 239, 480, 33, SOLID)   
            lcd.drawText( 120, 236, "No GPS SIGNAL", DBLSIZE + CUSTOM_COLOR + SHADOWED)
            return
        end
    
    ------------ Calculates Heading Bearing from previous and new location of the plane ----------------------
      if (LCD_Lat ~= TempLat) and (LCD_Long ~= TempLong) then
        Bearing = CalcBearing(TempLat,TempLong,LCD_Lat,LCD_Long)
        TempLat = LCD_Lat
        TempLong = LCD_Long
      end
      headingDeg = Bearing or 0
    
    
    
    -----------------------------------------LCD ROUTINES --------------------------------------------------   
    --                     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
     
     
    -- Preset info
        if LCD_Lat > 0 then
            NS = "N"
        else
            NS = "S"
        end
    
        if LCD_Long > 0 then
            EW = "E"
        else
            EW = "W"
        end
        
        if ImperialSet == 1 then
            FM  = "ft"
            SPD = "mph"
        else
            FM  = "m"
            SPD = "km/h"
        end 
     
     
    --draw background 
      lcd.drawBitmap(thisWidget.map.bmp[thisWidget.map.current], thisWidget.zone.x -10, thisWidget.zone.y -10)
     
    
    -- Draw nofly zone line --
      lcd.setColor(CUSTOM_COLOR, lcd.RGB(248,0,0))
    -- ********************************************
    -- polygon no-fly update
    -- ********************************************
    --  disable no-fly line drawing
    --  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) 
    -- draw polygon--
        local tmp = thisWidget.map.poly[thisWidget.map.current]
        for i = 1, #thisWidget.map.poly[thisWidget.map.current]-1  do
            lcd.drawLine(tmp[i][1],tmp[i][2],tmp[i+1][1],tmp[i+1][2], SOLID, CUSTOM_COLOR)
        end
        local k = #thisWidget.map.poly[thisWidget.map.current]
        lcd.drawLine(tmp[k][1],tmp[k][2],tmp[1][1],tmp[1][2], SOLID, CUSTOM_COLOR)
    -- ********************************************
    -- END OF polygon no-fly update
    -- ********************************************
     
     
      if PlaneVisible == 1 then
      -- Draws plane --
        lcd.setColor(CUSTOM_COLOR, lcd.RGB(248,252,0))
        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)
      end
    
    -- Draws the Windsock as Homepoint & display Plane direction angle from Homepoint
      if HomeVisible == 1 then
        if DrawSock == 1 then
          lcd.drawBitmap(WindSock, HomePosx-16, HomePosy-16, 50)
          lcd.setColor(CUSTOM_COLOR, lcd.RGB(248,0,248))
          local SockFlags = CUSTOM_COLOR + SMLSIZE + SHADOWED
          local SockX = HomePosx
          local SockY = HomePosy
          if SockX > 470 then
            SockFlags = SockFlags + RIGHT
          end
          if SockY < 10 then
            SockY = SockY + 10
          elseif SockY > 256 then
            SockY = SockY - 10
          end
          lcd.drawText(SockX, SockY, math.floor(HomeToPlaneBearing).."deg", SockFlags)
        end
      end
    
      if PlaneVisible == 1 and HomeVisible == 1 then
      -- Enables a Line of Sight line when homeposition has been set, and enabled in Widget config menu
        if (HomeSet == 0) and (LosLineSet == 1) then
          lcd.setColor(CUSTOM_COLOR, lcd.RGB(0, 252, 0))
          lcd.drawLine(x,y,HomePosx,HomePosy, DOTTED, CUSTOM_COLOR)
          local MidLosLineX = ((x + HomePosx)/2)
          local MidLosLineY = ((y + HomePosy)/2)
          local LosFlags = CUSTOM_COLOR + SMLSIZE + SHADOWED
          if MidLosLineX > 470 then
            LosFlags = LosFlags + RIGHT
          end
          if MidLosLineY < 10 then
            MidLosLineY = MidLosLineY + 10
          elseif MidLosLineY > 256 then
            MidLosLineY = MidLosLineY - 10
          end
          lcd.setColor(CUSTOM_COLOR, WHITE)
          lcd.drawText(MidLosLineX, MidLosLineY, math.floor(HomeToPlaneDistance)..FM , LosFlags)
        end
      else
        if PlaneVisible == 0 then
          lcd.setColor(CUSTOM_COLOR, lcd.RGB(255,0,0))
          lcd.drawText( 120, 120, "OUT OF RANGE", DBLSIZE + CUSTOM_COLOR + SHADOWED)
        end
      end 
        
      --lcd.setColor(CUSTOM_COLOR, lcd.RGB(255,0,0))
      lcd.drawFilledRectangle(0, 239, 480, 33, GREY_DEFAULT)
    
    -- Draws all flight information on screen --
     lcd.setColor(CUSTOM_COLOR, lcd.RGB(248,252,0))
    
      lcd.drawText(10, 239, "Speed: "..math.floor(LCD_Speed)..SPD, CUSTOM_COLOR + SMLSIZE + SHADOWED)   
      lcd.drawText(10, 255, "Max: "..math.floor(MaxSpeed)..SPD , CUSTOM_COLOR + SMLSIZE + SHADOWED)   
     
      lcd.drawText(130, 239, "Alt: "..math.floor(LCD_Alt)..FM, CUSTOM_COLOR + SMLSIZE + SHADOWED)   
      lcd.drawText(130, 255, "Max: "..math.floor(MaxAltitude)..FM , CUSTOM_COLOR + SMLSIZE + SHADOWED)   
     
      lcd.drawText(240, 239, "Dist: "..math.floor(HomeToPlaneDistance)..FM, CUSTOM_COLOR + SMLSIZE + SHADOWED)
      lcd.drawText(240, 255, "Max: "..math.floor(MaxDistance)..FM , CUSTOM_COLOR + SMLSIZE + SHADOWED)
     
      lcd.drawText(360, 239, "LoS: "..math.floor(LoSDistance)..FM, CUSTOM_COLOR + SMLSIZE + SHADOWED)
      lcd.drawText(360, 255, "Max: "..math.floor(MaxLoS)..FM , CUSTOM_COLOR + SMLSIZE + SHADOWED)
    
      if LCD_Sats > 0  then
        lcd.drawText(10, 32, "Satellites: "..math.floor(LCD_Sats), CUSTOM_COLOR + SMLSIZE + SHADOWED) 
      end
    
      lcd.drawText(10, 16, "Heading: "..math.floor(headingDeg).."deg" , CUSTOM_COLOR + SMLSIZE + SHADOWED) 
      lcd.drawText(10, 0, "Lat: "..NS..math.abs(LCD_Lat).." / Lon: "..EW..math.abs(LCD_Long), CUSTOM_COLOR + SMLSIZE +SHADOWED)
     
      lcd.drawText(470, 0, Version , CUSTOM_COLOR + SMLSIZE + RIGHT + SHADOWED)
    
    end
    return { name="Map", options=options, create=create, update=update, background=background, refresh=refresh }
    Voilà:
     
  8. gie

    gie

    Lid geworden:
    17 apr 2017
    Berichten:
    25
    Locatie:
    Belgie
    Dikke merci.
     
  9. l shems

    l shems

    Lid geworden:
    27 jan 2015
    Berichten:
    1.045
    Je kan het ook delen op de repository van www.justfly.solutions :)
     
  10. gie

    gie

    Lid geworden:
    17 apr 2017
    Berichten:
    25
    Locatie:
    Belgie

    Phaedra, ik heb bovenstaande niet meer teruggevonden in je laatste versie.
    1/ Ik veronderstel dat 8,1,1 en 8,2,1 voor FM1 en FM2 zijn - mag dit blijven staan indien alleen FM0 gebruikt wordt?
    2/ de test erboven ivm het alarm was wel uitgebreider dan in je laatse versie...?
    3/ -- No Fly Zone screen coordinates for ?? map-- Mag die code weg wanneer een polygoon gebruikt wordt?

    Ik probeer gewoon de lua code te begrijpen. Neem dit aub zeker niet op als commentaar, integendeel.
     
  11. Phaedra

    Phaedra

    Lid geworden:
    20 aug 2011
    Berichten:
    502
    Locatie:
    omgeving Antwerpen
    Gie, je hebt helemaal gelijk; ik heb niet de juiste versie gepubliceerd, hier is de juiste.

    Ja hoor, dat heeft dan gewoon geen effect

    Klopt, ik heb het in deze versie dan ook weggehaald.

    Een eerste test in de OpenTX simulator geeft goede resultaten nu, en het is wachten op beter vliegweer om het nog eens live uit te testen.

    Bedankt om mee te denken en kritisch naar de code te kijken!

    Phaedra


    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.                                                             #
    ---- #                                                                                                        #
    ---- # Original idea and credits goes to Tonnie Oostbeek (Tonnie78)                                             #
    ---- #                                                                                                        #
    ---- # Revised by Björn Pasteuning / Hobby4life 2019                                                          #
    ---- #            Phaedra Degreef - added no-fly polygon detection                                            #
    ---- #                                                                                                        #
    ---- # Changelog:                                                                                             #
    ---- #                                                                                                        #
    ---- # v1.6 - Added RSSI detect for noFlyzone alarm function                                                  #
    ---- # v1.7 - Added posibility to select maps with GV8                                                        #
    ---- # v1.8 - Added posibolity to select Heading/Bearing input with GV7                                       #
    ---- #        0 = Calculate, 1 = Use Sensor input                                                             #
    ---- # v1.9 - Added Reset function from a Source to reset all max values                                      #
    ---- # v1.9a- Small fix in reset function                                                                     #
    ---- # v2.0 - Added Satellite indicator                                                                       #
    ---- # v2.1 - 1) HomePoint indicator / will show after a sat fix...                                           #
    ---- #        2) Line of sight line added, can be turned on and off in widget settings                        #
    ---- #        3) NoFlyZone line color is fixed to RED                                                         #
    ---- #        4) PlaneColor is fixed to YELLOW                                                                #
    ---- #        5) Map now selectable from Widget Settings page                                                 #
    ---- # v2.3 - Cleaned up code, fixed NIL issue in LCD draw routines                                           #
    ---- # v2.4 - Added LoS distance in middle of LoSLine, and added bearing indicator from home to plane         #
    ---- # v2.5 - Distance is now calculated from 2 coordinates                                                   #
    ---- # v2.6 - Heading is now only calculated from 2 upfollowing coordinates                                   #
    ---- # v2.7 - Automatic detection of Altitude sensor, Vario Altimeter or GPS Altimeter                        #
    ---- #        Vario Altimeter has priority over GPS Altimeter                                                 #
    ---- # v2.8 - 1) If Plane is outside view of maps, "OUT OF RANGE" Message will appear                         #
    ---- #        2) If HomePoint is outside zoom level, HomePoint is not visible (fix)                           #
    ---- # v2.9   Changed Layout and masked bottom area due new map download function                             #
    ---- #        Maps can now be generated and downloaded from: https://www.hobby4life.nl/mapgen.htm             #
    ---- # v3.0   Now creating maps is much easier, 5 maps are now used                                           #
    ---- #        File structure changed!, remove GPSmap widget, and reinstall widget..                           #
    ---- #        Sometimes it looks like no map is loaded.                                                       #
    ---- #        Go to widget settings -> MapSelect and toggle between 0 and another map and back to 0           #
    ---- #        then close widget and restart radio to take effect.                                             #
    ---- # v3.1   Added a no-fly zone polygon                                                                     #
    ---- #        Added polygon definition array to map definitions                                               #
    ---- #        Added checking of model position inside polygon, and callout in all flight modes used           #
    ---- ##########################################################################################################
    
    Version     = "v3.1"  -- Current version
     
    TotalMaps   = 0       -- Enter the amount of maps loaded, starts with 0 !!!!
    
    
    local options = {
      { "ResetAll"  , SOURCE  , 1     },  --Define a source for trigger a reset of al max values
      { "Imperial"  , VALUE   , 0,0,1 },  --Toggle between Metric or Imperial notation, note that correct settings have to be set on the sensor page too!
      { "LosLine"   , VALUE   , 0,0,1 },  --Enable / Disable line of sight line between Home point and plane. 0 = off, 1 = on
      { "MapSelect" , VALUE   , 0,0,TotalMaps },  --Selects Map to load, needs model change or power cycle to take effect, 0 correnspondents to map0small.png, map0medium.png and map0large.png etc...
    }
    
    
    -- 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     = thisWidget.options.MapSelect or 0
    
    -- Declaration and preset of Global Widget Variables used in the entire scope --
      HomeLat     = 0
      HomeLong    = 0
      HomeSet     = 1
      DrawSock    = 0
      MaxDistance = 0
      MaxSpeed    = 0
      MaxAltitude = 0
      LoSDistance = 0
      MaxLoS      = 0
      TempLat     = 0
      TempLong    = 0
      HomePosx    = 0
      HomePosy    = 0
      HomeVisible = 1
     
      PlaneVisible= 0
     
      --create array containing all sensor ID's used for quicker retrieval
      local ID = {}
      ID.GPS        = getFieldInfo("GPS")  and getFieldInfo("GPS").id     or 0
      ID.GSpd       = getFieldInfo("GSpd") and getFieldInfo("GSpd").id or 0
      ID.Altimeter  = (getFieldInfo("Alt") and getFieldInfo("Alt").id) or (getFieldInfo("GAlt") and getFieldInfo("GAlt").id) or 0  -- Vario Altimeter has priority over GPS Altimeter
      ID.RSSI       = getFieldInfo("RSSI") and getFieldInfo("RSSI").id or 0
      ID.Tmp1       = getFieldInfo("Tmp1") and getFieldInfo("Tmp1").id or 0 -- used with OpenXsenor or sallites in view indicator
    
     
      --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={}, poly={}}
    --  local map = {North={},South={},West={},East={},wx={},wy={},zx={},zy={}}
    --LoadMap = 1
    
    if LoadMap == 0 then
     
    -- LAC Lier
    
    -- coordinates for the extra small map.
    map.North.xsmall = 51.114654
    map.South.xsmall = 51.113738
    map.West.xsmall = 4.561133
    map.East.xsmall = 4.563707
    -- No Fly Zone screen coordinates for extra small map--
    map.poly.xsmall = {{90,0}, {479,0}, {479,272}, {250,272}, {20,70}}
    
    -- coordinates for the small map.
    map.North.small = 51.115112
    map.South.small = 51.11328
    map.West.small = 4.559845
    map.East.small = 4.564995
    -- No Fly Zone screen coordinates for small map--
    map.poly.small = {{250,0}, {479,0}, {479,272}, {320,272}, {150,110}}
    
    -- coordinates for the medium map.
    map.North.medium = 51.116028
    map.South.medium = 51.112364
    map.West.medium = 4.55727
    map.East.medium = 4.56757
    -- No Fly Zone screen coordinates for medium map--
    map.poly.medium = {{280,0}, {479,0}, {479,272}, {360,272}, {195,125}}
    
    -- coordinates for the large map.
    map.North.large = 51.11786
    map.South.large = 51.110532
    map.West.large = 4.55212
    map.East.large = 4.57272
    -- No Fly Zone screen coordinates for large map--
    map.poly.large = {{300,0}, {479,0}, {479,272}, {380,272}, {210,120}}
    
    -- coordinates for the extra large map.
    map.North.xlarge = 51.121524
    map.South.xlarge = 51.106868
    map.West.xlarge = 4.541821
    map.East.xlarge = 4.583019
    -- No Fly Zone screen coordinates for extra large map--
    map.poly.xlarge = {{300,0}, {479,0}, {479,235}, {345,235}, {225,130}}
    
    
    end
    
        --add one bitmap per map size and set current map size
      map.bmp={}
      map.bmp.xsmall  = Bitmap.open("/widgets/GPSMap/maps/map"..LoadMap.."xsmall.png")
      map.bmp.small   = Bitmap.open("/widgets/GPSMap/maps/map"..LoadMap.."small.png")
      map.bmp.medium  = Bitmap.open("/widgets/GPSMap/maps/map"..LoadMap.."medium.png")
      map.bmp.large   = Bitmap.open("/widgets/GPSMap/maps/map"..LoadMap.."large.png")
      map.bmp.xlarge  = Bitmap.open("/widgets/GPSMap/maps/map"..LoadMap.."xlarge.png")
    
      WindSock = Bitmap.open("/widgets/GPSMap/icons/windsock.png")
      --HomeIcon = Bitmap.open("/widgets/GPSMap/home.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
    
    
    --***********************************************************************
    --*                           NO-FLY DETECTION FUNCTION                          *
    --***********************************************************************
    local function insidePolygon(polygon, planex, planey)
    --  local polygon = thisWidget.map.poly[thisWidget.map.current]
        local oddNodes = false
        local j = #polygon
        for i = 1, #polygon do
            if (polygon[i][2] < planey and polygon[j][2] >= planey or polygon[j][2] < planey and polygon[i][2] >= planey) then
                if (polygon[i][1] + ( planey - polygon[i][2] ) / (polygon[j][2] - polygon[i][2]) * (polygon[j][1] - polygon[i][1]) < planex) then
                    oddNodes = not oddNodes;
                end
            end
            j = i;
        end
      
       return oddNodes
    end
    
    
    
    
    
    --***********************************************************************
    --*                        BACKGROUND FUNCTION                          *
    --***********************************************************************
    local function background(thisWidget)
     
      ImperialSet = thisWidget.options.Imperial or 0
      --ExtHeadingSensor = thisWidget.options.ExtHdg or 0
      LosLineSet = thisWidget.options.LosLine or 0
    
     
      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.GSpd      = getFieldInfo("GSpd") and getFieldInfo("GSpd").id or 0
        thisWidget.ID.Altimeter = (getFieldInfo("Alt") and getFieldInfo("Alt").id) or (getFieldInfo("GAlt") and getFieldInfo("GAlt").id) or 0
        thisWidget.ID.RSSI      = getFieldInfo("RSSI") and getFieldInfo("RSSI").id or 0
        thisWidget.ID.Tmp1      = getFieldInfo("Tmp1") and getFieldInfo("Tmp1").id or 0
        model.setGlobalVariable(8,0,0)
        return
      end
     
      thisWidget.Speed      = getValue(thisWidget.ID.GSpd)
      thisWidget.Altitude   = getValue(thisWidget.ID.Altimeter)
      thisWidget.Rssi       = getValue(thisWidget.ID.RSSI)
      thisWidget.Sats       = getValue(thisWidget.ID.Tmp1)
    
     
      thisWidget.gpsLat     = thisWidget.gpsLatLong.lat
      thisWidget.gpsLong    = thisWidget.gpsLatLong.lon
     
      -- 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
      
      ------ Checks if Plane is visible in any map, otherwise disable plane view ------
      if thisWidget.gpsLat < North.xsmall and thisWidget.gpsLat > South.xsmall and thisWidget.gpsLong < East.xsmall and thisWidget.gpsLong > West.xsmall then
        thisWidget.map.current = "xsmall"
        PlaneVisible = 1
      elseif thisWidget.gpsLat < North.small and thisWidget.gpsLat > South.small and thisWidget.gpsLong < East.small and thisWidget.gpsLong > West.small then
        thisWidget.map.current = "small"
        PlaneVisible = 1
      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"
        PlaneVisible = 1
      elseif thisWidget.gpsLat < North.large and thisWidget.gpsLat > South.large and thisWidget.gpsLong < East.large and thisWidget.gpsLong > West.large then 
        thisWidget.map.current = "large"
        PlaneVisible = 1
      elseif thisWidget.gpsLat < North.xlarge and thisWidget.gpsLat > South.xlarge and thisWidget.gpsLong < East.xlarge and thisWidget.gpsLong > West.xlarge then 
        thisWidget.map.current = "xlarge"
        PlaneVisible = 1 
      else
        thisWidget.map.current = "large"
        PlaneVisible = 0
      end
    
    -- Part for setting the correct zoomlevel ends here.
      North = North[thisWidget.map.current]
      South = South[thisWidget.map.current]
      East  = East[thisWidget.map.current]
      West  = West[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)
    
    -- Calculate  home position in relation to map.
     
      if thisWidget.gpsLat ~= 0 and thisWidget.gpsLong ~= 0 then
        if HomeSet == 1 then
            HomeLat = thisWidget.gpsLat
            HomeLong = thisWidget.gpsLong
            HomeSet = 0
            DrawSock = 1
        end
          HomePosx = math.floor(480*((HomeLong - West)/(East - West)))
          HomePosy = math.floor(272*((North - HomeLat)/(North - South)))
          HomePosx = math.max(10,HomePosx)
          HomePosx = math.min(HomePosx,470)
          HomePosy = math.max(10,HomePosy)
          HomePosy = math.min(HomePosy,262) 
      end 
    
    ------ Checks if Homepoint is visible on the map otherwise disable view -------
      if HomeLat < North and HomeLat > South and HomeLong < East and HomeLong > West then
        HomeVisible = 1
      else
        HomeVisible = 0
      end
    
    -------------------- Checks if plane crossed the nofly zone line and toggles GV9 Variable --------------
    --  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]
    
    -- ********************************************
    -- no-fly polygon update
    -- if a valid GPS position is received, and RSSI is valid, and position is inside polygon, set GVAR 9 to 1
    -- This is to avoid the alarm when receiver or GPS sensor is not ready
    -- *******************************************************************************************************
    local testpolygon = thisWidget.map.poly[thisWidget.map.current]
    
      if ((insidePolygon(testpolygon,thisWidget.x,thisWidget.y) == false) and (thisWidget.Rssi > 0) and
          (type(thisWidget.gpsLatLong) == "table") and (PlaneVisible == 1)) then
            -- set this GVAR in every flight mode that is used
        model.setGlobalVariable(8,0,1)
        model.setGlobalVariable(8,1,1)
        model.setGlobalVariable(8,2,1)
      else
        model.setGlobalVariable(8,0,0)
        model.setGlobalVariable(8,1,0)
        model.setGlobalVariable(8,2,0)
      end
    
    -- ********************************************
    -- END OF no-fly polygon update
    -- ********************************************
    
    end
    ---------------------------------------------------------------------------------------------------------
    
    --***********************************************************************
    --*                          SPECIAL FUNCTIONS                          *
    --***********************************************************************
    
    ----------------------- Function to calculated bearing angle between 2 coordinates ----------------------
    function CalcBearing(PrevLat,PrevLong,NewLat,NewLong)
      local yCalc = math.sin(math.rad(NewLong)-math.rad(PrevLong)) * math.cos(math.rad(NewLat))
      local xCalc = math.cos(math.rad(PrevLat)) * math.sin(math.rad(NewLat)) - math.sin(math.rad(PrevLat)) * math.cos(math.rad(NewLat)) * math.cos(math.rad(NewLat) - math.rad(PrevLat))
      local Bearing = math.deg(math.atan2(yCalc,xCalc))
      if Bearing < 0 then
        Bearing = 360 + Bearing
      end
      return Bearing
    end
    
    ----------------------- Function to calculate distance between 2 coordinates -----------------------------
    function CalcDistance(PrevLat,PrevLong,NewLat,NewLong)
      local earthRadius = 0
      if ImperialSet == 1 then
        earthRadius = 20902000  --feet  --3958.8 miles
      else
        earthRadius = 6371000   --meters
      end
      local dLat = math.rad(NewLat-PrevLat)
      local dLon = math.rad(NewLong-PrevLong)
      PrevLat = math.rad(PrevLat)
      NewLat = math.rad(NewLat)
      local a = math.sin(dLat/2) * math.sin(dLat/2) + math.sin(dLon/2) * math.sin(dLon/2) * math.cos(PrevLat) * math.cos(NewLat)
      local c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
      return (earthRadius * c)
    end 
    
    --***********************************************************************
    --*                            UPDATE FUNCTION                          *
    --***********************************************************************
    local function update(thisWidget, options)
      thisWidget.options = options
    end
    
    --***********************************************************************
    --*                           REFRESH FUNCTION                          *
    --***********************************************************************
    local function refresh(thisWidget)
     
      local NS        = ""
      local EW        = ""
      local FM        = ""
      local SPD       = ""
      local LCD_Lat   = thisWidget.gpsLat or 0
      local LCD_Long  = thisWidget.gpsLong or 0
      local LCD_Speed = thisWidget.Speed or 0
      local LCD_Alt   = thisWidget.Altitude or 0
      local LCD_Sats  = thisWidget.Sats or 0
      local xvalues   = { }
      local yvalues   = { }
      local x         = thisWidget.x or 0
      local y         = thisWidget.y or 0
     
        background(thisWidget)
     
      ------------------------------------------------------------------------------------------------------------
      RstAll = getValue(thisWidget.options.ResetAll) or 0
      
      if RstAll > 1000 then
        MaxDistance   = 0
        MaxSpeed      = 0
        MaxAltitude   = 0
        MaxLoS        = 0
        HomeSet       = 1
        DrawSock      = 0
        HomeLat       = thisWidget.gpsLat or 0
        HomeLong      = thisWidget.gpsLong or 0
      end
     
       ------------ Calculates Heading and Distance from Home to Plane position -------------------------------------------
      local HomeToPlaneBearing = CalcBearing(HomeLat,HomeLong,LCD_Lat,LCD_Long) or 0
      local HomeToPlaneDistance = CalcDistance(HomeLat,HomeLong,LCD_Lat,LCD_Long) or 0
      --- Temporary fix for overflow HomeToPlaneDistance variable.. on Reset it sometimes overflows
      if HomeToPlaneDistance > 100000 then -- When overflowing with 100
        HomeToPlaneDistance = 0
      end
    ----------------------------------------- Calculates max Ground Distance ----------------------------------
        if (HomeToPlaneDistance > MaxDistance) then
                MaxDistance = HomeToPlaneDistance
      end
    -----------------------------------------------------------------------------------------------------------
    
    ------------------------------------------- Calculates max Speed ------------------------------------------
        if (LCD_Speed > MaxSpeed) then
            MaxSpeed = LCD_Speed
        end
    ----------------------------------------------------------------------------------------------------------
    
    ---------------------------------------- Calculates max Altitude -----------------------------------------
        if (LCD_Alt > MaxAltitude) then
            MaxAltitude = LCD_Alt
        end
    -------------------------------------------------------------------------------------------------------------
    
    -------------------------------- Calculates (max) Line Of Sight Distance ---------------------------------
        local a = math.floor(LCD_Alt)
        local b = math.floor(HomeToPlaneDistance)
        LoSDistance = math.floor(math.sqrt((a * a) + (b * b)))
        if LoSDistance > MaxLoS then
            MaxLoS = LoSDistance
        end
    
    ------------------------------ Checks if valid GPS data is received -------------------------------------
     if  (type(thisWidget.gpsLatLong) ~= "table") then
        lcd.drawBitmap(thisWidget.map.bmp.xlarge, thisWidget.zone.x -10, thisWidget.zone.y -10)
        lcd.setColor(CUSTOM_COLOR, lcd.RGB(255,0,0))
        lcd.drawFilledRectangle(0, 239, 480, 33, SOLID) 
        lcd.drawText( 120, 236, "No GPS SIGNAL", DBLSIZE + CUSTOM_COLOR + SHADOWED)
        return
    end
    
    ------------ Calculates Heading Bearing from previous and new location of the plane ----------------------
      if (LCD_Lat ~= TempLat) and (LCD_Long ~= TempLong) then
        Bearing = CalcBearing(TempLat,TempLong,LCD_Lat,LCD_Long)
        TempLat = LCD_Lat
        TempLong = LCD_Long
      end
      headingDeg = Bearing or 0
    
    
    
    -----------------------------------------LCD ROUTINES -------------------------------------------------- 
    --                     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
     
     
    -- Preset info
        if LCD_Lat > 0 then
            NS = "N"
        else
            NS = "S"
        end
    
        if LCD_Long > 0 then
            EW = "E"
        else
            EW = "W"
        end
      
        if ImperialSet == 1 then
            FM  = "ft"
            SPD = "mph"
        else
            FM  = "m"
            SPD = "km/h"
        end
     
     
    --draw background
      lcd.drawBitmap(thisWidget.map.bmp[thisWidget.map.current], thisWidget.zone.x -10, thisWidget.zone.y -10)
     
    
    -- Draw nofly zone line -- in RED color
      lcd.setColor(CUSTOM_COLOR, lcd.RGB(248,0,0))
    -- ********************************************
    -- polygon no-fly update
    -- ********************************************
    --  disable no-fly line drawing
    --  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)
    -- draw polygon--
        local tmp = thisWidget.map.poly[thisWidget.map.current]
        for i = 1, #thisWidget.map.poly[thisWidget.map.current]-1  do
            lcd.drawLine(tmp[i][1],tmp[i][2],tmp[i+1][1],tmp[i+1][2], SOLID, CUSTOM_COLOR)
        end
        local k = #thisWidget.map.poly[thisWidget.map.current]
        lcd.drawLine(tmp[k][1],tmp[k][2],tmp[1][1],tmp[1][2], SOLID, CUSTOM_COLOR)
    -- ********************************************
    -- END OF polygon no-fly update
    -- ********************************************
     
     
      if PlaneVisible == 1 then
      -- Draws plane --
        lcd.setColor(CUSTOM_COLOR, lcd.RGB(248,252,0))
        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)
      end
    
    -- Draws the Windsock as Homepoint & display Plane direction angle from Homepoint
      if HomeVisible == 1 then
        if DrawSock == 1 then
          lcd.drawBitmap(WindSock, HomePosx-16, HomePosy-16, 50)
          lcd.setColor(CUSTOM_COLOR, lcd.RGB(248,0,248))
          local SockFlags = CUSTOM_COLOR + SMLSIZE + SHADOWED
          local SockX = HomePosx
          local SockY = HomePosy
          if SockX > 470 then
            SockFlags = SockFlags + RIGHT
          end
          if SockY < 10 then
            SockY = SockY + 10
          elseif SockY > 256 then
            SockY = SockY - 10
          end
          lcd.drawText(SockX, SockY, math.floor(HomeToPlaneBearing).."deg", SockFlags)
        end
      end
    
      if PlaneVisible == 1 and HomeVisible == 1 then
      -- Enables a Line of Sight line when homeposition has been set, and enabled in Widget config menu
        if (HomeSet == 0) and (LosLineSet == 1) then
          lcd.setColor(CUSTOM_COLOR, lcd.RGB(0, 252, 0))
          lcd.drawLine(x,y,HomePosx,HomePosy, DOTTED, CUSTOM_COLOR)
          local MidLosLineX = ((x + HomePosx)/2)
          local MidLosLineY = ((y + HomePosy)/2)
          local LosFlags = CUSTOM_COLOR + SMLSIZE + SHADOWED
          if MidLosLineX > 470 then
            LosFlags = LosFlags + RIGHT
          end
          if MidLosLineY < 10 then
            MidLosLineY = MidLosLineY + 10
          elseif MidLosLineY > 256 then
            MidLosLineY = MidLosLineY - 10
          end
          lcd.setColor(CUSTOM_COLOR, WHITE)
          lcd.drawText(MidLosLineX, MidLosLineY, math.floor(HomeToPlaneDistance)..FM , LosFlags)
        end
      else
        if PlaneVisible == 0 then
          lcd.setColor(CUSTOM_COLOR, lcd.RGB(255,0,0))
          lcd.drawText( 120, 120, "OUT OF RANGE", DBLSIZE + CUSTOM_COLOR + SHADOWED)
        end
      end
     
      lcd.drawFilledRectangle(0, 239, 480, 33, GREY_DEFAULT)
    
    -- Draws all flight information on screen --
     lcd.setColor(CUSTOM_COLOR, lcd.RGB(248,252,0))
    
      lcd.drawText(10, 239, "Speed: "..math.floor(LCD_Speed)..SPD, CUSTOM_COLOR + SMLSIZE + SHADOWED) 
      lcd.drawText(10, 255, "Max: "..math.floor(MaxSpeed)..SPD , CUSTOM_COLOR + SMLSIZE + SHADOWED) 
     
      lcd.drawText(130, 239, "Alt: "..math.floor(LCD_Alt)..FM, CUSTOM_COLOR + SMLSIZE + SHADOWED) 
      lcd.drawText(130, 255, "Max: "..math.floor(MaxAltitude)..FM , CUSTOM_COLOR + SMLSIZE + SHADOWED) 
     
      lcd.drawText(240, 239, "Dist: "..math.floor(HomeToPlaneDistance)..FM, CUSTOM_COLOR + SMLSIZE + SHADOWED)
      lcd.drawText(240, 255, "Max: "..math.floor(MaxDistance)..FM , CUSTOM_COLOR + SMLSIZE + SHADOWED)
     
      lcd.drawText(360, 239, "LoS: "..math.floor(LoSDistance)..FM, CUSTOM_COLOR + SMLSIZE + SHADOWED)
      lcd.drawText(360, 255, "Max: "..math.floor(MaxLoS)..FM , CUSTOM_COLOR + SMLSIZE + SHADOWED)
    
      if LCD_Sats > 0  then
        lcd.drawText(10, 32, "Satellites: "..math.floor(LCD_Sats), CUSTOM_COLOR + SMLSIZE + SHADOWED)
      end
    
      lcd.drawText(10, 16, "Heading: "..math.floor(headingDeg).."deg" , CUSTOM_COLOR + SMLSIZE + SHADOWED)
      lcd.drawText(10, 0, "Lat: "..NS..math.abs(LCD_Lat).." / Lon: "..EW..math.abs(LCD_Long), CUSTOM_COLOR + SMLSIZE +SHADOWED)
     
      lcd.drawText(470, 0, Version , CUSTOM_COLOR + SMLSIZE + RIGHT + SHADOWED)
    
    end
    return { name="Map", options=options, create=create, update=update, background=background, refresh=refresh }
     
    Laatst bewerkt: 14 jan 2020
  12. toostbeek

    toostbeek

    Lid geworden:
    6 dec 2014
    Berichten:
    1.403
    Wat mooi om te zien dat dit zich doorontwikkeld!
     
  13. Phaedra

    Phaedra

    Lid geworden:
    20 aug 2011
    Berichten:
    502
    Locatie:
    omgeving Antwerpen
    Het is dan ook een schitterend script, de moeite waard om aan mee te helpen. Dit is dan maar mijn "dankjewel" voor het werk dat al gedaan was :)
    Ik ga hier alleszins heel veel aan hebben in de toekomst, gezien de limitaties die wij hebben op ons vliegterrein. Die zijn niet altijd makkelijk na te leven als je met een zwever in thermiek hoger en hoger klimt, en dankzij dit script wordt dat iets makkelijker.
    Blij dat ik mijn steentje kan bijdragen.....
     
  14. Hobby4Life

    Hobby4Life

    Lid geworden:
    20 nov 2009
    Berichten:
    1.329
    Locatie:
    Avenhorn, NL
    Dit gaat lekker zo :), zet ook even je naam boven in de code.. zo weet iedereen wie er aan meegewerkt heeft.. :)

    Vraagje aan ieder..

    Netzoals Tonnie gebruik ik de bn-220(gps) + ms5611(baro).
    Ik gebruik deze combo op vrijwel alle ontvangers die er van frsky met smartport zijn.

    Nu merk ik veel dat de hoogte meting af en toen de pan uit knalt.. en ik zomaar ineens op 6km hoogte gevlogen heb.
    Haal ik de GPS module eruit en compile ik de boel zonder GPS functie.. dan functioneerd de Baro perfect.. (beter zelfs!!!)

    Merken jullie dat ook, mits jullie deze combo gebruiken?
     
  15. toostbeek

    toostbeek

    Lid geworden:
    6 dec 2014
    Berichten:
    1.403
    Ik heb dat nog nooit gehad eigenlijk. Ik lees ook regelmatig mijn logjes uit dus ik had het wel moeten merken anders.
     
  16. Hobby4Life

    Hobby4Life

    Lid geworden:
    20 nov 2009
    Berichten:
    1.329
    Locatie:
    Avenhorn, NL
    Ik moet erbij zeggen dat ik het gemerkt heb na de overgang naar otx v2.3.x
     
  17. Phaedra

    Phaedra

    Lid geworden:
    20 aug 2011
    Berichten:
    502
    Locatie:
    omgeving Antwerpen
    Nog enkele wijzigingen aangebracht, voornamelijk esthetisch:
    1) op de kaart die getoond wordt met de "NO GPS DATA" (voor het model actief is) toon ik ook de no-fly zone, en de versie van het script
    2) de zijden van de polygoon die samenvallen met de rand van het scherm worden niet meer getekend; deze zijden dienen alleen om de polygoon te sluiten, en als je die lijn overschrijdt wordt er uitgezoomd
    3) wat algemene opkuis van de code, rommeltjes weggehaald, commentaar toegevoegd
    4) de versie werd niet correct weergegeven op het scherm; ik heb van die variabele een lokale gemaakt, en dan werkt het correct.

    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.                                                             #
    ---- #                                                                                                        #
    ---- # Original idea and credits goes to Tonnie Oostbeek (Tonnie78)                                             #
    ---- #                                                                                                        #
    ---- # Revised by Björn Pasteuning / Hobby4life 2019                                                          #
    ---- #            Phaedra Degreef - polygon shaped no-fly zone detection added                                #
    ---- #                                                                                                        #
    ---- # Changelog:                                                                                             #
    ---- #                                                                                                        #
    ---- # v1.6 - Added RSSI detect for noFlyzone alarm function                                                  #
    ---- # v1.7 - Added posibility to select maps with GV8                                                        #
    ---- # v1.8 - Added posibolity to select Heading/Bearing input with GV7                                       #
    ---- #        0 = Calculate, 1 = Use Sensor input                                                             #
    ---- # v1.9 - Added Reset function from a Source to reset all max values                                      #
    ---- # v1.9a- Small fix in reset function                                                                     #
    ---- # v2.0 - Added Satellite indicator                                                                       #
    ---- # v2.1 - 1) HomePoint indicator / will show after a sat fix...                                           #
    ---- #        2) Line of sight line added, can be turned on and off in widget settings                        #
    ---- #        3) NoFlyZone line color is fixed to RED                                                         #
    ---- #        4) PlaneColor is fixed to YELLOW                                                                #
    ---- #        5) Map now selectable from Widget Settings page                                                 #
    ---- # v2.3 - Cleaned up code, fixed NIL issue in LCD draw routines                                           #
    ---- # v2.4 - Added LoS distance in middle of LoSLine, and added bearing indicator from home to plane         #
    ---- # v2.5 - Distance is now calculated from 2 coordinates                                                   #
    ---- # v2.6 - Heading is now only calculated from 2 upfollowing coordinates                                   #
    ---- # v2.7 - Automatic detection of Altitude sensor, Vario Altimeter or GPS Altimeter                        #
    ---- #        Vario Altimeter has priority over GPS Altimeter                                                 #
    ---- # v2.8 - 1) If Plane is outside view of maps, "OUT OF RANGE" Message will appear                         #
    ---- #        2) If HomePoint is outside zoom level, HomePoint is not visible (fix)                           #
    ---- # v2.9   Changed Layout and masked bottom area due new map download function                             #
    ---- #        Maps can now be generated and downloaded from: https://www.hobby4life.nl/mapgen.htm             #
    ---- # v3.0   Now creating maps is much easier, 5 maps are now used                                           #
    ---- #        File structure changed!, remove GPSmap widget, and reinstall widget..                           #
    ---- #        Sometimes it looks like no map is loaded.                                                       #
    ---- #        Go to widget settings -> MapSelect and toggle between 0 and another map and back to 0           #
    ---- #        then close widget and restart radio to take effect.                                             #
    ---- # v3.1   Added a no-fly zone polygon                                                                     #
    ---- #        Added polygon definition array to map definitions                                               #
    ---- #        Added checking of model position inside polygon, and callout in all flight modes used           #
    ---- ##########################################################################################################
    
    local Version     = "v3.1"  -- Current version
     
    TotalMaps   = 0       -- Enter the amount of maps loaded, starts with 0 !!!!
    
    
    local options = {
      { "ResetAll"  , SOURCE  , 1     },  --Define a source for trigger a reset of al max values
      { "Imperial"  , VALUE   , 0,0,1 },  --Toggle between Metric or Imperial notation, note that correct settings have to be set on the sensor page too!
      { "LosLine"   , VALUE   , 0,0,1 },  --Enable / Disable line of sight line between Home point and plane. 0 = off, 1 = on
      { "MapSelect" , VALUE   , 0,0,TotalMaps },  --Selects Map to load, needs model change or power cycle to take effect, 0 correnspondents to map0small.png, map0medium.png and map0large.png etc...
    }
    
    
    -- 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     = thisWidget.options.MapSelect or 0
    
    -- Declaration and preset of Global Widget Variables used in the entire scope --
      HomeLat     = 0
      HomeLong    = 0
      HomeSet     = 1
      DrawSock    = 0
      MaxDistance = 0
      MaxSpeed    = 0
      MaxAltitude = 0
      LoSDistance = 0
      MaxLoS      = 0
      TempLat     = 0
      TempLong    = 0
      HomePosx    = 0
      HomePosy    = 0
      HomeVisible = 1
     
      PlaneVisible= 0
     
      --create array containing all sensor ID's used for quicker retrieval
      local ID = {}
      ID.GPS        = getFieldInfo("GPS")  and getFieldInfo("GPS").id     or 0
      ID.GSpd       = getFieldInfo("GSpd") and getFieldInfo("GSpd").id or 0
      ID.Altimeter  = (getFieldInfo("Alt") and getFieldInfo("Alt").id) or (getFieldInfo("GAlt") and getFieldInfo("GAlt").id) or 0  -- Vario Altimeter has priority over GPS Altimeter
      ID.RSSI       = getFieldInfo("RSSI") and getFieldInfo("RSSI").id or 0
      ID.Tmp1       = getFieldInfo("Tmp1") and getFieldInfo("Tmp1").id or 0 -- used with OpenXsenor or sallites in view indicator
    
     
      --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={}, poly={}}
    --  local map = {North={},South={},West={},East={},wx={},wy={},zx={},zy={}}
    --LoadMap = 1
    
    if LoadMap == 0 then
     
    -- LAC Lier
    
    -- coordinates for the extra small map.
    map.North.xsmall = 51.114654
    map.South.xsmall = 51.113738
    map.West.xsmall = 4.561133
    map.East.xsmall = 4.563707
    -- No Fly Zone screen coordinates for extra small map--
    map.poly.xsmall = {{90,0}, {479,0}, {479,272}, {250,272}, {20,70}}
    
    -- coordinates for the small map.
    map.North.small = 51.115112
    map.South.small = 51.11328
    map.West.small = 4.559845
    map.East.small = 4.564995
    -- No Fly Zone screen coordinates for small map--
    map.poly.small = {{250,0}, {479,0}, {479,272}, {320,272}, {150,110}}
    
    -- coordinates for the medium map.
    map.North.medium = 51.116028
    map.South.medium = 51.112364
    map.West.medium = 4.55727
    map.East.medium = 4.56757
    -- No Fly Zone screen coordinates for medium map--
    map.poly.medium = {{280,0}, {479,0}, {479,272}, {360,272}, {195,125}}
    
    -- coordinates for the large map.
    map.North.large = 51.11786
    map.South.large = 51.110532
    map.West.large = 4.55212
    map.East.large = 4.57272
    -- No Fly Zone screen coordinates for large map--
    map.poly.large = {{300,0}, {479,0}, {479,272}, {380,272}, {210,120}}
    
    -- coordinates for the extra large map.
    map.North.xlarge = 51.121524
    map.South.xlarge = 51.106868
    map.West.xlarge = 4.541821
    map.East.xlarge = 4.583019
    -- No Fly Zone screen coordinates for extra large map--
    map.poly.xlarge = {{300,0}, {479,0}, {479,235}, {345,235}, {225,130}}
    
    
    
    end
    
        --add one bitmap per map size and set current map size
      map.bmp={}
      map.bmp.xsmall  = Bitmap.open("/widgets/GPSMap/maps/map"..LoadMap.."xsmall.png")
      map.bmp.small   = Bitmap.open("/widgets/GPSMap/maps/map"..LoadMap.."small.png")
      map.bmp.medium  = Bitmap.open("/widgets/GPSMap/maps/map"..LoadMap.."medium.png")
      map.bmp.large   = Bitmap.open("/widgets/GPSMap/maps/map"..LoadMap.."large.png")
      map.bmp.xlarge  = Bitmap.open("/widgets/GPSMap/maps/map"..LoadMap.."xlarge.png")
    
      WindSock = Bitmap.open("/widgets/GPSMap/icons/windsock.png")
      --HomeIcon = Bitmap.open("/widgets/GPSMap/home.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
    
    
    --***********************************************************************
    --*                           NO-FLY DETECTION FUNCTION                          *
    --***********************************************************************
    local function insidePolygon(polygon, planex, planey)
    --  local polygon = thisWidget.map.poly[thisWidget.map.current]
        local oddNodes = false
        local j = #polygon
        for i = 1, #polygon do
            if (polygon[i][2] < planey and polygon[j][2] >= planey or polygon[j][2] < planey and polygon[i][2] >= planey) then
                if (polygon[i][1] + ( planey - polygon[i][2] ) / (polygon[j][2] - polygon[i][2]) * (polygon[j][1] - polygon[i][1]) < planex) then
                    oddNodes = not oddNodes;
                end
            end
            j = i;
        end
        
       return oddNodes
    end
    
    
    --***********************************************************************
    --*                        BACKGROUND FUNCTION                          *
    --***********************************************************************
    local function background(thisWidget)
     
      ImperialSet = thisWidget.options.Imperial or 0
      --ExtHeadingSensor = thisWidget.options.ExtHdg or 0
      LosLineSet = thisWidget.options.LosLine or 0
    
     
      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.GSpd      = getFieldInfo("GSpd") and getFieldInfo("GSpd").id or 0
        thisWidget.ID.Altimeter = (getFieldInfo("Alt") and getFieldInfo("Alt").id) or (getFieldInfo("GAlt") and getFieldInfo("GAlt").id) or 0
        thisWidget.ID.RSSI      = getFieldInfo("RSSI") and getFieldInfo("RSSI").id or 0
        thisWidget.ID.Tmp1      = getFieldInfo("Tmp1") and getFieldInfo("Tmp1").id or 0
        model.setGlobalVariable(8,0,0)
        return
      end
     
      thisWidget.Speed      = getValue(thisWidget.ID.GSpd)
      thisWidget.Altitude   = getValue(thisWidget.ID.Altimeter)
      thisWidget.Rssi       = getValue(thisWidget.ID.RSSI)
      thisWidget.Sats       = getValue(thisWidget.ID.Tmp1)
    
     
      thisWidget.gpsLat     = thisWidget.gpsLatLong.lat
      thisWidget.gpsLong    = thisWidget.gpsLatLong.lon
     
      -- 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
        
      ------ Checks if Plane is visible in any map, otherwise disable plane view ------
      if thisWidget.gpsLat < North.xsmall and thisWidget.gpsLat > South.xsmall and thisWidget.gpsLong < East.xsmall and thisWidget.gpsLong > West.xsmall then
        thisWidget.map.current = "xsmall"
        PlaneVisible = 1
      elseif thisWidget.gpsLat < North.small and thisWidget.gpsLat > South.small and thisWidget.gpsLong < East.small and thisWidget.gpsLong > West.small then
        thisWidget.map.current = "small"
        PlaneVisible = 1
      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"
        PlaneVisible = 1
      elseif thisWidget.gpsLat < North.large and thisWidget.gpsLat > South.large and thisWidget.gpsLong < East.large and thisWidget.gpsLong > West.large then   
        thisWidget.map.current = "large"
        PlaneVisible = 1
      elseif thisWidget.gpsLat < North.xlarge and thisWidget.gpsLat > South.xlarge and thisWidget.gpsLong < East.xlarge and thisWidget.gpsLong > West.xlarge then   
        thisWidget.map.current = "xlarge"
        PlaneVisible = 1   
      else
        thisWidget.map.current = "large"
        PlaneVisible = 0 
      end
    
    -- Part for setting the correct zoomlevel ends here.
      North = North[thisWidget.map.current]
      South = South[thisWidget.map.current]
      East  = East[thisWidget.map.current]
      West  = West[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)
    
    -- Calculate  home position in relation to map. 
     
      if thisWidget.gpsLat ~= 0 and thisWidget.gpsLong ~= 0 then
        if HomeSet == 1 then
            HomeLat = thisWidget.gpsLat
            HomeLong = thisWidget.gpsLong
            HomeSet = 0
            DrawSock = 1
        end
          HomePosx = math.floor(480*((HomeLong - West)/(East - West)))
          HomePosy = math.floor(272*((North - HomeLat)/(North - South)))
          HomePosx = math.max(10,HomePosx)
          HomePosx = math.min(HomePosx,470)
          HomePosy = math.max(10,HomePosy)
          HomePosy = math.min(HomePosy,262)   
      end   
    
    ------ Checks if Homepoint is visible on the map otherwise disable view -------
      if HomeLat < North and HomeLat > South and HomeLong < East and HomeLong > West then
        HomeVisible = 1
      else
        HomeVisible = 0 
      end
    
    -------------------- Checks if plane crossed the nofly zone line and toggles GV9 Variable --------------
    
    -- ********************************************
    -- no-fly polygon update
    -- if a valid GPS position is received, and RSSI is valid, and position is inside polygon, set GVAR 9 to 1
    -- This is to avoid the alarm when receiver or GPS sensor is not ready
    -- *******************************************************************************************************
    local testpolygon = thisWidget.map.poly[thisWidget.map.current]
    
      if ((insidePolygon(testpolygon,thisWidget.x,thisWidget.y) == false) and (thisWidget.Rssi > 0) and
          (type(thisWidget.gpsLatLong) == "table") and (PlaneVisible == 1)) then
            -- set this GVAR in every flight mode that is used (in this case 3 flight modes are used)
        model.setGlobalVariable(8,0,1)
        model.setGlobalVariable(8,1,1)
        model.setGlobalVariable(8,2,1)
      else
        model.setGlobalVariable(8,0,0)
        model.setGlobalVariable(8,1,0)
        model.setGlobalVariable(8,2,0)
      end
    
    -- ********************************************
    -- END OF no-fly polygon update
    -- ********************************************
    
    end
    ---------------------------------------------------------------------------------------------------------
    
    --***********************************************************************
    --*                          SPECIAL FUNCTIONS                          *
    --***********************************************************************
    
    ----------------------- Function to calculated bearing angle between 2 coordinates ----------------------
    function CalcBearing(PrevLat,PrevLong,NewLat,NewLong)
      local yCalc = math.sin(math.rad(NewLong)-math.rad(PrevLong)) * math.cos(math.rad(NewLat))
      local xCalc = math.cos(math.rad(PrevLat)) * math.sin(math.rad(NewLat)) - math.sin(math.rad(PrevLat)) * math.cos(math.rad(NewLat)) * math.cos(math.rad(NewLat) - math.rad(PrevLat))
      local Bearing = math.deg(math.atan2(yCalc,xCalc))
      if Bearing < 0 then
        Bearing = 360 + Bearing
      end 
      return Bearing
    end
    
    ----------------------- Function to calculate distance between 2 coordinates -----------------------------
    function CalcDistance(PrevLat,PrevLong,NewLat,NewLong)
      local earthRadius = 0
      if ImperialSet == 1 then
        earthRadius = 20902000  --feet  --3958.8 miles
      else
        earthRadius = 6371000   --meters
      end
      local dLat = math.rad(NewLat-PrevLat)
      local dLon = math.rad(NewLong-PrevLong)
      PrevLat = math.rad(PrevLat)
      NewLat = math.rad(NewLat)
      local a = math.sin(dLat/2) * math.sin(dLat/2) + math.sin(dLon/2) * math.sin(dLon/2) * math.cos(PrevLat) * math.cos(NewLat)
      local c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
      return (earthRadius * c)
    end   
    
    function drawNoFly(thisWidget)
    -- do not draw the lines that are on any edge of the screen (but they are detected)
    -- draw polygon--
        lcd.setColor(CUSTOM_COLOR, lcd.RGB(255,0,0))
        local tmp = thisWidget.map.poly[thisWidget.map.current]
        for i = 1, #thisWidget.map.poly[thisWidget.map.current]-1  do
            if (tmp[i][1] < 479 or tmp[i+1][1] < 479) and (tmp[i][2] > 0 or tmp[i+1][2] > 0) then
              lcd.drawLine(tmp[i][1],tmp[i][2],tmp[i+1][1],tmp[i+1][2], SOLID, CUSTOM_COLOR)
            end
        end
    -- For some reason, the last segment must be drawn separately....
        local k = #thisWidget.map.poly[thisWidget.map.current]
        lcd.drawLine(tmp[k][1],tmp[k][2],tmp[1][1],tmp[1][2], SOLID, CUSTOM_COLOR)
    end
    
    
    --***********************************************************************
    --*                            UPDATE FUNCTION                          *
    --***********************************************************************
    local function update(thisWidget, options)
      thisWidget.options = options
    end
    
    --***********************************************************************
    --*                           REFRESH FUNCTION                          *
    --***********************************************************************
    local function refresh(thisWidget)
     
      local NS        = ""
      local EW        = ""
      local FM        = ""
      local SPD       = ""
      local LCD_Lat   = thisWidget.gpsLat or 0
      local LCD_Long  = thisWidget.gpsLong or 0
      local LCD_Speed = thisWidget.Speed or 0
      local LCD_Alt   = thisWidget.Altitude or 0
      local LCD_Sats  = thisWidget.Sats or 0 
      local xvalues   = { }
      local yvalues   = { }
      local x         = thisWidget.x or 0
      local y         = thisWidget.y or 0
     
        background(thisWidget)
     
      ------------------------------------------------------------------------------------------------------------
      RstAll = getValue(thisWidget.options.ResetAll) or 0
        
      if RstAll > 1000 then
        MaxDistance   = 0
        MaxSpeed      = 0
        MaxAltitude   = 0
        MaxLoS        = 0
        HomeSet       = 1
        DrawSock      = 0
        HomeLat       = thisWidget.gpsLat or 0
        HomeLong      = thisWidget.gpsLong or 0
      end 
     
       ------------ Calculates Heading and Distance from Home to Plane position -------------------------------------------
      local HomeToPlaneBearing = CalcBearing(HomeLat,HomeLong,LCD_Lat,LCD_Long) or 0
      local HomeToPlaneDistance = CalcDistance(HomeLat,HomeLong,LCD_Lat,LCD_Long) or 0
      --- Temporary fix for overflow HomeToPlaneDistance variable.. on Reset it sometimes overflows
      if HomeToPlaneDistance > 100000 then -- When overflowing with 100
        HomeToPlaneDistance = 0
      end
    ----------------------------------------- Calculates max Ground Distance ----------------------------------
        if (HomeToPlaneDistance > MaxDistance) then
                MaxDistance = HomeToPlaneDistance
      end
    -----------------------------------------------------------------------------------------------------------
    
    ------------------------------------------- Calculates max Speed ------------------------------------------
        if (LCD_Speed > MaxSpeed) then
            MaxSpeed = LCD_Speed
        end
    ----------------------------------------------------------------------------------------------------------
    
    ---------------------------------------- Calculates max Altitude -----------------------------------------
        if (LCD_Alt > MaxAltitude) then
            MaxAltitude = LCD_Alt
        end
    -------------------------------------------------------------------------------------------------------------
    
    -------------------------------- Calculates (max) Line Of Sight Distance ---------------------------------
        local a = math.floor(LCD_Alt)
        local b = math.floor(HomeToPlaneDistance)
        LoSDistance = math.floor(math.sqrt((a * a) + (b * b)))
        if LoSDistance > MaxLoS then
            MaxLoS = LoSDistance
        end
    
    ------------------------------ Checks if valid GPS data is received ------------------------------------- 
     if  (type(thisWidget.gpsLatLong) ~= "table") then
        lcd.drawBitmap(thisWidget.map.bmp.xlarge, thisWidget.zone.x -10, thisWidget.zone.y -10)
        drawNoFly(thisWidget)
        lcd.setColor(CUSTOM_COLOR, lcd.RGB(255,0,0))
        lcd.drawFilledRectangle(0, 239, 480, 33, SOLID)   
        lcd.drawText( 120, 236, "No GPS SIGNAL", DBLSIZE + CUSTOM_COLOR + SHADOWED)
        lcd.drawText(470, 0, Version , CUSTOM_COLOR + SMLSIZE + RIGHT + SHADOWED)
        return
    end
    
    ------------ Calculates Heading Bearing from previous and new location of the plane ----------------------
      if (LCD_Lat ~= TempLat) and (LCD_Long ~= TempLong) then
        Bearing = CalcBearing(TempLat,TempLong,LCD_Lat,LCD_Long)
        TempLat = LCD_Lat
        TempLong = LCD_Long
      end
      headingDeg = Bearing or 0
    
    
    
    -----------------------------------------LCD ROUTINES --------------------------------------------------   
    --                     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
     
     
    -- Preset info
        if LCD_Lat > 0 then
            NS = "N"
        else
            NS = "S"
        end
    
        if LCD_Long > 0 then
            EW = "E"
        else
            EW = "W"
        end
        
        if ImperialSet == 1 then
            FM  = "ft"
            SPD = "mph"
        else
            FM  = "m"
            SPD = "km/h"
        end 
     
     
    --draw background 
      lcd.drawBitmap(thisWidget.map.bmp[thisWidget.map.current], thisWidget.zone.x -10, thisWidget.zone.y -10)
    
    -- Draw nofly zone polygon -- in RED color
      lcd.setColor(CUSTOM_COLOR, lcd.RGB(248,0,0))
      drawNoFly(thisWidget)
     
      if PlaneVisible == 1 then
      -- Draws plane --
        lcd.setColor(CUSTOM_COLOR, lcd.RGB(248,252,0))
        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)
      end
    
    -- Draws the Windsock as Homepoint & display Plane direction angle from Homepoint
      if HomeVisible == 1 then
        if DrawSock == 1 then
          lcd.drawBitmap(WindSock, HomePosx-16, HomePosy-16, 50)
          lcd.setColor(CUSTOM_COLOR, lcd.RGB(248,0,248))
          local SockFlags = CUSTOM_COLOR + SMLSIZE + SHADOWED
          local SockX = HomePosx
          local SockY = HomePosy
          if SockX > 470 then
            SockFlags = SockFlags + RIGHT
          end
          if SockY < 10 then
            SockY = SockY + 10
          elseif SockY > 256 then
            SockY = SockY - 10
          end
          lcd.drawText(SockX, SockY, math.floor(HomeToPlaneBearing).."deg", SockFlags)
        end
      end
    
      if PlaneVisible == 1 and HomeVisible == 1 then
      -- Enables a Line of Sight line when homeposition has been set, and enabled in Widget config menu
        if (HomeSet == 0) and (LosLineSet == 1) then
          lcd.setColor(CUSTOM_COLOR, lcd.RGB(0, 252, 0))
          lcd.drawLine(x,y,HomePosx,HomePosy, DOTTED, CUSTOM_COLOR)
          local MidLosLineX = ((x + HomePosx)/2)
          local MidLosLineY = ((y + HomePosy)/2)
          local LosFlags = CUSTOM_COLOR + SMLSIZE + SHADOWED
          if MidLosLineX > 470 then
            LosFlags = LosFlags + RIGHT
          end
          if MidLosLineY < 10 then
            MidLosLineY = MidLosLineY + 10
          elseif MidLosLineY > 256 then
            MidLosLineY = MidLosLineY - 10
          end
          lcd.setColor(CUSTOM_COLOR, WHITE)
          lcd.drawText(MidLosLineX, MidLosLineY, math.floor(HomeToPlaneDistance)..FM , LosFlags)
        end
      else
        if PlaneVisible == 0 then
          lcd.setColor(CUSTOM_COLOR, lcd.RGB(255,0,0))
          lcd.drawText( 120, 120, "OUT OF RANGE", DBLSIZE + CUSTOM_COLOR + SHADOWED)
          lcd.drawText(470, 0, Version , CUSTOM_COLOR + SMLSIZE + RIGHT + SHADOWED)
        end
      end 
     
      lcd.drawFilledRectangle(0, 239, 480, 33, GREY_DEFAULT)
    
    -- Draws all flight information on screen --
     lcd.setColor(CUSTOM_COLOR, lcd.RGB(248,252,0))
    
      lcd.drawText(10, 239, "Speed: "..math.floor(LCD_Speed)..SPD, CUSTOM_COLOR + SMLSIZE + SHADOWED)   
      lcd.drawText(10, 255, "Max: "..math.floor(MaxSpeed)..SPD , CUSTOM_COLOR + SMLSIZE + SHADOWED)   
     
      lcd.drawText(130, 239, "Alt: "..math.floor(LCD_Alt)..FM, CUSTOM_COLOR + SMLSIZE + SHADOWED)   
      lcd.drawText(130, 255, "Max: "..math.floor(MaxAltitude)..FM , CUSTOM_COLOR + SMLSIZE + SHADOWED)   
     
      lcd.drawText(240, 239, "Dist: "..math.floor(HomeToPlaneDistance)..FM, CUSTOM_COLOR + SMLSIZE + SHADOWED)
      lcd.drawText(240, 255, "Max: "..math.floor(MaxDistance)..FM , CUSTOM_COLOR + SMLSIZE + SHADOWED)
     
      lcd.drawText(360, 239, "LoS: "..math.floor(LoSDistance)..FM, CUSTOM_COLOR + SMLSIZE + SHADOWED)
      lcd.drawText(360, 255, "Max: "..math.floor(MaxLoS)..FM , CUSTOM_COLOR + SMLSIZE + SHADOWED)
    
      if LCD_Sats > 0  then
        lcd.drawText(10, 32, "Satellites: "..math.floor(LCD_Sats), CUSTOM_COLOR + SMLSIZE + SHADOWED) 
      end
    
      lcd.drawText(10, 16, "Heading: "..math.floor(headingDeg).."deg" , CUSTOM_COLOR + SMLSIZE + SHADOWED) 
      lcd.drawText(10, 0, "Lat: "..NS..math.abs(LCD_Lat).." / Lon: "..EW..math.abs(LCD_Long), CUSTOM_COLOR + SMLSIZE +SHADOWED)
     
      lcd.drawText(470, 0, Version , CUSTOM_COLOR + SMLSIZE + RIGHT + SHADOWED)
    
    end
    return { name="Map", options=options, create=create, update=update, background=background, refresh=refresh }
     
  18. gie

    gie

    Lid geworden:
    17 apr 2017
    Berichten:
    25
    Locatie:
    Belgie
    Dag allen.

    OpenTX2_3_4, Horus 12S, laatste versie van Phaedra.

    Heb een probleem wanneer ik een 2de vliegplein toevoeg (TotalMaps = 1) en in de widget setting de mapselect van 0 naar 1 zet.
    Met 1 vliegveld (gewoon de omgeving rond thuisadres) doet het programma het prima!
    Hieronder een afbeelding Companion van het scherm met 1 vliegveld.
    De 2de afbeelding is er een van de foutboodschap (op lijn 420 bij mij) in de function drawNoFly(thisWidget)
    for i = 1, #thisWidget.map.poly[thisWidget.map.current]-1 do

    In de Horus 12 krijg ik een gelijkaardige boodschap en gaat dan 'hangen' ...

    upload_2020-1-17_18-14-17.png



    upload_2020-1-17_18-14-49.png
     
  19. gie

    gie

    Lid geworden:
    17 apr 2017
    Berichten:
    25
    Locatie:
    Belgie
    Dag allen, vergeet mijn vorige citaat.
    Had een fout gemaakt bij het kopiëren van de coördinaten van het 2de vliegveld.:hammer:

    Sorry Phaedra, je laatste versie doet het prima!:worship:
     
  20. Phaedra

    Phaedra

    Lid geworden:
    20 aug 2011
    Berichten:
    502
    Locatie:
    omgeving Antwerpen
    Ik ging daar vanavond eens naar kijken, maar je was me al voor.
    Uit de foutmeding af te leiden dacht ik inderdaad aan ontbrekende gegevens. Als je me het stuk van je code (waar je de coordinaten was vergeten) even kan doorgeven, dan kan ik eens kijken of dit soort problemen niet eleganter kan opgelost worden in de code, met een degelijke foutmelding op het scherm (ipv cryptische meldingen zoals jij kreeg).

    Ben benieuwd naar jouw ervaringen met dit script; ik heb zelf nog niet veel gelegenheid gehad om het in vlucht te testen.
     

Deel Deze Pagina