GPS Widget voor FrSky Horus

Nee er wordt berekend aan welke kant vancde lijn je zit. Op basis daarvan verandert de waarde van de global variabele gv8.

Bij mij is 0 goed en 1 no flight zone. Dit wordt getriggert door een logic switch in OpenTx buiten dit script. In jou geval zal dat net andersom zijn. Dus Gv8 = 0 = noflightzone GV8 = 1 = Geen waarschuwing.

Logische schakelaar aanmaken met a = x GV8 = 1

Duidelijk :)

Ik zal nu eens kijken of meerdere maps kan maken, en via de widget instellingen kan selecteren.. tussen 1 en 10..

map1a
map1b
map1c

map2a
map2b
map2c

etc etc :-)
 
Laatst bewerkt:
Grappig, ik heb in het verleden wel eens bedacht dat dit op het veld in Enkhuizen ook geschikt zou zijn om vliegen boven de paarden te voorkomen [emoji3][emoji3][emoji3]

Wat is de distance? Tot waar bedoel ik?
 
Duidelijk :)

Ik zal nu eens kijken of meerdere maps kan maken, en via de widget instellingen kan selecteren.. tussen 1 en 10..

map1a
map1b
map1c

map2a
map2b
map2c

etc etc :-)
Dat kiezen tussen verschillende maps zou mooi zijn. Als je hulp nodig hebt, dan help ik graag.

Het zou mooi zijn om de Widget verder uit te breiden voor alle velden in Nederland.

Laden van de maps uit een specifieke folder op de SD kaart en de data lezen uit een tekstbestand?
 
Het zou mooi wezen al ik snap hoe git werkt.. kunnen we daar in verder werken.

Dit is mijn versie so far.

Wat betreft de extra mappen toevoeging.. ik zou echt niet weten hoe een externe file uit te lezen qua data.

Code:
---- #########################################################################
---- #                                                                       #
---- # GPS Widget for FrSky Horus                                                  #
-----#                                                                       #
---- # License GPLv3: http://www.gnu.org/licenses/gpl-3.0.html               #
---- #                                                                       #
---- # This program is free software; you can redistribute it and/or modify  #
---- # it under the terms of the GNU General Public License version 3 as     #
---- # published by the Free Software Foundation.                            #
---- #                                                                       #
---- # Rev 0.1                                                                                         #
---- # Tonnie Oostbeek                                                                                  #
---- #                                                                       #
---- #########################################################################


local options = {
  { "TextColor", COLOR, Black },
  { "Imperial", BOOL, 0 },
}


-- in the create function you add all shared variables to the array containing the widget data ('thisWidget')
local function create(zone, options)
  local thisWidget  = { zone=zone, options=options}
 
  --create array containing all sensor ID's used for quicker retrieval
  local ID = {}
  ID.GPS = getFieldInfo("GPS") and getFieldInfo("GPS").id    or 0
  ID.Hdg = getFieldInfo("Hdg") and getFieldInfo("Hdg").id or 0
  ID.GSpd = getFieldInfo("GSpd") and getFieldInfo("GSpd").id or 0
  ID.GDis = getFieldInfo("GDis") and getFieldInfo("GDis").id or 0
  ID.GAlt = getFieldInfo("GAlt") and getFieldInfo("GAlt").id or 0
 
  --add ID to thisWidget
  thisWidget.ID = ID   

  --create array containing all map info per map size
  local map = {North={},South={},West={},East={},wx={},wy={},zx={},zy={}}
        
  -- coordinates for the small map.
  map.North.small = 52.734818
  map.South.small = 52.731422
  map.West.small = 5.273051
  map.East.small = 5.283480
  -- No Fly Zone screen coordinates for small map--
  map.wx.small = 0
  map.wy.small = 183
  map.zx.small = 261
  map.zy.small = 272

  -- coordinates for the medium map.
  map.North.medium = 52.736097
  map.South.medium = 52.730953
  map.West.medium = 5.270331
  map.East.medium = 5.286034
  -- No Fly Zone screen coordinates for medium map--
  map.wx.medium = 0
  map.wy.medium = 153
  map.zx.medium = 323
  map.zy.medium = 272

  --coordinates for the largest map.
  map.North.large = 52.737878
  map.South.large = 52.730145
  map.West.large = 5.266206
  map.East.large = 5.289811
  -- No Fly Zone screen coordinates for large map--
  map.wx.large = 0
  map.wy.large = 121
  map.zx.large = 354
  map.zy.large = 272
        
  --add one bitmap per map size and set current map size
  map.bmp={}
  map.bmp.small = Bitmap.open("/Widgets/Mapnew/map.png")
  map.bmp.medium = Bitmap.open("/Widgets/Mapnew/map1.png")
  map.bmp.large = Bitmap.open("/Widgets/Mapnew/map2.png")
 
  --set current size
  map.current = "large"

  --add the map array to thisWidget
  thisWidget.map = map   
 
  --return the thisWidget array to the opentx API, containing all data to be shared across functions
  return thisWidget
