From 041a174921914a76aa4b0abd4fe3eef1be46c4ec Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Thu, 24 Sep 2026 21:43:35 +0200 Subject: [PATCH] Resolve the acquisition role when reading dual_freq_assisted_doppler_narrowing The flowgraph read Acquisition_.dual_freq_assisted_doppler_narrowing unconditionally, but GetChannel() instantiates the acquisition block from Acquisition_ whenever that per-channel role defines an .implementation, so a receiver configured with per-channel acquisition roles would have had the flag read from a role the block was never built from. Expose get_role_name() from block_factory and use it in acquisition_manager() to look the property up on the same role the block was instantiated with, so the opt-out can be set per signal or, with a per-channel role, per channel. --- src/core/receiver/gnss_block_factory.cc | 25 +++++++++++++------------ src/core/receiver/gnss_block_factory.h | 12 ++++++++++++ src/core/receiver/gnss_flowgraph.cc | 20 ++++++-------------- 3 files changed, 31 insertions(+), 26 deletions(-) diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index 02cfe6fe9..0a1b3a052 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -197,18 +197,6 @@ auto findRole(const ConfigurationInterface* configuration, const std::string& ba return role; }; -std::string get_role_name(const ConfigurationInterface* configuration, const std::string& role_prefix, const std::string& signal, int channel) -{ - const auto role_name = role_prefix + signal + std::to_string(channel); - - if (configuration->is_present(role_name + impl_prop)) - { - return role_name; - } - - return role_prefix + signal; -} - const auto signal_mapping = std::vector>{ {"1C", "GPS L1 C/A"}, {"2S", "GPS L2C (M)"}, @@ -968,8 +956,21 @@ std::unique_ptr get_block_force_impl( } // namespace + namespace block_factory { +std::string get_role_name(const ConfigurationInterface* configuration, const std::string& role_prefix, const std::string& signal, int channel) +{ + const auto role_name = role_prefix + signal + std::to_string(channel); + + if (configuration->is_present(role_name + impl_prop)) + { + return role_name; + } + + return role_prefix + signal; +} + std::unique_ptr GetSignalSource( const ConfigurationInterface* configuration, Concurrent_Queue* queue, int ID) diff --git a/src/core/receiver/gnss_block_factory.h b/src/core/receiver/gnss_block_factory.h index 67dfdc4b5..bf867024a 100644 --- a/src/core/receiver/gnss_block_factory.h +++ b/src/core/receiver/gnss_block_factory.h @@ -69,6 +69,18 @@ std::unique_ptr GetBlock(const ConfigurationInterface* confi unsigned int out_streams, Concurrent_Queue* queue = nullptr); +/*! + * \brief Returns the role name of a channel's block: role_prefix + signal + + * channel (e.g. "Acquisition_5X12") if that per-channel role has an + * .implementation property in the configuration, role_prefix + signal (e.g. + * "Acquisition_5X") otherwise. Use it to read a property of an already built + * channel block from the same role the block was instantiated with. + */ +std::string get_role_name(const ConfigurationInterface* configuration, + const std::string& role_prefix, + const std::string& signal, + int channel); + std::unique_ptr GetChannel( const ConfigurationInterface* configuration, const std::string& signal, diff --git a/src/core/receiver/gnss_flowgraph.cc b/src/core/receiver/gnss_flowgraph.cc index 5cef916cb..38f0aa4b8 100644 --- a/src/core/receiver/gnss_flowgraph.cc +++ b/src/core/receiver/gnss_flowgraph.cc @@ -1825,20 +1825,12 @@ void GNSSFlowgraph::acquisition_manager(unsigned int who) << ", Signal " << channels_[current_channel]->get_signal().get_signal_str(); if (assistance_available == true && configuration_->property("GNSS-SDR.assist_dual_frequency_acq", multiband_)) { - // Doppler is exactly known from the already-tracked assisting - // frequency (search_next_signal() returns it already projected - // to this band): restrict the search to a single Doppler bin. - // - // Whether to actually narrow to it is itself opt-out via - // Acquisition_.dual_freq_assisted_doppler_narrowing - // (default true, preserving today's behavior) -- lets a specific - // signal's acquisition be forced to a full, completely unaided - // search for test purposes (e.g. characterizing acquisition - // performance/timing on every band without any cross-signal - // assist in the loop) without having to disable - // GNSS-SDR.assist_dual_frequency_acq globally, which would also - // suppress it for every other signal. - if (configuration_->property("Acquisition_" + channels_[current_channel]->get_signal().get_signal_str() + ".dual_freq_assisted_doppler_narrowing", true)) + // Doppler known from the tracked primary band (already projected to this + // band by search_next_signal()): search a single bin, unless + // .dual_freq_assisted_doppler_narrowing=false forces a full + // Doppler search for this signal (or channel, via a per-channel role). + const std::string acq_role = block_factory::get_role_name(configuration_.get(), "Acquisition_", channels_[current_channel]->get_signal().get_signal_str(), static_cast(current_channel)); + if (configuration_->property(acq_role + ".dual_freq_assisted_doppler_narrowing", true)) { channels_[current_channel]->assist_acquisition_doppler(estimated_doppler, 1); }