Added in plotting of secondary antenna data if it exists#416
Conversation
adamshapiro0
left a comment
There was a problem hiding this comment.
Looks good. We should think about generalizing this more as a follow-on step.
054c1a2 to
0a87f95
Compare
There was a problem hiding this comment.
Pull request overview
This PR extends the Python analyzer plotting to support per-antenna GNSS visualization, generating separate C/N0, signal status, and skyplot outputs when multiple GNSS antenna source IDs are present in the log.
Changes:
- Added a
SourceIdentifierenum to formalize known source identifier values (e.g., primary/secondary GNSS antenna). - Updated GNSS plotting in
Analyzerto generate per-source plots (with backward-compatible filenames for the primary antenna). - Adjusted skyplot C/N0 aggregation logic to better handle out-of-order/merged logs by grouping C/N0 by time value.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| python/fusion_engine_client/messages/defs.py | Introduces SourceIdentifier values for consistent source ID labeling across the codebase. |
| python/fusion_engine_client/analysis/analyzer.py | Adds per-source GNSS plot generation, per-source GNSS signal data caching, and updates skyplot C/N0 epoch aggregation. |
Comments suppressed due to low confidence (3)
python/fusion_engine_client/analysis/analyzer.py:1422
- plot_gnss_azimuth_elevation() now reads GNSS signals using self.default_source_id, which is the minimum of all source IDs in the log (often a pose source like 0). If GNSS signals are under SourceIdentifier.PRIMARY_GNSS_ANTENNA (300), this will incorrectly skip the plot even though GNSS data exists.
'x': 0.0,
'xanchor': 'left',
'y': 1.1,
python/fusion_engine_client/analysis/analyzer.py:1244
- cn0_per_epoch is computed using the old split-by-unique-time approach before max_cn0_dbhz is initialized, but that result is never used (it gets recomputed inside the idx.any() block). This is unnecessary work and makes the updated logic harder to follow.
sv_id = SatelliteID(sv_hash=sv_hash)
name = sv_id.to_string(short=False)
system = sv_id.get_satellite_type()
python/fusion_engine_client/analysis/analyzer.py:1190
- plot_gnss_skyplot()/plot_gnss_cn0()/plot_gnss_signal_status() now iterate over Analyzer.source_ids (all source IDs present in the log, not just GNSS). For each source ID, _get_gnss_signals_data() performs a read pass over GNSSSignals/GNSSSatellite messages, and MixedLogReader applies source_id filtering during iteration (not as an index prefilter). This can multiply I/O and parsing time when the log has many non-GNSS source IDs.
buttons.append(dict(label=name, method='restyle', args=['visible', visible]))
figure['layout']['updatemenus'] = [{
'type': 'buttons',
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
python/fusion_engine_client/analysis/analyzer.py:1832
- _get_gnss_antenna_source_ids() includes legacy IDs 0/1 unconditionally. With the new SourceIdentifier enum, 0 is also a pose-related identifier (OUTPUT_LEVER_ARM). If a log contains source ID 0 for pose data and 300/301 for GNSS, this will attempt GNSS plots for source 0 (noise), and can also lead to filename/figure-name collisions because 0 and 300 are both labeled "Primary" and produce the same unsuffixed filename.
if self._gnss_antenna_source_ids is None:
# 0/1 are the legacy primary/secondary antenna identifiers, predating the SourceIdentifier reserved
# ranges. 300-399 is reserved for GNSS receivers/antennae.
self._gnss_antenna_source_ids = sorted(
sid for sid in self.source_ids if sid in (0, 1) or 300 <= sid <= 399)
| """ | ||
| # Read the GNSS signal data. | ||
| data = self._get_gnss_signals_data() | ||
| data = self._get_gnss_signals_data(self.default_source_id) |
Changes