end

local function background(thisWidget)

  ImperialSet = thisWidget.options.Imperial
 
  thisWidget.gpsLatLong = getValue(thisWidget.ID.GPS)
  if  (type(thisWidget.gpsLatLong) ~= "table") then
    thisWidget.ID.GPS = getFieldInfo("GPS") and getFieldInfo("GPS").id    or 0
    thisWidget.ID.Hdg = getFieldInfo("Hdg") and getFieldInfo("Hdg").id or 0
    thisWidget.ID.GSpd = getFieldInfo("GSpd") and getFieldInfo("GSpd").id or 0
    thisWidget.ID.GDis = getFieldInfo("GDis") and getFieldInfo("GDis").id or 0
    thisWidget.ID.GAlt = getFieldInfo("GAlt") and getFieldInfo("GAlt").id or 0
    model.setGlobalVariable(8,0,0)
    return
  end
 
  thisWidget.Distance= getValue(thisWidget.ID.GDis) 
  thisWidget.headingDeg= getValue(thisWidget.ID.Hdg)
  thisWidget.Speed= getValue(thisWidget.ID.GSpd)
  thisWidget.Altitude = getValue(thisWidget.ID.GAlt)
  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
    
  if thisWidget.gpsLat < North.small and thisWidget.gpsLat > South.small and thisWidget.gpsLong < East.small and thisWidget.gpsLong > West.small then   
    thisWidget.map.current = "small"
  elseif thisWidget.gpsLat < North.medium and thisWidget.gpsLat > South.medium and thisWidget.gpsLong < East.medium and thisWidget.gpsLong > West.medium then   
    thisWidget.map.current = "medium"
  else   
    thisWidget.map.current = "large"
  end

-- Part for setting the correct zoomlevel ends here.

-- Calculate Position in relation to map.

  North = North[thisWidget.map.current]
  South = South[thisWidget.map.current]
  East = East[thisWidget.map.current]
  West = West[thisWidget.map.current]
  local wx = thisWidget.map.wx[thisWidget.map.current]
  local wy = thisWidget.map.wy[thisWidget.map.current]
  local zx = thisWidget.map.zx[thisWidget.map.current]
  local zy = thisWidget.map.zy[thisWidget.map.current]


  thisWidget.x = math.floor(480*((thisWidget.gpsLong - West)/(East - West)))
  thisWidget.y = math.floor(272*((North - thisWidget.gpsLat)/(North - South)))

  thisWidget.x=math.max(10,thisWidget.x)
  thisWidget.x=math.min(thisWidget.x,470)

  thisWidget.y=math.max(10,thisWidget.y)
  thisWidget.y=math.min(thisWidget.y,262)

  if ((thisWidget.x - wx)*(zy-wy))-((thisWidget.y - wy)*(zx-wx)) < 0 then
    model.setGlobalVariable(8,0,0)
  else
    model.setGlobalVariable(8,0,1)
  end

end

local function update(thisWidget, options)
  thisWidget.options = options
end

