Added EGM2008 world altitude correction.
This commit is contained in:
parent
e2cb57d1fb
commit
a2f04e23a6
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,18 @@
|
||||||
|
<PAMDataset>
|
||||||
|
<SRS>GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],UNIT["degree",0.017453292519943295769],AUTHORITY["EPSG","4326"]]</SRS>
|
||||||
|
<GeoTransform>-0.04166666666666666,0.08333333333333333,0,90.04166666666666666,0,-0.08333333333333333</GeoTransform>
|
||||||
|
<Metadata>
|
||||||
|
<MDI key="Description">WGS84 EGM2008, 5-minute grid</MDI>
|
||||||
|
<MDI key="URL">http://earth-info.nga.mil/GandG/wgs84/gravitymod/egm2008</MDI>
|
||||||
|
<MDI key="DateTime">2009-08-29 18:45:00</MDI>
|
||||||
|
<MDI key="MaxBilinearError">0.478</MDI>
|
||||||
|
<MDI key="RMSBilinearError">0.012</MDI>
|
||||||
|
<MDI key="MaxCubicError">0.294</MDI>
|
||||||
|
<MDI key="RMSCubicError">0.005</MDI>
|
||||||
|
<MDI key="Offset">-108</MDI>
|
||||||
|
<MDI key="Scale">0.003</MDI>
|
||||||
|
<MDI key="AREA_OR_POINT">Point</MDI>
|
||||||
|
<MDI key="Vertical_Datum">WGS84</MDI>
|
||||||
|
<MDI key="Tie_Point_Location">pixel_corner</MDI>
|
||||||
|
</Metadata>
|
||||||
|
</PAMDataset>
|
|
@ -0,0 +1,6 @@
|
||||||
|
0.08333333333333333
|
||||||
|
0
|
||||||
|
0
|
||||||
|
-0.08333333333333333
|
||||||
|
0
|
||||||
|
90
|
|
@ -4,7 +4,7 @@ package.name = sideband
|
||||||
package.domain = io.unsigned
|
package.domain = io.unsigned
|
||||||
|
|
||||||
source.dir = .
|
source.dir = .
|
||||||
source.include_exts = py,png,jpg,jpeg,webp,ttf,kv,pyi,typed,so,0,1,2,3,atlas,frag,html,css,js,whl,zip,gz,woff2,pdf,epub
|
source.include_exts = py,png,jpg,jpeg,webp,ttf,kv,pyi,typed,so,0,1,2,3,atlas,frag,html,css,js,whl,zip,gz,woff2,pdf,epub,pgm
|
||||||
source.include_patterns = assets/*,assets/fonts/*,share/*
|
source.include_patterns = assets/*,assets/fonts/*,share/*
|
||||||
source.exclude_patterns = app_storage/*,venv/*,Makefile,./Makefil*,requirements,precompiled/*,parked/*,./setup.py,Makef*,./Makefile,Makefile
|
source.exclude_patterns = app_storage/*,venv/*,Makefile,./Makefil*,requirements,precompiled/*,parked/*,./setup.py,Makef*,./Makefile,Makefile
|
||||||
|
|
||||||
|
|
|
@ -1798,7 +1798,7 @@ class SidebandApp(MDApp):
|
||||||
self.information_screen.ids.information_scrollview.effect_cls = ScrollEffect
|
self.information_screen.ids.information_scrollview.effect_cls = ScrollEffect
|
||||||
self.information_screen.ids.information_logo.icon = self.sideband.asset_dir+"/rns_256.png"
|
self.information_screen.ids.information_logo.icon = self.sideband.asset_dir+"/rns_256.png"
|
||||||
|
|
||||||
info = "This is "+self.root.ids.app_version_info.text+", on RNS v"+RNS.__version__+" and LXMF v"+LXMF.__version__+".\n\nHumbly build using the following open components:\n\n - [b]Reticulum[/b] (MIT License)\n - [b]LXMF[/b] (MIT License)\n - [b]KivyMD[/b] (MIT License)\n - [b]Kivy[/b] (MIT License)\n - [b]Python[/b] (PSF License)"+"\n\nGo to [u][ref=link]https://unsigned.io/donate[/ref][/u] to support the project.\n\nThe Sideband app is Copyright (c) 2024 Mark Qvist / unsigned.io\n\nPermission is granted to freely share and distribute binary copies of Sideband v"+__version__+" "+__variant__+", so long as no payment or compensation is charged for said distribution or sharing.\n\nIf you were charged or paid anything for this copy of Sideband, please report it to [b]license@unsigned.io[/b].\n\nTHIS IS EXPERIMENTAL SOFTWARE - SIDEBAND COMES WITH ABSOLUTELY NO WARRANTY - USE AT YOUR OWN RISK AND RESPONSIBILITY"
|
info = "This is "+self.root.ids.app_version_info.text+", on RNS v"+RNS.__version__+" and LXMF v"+LXMF.__version__+".\n\nHumbly build using the following open components:\n\n - [b]Reticulum[/b] (MIT License)\n - [b]LXMF[/b] (MIT License)\n - [b]KivyMD[/b] (MIT License)\n - [b]Kivy[/b] (MIT License)\n - [b]GeoidHeight[/b] (LGPL License)\n - [b]Python[/b] (PSF License)"+"\n\nGo to [u][ref=link]https://unsigned.io/donate[/ref][/u] to support the project.\n\nThe Sideband app is Copyright (c) 2024 Mark Qvist / unsigned.io\n\nPermission is granted to freely share and distribute binary copies of Sideband v"+__version__+" "+__variant__+", so long as no payment or compensation is charged for said distribution or sharing.\n\nIf you were charged or paid anything for this copy of Sideband, please report it to [b]license@unsigned.io[/b].\n\nTHIS IS EXPERIMENTAL SOFTWARE - SIDEBAND COMES WITH ABSOLUTELY NO WARRANTY - USE AT YOUR OWN RISK AND RESPONSIBILITY"
|
||||||
self.information_screen.ids.information_info.text = info
|
self.information_screen.ids.information_info.text = info
|
||||||
self.information_screen.ids.information_info.bind(on_ref_press=link_exec)
|
self.information_screen.ids.information_info.bind(on_ref_press=link_exec)
|
||||||
|
|
||||||
|
|
|
@ -168,6 +168,8 @@ class SidebandCore():
|
||||||
self.icon_macos = self.asset_dir+"/icon_macos.png"
|
self.icon_macos = self.asset_dir+"/icon_macos.png"
|
||||||
self.notification_icon = self.asset_dir+"/notification_icon.png"
|
self.notification_icon = self.asset_dir+"/notification_icon.png"
|
||||||
|
|
||||||
|
os.environ["TELEMETER_GEOID_PATH"] = os.path.join(self.asset_dir, "geoids")
|
||||||
|
|
||||||
if not os.path.isdir(self.app_dir+"/app_storage"):
|
if not os.path.isdir(self.app_dir+"/app_storage"):
|
||||||
os.makedirs(self.app_dir+"/app_storage")
|
os.makedirs(self.app_dir+"/app_storage")
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
|
import os
|
||||||
import time
|
import time
|
||||||
|
import mmap
|
||||||
|
import struct
|
||||||
import RNS
|
import RNS
|
||||||
from math import pi, sin, cos, acos, asin, tan, atan, atan2
|
from math import pi, sin, cos, acos, asin, tan, atan, atan2
|
||||||
from math import radians, degrees, sqrt
|
from math import radians, degrees, sqrt
|
||||||
|
@ -17,6 +20,7 @@ eccentricity_squared = 2*ellipsoid_flattening-pow(ellipsoid_flattening,2)
|
||||||
###############################
|
###############################
|
||||||
|
|
||||||
mean_earth_radius = (1/3)*(2*equatorial_radius+polar_radius)
|
mean_earth_radius = (1/3)*(2*equatorial_radius+polar_radius)
|
||||||
|
geoid_height = None
|
||||||
|
|
||||||
def geocentric_latitude(geodetic_latitude):
|
def geocentric_latitude(geodetic_latitude):
|
||||||
e2 = eccentricity_squared
|
e2 = eccentricity_squared
|
||||||
|
@ -290,19 +294,216 @@ def shared_radio_horizon(c1, c2,):
|
||||||
"antenna_distance": antenna_distance
|
"antenna_distance": antenna_distance
|
||||||
}
|
}
|
||||||
|
|
||||||
def ghtest():
|
def geoid_offset(lat, lon):
|
||||||
import pygeodesy
|
global geoid_height
|
||||||
from pygeodesy.ellipsoidalKarney import LatLon
|
if geoid_height == None:
|
||||||
ginterpolator = pygeodesy.GeoidKarney("./assets/geoids/egm2008-5.pgm")
|
geoid_height = GeoidHeight()
|
||||||
|
return geoid_height.get(lat, lon)
|
||||||
|
|
||||||
# Make an example location
|
def altitude_to_aamsl(alt, lat, lon):
|
||||||
lat=51.416422
|
if alt == None or lat == None or lon == None:
|
||||||
lon=-116.217151
|
return None
|
||||||
|
else:
|
||||||
|
return alt-geoid_offset(lat, lon)
|
||||||
|
|
||||||
|
######################################################
|
||||||
|
# GeoidHeight class by Kim Vandry <vandry@TZoNE.ORG> #
|
||||||
|
# Originally ported fromGeographicLib/src/Geoid.cpp #
|
||||||
|
# LGPLv3 License #
|
||||||
|
######################################################
|
||||||
|
|
||||||
|
class GeoidHeight(object):
|
||||||
|
c0 = 240
|
||||||
|
c3 = (
|
||||||
|
( 9, -18, -88, 0, 96, 90, 0, 0, -60, -20),
|
||||||
|
( -9, 18, 8, 0, -96, 30, 0, 0, 60, -20),
|
||||||
|
( 9, -88, -18, 90, 96, 0, -20, -60, 0, 0),
|
||||||
|
(186, -42, -42, -150, -96, -150, 60, 60, 60, 60),
|
||||||
|
( 54, 162, -78, 30, -24, -90, -60, 60, -60, 60),
|
||||||
|
( -9, -32, 18, 30, 24, 0, 20, -60, 0, 0),
|
||||||
|
( -9, 8, 18, 30, -96, 0, -20, 60, 0, 0),
|
||||||
|
( 54, -78, 162, -90, -24, 30, 60, -60, 60, -60),
|
||||||
|
(-54, 78, 78, 90, 144, 90, -60, -60, -60, -60),
|
||||||
|
( 9, -8, -18, -30, -24, 0, 20, 60, 0, 0),
|
||||||
|
( -9, 18, -32, 0, 24, 30, 0, 0, -60, 20),
|
||||||
|
( 9, -18, -8, 0, -24, -30, 0, 0, 60, 20),
|
||||||
|
)
|
||||||
|
|
||||||
|
c0n = 372
|
||||||
|
c3n = (
|
||||||
|
( 0, 0, -131, 0, 138, 144, 0, 0, -102, -31),
|
||||||
|
( 0, 0, 7, 0, -138, 42, 0, 0, 102, -31),
|
||||||
|
( 62, 0, -31, 0, 0, -62, 0, 0, 0, 31),
|
||||||
|
(124, 0, -62, 0, 0, -124, 0, 0, 0, 62),
|
||||||
|
(124, 0, -62, 0, 0, -124, 0, 0, 0, 62),
|
||||||
|
( 62, 0, -31, 0, 0, -62, 0, 0, 0, 31),
|
||||||
|
( 0, 0, 45, 0, -183, -9, 0, 93, 18, 0),
|
||||||
|
( 0, 0, 216, 0, 33, 87, 0, -93, 12, -93),
|
||||||
|
( 0, 0, 156, 0, 153, 99, 0, -93, -12, -93),
|
||||||
|
( 0, 0, -45, 0, -3, 9, 0, 93, -18, 0),
|
||||||
|
( 0, 0, -55, 0, 48, 42, 0, 0, -84, 31),
|
||||||
|
( 0, 0, -7, 0, -48, -42, 0, 0, 84, 31),
|
||||||
|
)
|
||||||
|
|
||||||
|
c0s = 372
|
||||||
|
c3s = (
|
||||||
|
( 18, -36, -122, 0, 120, 135, 0, 0, -84, -31),
|
||||||
|
(-18, 36, -2, 0, -120, 51, 0, 0, 84, -31),
|
||||||
|
( 36, -165, -27, 93, 147, -9, 0, -93, 18, 0),
|
||||||
|
(210, 45, -111, -93, -57, -192, 0, 93, 12, 93),
|
||||||
|
(162, 141, -75, -93, -129, -180, 0, 93, -12, 93),
|
||||||
|
(-36, -21, 27, 93, 39, 9, 0, -93, -18, 0),
|
||||||
|
( 0, 0, 62, 0, 0, 31, 0, 0, 0, -31),
|
||||||
|
( 0, 0, 124, 0, 0, 62, 0, 0, 0, -62),
|
||||||
|
( 0, 0, 124, 0, 0, 62, 0, 0, 0, -62),
|
||||||
|
( 0, 0, 62, 0, 0, 31, 0, 0, 0, -31),
|
||||||
|
(-18, 36, -64, 0, 66, 51, 0, 0, -102, 31),
|
||||||
|
( 18, -36, 2, 0, -66, -51, 0, 0, 102, 31),
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(self, name="egm2008-5.pgm"):
|
||||||
|
self.offset = None
|
||||||
|
self.scale = None
|
||||||
|
|
||||||
|
if "TELEMETER_GEOID_PATH" in os.environ:
|
||||||
|
geoid_dir = os.environ["TELEMETER_GEOID_PATH"]
|
||||||
|
else:
|
||||||
|
geoid_dir = "./"
|
||||||
|
|
||||||
|
pgm_path = os.path.join(geoid_dir, name)
|
||||||
|
RNS.log(f"Opening {pgm_path} as EGM for altitude correction", RNS.LOG_DEBUG)
|
||||||
|
with open(pgm_path, "rb") as f:
|
||||||
|
line = f.readline()
|
||||||
|
if line != b"P5\012" and line != b"P5\015\012":
|
||||||
|
raise Exception("No PGM header")
|
||||||
|
headerlen = len(line)
|
||||||
|
while True:
|
||||||
|
line = f.readline()
|
||||||
|
if len(line) == 0:
|
||||||
|
raise Exception("EOF before end of file header")
|
||||||
|
headerlen += len(line)
|
||||||
|
if line.startswith(b'# Offset '):
|
||||||
|
try:
|
||||||
|
self.offset = int(line[9:])
|
||||||
|
except ValueError as e:
|
||||||
|
raise Exception("Error reading offset", e)
|
||||||
|
elif line.startswith(b'# Scale '):
|
||||||
|
try:
|
||||||
|
self.scale = float(line[8:])
|
||||||
|
except ValueError as e:
|
||||||
|
raise Exception("Error reading scale", e)
|
||||||
|
elif not line.startswith(b'#'):
|
||||||
|
try:
|
||||||
|
self.width, self.height = list(map(int, line.split()))
|
||||||
|
except ValueError as e:
|
||||||
|
raise Exception("Bad PGM width&height line", e)
|
||||||
|
break
|
||||||
|
line = f.readline()
|
||||||
|
headerlen += len(line)
|
||||||
|
levels = int(line)
|
||||||
|
if levels != 65535:
|
||||||
|
raise Exception("PGM file must have 65535 gray levels")
|
||||||
|
if self.offset is None:
|
||||||
|
raise Exception("PGM file does not contain offset")
|
||||||
|
if self.scale is None:
|
||||||
|
raise Exception("PGM file does not contain scale")
|
||||||
|
|
||||||
|
if self.width < 2 or self.height < 2:
|
||||||
|
raise Exception("Raster size too small")
|
||||||
|
|
||||||
|
fd = f.fileno()
|
||||||
|
fullsize = os.fstat(fd).st_size
|
||||||
|
|
||||||
|
if fullsize - headerlen != self.width * self.height * 2:
|
||||||
|
raise Exception("File has the wrong length")
|
||||||
|
|
||||||
|
self.headerlen = headerlen
|
||||||
|
self.raw = mmap.mmap(fd, fullsize, mmap.MAP_SHARED, mmap.PROT_READ)
|
||||||
|
|
||||||
|
self.rlonres = self.width / 360.0
|
||||||
|
self.rlatres = (self.height - 1) / 180.0
|
||||||
|
self.ix = None
|
||||||
|
self.iy = None
|
||||||
|
|
||||||
|
def _rawval(self, ix, iy):
|
||||||
|
if iy < 0:
|
||||||
|
iy = -iy
|
||||||
|
ix += self.width/2
|
||||||
|
elif iy >= self.height:
|
||||||
|
iy = 2 * (self.height - 1) - iy
|
||||||
|
ix += self.width/2
|
||||||
|
if ix < 0:
|
||||||
|
ix += self.width
|
||||||
|
elif ix >= self.width:
|
||||||
|
ix -= self.width
|
||||||
|
|
||||||
|
return struct.unpack_from('>H', self.raw,
|
||||||
|
(iy * self.width + ix) * 2 + self.headerlen
|
||||||
|
)[0]
|
||||||
|
|
||||||
|
def get(self, lat, lon, cubic=True):
|
||||||
|
if lon < 0:
|
||||||
|
lon += 360
|
||||||
|
fy = (90 - lat) * self.rlatres
|
||||||
|
fx = lon * self.rlonres
|
||||||
|
iy = int(fy)
|
||||||
|
ix = int(fx)
|
||||||
|
fx -= ix
|
||||||
|
fy -= iy
|
||||||
|
if iy == self.height - 1:
|
||||||
|
iy -= 1
|
||||||
|
|
||||||
|
if ix != self.ix or iy != self.iy:
|
||||||
|
self.ix = ix
|
||||||
|
self.iy = iy
|
||||||
|
if not cubic:
|
||||||
|
self.v00 = self._rawval(ix, iy)
|
||||||
|
self.v01 = self._rawval(ix+1, iy)
|
||||||
|
self.v10 = self._rawval(ix, iy+1)
|
||||||
|
self.v11 = self._rawval(ix+1, iy+1)
|
||||||
|
else:
|
||||||
|
v = (
|
||||||
|
self._rawval(ix , iy - 1),
|
||||||
|
self._rawval(ix + 1, iy - 1),
|
||||||
|
self._rawval(ix - 1, iy ),
|
||||||
|
self._rawval(ix , iy ),
|
||||||
|
self._rawval(ix + 1, iy ),
|
||||||
|
self._rawval(ix + 2, iy ),
|
||||||
|
self._rawval(ix - 1, iy + 1),
|
||||||
|
self._rawval(ix , iy + 1),
|
||||||
|
self._rawval(ix + 1, iy + 1),
|
||||||
|
self._rawval(ix + 2, iy + 1),
|
||||||
|
self._rawval(ix , iy + 2),
|
||||||
|
self._rawval(ix + 1, iy + 2)
|
||||||
|
)
|
||||||
|
if iy == 0:
|
||||||
|
c3x = GeoidHeight.c3n
|
||||||
|
c0x = GeoidHeight.c0n
|
||||||
|
elif iy == self.height - 2:
|
||||||
|
c3x = GeoidHeight.c3s
|
||||||
|
c0x = GeoidHeight.c0s
|
||||||
|
else:
|
||||||
|
c3x = GeoidHeight.c3
|
||||||
|
c0x = GeoidHeight.c0
|
||||||
|
self.t = [
|
||||||
|
sum([ v[j] * c3x[j][i] for j in range(12) ]) / float(c0x)
|
||||||
|
for i in range(10)
|
||||||
|
]
|
||||||
|
if not cubic:
|
||||||
|
a = (1 - fx) * self.v00 + fx * self.v01
|
||||||
|
b = (1 - fx) * self.v10 + fx * self.v11
|
||||||
|
h = (1 - fy) * a + fy * b
|
||||||
|
else:
|
||||||
|
h = (
|
||||||
|
self.t[0] +
|
||||||
|
fx * (self.t[1] + fx * (self.t[3] + fx * self.t[6])) +
|
||||||
|
fy * (
|
||||||
|
self.t[2] + fx * (self.t[4] + fx * self.t[7]) +
|
||||||
|
fy * (self.t[5] + fx * self.t[8] + fy * self.t[9])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return self.offset + self.scale * h
|
||||||
|
|
||||||
# Get the geoid height
|
|
||||||
single_position=LatLon(lat, lon)
|
|
||||||
h = ginterpolator(single_position)
|
|
||||||
print(h)
|
|
||||||
|
|
||||||
# def tests():
|
# def tests():
|
||||||
# import RNS
|
# import RNS
|
||||||
|
@ -345,3 +546,19 @@ def ghtest():
|
||||||
# print("Euclidian = "+RNS.prettydistance(ed_own)+f" {fac*ed_own}")
|
# print("Euclidian = "+RNS.prettydistance(ed_own)+f" {fac*ed_own}")
|
||||||
# print("AzAlt = "+f" {aa[0]} / {aa[1]}")
|
# print("AzAlt = "+f" {aa[0]} / {aa[1]}")
|
||||||
# print("")
|
# print("")
|
||||||
|
|
||||||
|
# def ghtest():
|
||||||
|
# import pygeodesy
|
||||||
|
# from pygeodesy.ellipsoidalKarney import LatLon
|
||||||
|
# ginterpolator = pygeodesy.GeoidKarney("./assets/geoids/egm2008-5.pgm")
|
||||||
|
# # Make an example location
|
||||||
|
# lat=51.416422
|
||||||
|
# lon=-116.217151
|
||||||
|
# if geoid_height == None:
|
||||||
|
# geoid_height = GeoidHeight()
|
||||||
|
# h2 = geoid_height.get(lat, lon)
|
||||||
|
# # Get the geoid height
|
||||||
|
# single_position=LatLon(lat, lon)
|
||||||
|
# h1 = ginterpolator(single_position)
|
||||||
|
# print(h1)
|
||||||
|
# print(h2)
|
||||||
|
|
|
@ -5,7 +5,7 @@ import struct
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
from RNS.vendor import umsgpack as umsgpack
|
from RNS.vendor import umsgpack as umsgpack
|
||||||
from .geo import orthodromic_distance, euclidian_distance
|
from .geo import orthodromic_distance, euclidian_distance, altitude_to_aamsl
|
||||||
from .geo import azalt, angle_to_horizon, radio_horizon, shared_radio_horizon
|
from .geo import azalt, angle_to_horizon, radio_horizon, shared_radio_horizon
|
||||||
|
|
||||||
class Commands():
|
class Commands():
|
||||||
|
@ -680,6 +680,12 @@ class Location(Sensor):
|
||||||
self._raw = kwargs
|
self._raw = kwargs
|
||||||
self._last_update = time.time()
|
self._last_update = time.time()
|
||||||
|
|
||||||
|
def get_aamsl(self):
|
||||||
|
if self.data["altitude"] == None or self.data["latitude"] == None or self.data["longitude"] == None:
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
return altitude_to_aamsl(self.data["altitude"], self.data["latitude"], self.data["longitude"])
|
||||||
|
|
||||||
def set_update_time(self, update_time):
|
def set_update_time(self, update_time):
|
||||||
self._synthesized_updates = True
|
self._synthesized_updates = True
|
||||||
self._last_update = update_time
|
self._last_update = update_time
|
||||||
|
@ -788,10 +794,12 @@ class Location(Sensor):
|
||||||
|
|
||||||
obj_ath = None
|
obj_ath = None
|
||||||
obj_rh = None
|
obj_rh = None
|
||||||
|
aamsl = None
|
||||||
if self.data["altitude"] != None and self.data["latitude"] != None and self.data["longitude"] != None:
|
if self.data["altitude"] != None and self.data["latitude"] != None and self.data["longitude"] != None:
|
||||||
coords = (self.data["latitude"], self.data["longitude"], self.data["altitude"])
|
aamsl = self.get_aamsl()
|
||||||
|
coords = (self.data["latitude"], self.data["longitude"], aamsl)
|
||||||
obj_ath = angle_to_horizon(coords)
|
obj_ath = angle_to_horizon(coords)
|
||||||
obj_rh = radio_horizon(self.data["altitude"])
|
obj_rh = radio_horizon(aamsl)
|
||||||
|
|
||||||
rendered = {
|
rendered = {
|
||||||
"icon": "map-marker",
|
"icon": "map-marker",
|
||||||
|
@ -799,7 +807,7 @@ class Location(Sensor):
|
||||||
"values": {
|
"values": {
|
||||||
"latitude": self.data["latitude"],
|
"latitude": self.data["latitude"],
|
||||||
"longitude": self.data["longitude"],
|
"longitude": self.data["longitude"],
|
||||||
"altitude": self.data["altitude"],
|
"altitude": aamsl,
|
||||||
"speed": self.data["speed"],
|
"speed": self.data["speed"],
|
||||||
"heading": self.data["bearing"],
|
"heading": self.data["bearing"],
|
||||||
"accuracy": self.data["accuracy"],
|
"accuracy": self.data["accuracy"],
|
||||||
|
@ -811,13 +819,13 @@ class Location(Sensor):
|
||||||
|
|
||||||
if relative_to != None and "location" in relative_to.sensors:
|
if relative_to != None and "location" in relative_to.sensors:
|
||||||
slat = self.data["latitude"]; slon = self.data["longitude"]
|
slat = self.data["latitude"]; slon = self.data["longitude"]
|
||||||
salt = self.data["altitude"];
|
salt = aamsl
|
||||||
if salt == None: salt = 0
|
if salt == None: salt = 0
|
||||||
if slat != None and slon != None:
|
if slat != None and slon != None:
|
||||||
s = relative_to.sensors["location"]
|
s = relative_to.sensors["location"]
|
||||||
d = s.data
|
d = s.data
|
||||||
if d != None and "latitude" in d and "longitude" in d and "altitude" in d:
|
if d != None and "latitude" in d and "longitude" in d and "altitude" in d:
|
||||||
lat = d["latitude"]; lon = d["longitude"]; alt = d["altitude"]
|
lat = d["latitude"]; lon = d["longitude"]; alt = altitude_to_aamsl(d["altitude"], lat, lon)
|
||||||
if lat != None and lon != None:
|
if lat != None and lon != None:
|
||||||
if alt == None: alt = 0
|
if alt == None: alt = 0
|
||||||
cs = (slat, slon, salt); cr = (lat, lon, alt)
|
cs = (slat, slon, salt); cr = (lat, lon, alt)
|
||||||
|
@ -834,7 +842,7 @@ class Location(Sensor):
|
||||||
above_horizon = False
|
above_horizon = False
|
||||||
|
|
||||||
srh = shared_radio_horizon(cs, cr)
|
srh = shared_radio_horizon(cs, cr)
|
||||||
if self.data["altitude"] != None and d["altitude"] != None:
|
if salt != None and alt != None:
|
||||||
dalt = salt-alt
|
dalt = salt-alt
|
||||||
else:
|
else:
|
||||||
dalt = None
|
dalt = None
|
||||||
|
|
Loading…
Reference in New Issue