parse and show p_dop
This commit is contained in:
+10
-10
@@ -6,10 +6,10 @@ import socket
|
|||||||
import serial
|
import serial
|
||||||
from PyQt5.QtCore import QThread, pyqtSignal
|
from PyQt5.QtCore import QThread, pyqtSignal
|
||||||
|
|
||||||
from ubx import UbxPacketizer, build_poll, UBX_CLASS_NAV, UBX_ID_NAV_SAT, extract_satellites
|
from ubx import UbxPacketizer, build_poll, UBX_CLASS_NAV, UBX_ID_NAV_SAT, UBX_ID_NAV_DOP, extract_satellites
|
||||||
|
|
||||||
class GnssReader(QThread):
|
class GnssReader(QThread):
|
||||||
satellites_updated = pyqtSignal(list)
|
satellites_updated = pyqtSignal(dict)
|
||||||
error_occurred = pyqtSignal(str)
|
error_occurred = pyqtSignal(str)
|
||||||
connected = pyqtSignal(str)
|
connected = pyqtSignal(str)
|
||||||
|
|
||||||
@@ -26,18 +26,18 @@ class GnssReader(QThread):
|
|||||||
try:
|
try:
|
||||||
self._transport = self._factory()
|
self._transport = self._factory()
|
||||||
self.connected.emit("Verbunden")
|
self.connected.emit("Verbunden")
|
||||||
|
while self._running:
|
||||||
poll_msg = build_poll(UBX_CLASS_NAV, UBX_ID_NAV_SAT)
|
poll_msg = build_poll(UBX_CLASS_NAV, UBX_ID_NAV_SAT)
|
||||||
self._transport.write(poll_msg)
|
self._transport.write(poll_msg)
|
||||||
|
poll_msg = build_poll(UBX_CLASS_NAV, UBX_ID_NAV_DOP)
|
||||||
while self._running:
|
self._transport.write(poll_msg)
|
||||||
chunk = self._transport.read(512)
|
chunk = self._transport.read(512)
|
||||||
frames = self.packetizer.on_recv(chunk)
|
frames = self.packetizer.on_recv(chunk)
|
||||||
sats = extract_satellites(frames)
|
res = extract_satellites(frames)
|
||||||
if sats:
|
if 'sat' in res:
|
||||||
self.satellites_updated.emit(sats)
|
self.satellites_updated.emit(res)
|
||||||
else:
|
if 'dop' in res:
|
||||||
# Kein Datum – erneut pollen
|
self.satellites_updated.emit(res)
|
||||||
self._transport.write(poll_msg)
|
|
||||||
|
|
||||||
except (serial.SerialException, OSError, ConnectionRefusedError,
|
except (serial.SerialException, OSError, ConnectionRefusedError,
|
||||||
socket.timeout, socket.gaierror) as exc:
|
socket.timeout, socket.gaierror) as exc:
|
||||||
|
|||||||
+4
-1
@@ -165,8 +165,11 @@ class SinglePlotPanel(QWidget):
|
|||||||
active_keys: set[str] = set()
|
active_keys: set[str] = set()
|
||||||
|
|
||||||
if self._field == "pdop":
|
if self._field == "pdop":
|
||||||
|
if pdop is None:
|
||||||
|
return
|
||||||
active_keys.add("PDOP")
|
active_keys.add("PDOP")
|
||||||
self._push("PDOP", ts, pdop if pdop is not None else float("nan"))
|
print(f"PDOP: {pdop}")
|
||||||
|
self._push("PDOP", ts, pdop)
|
||||||
else:
|
else:
|
||||||
for sat in sats:
|
for sat in sats:
|
||||||
key = f"{GNSS_NAMES.get(sat['gnssId'], '?')}-{sat['svId']}"
|
key = f"{GNSS_NAMES.get(sat['gnssId'], '?')}-{sat['svId']}"
|
||||||
|
|||||||
+7
-1
@@ -163,13 +163,19 @@ class MainWindow(QMainWindow):
|
|||||||
self._conn_panel.set_connected(False)
|
self._conn_panel.set_connected(False)
|
||||||
self._status.showMessage("Verbindung getrennt.")
|
self._status.showMessage("Verbindung getrennt.")
|
||||||
|
|
||||||
def _on_satellites(self, sats: list):
|
def _on_satellites(self, msg: dict):
|
||||||
|
if 'sat' in msg:
|
||||||
|
sats = msg['sat']
|
||||||
visible = [s for s in sats if s["elev"] >= 0]
|
visible = [s for s in sats if s["elev"] >= 0]
|
||||||
used = sum(1 for s in sats if s["used"])
|
used = sum(1 for s in sats if s["used"])
|
||||||
self._sat_label.setText(f"Satelliten: {len(visible)} sichtbar, {used} genutzt")
|
self._sat_label.setText(f"Satelliten: {len(visible)} sichtbar, {used} genutzt")
|
||||||
self._sky_plot.update_satellites(visible)
|
self._sky_plot.update_satellites(visible)
|
||||||
self._table.update_satellites(visible)
|
self._table.update_satellites(visible)
|
||||||
self._plot_tab.update_data(visible) # ← neu
|
self._plot_tab.update_data(visible) # ← neu
|
||||||
|
if 'dop' in msg:
|
||||||
|
dop = msg['dop']
|
||||||
|
self._plot_tab.update_data([], pdop=dop['p_dop']) # ← neu
|
||||||
|
|
||||||
|
|
||||||
def _on_error(self, msg: str):
|
def _on_error(self, msg: str):
|
||||||
self._status.showMessage(f"Fehler: {msg}")
|
self._status.showMessage(f"Fehler: {msg}")
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ UBX_SYNC2 = 0x62
|
|||||||
UBX_CLASS_NAV = 0x01
|
UBX_CLASS_NAV = 0x01
|
||||||
UBX_ID_NAV_SAT = 0x35
|
UBX_ID_NAV_SAT = 0x35
|
||||||
UBX_ID_NAV_SVINFO = 0x30
|
UBX_ID_NAV_SVINFO = 0x30
|
||||||
|
UBX_ID_NAV_DOP = 0x04
|
||||||
|
|
||||||
UBX_SYNC_WORD = b'\xb5\x62'
|
UBX_SYNC_WORD = b'\xb5\x62'
|
||||||
|
|
||||||
|
|
||||||
@@ -156,12 +158,27 @@ def parse_nav_svinfo(payload: bytes) -> list[dict]:
|
|||||||
})
|
})
|
||||||
return sats
|
return sats
|
||||||
|
|
||||||
def extract_satellites(frames: list[dict]) -> list[dict]:
|
def parse_nav_dop(payload: bytes) -> dict:
|
||||||
|
if len(payload) < 18:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
i_tow, p_dop, g_dop, t_dop, v_dop, h_dop, n_dop, e_dop = struct.unpack_from(
|
||||||
|
"<IHHHHHHH", payload
|
||||||
|
)
|
||||||
|
scale = 0.01
|
||||||
|
res = {
|
||||||
|
"p_dop": p_dop*scale, "g_dop": g_dop*scale, "t_dop": t_dop*scale,
|
||||||
|
"v_dop": v_dop*scale, "h_dop": h_dop*scale, "n_dop": n_dop*scale, "e_dop": e_dop*scale
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
|
def extract_satellites(frames: list[dict]) -> dict:
|
||||||
for f in frames:
|
for f in frames:
|
||||||
if f["cls"] == UBX_CLASS_NAV and f["id"] == UBX_ID_NAV_SAT:
|
if f["cls"] == UBX_CLASS_NAV and f["id"] == UBX_ID_NAV_SAT:
|
||||||
return parse_nav_sat(f["payload"])
|
return {'sat': parse_nav_sat(f["payload"])}
|
||||||
if f["cls"] == UBX_CLASS_NAV and f["id"] == UBX_ID_NAV_SVINFO:
|
if f["cls"] == UBX_CLASS_NAV and f["id"] == UBX_ID_NAV_SVINFO:
|
||||||
return parse_nav_svinfo(f["payload"])
|
return {'sat': parse_nav_svinfo(f["payload"])}
|
||||||
return []
|
if f["cls"] == UBX_CLASS_NAV and f["id"] == UBX_ID_NAV_DOP:
|
||||||
|
return {'dop': parse_nav_dop(f["payload"])}
|
||||||
|
return {}
|
||||||
|
|||||||
Reference in New Issue
Block a user