Added horizon metrics, radio coverage, azimuth, altitude and calculated deltas to telemetry rendering
This commit is contained in:
parent
07202396ae
commit
761fb86033
|
@ -5,7 +5,8 @@ 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, azalt, angle_to_horizon, radio_horizon
|
from .geo import orthodromic_distance, euclidian_distance
|
||||||
|
from .geo import azalt, angle_to_horizon, radio_horizon, shared_radio_horizon
|
||||||
|
|
||||||
class Telemeter():
|
class Telemeter():
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -603,6 +604,13 @@ class Location(Sensor):
|
||||||
def render(self, relative_to=None):
|
def render(self, relative_to=None):
|
||||||
if self.data == None:
|
if self.data == None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
obj_ath = None
|
||||||
|
obj_rh = None
|
||||||
|
if self.data["altitude"] != None and self.data["latitude"] != None and self.data["longtitude"] != None:
|
||||||
|
coords = (self.data["latitude"], self.data["longtitude"], self.data["altitude"])
|
||||||
|
obj_ath = angle_to_horizon(coords)
|
||||||
|
obj_rh = radio_horizon(self.data["altitude"])
|
||||||
|
|
||||||
rendered = {
|
rendered = {
|
||||||
"icon": "map-marker",
|
"icon": "map-marker",
|
||||||
|
@ -615,6 +623,8 @@ class Location(Sensor):
|
||||||
"heading": self.data["bearing"],
|
"heading": self.data["bearing"],
|
||||||
"accuracy": self.data["accuracy"],
|
"accuracy": self.data["accuracy"],
|
||||||
"updated": self.data["last_update"],
|
"updated": self.data["last_update"],
|
||||||
|
"angle_to_horizon": obj_ath,
|
||||||
|
"radio_horizon": obj_rh,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -634,16 +644,25 @@ class Location(Sensor):
|
||||||
od = orthodromic_distance(cs, cr)
|
od = orthodromic_distance(cs, cr)
|
||||||
aa = azalt(cs, cr)
|
aa = azalt(cs, cr)
|
||||||
ath = angle_to_horizon(cr)
|
ath = angle_to_horizon(cr)
|
||||||
rh = radio_horizon(cs, cr)
|
atd = aa[1]-ath
|
||||||
above_horizon = None
|
above_horizon = None
|
||||||
if aa[1] != None:
|
if aa[1] != None:
|
||||||
if aa[1] > ath:
|
if aa[1] > ath:
|
||||||
above_horizon = True
|
above_horizon = True
|
||||||
else:
|
else:
|
||||||
above_horizon = False
|
above_horizon = False
|
||||||
|
|
||||||
|
srh = shared_radio_horizon(cs, cr)
|
||||||
|
|
||||||
rendered["distance"] = {"euclidian": ed, "orthodromic": od}
|
rendered["distance"] = {"euclidian": ed, "orthodromic": od}
|
||||||
rendered["azalt"] = {"azimuth": aa[0], "altitude": aa[1], "above_horizon": above_horizon}
|
rendered["azalt"] = {
|
||||||
rendered["radio_horizon"] = {"object_range": rh[0], "related_range": rh[1], "combined_range": rh[2], "within_range": rh[3]}
|
"azimuth": aa[0], "altitude": aa[1], "above_horizon": above_horizon,
|
||||||
|
"altitude_delta": atd, "local_angle_to_horizon": ath}
|
||||||
|
rendered["radio_horizon"] = {
|
||||||
|
"object_range": srh["horizon1"], "related_range": srh["horizon2"],
|
||||||
|
"combined_range": srh["shared"], "within_range": srh["within"],
|
||||||
|
"geodesic_distance": srh["geodesic_distance"],
|
||||||
|
"antenna_distance": srh["antenna_distance"]}
|
||||||
|
|
||||||
return rendered
|
return rendered
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ class ObjectDetails():
|
||||||
self.coords = None
|
self.coords = None
|
||||||
self.raw_telemetry = None
|
self.raw_telemetry = None
|
||||||
self.from_conv = False
|
self.from_conv = False
|
||||||
|
self.viewing_self = False
|
||||||
|
|
||||||
if not self.app.root.ids.screen_manager.has_screen("object_details_screen"):
|
if not self.app.root.ids.screen_manager.has_screen("object_details_screen"):
|
||||||
self.screen = Builder.load_string(layou_object_details)
|
self.screen = Builder.load_string(layou_object_details)
|
||||||
|
@ -75,6 +76,9 @@ class ObjectDetails():
|
||||||
relative_to = None
|
relative_to = None
|
||||||
if source_dest != own_address:
|
if source_dest != own_address:
|
||||||
relative_to = self.app.sideband.telemeter
|
relative_to = self.app.sideband.telemeter
|
||||||
|
self.viewing_self = False
|
||||||
|
else:
|
||||||
|
self.viewing_self = True
|
||||||
|
|
||||||
rendered_telemetry = telemeter.render(relative_to=relative_to)
|
rendered_telemetry = telemeter.render(relative_to=relative_to)
|
||||||
if "location" in telemeter.sensors:
|
if "location" in telemeter.sensors:
|
||||||
|
@ -207,64 +211,81 @@ class RVDetails(MDRecycleView):
|
||||||
updated_str = f", logged [b]{RNS.prettytime(time.time()-updated, compact=True)} ago[/b]"
|
updated_str = f", logged [b]{RNS.prettytime(time.time()-updated, compact=True)} ago[/b]"
|
||||||
|
|
||||||
coords = f"{lat}, {lon}"
|
coords = f"{lat}, {lon}"
|
||||||
|
fcoords = f"{round(lat,4)}, {round(lon,4)}"
|
||||||
self.delegate.coords = coords
|
self.delegate.coords = coords
|
||||||
formatted_values = f"Coordinates [b]{coords}[/b], altitude [b]{alt} meters[/b]"
|
formatted_values = f"Coordinates [b]{fcoords}[/b], altitude [b]{alt} meters[/b]"
|
||||||
speed_formatted_values = f"Speed [b]{speed} Km/h[/b], heading [b]{heading}°[/b]"
|
speed_formatted_values = f"Speed [b]{speed} Km/h[/b], heading [b]{heading}°[/b]"
|
||||||
extra_formatted_values = f"Uncertainty [b]{accuracy} meters[/b]"+updated_str
|
extra_formatted_values = f"Uncertainty [b]{accuracy} meters[/b]"+updated_str
|
||||||
|
|
||||||
data = {"icon": s["icon"], "text": f"{formatted_values}"}
|
data = {"icon": s["icon"], "text": f"{formatted_values}"}
|
||||||
|
|
||||||
|
extra_entries.append({"icon": "map-marker-question", "text": extra_formatted_values})
|
||||||
|
|
||||||
if "distance" in s:
|
if "distance" in s:
|
||||||
distance_formatted_text = ""
|
|
||||||
if "orthodromic" in s["distance"]:
|
if "orthodromic" in s["distance"]:
|
||||||
od = s["distance"]["orthodromic"]
|
od = s["distance"]["orthodromic"]
|
||||||
if od != None:
|
if od != None:
|
||||||
od_text = f"Geodesic distance [b]{RNS.prettydistance(od)}[/b]"
|
od_text = f"Geodesic distance [b]{RNS.prettydistance(od)}[/b]"
|
||||||
distance_formatted_text += od_text
|
extra_entries.append({"icon": "earth", "text": od_text})
|
||||||
|
|
||||||
if "euclidian" in s["distance"]:
|
if "euclidian" in s["distance"]:
|
||||||
ed = s["distance"]["euclidian"]
|
ed = s["distance"]["euclidian"]
|
||||||
if ed != None:
|
if ed != None:
|
||||||
ed_text = f"euclidian distance [b]{RNS.prettydistance(ed)}[/b]"
|
ed_text = f"Euclidian distance [b]{RNS.prettydistance(ed)}[/b]"
|
||||||
if len(distance_formatted_text) != 0:
|
extra_entries.append({"icon": "axis-arrow", "text": ed_text})
|
||||||
distance_formatted_text += ", "
|
|
||||||
else:
|
|
||||||
ed_text = ed_text.replace("euclidian", "Euclidian")
|
|
||||||
distance_formatted_text += ed_text
|
|
||||||
|
|
||||||
extra_entries.append({"icon": "earth", "text": distance_formatted_text})
|
if "angle_to_horizon" in s["values"]:
|
||||||
|
oath = s["values"]["angle_to_horizon"]
|
||||||
|
if oath != None:
|
||||||
|
if self.delegate.viewing_self:
|
||||||
|
oath_text = f"Local horizon is at [b]{round(oath,3)}°[/b]"
|
||||||
|
else:
|
||||||
|
oath_text = f"Object's horizon is at [b]{round(oath,3)}°[/b]"
|
||||||
|
extra_entries.append({"icon": "arrow-split-horizontal", "text": oath_text})
|
||||||
|
|
||||||
|
if self.delegate.viewing_self and "radio_horizon" in s["values"]:
|
||||||
|
orh = s["values"]["radio_horizon"]
|
||||||
|
if orh != None:
|
||||||
|
range_text = RNS.prettydistance(orh)
|
||||||
|
rh_formatted_text = f"Radio horizon of [b]{range_text}[/b]"
|
||||||
|
extra_entries.append({"icon": "radio-tower", "text": rh_formatted_text})
|
||||||
|
|
||||||
|
if "azalt" in s and "local_angle_to_horizon" in s["azalt"]:
|
||||||
|
lath = s["azalt"]["local_angle_to_horizon"]
|
||||||
|
if lath != None:
|
||||||
|
lath_text = f"Local horizon is at [b]{round(lath,3)}°[/b]"
|
||||||
|
extra_entries.append({"icon": "align-vertical-distribute", "text": lath_text})
|
||||||
|
|
||||||
if "azalt" in s:
|
if "azalt" in s:
|
||||||
azalt_formatted_text = ""
|
azalt_formatted_text = ""
|
||||||
if "azimuth" in s["azalt"]:
|
if "azimuth" in s["azalt"]:
|
||||||
az = s["azalt"]["azimuth"]
|
az = s["azalt"]["azimuth"]
|
||||||
az_text = f"Azimuth [b]{round(az,4)}°[/b]"
|
az_text = f"Azimuth [b]{round(az,3)}°[/b]"
|
||||||
azalt_formatted_text += az_text
|
azalt_formatted_text += az_text
|
||||||
|
|
||||||
if "altitude" in s["azalt"]:
|
if "altitude" in s["azalt"]:
|
||||||
al = s["azalt"]["altitude"]
|
al = s["azalt"]["altitude"]
|
||||||
al_text = f"altitude [b]{round(al,4)}°[/b]"
|
al_text = f"altitude [b]{round(al,3)}°[/b]"
|
||||||
if len(azalt_formatted_text) != 0: azalt_formatted_text += ", "
|
if len(azalt_formatted_text) != 0: azalt_formatted_text += ", "
|
||||||
azalt_formatted_text += al_text
|
azalt_formatted_text += al_text
|
||||||
|
|
||||||
|
extra_entries.append({"icon": "compass-rose", "text": azalt_formatted_text})
|
||||||
|
|
||||||
if "above_horizon" in s["azalt"]:
|
if "above_horizon" in s["azalt"]:
|
||||||
astr = "above" if s["azalt"]["above_horizon"] == True else "below"
|
astr = "above" if s["azalt"]["above_horizon"] == True else "below"
|
||||||
ah_text = f"object is [b]{astr}[/b] the horizon"
|
dstr = str(round(s["azalt"]["altitude_delta"], 3))
|
||||||
if len(azalt_formatted_text) != 0: azalt_formatted_text += ", "
|
ah_text = f"Object is [b]{astr}[/b] the horizon (Δ = {dstr}°)"
|
||||||
azalt_formatted_text += ah_text
|
extra_entries.append({"icon": "angle-acute", "text": ah_text})
|
||||||
|
|
||||||
extra_entries.append({"icon": "compass-rose", "text": azalt_formatted_text})
|
|
||||||
|
|
||||||
if "radio_horizon" in s:
|
if "radio_horizon" in s:
|
||||||
crange_text = RNS.prettydistance(s["radio_horizon"]["combined_range"])
|
crange_text = RNS.prettydistance(s["radio_horizon"]["combined_range"])
|
||||||
if s["radio_horizon"]["within_range"]:
|
if s["radio_horizon"]["within_range"]:
|
||||||
rh_formatted_text = f"Object is [b]within[/b] combined radio horizon of [b]{crange_text}[/b]"
|
rh_formatted_text = f"[b]Within[/b] shared radio horizon of [b]{crange_text}[/b]"
|
||||||
else:
|
else:
|
||||||
rh_formatted_text = f"Object is [b]not within[/b] within combined radio horizon of [b]{crange_text}[/b]"
|
rh_formatted_text = f"[b]Outside[/b] shared radio horizon of [b]{crange_text}[/b]"
|
||||||
|
|
||||||
extra_entries.append({"icon": "radio-tower", "text": rh_formatted_text})
|
extra_entries.append({"icon": "radio-tower", "text": rh_formatted_text})
|
||||||
|
|
||||||
extra_entries.append({"icon": "map-marker-question", "text": extra_formatted_values})
|
|
||||||
extra_entries.append({"icon": "speedometer", "text": speed_formatted_values})
|
extra_entries.append({"icon": "speedometer", "text": speed_formatted_values})
|
||||||
|
|
||||||
def select(e=None):
|
def select(e=None):
|
||||||
|
|
Loading…
Reference in New Issue