3.0 KiB
3.0 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Running the application
# Activate the virtual environment first
source .venv/bin/activate
# Run the app
python sky_plot.py
Architecture
This is a PyQt5 desktop app that reads GNSS satellite data from a u-blox receiver (UBX protocol) over serial or TCP/IP and visualizes it in real time.
Data flow
GnssReader(QThread ingnss_thread.py) polls the device in a loop: sendsNAV-SATandNAV-DOPpoll requests, reads 512 bytes, feeds them throughUbxPacketizer.- Decoded frames are passed to
extract_satellites()inubx.py, which returns a dict with optional keys'sat'(list of satellite dicts) and'dop'(dict withp_dop,h_dop, etc.). GnssReaderemits thesatellites_updated(dict)signal.MainWindow._on_satellites()routes the payload to three widgets:SkyPlotWidget,SatelliteTable, andPlotTab.
Module overview
| File | Responsibility |
|---|---|
sky_plot.py |
Entry point; MainWindow with three tabs: Connection, Sky View, Plot |
gnss_thread.py |
GnssReader(QThread) — device I/O loop, emits signals |
ubx.py |
UBX protocol: UbxPacketizer (byte-stream → frames), parse_nav_sat, parse_nav_dop, extract_satellites |
transport.py |
Abstract GnssTransport base class |
transport_serial.py |
SerialTransport — wraps pyserial |
transport_network.py |
TcpTransport — wraps socket (for ser2net) |
connection_panel.py |
ConnectionPanel(QGroupBox) — serial/TCP UI, emits connect_requested(factory, label) |
lru_store.py |
LruStore — persists up to 5 recent TCP connections via QSettings |
sky_plot_widget.py |
SkyPlotWidget(QWidget) — polar sky plot, custom paintEvent |
sat_table.py |
SatelliteTable(QTableWidget) — tabular satellite list |
plot_tab.py |
PlotTab — 2×4 grid of SinglePlotPanels (pyqtgraph), time-series plots with persistent settings |
defines.py |
GNSS_NAMES and GNSS_COLORS shared constants |
Key design notes
- Transport factory pattern:
ConnectionPanelemits afactorycallable (a lambda that creates a transport).GnssReadercalls the factory in its thread, keeping socket/serial construction off the main thread. - Disabled old code:
MainWindow.__build_uiandMainWindow.__connect(double-underscore prefix) are the original single-view implementations, effectively disabled by Python name mangling. The active methods are_build_uiand_connect. sat_table.pyduplicatesGNSS_NAMES/GNSS_COLORSfromdefines.py— preferdefines.pyas the source of truth when extending.- Plot settings persistence:
PlotSettingsStoresaves each panel's selected field and SV filter toQSettings("gnss_skyplot", "connections")(same org/app asLruStore). - History cap: each
SinglePlotPanelkeeps at mostMAX_HISTORY = 300data points per satellite/PDOP curve.