Today, GNSSFlowgraph picks the next satellite to acquire on an idle
channel from a single FIFO queue per signal type. Visibility only ever
affects that queue's initial order, computed once at hot/warm start;
after that, every satellite -- visible or not -- is just a FIFO entry,
and a satellite that fails acquisition goes to the back of the same
queue. On a receiver with a large candidate PRN pool relative to the
satellites actually in view, this means channels keep grinding through
acquisition attempts against satellites that were never going to be
found, burning CPU that could go toward satellites actually overhead.
This adds continuous visibility tracking instead: as the receiver gets
a fix (or an AGNSS reference position) and as ephemeris/almanac data
arrives, satellites are classified into "visible" (elevation computable
and above GNSS-SDR.search_elevation_mask), "excluded" (elevation
computable and at/below the mask), or implicitly "maybe visible" (no
data yet -- still searched, just at lower priority). Classification is
re-evaluated whenever the fix becomes valid, new/updated ephemeris or
almanac data arrives for a PRN, the receiver moves significantly, a
periodic interval elapses, or classified data ages past its staleness
threshold -- not just once at startup.
A satellite that's actually acquired or tracking is never torn down
because of this classification: the search mask exists purely to avoid
wasting CPU on unlikely candidates, not as a correctness gate --
PVT.elevation_mask remains the real gate on whether a tracked
satellite's observations get used in the fix. Only the search layer
(picking new acquisitions, and not retrying a specific satellite after
a genuine loss of lock) is scoped by visibility.
Whole feature is gated behind GNSS-SDR.enable_visibility_aware_search,
default false -- disabled, every existing code path is untouched.
Key pieces:
- New SatelliteVisibility class (src/core/receiver/satellite_visibility.cc/.h):
owns the classification state and the recompute logic, including a
targeted-recompute path that only touches the satellite(s) whose data
actually changed instead of the whole constellation, when nothing else
that could affect every satellite's elevation (receiver position,
elapsed time) has changed.
- GNSSFlowgraph: new visible/maybe-visible queue selection in
search_next_signal(), ratio-controlled via
GNSS-SDR.visible_vs_mayvisible_search_ratio, plus reclassification
handling when a channel's assigned-but-not-yet-started satellite
becomes known excluded.
- ControlThread: MaybeUpdateVisibility() is called unconditionally from
event_dispatcher(), not just its idle branch -- the search layer's own
acquisition churn keeps the control queue busy enough that an
idle-only trigger would starve for the entire run right when
reclassifying satellites out of "maybe visible" is what would reduce
that churn.
- rtklib_conversions/rtklib_ephemeris: resolve_truncated_week() and
reference-week-aware alm_to_rtklib() overloads, needed to correctly
resolve Galileo's 2-bit and GPS's 8-bit truncated almanac week numbers
against an arbitrary query time rather than only the receiver's own
current time.
If a channel event was happening after flowgraph stop and before flowgraph disconnection, it caused a crash. This was avoided by sleeping the control thread during 500 ms after disconnection and before the block destructors were called, so the event could be processed, but this was not a robust solution.
Improve modularity of CMake design
Improve building speed in multicore processors
Files command_event.* moved to core/libs
Remove Armadillo from public core_receiver interface
Uniformize name format for classes
Apply some fixes by clang-tidy
Improve documentation
This commit enforces naming style for Classes and global constants:
Camel_Snake_Case for Classes
UPPER_CASE for global constants
CamelCase for abstract classes