local function refresh(thisWidget)
  background(thisWidget)

  if  (type(thisWidget.gpsLatLong) ~= "table") then
    lcd.drawBitmap(thisWidget.map.bmp.large, thisWidget.zone.x -10, thisWidget.zone.y -10)
    lcd.setColor(CUSTOM_COLOR, lcd.RGB(255,0,0))
    lcd.drawText( 120, 130, "No GPS SIGNAL", DBLSIZE, CUSTOM_COLOR)
    return
  end

  local xvalues = { }
  local yvalues = { }
  local headingDeg = thisWidget.headingDeg
  local x = thisWidget.x
  local y = thisWidget.y
--                     A
--                     |
--                     |
-- C   _________________|___________________  D
--                     |
--                     |
--                     |
--                     |
--                     |
--                     |
--                     |
--                E ---|--- F
--                     B


  xvalues.ax = x + (4 * math.sin(math.rad(headingDeg)))                             -- front of fuselage x position
  yvalues.ay = y - (4 * math.cos(math.rad(headingDeg)))                             -- front of fuselage y position
  xvalues.bx = x - (7 * math.sin(math.rad(headingDeg)))                             -- rear of fuselage x position
  yvalues.by = y + (7 * math.cos(math.rad(headingDeg)))                             -- rear of fuselage y position
  xvalues.cx = x + (10 * math.cos(math.rad(headingDeg)))                             -- left wingtip x position
  yvalues.cy = y + (10 * math.sin(math.rad(headingDeg)))                            -- left wingtip y position
  xvalues.dx = x - (10 * math.cos(math.rad(headingDeg)))                            -- right wingtip x position
  yvalues.dy = y - (10 * math.sin(math.rad(headingDeg)))                            -- right wingtip y position
  xvalues.ex = x - ((7 * math.sin(math.rad(headingDeg))) + (3 * math.cos(math.rad(headingDeg))))    -- left tailwing tip x position
  yvalues.ey = y + ((7 * math.cos(math.rad(headingDeg))) - (3 * math.sin(math.rad(headingDeg))))    -- left tailwing tip y position
  xvalues.fx = x - ((7 * math.sin(math.rad(headingDeg))) - (3 * math.cos(math.rad(headingDeg))))    -- right tailwing tip x position
  yvalues.fy = y + ((7 * math.cos(math.rad(headingDeg))) + (3 * math.sin(math.rad(headingDeg))))    -- right tailwing tip y position
 
 
--draw background 
  lcd.drawBitmap(thisWidget.map.bmp[thisWidget.map.current], thisWidget.zone.x -10, thisWidget.zone.y -10)

--draw info

    if thisWidget.gpsLat > 0 then
        NS = "N"
    else
        NS = "S"
    end

    if thisWidget.gpsLong > 0 then
        EW = "E"
    else
        EW = "W"
    end
    
    if ImperialSet == 1 then
        FM = "ft"
        FMx = "miles"
        SPD = "mph"
    else
        FM = "m"
        FMx = "Kilometers"
        SPD = "km/h"
    end

  lcd.setColor(CUSTOM_COLOR, WHITE)
 
  lcd.drawText(10, 5, "Speed: "..math.floor(thisWidget.Speed)..SPD , CUSTOM_COLOR  + SHADOWED)   
  lcd.drawText(10, 25, "Altitude: "..math.floor(thisWidget.Altitude)..FM , CUSTOM_COLOR  + SHADOWED)   
  lcd.drawText(180, 5, "Distance: "..math.floor(thisWidget.Distance)..FM , CUSTOM_COLOR + SHADOWED)

  lcd.drawText(460, 5, "Heading: "..math.floor(thisWidget.headingDeg).."deg" , CUSTOM_COLOR + RIGHT + SHADOWED)
 
  lcd.drawText(10, 247, "Lat:"..NS..math.abs(thisWidget.gpsLat).." / Lon:"..EW..math.abs(thisWidget.gpsLong), CUSTOM_COLOR + SMLSIZE +SHADOWED)
  lcd.drawText(460, 247, "X:"..thisWidget.x.." / Y:"..thisWidget.y , CUSTOM_COLOR + RIGHT + SMLSIZE + SHADOWED)
 
--draw plane 
  lcd.setColor(CUSTOM_COLOR, lcd.RGB(255,255,255))
  lcd.drawLine(xvalues.ax, yvalues.ay, xvalues.bx, yvalues.by, SOLID, CUSTOM_COLOR)
  lcd.drawLine(xvalues.cx, yvalues.cy, xvalues.dx, yvalues.dy, SOLID, CUSTOM_COLOR)
  lcd.drawLine(xvalues.ex, yvalues.ey, xvalues.fx, yvalues.fy, SOLID, CUSTOM_COLOR)

--draw noflightzone
  lcd.setColor(CUSTOM_COLOR, lcd.RGB(255,0,0))
  lcd.drawLine(thisWidget.map.wx[thisWidget.map.current], thisWidget.map.wy[thisWidget.map.current], thisWidget.map.zx[thisWidget.map.current], thisWidget.map.zy[thisWidget.map.current], SOLID, CUSTOM_COLOR)

end
return { name="Map", options=options, create=create, update=update, background=background, refresh=refresh }
 
Vreemd, zojuist de code vanuit de simulator in de zender geladen.. en de zender schiet direct in Emergency mode.. kan ook niet zien waar het fout gaat.. hmmmm
 
Wat me trouwens ook opviel is dat Heading niet weergegeven wordt, omdat deze geen standaard sensor output is van de GPS. waar komt die dan wel vandaan?

Ik ben bezig om er een extra map aan toe te voegen:

Het volgende heb ik als optie gemaakt:

Code:
  { "Map", VALUE, 1,1,2 },

Je kan nu uit max 2 mappen kiezen..

Alleen omdat alle init data in de "Create" function staan kom ik er ff niet uit hoe ik dit moet aanpakken.. want ik kan niet in deze functie bijvoorbeeld aanroepen:

Code:
if thisWidget.options.Map == 1 then

elseif thisWidget.options.Map == 2 then

end

Dit werk daar natuurlijk niet.
 
Laatst bewerkt:
Wat me trouwens ook opviel is dat Heading niet weergegeven wordt, omdat deze geen standaard sensor output is van de GPS. waar komt die dan wel vandaan?

Ik ben bezig om er een extra map aan toe te voegen:

Het volgende heb ik als optie gemaakt:

Code:
  { "Map", VALUE, 1,1,2 },

Je kan nu uit max 2 mappen kiezen..

Alleen omdat alle init data in de "Create" function staan kom ik er ff niet uit hoe ik dit moet aanpakken.. want ik kan niet in deze functie bijvoorbeeld aanroepen:

Code:
if thisWidget.options.Map == 1 then

elseif thisWidget.options.Map == 2 then

end

Dit werk daar natuurlijk niet.
Heading geen standaard sensor output?
Ik gebruik eigenlijk altijd een DIY GPS sensor op basis van OpenXsensor, maar ik dacht dat Heading ook standaard was bij de FrSky GPS. Maar ik zit de manual door te lezen nu en het staat er niet bij inderdaad.
 
@toostbeek

Inderdaad, deze wordt niet mee gestuurd met de Frsky GPS, er zal dus een berekening in moeten komen die tussen 2 coordinaten de hoek bepaald..

Bij deze de main.lua bijgevoegd als text file
 

Bijlagen

Zou je niet liever overstsppen op een OpenXsensor GPS. Goedkoper en completer.

Ik persoonlijk wel..voor mijn geen punt qua diy electronica.. daar werk ik zelf nu ook al mee met andere sensoren..

Alleen uit het oogpunt van mensen die daar geen kaas van gegeten hebben en kiezen voor standaard sensoren, is het wel handig om het universeel te maken..
De hoek van het vliegtuigje wordt er immers mee bepaald.



https://www.igismap.com/formula-to-...-angle-between-two-points-latitude-longitude/
 
Welke GPS gebruik je trouwens? ik heb hier een aantal ubloxen liggen, van X aantal jaar geleden.. niet te programmeren die dingen in Ucenter :-S
 
Tnx, ik had er zojuist eentje bij banggood gekocht.. UK warehouse had hem ook :-)

Ben ondertussen ook aan het kijken hoe ik tussen 2 coordinaten de bearing uit kan rekenen.. valt nog niet mee :-(
 
Daar zijn op het Internet wel voorbeelden van te vinden. Misschien hulp vragen van iemand met een nautische achtergrond?
 
Back
Top