mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2026-10-15 04:01:49 +00:00
Drop the config-driven widening this PR mistakenly added
set_doppler_num_bins(1) (an exactly-known Doppler, e.g. from a dual-frequency assist) previously honored a widening exception: if Acquisition_<Sig>.enable_assisted_doppler_narrowing was set, a literal N == 1 request could get silently expanded into doppler_narrowing_num_bins candidate bins instead of searched as requested. That was never asked for and contradicts the whole point of this unification -- N is supposed to be authoritative, full stop. A caller that actually wants a safety margin around its own estimate should just request that many bins directly (set_doppler_num_bins(3), not set_doppler_num_bins(1) plus a config flag that silently changes what "1" means). Removes both config parameters entirely (enable_assisted_doppler_narrowing, doppler_narrowing_num_bins) along with the widening branch in set_doppler_num_bins(). Dual-frequency-assisted secondary acquisition now always searches exactly 1 bin, unconditionally -- no config knob changes that. Does not reintroduce next's original enable_doppler_narrowing name/semantics either (a master on/off switch that could fall back an assisted request to the full grid): under the unified API, the caller's N is never second-guessed by a flag, matching this PR's whole premise. Test file updated to match: init() drops both removed parameters, and the two tests that specifically exercised the widening path (NarrowingWithMultipleCandidateBinsRecoversOffsetEstimate, NarrowedDumpMetadataMultipleCandidateBins) now request their multi-bin coverage directly (set_doppler_num_bins(5)) instead of relying on config-driven expansion from N == 1 -- same coverage, no removed feature required to exercise it. Verified: full local test suite (105 tests) passes against a from-scratch build, isolated from other in-progress work.
This commit is contained in:
@@ -474,7 +474,7 @@ void pcps_acquisition::dump_results(const AcquisitionResult& result)
|
||||
std::array<size_t, 2> dims_2d{d_effective_fft_size, d_num_doppler_bins_active};
|
||||
|
||||
// acq_grid's candidate columns -- all of them for a plain full-grid
|
||||
// search, or the first doppler_narrowing_num_bins of them when narrowed
|
||||
// search, or just the requested candidate count when narrowed
|
||||
// (the trailing column there is the noise-reference bin at
|
||||
// doppler_center + d_doppler_max, not representable in this linear
|
||||
// encoding) -- are placed symmetrically around doppler_center, matching
|
||||
@@ -1024,24 +1024,12 @@ void pcps_acquisition::set_doppler_num_bins(uint32_t num_doppler_bins)
|
||||
gr::thread::scoped_lock lock(d_setlock); // require mutex with work function called by the scheduler
|
||||
// 0 is the only value a caller can't just supply directly -- the full
|
||||
// grid's own candidate count is otherwise private to this class -- so it
|
||||
// means "the full configured range" here, same as always.
|
||||
// means "the full configured range" here, same as always. Any other
|
||||
// value is taken literally and unconditionally: an assisted, exactly-
|
||||
// known Doppler (num_doppler_bins == 1) always searches exactly 1 bin,
|
||||
// no config-driven widening -- a caller that wants a safety margin
|
||||
// around its own estimate should just ask for that many bins directly.
|
||||
uint32_t candidate_bins = (num_doppler_bins == 0U) ? d_num_doppler_bins : num_doppler_bins;
|
||||
// An exactly-known Doppler (num_doppler_bins == 1, from a primary-
|
||||
// frequency assist) can still be widened into a small safety-margin
|
||||
// window: enable_assisted_doppler_narrowing exists because a caller's
|
||||
// exact estimate doesn't always cover receiver dynamics/clock drift
|
||||
// accrued since it was made. Tested against the caller's *original*
|
||||
// request (num_doppler_bins == 1), not the resolved candidate_bins -- a
|
||||
// full-grid request (the 0 sentinel) that happens to compute to a 1-bin
|
||||
// grid is a different thing entirely and must never be widened.
|
||||
// d_num_doppler_bins > doppler_narrowing_num_bins guard: a full grid no
|
||||
// bigger than the configured window is already as narrow as it can be,
|
||||
// and widening past it would write past the bin-count-sized grid
|
||||
// allocations.
|
||||
if (num_doppler_bins == 1U && d_acq_parameters.enable_assisted_doppler_narrowing && d_num_doppler_bins > d_acq_parameters.doppler_narrowing_num_bins)
|
||||
{
|
||||
candidate_bins = d_acq_parameters.doppler_narrowing_num_bins;
|
||||
}
|
||||
candidate_bins = std::min(candidate_bins, d_num_doppler_bins);
|
||||
// See d_num_reference_rows_active's doc comment: 2 dedicated rows
|
||||
// (opposite-sign pair) whenever a reference is needed and there's more
|
||||
|
||||
@@ -82,17 +82,6 @@ void Acq_Conf::SetFromConfiguration(const ConfigurationInterface *configuration,
|
||||
}
|
||||
make_2_steps = configuration->property(role + ".make_two_steps", make_2_steps);
|
||||
blocking_on_standby = configuration->property(role + ".blocking_on_standby", blocking_on_standby);
|
||||
enable_assisted_doppler_narrowing = configuration->property(role + ".enable_assisted_doppler_narrowing", enable_assisted_doppler_narrowing);
|
||||
doppler_narrowing_num_bins = configuration->property(role + ".doppler_narrowing_num_bins", doppler_narrowing_num_bins);
|
||||
if ((doppler_narrowing_num_bins != 0) && ((doppler_narrowing_num_bins % 2) == 0))
|
||||
{
|
||||
// must be odd (a center bin plus a symmetric number of +/- steps)
|
||||
doppler_narrowing_num_bins += 1;
|
||||
}
|
||||
if (doppler_narrowing_num_bins == 0)
|
||||
{
|
||||
doppler_narrowing_num_bins = 1;
|
||||
}
|
||||
reference_bin_min_sidelobes = configuration->property(role + ".reference_bin_min_sidelobes", reference_bin_min_sidelobes);
|
||||
|
||||
if (pfa <= 0.0)
|
||||
|
||||
@@ -74,20 +74,6 @@ public:
|
||||
bool make_2_steps{false};
|
||||
bool use_automatic_resampler{false};
|
||||
bool enable_monitor_output{false};
|
||||
// When Doppler is assisted (doppler_num_bins == 1), collapse the search to
|
||||
// doppler_narrowing_num_bins candidate bins (plus one reference bin, see
|
||||
// below) instead of the full grid. Opt-in (new, still-experimental feature):
|
||||
// off by default, enable per-implementation in the .conf (e.g.
|
||||
// Acquisition_5X.enable_assisted_doppler_narrowing = true).
|
||||
bool enable_assisted_doppler_narrowing{false};
|
||||
// How many candidate Doppler bins (spaced doppler_step apart, centered on
|
||||
// the assisted Doppler estimate) the narrowed search above actually tests,
|
||||
// to absorb residual assist error (receiver dynamics, clock drift
|
||||
// uncertainty) instead of requiring the assist to be exact. Must be odd
|
||||
// (a center bin plus a symmetric number of +/- steps); 1 (default) is the
|
||||
// original assisted-search behavior -- exactly the assisted Doppler,
|
||||
// no margin. Only takes effect together with enable_assisted_doppler_narrowing.
|
||||
uint32_t doppler_narrowing_num_bins{1U};
|
||||
// Target number of correlation sidelobes (in Doppler) the CFAR noise-floor
|
||||
// reference bin should clear from the search grid's own candidate span, used
|
||||
// only to decide WHETHER a plain full grid needs a dedicated extra reference
|
||||
|
||||
+62
-65
@@ -1,7 +1,8 @@
|
||||
/*!
|
||||
* \file pcps_acquisition_doppler_narrowing_test.cc
|
||||
* \brief Tests for Acq_Conf::enable_assisted_doppler_narrowing (assisted-acquisition
|
||||
* Doppler search narrowing) in pcps_acquisition, using the same GPS L1 C/A
|
||||
* \brief Tests for pcps_acquisition::set_doppler_num_bins() (the unified
|
||||
* Doppler search bin-count API, covering both the full configured grid and
|
||||
* any narrower/assisted candidate count), using the same GPS L1 C/A
|
||||
* signal/fixture pattern as gps_l1_ca_pcps_acquisition_test.cc.
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
@@ -135,7 +136,7 @@ protected:
|
||||
// full-grid Doppler bins pcps_acquisition computes
|
||||
// (d_num_doppler_bins == ceil(2*doppler_max/doppler_step)), since that bin
|
||||
// count is exactly what the reviewed bug depended on.
|
||||
void init(unsigned int doppler_max, unsigned int doppler_step, bool enable_assisted_doppler_narrowing, bool use_cfar, unsigned int doppler_narrowing_num_bins = 1U);
|
||||
void init(unsigned int doppler_max, unsigned int doppler_step, bool use_cfar);
|
||||
|
||||
gr::top_block_sptr top_block;
|
||||
std::shared_ptr<InMemoryConfiguration> config;
|
||||
@@ -143,7 +144,7 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
void PcpsAcquisitionDopplerNarrowingTest::init(unsigned int doppler_max, unsigned int doppler_step, bool enable_assisted_doppler_narrowing, bool use_cfar, unsigned int doppler_narrowing_num_bins)
|
||||
void PcpsAcquisitionDopplerNarrowingTest::init(unsigned int doppler_max, unsigned int doppler_step, bool use_cfar)
|
||||
{
|
||||
gnss_synchro.Channel_ID = 0;
|
||||
gnss_synchro.System = 'G';
|
||||
@@ -158,8 +159,6 @@ void PcpsAcquisitionDopplerNarrowingTest::init(unsigned int doppler_max, unsigne
|
||||
config->set_property("Acquisition_1C.doppler_max", std::to_string(doppler_max));
|
||||
config->set_property("Acquisition_1C.doppler_step", std::to_string(doppler_step));
|
||||
config->set_property("Acquisition_1C.repeat_satellite", "false");
|
||||
config->set_property("Acquisition_1C.enable_assisted_doppler_narrowing", enable_assisted_doppler_narrowing ? "true" : "false");
|
||||
config->set_property("Acquisition_1C.doppler_narrowing_num_bins", std::to_string(doppler_narrowing_num_bins));
|
||||
if (use_cfar)
|
||||
{
|
||||
// pfa > 0 both switches Acq_Conf::use_CFAR_algorithm_flag to true and
|
||||
@@ -229,10 +228,10 @@ RunResult run_acquisition(gr::top_block_sptr &top_block, InMemoryConfiguration *
|
||||
|
||||
TEST_F(PcpsAcquisitionDopplerNarrowingTest /*unused*/, NarrowingDisabled /*unused*/)
|
||||
{
|
||||
// enable_assisted_doppler_narrowing = false: a regular (unassisted, N == 0
|
||||
// full-grid sentinel) request must still search the full configured
|
||||
// Doppler grid, same as any Acquisition_<sig> not using assisted search.
|
||||
init(/*doppler_max=*/5000, /*doppler_step=*/100, /*enable_assisted_doppler_narrowing=*/false, /*use_cfar=*/false);
|
||||
// A regular (unassisted, N == 0 full-grid sentinel) request must search
|
||||
// the full configured Doppler grid, same as any Acquisition_<sig> not
|
||||
// using assisted search.
|
||||
init(/*doppler_max=*/5000, /*doppler_step=*/100, /*use_cfar=*/false);
|
||||
|
||||
const RunResult result = run_acquisition(top_block, config.get(), gnss_synchro, static_cast<int>(kTrueDopplerHz), 0);
|
||||
|
||||
@@ -244,21 +243,21 @@ TEST_F(PcpsAcquisitionDopplerNarrowingTest /*unused*/, NarrowingDisabled /*unuse
|
||||
|
||||
TEST_F(PcpsAcquisitionDopplerNarrowingTest /*unused*/, NarrowingEnabledOneBinGrid /*unused*/)
|
||||
{
|
||||
// doppler_step >= 2*doppler_max -> d_num_doppler_bins == 1. Regression test
|
||||
// for the P1 fix: narrowing must NOT force a second active bin into a
|
||||
// 1-row grid allocation (that was an out-of-bounds write). With the
|
||||
// d_num_doppler_bins > 1 guard, narrowing silently stays off here and the
|
||||
// block just runs its (degenerate, single-hypothesis) full grid. The single
|
||||
// bin is placed exactly at doppler_center (update_grid_doppler_wipeoffs()'s
|
||||
// doppler_step >= 2*doppler_max -> d_num_doppler_bins == 1, so an assisted
|
||||
// request (N == 1) coincides exactly with the full grid's own size.
|
||||
// Regression test for the P1 fix: this must NOT force a second active bin
|
||||
// into a 1-row grid allocation (that was an out-of-bounds write) -- the
|
||||
// block just runs its (degenerate, single-hypothesis) grid either way. The
|
||||
// single bin is placed exactly at doppler_center (update_grid_doppler_wipeoffs()'s
|
||||
// symmetric half_span placement collapses to zero offset when there's only
|
||||
// one bin), so a successful acquisition here also confirms that centering,
|
||||
// not just "didn't crash".
|
||||
init(/*doppler_max=*/5000, /*doppler_step=*/10000, /*enable_assisted_doppler_narrowing=*/true, /*use_cfar=*/false);
|
||||
init(/*doppler_max=*/5000, /*doppler_step=*/10000, /*use_cfar=*/false);
|
||||
|
||||
const int doppler_center = static_cast<int>(kTrueDopplerHz);
|
||||
const RunResult result = run_acquisition(top_block, config.get(), gnss_synchro, doppler_center, 1);
|
||||
|
||||
ASSERT_EQ(1, result.rx_message) << "Acquisition failure with a 1-bin full grid (narrowing should have stayed disabled, not crashed).";
|
||||
ASSERT_EQ(1, result.rx_message) << "Acquisition failure with a 1-bin full grid.";
|
||||
EXPECT_LE(result.doppler_error_hz, 666) << "Doppler error exceeds the expected value: 666 Hz = 2/(3*integration period)";
|
||||
EXPECT_LT(result.delay_error_chips, 0.5) << "Delay error exceeds the expected value: 0.5 chips";
|
||||
}
|
||||
@@ -267,15 +266,15 @@ TEST_F(PcpsAcquisitionDopplerNarrowingTest /*unused*/, NarrowingEnabledOneBinGri
|
||||
TEST_F(PcpsAcquisitionDopplerNarrowingTest /*unused*/, NarrowingEnabledTwoBinGrid /*unused*/)
|
||||
{
|
||||
// doppler_max=5000, doppler_step=6000 -> d_num_doppler_bins == 2, exactly
|
||||
// matching narrowed mode's own active-bin count. Regression test for the
|
||||
// other half of the P1 fix: the old code inferred "is this narrowed?" as
|
||||
// active_bins < full_bins, which is false here (2 < 2) even though this
|
||||
// *is* a narrowed request, so it silently fell back to a plain 2-bin full
|
||||
// grid instead of {known center, center + doppler_max}. That fallback's
|
||||
// nearest bin to the true Doppler is 1000 Hz off (a near-total phase
|
||||
// cancellation over the 1 ms coherent window), while the correct assisted
|
||||
// bin 0 lands exactly on it.
|
||||
init(/*doppler_max=*/5000, /*doppler_step=*/6000, /*enable_assisted_doppler_narrowing=*/true, /*use_cfar=*/false);
|
||||
// matching an assisted (N == 1 + 1 reference row) request's own active-bin
|
||||
// count. Regression test for the other half of the P1 fix: the old code
|
||||
// inferred "is this narrowed?" as active_bins < full_bins, which is false
|
||||
// here (2 < 2) even though this *is* a narrowed (N == 1) request, so it
|
||||
// silently fell back to a plain 2-bin full grid instead of {known center,
|
||||
// center + doppler_max}. That fallback's nearest bin to the true Doppler
|
||||
// is 1000 Hz off (a near-total phase cancellation over the 1 ms coherent
|
||||
// window), while the correct assisted bin 0 lands exactly on it.
|
||||
init(/*doppler_max=*/5000, /*doppler_step=*/6000, /*use_cfar=*/false);
|
||||
|
||||
const RunResult result = run_acquisition(top_block, config.get(), gnss_synchro, static_cast<int>(kTrueDopplerHz), 1);
|
||||
|
||||
@@ -286,20 +285,20 @@ TEST_F(PcpsAcquisitionDopplerNarrowingTest /*unused*/, NarrowingEnabledTwoBinGri
|
||||
|
||||
TEST_F(PcpsAcquisitionDopplerNarrowingTest /*unused*/, NarrowingWithMultipleCandidateBinsRecoversOffsetEstimate /*unused*/)
|
||||
{
|
||||
// doppler_narrowing_num_bins = 5, doppler_step = 200: candidate bins span
|
||||
// assisted_center + {-2,-1,0,+1,+2}*200 Hz, i.e. +/-400 Hz around the
|
||||
// assisted estimate. Deliberately mis-center the assisted estimate by
|
||||
// exactly -2 steps (-400 Hz) from the true Doppler, so the true value
|
||||
// only exists at the *last* (k=4, +2 steps) candidate bin -- proving the
|
||||
// extra candidate bins are actually searched, not just allocated.
|
||||
// A literal N == 5 request, doppler_step = 200: candidate bins span
|
||||
// center + {-2,-1,0,+1,+2}*200 Hz, i.e. +/-400 Hz around the requested
|
||||
// center. Deliberately mis-center that request by exactly -2 steps
|
||||
// (-400 Hz) from the true Doppler, so the true value only exists at the
|
||||
// *last* (k=4, +2 steps) candidate bin -- proving the extra candidate
|
||||
// bins are actually searched, not just allocated.
|
||||
constexpr unsigned int kDopplerStep = 200;
|
||||
constexpr unsigned int kNumBins = 5;
|
||||
init(/*doppler_max=*/5000, /*doppler_step=*/kDopplerStep, /*enable_assisted_doppler_narrowing=*/true, /*use_cfar=*/false, /*doppler_narrowing_num_bins=*/kNumBins);
|
||||
init(/*doppler_max=*/5000, /*doppler_step=*/kDopplerStep, /*use_cfar=*/false);
|
||||
|
||||
const int assisted_center = static_cast<int>(kTrueDopplerHz) - 2 * static_cast<int>(kDopplerStep);
|
||||
const RunResult result = run_acquisition(top_block, config.get(), gnss_synchro, assisted_center, 1);
|
||||
const int center = static_cast<int>(kTrueDopplerHz) - 2 * static_cast<int>(kDopplerStep);
|
||||
const RunResult result = run_acquisition(top_block, config.get(), gnss_synchro, center, kNumBins);
|
||||
|
||||
ASSERT_EQ(1, result.rx_message) << "Acquisition failure: the true Doppler is 2 steps away from the assisted center, only reachable via the extra candidate bins.";
|
||||
ASSERT_EQ(1, result.rx_message) << "Acquisition failure: the true Doppler is 2 steps away from the requested center, only reachable via the extra candidate bins.";
|
||||
EXPECT_LE(result.doppler_error_hz, 200) << "Doppler error indicates the wrong candidate bin (or the reference bin) was selected.";
|
||||
}
|
||||
|
||||
@@ -312,7 +311,7 @@ TEST_F(PcpsAcquisitionDopplerNarrowingTest /*unused*/, CfarExcludesReferenceBinF
|
||||
// scanned every computed bin, so bin 1's strong real correlation could win
|
||||
// and get reported as if it were the trusted assisted center. With the
|
||||
// fix, only bin 0 (pure noise here) is ever a candidate.
|
||||
init(/*doppler_max=*/5000, /*doppler_step=*/5000, /*enable_assisted_doppler_narrowing=*/true, /*use_cfar=*/true);
|
||||
init(/*doppler_max=*/5000, /*doppler_step=*/5000, /*use_cfar=*/true);
|
||||
|
||||
const int doppler_center = static_cast<int>(kTrueDopplerHz) - 5000; // bin 0 = center (noise); bin 1 = center + 5000 = true Doppler
|
||||
const RunResult result = run_acquisition(top_block, config.get(), gnss_synchro, doppler_center, 1);
|
||||
@@ -325,7 +324,7 @@ TEST_F(PcpsAcquisitionDopplerNarrowingTest /*unused*/, PeakRatioExcludesReferenc
|
||||
{
|
||||
// Same construction as CfarExcludesReferenceBinFromCandidacy, exercising
|
||||
// the non-CFAR (first_vs_second_peak_statistic) path instead.
|
||||
init(/*doppler_max=*/5000, /*doppler_step=*/5000, /*enable_assisted_doppler_narrowing=*/true, /*use_cfar=*/false);
|
||||
init(/*doppler_max=*/5000, /*doppler_step=*/5000, /*use_cfar=*/false);
|
||||
|
||||
const int doppler_center = static_cast<int>(kTrueDopplerHz) - 5000;
|
||||
const RunResult result = run_acquisition(top_block, config.get(), gnss_synchro, doppler_center, 1);
|
||||
@@ -342,7 +341,7 @@ TEST_F(PcpsAcquisitionDopplerNarrowingTest /*unused*/, FullToNarrowTransition /*
|
||||
// instance, then verify the final (full-grid) state still acquires
|
||||
// correctly -- regression coverage for the dump/grid-sizing fix (section 5)
|
||||
// interacting with d_num_reference_rows_active toggling.
|
||||
init(/*doppler_max=*/5000, /*doppler_step=*/100, /*enable_assisted_doppler_narrowing=*/true, /*use_cfar=*/false);
|
||||
init(/*doppler_max=*/5000, /*doppler_step=*/100, /*use_cfar=*/false);
|
||||
|
||||
top_block = gr::make_top_block("Doppler narrowing transition test");
|
||||
auto acquisition = std::make_shared<PcpsAcquisitionAdapter>(config.get(), "Acquisition_1C", "GPS_L1_CA_PCPS_Acquisition", 1, 0, GPS_1C);
|
||||
@@ -389,7 +388,6 @@ double probe_doppler_hz_4ms_capture(std::shared_ptr<InMemoryConfiguration> &conf
|
||||
// second set_property() call for the same key is a silent no-op.
|
||||
config->supersede_property("Acquisition_1C.doppler_max", "10000");
|
||||
config->supersede_property("Acquisition_1C.doppler_step", "100");
|
||||
config->supersede_property("Acquisition_1C.enable_assisted_doppler_narrowing", "false");
|
||||
|
||||
auto acquisition = std::make_shared<PcpsAcquisitionAdapter>(config.get(), "Acquisition_1C", "GPS_L1_CA_PCPS_Acquisition", 1, 0, GPS_1C);
|
||||
auto msg_rx = PcpsAcquisitionDopplerNarrowingTest_msg_rx_make();
|
||||
@@ -424,7 +422,7 @@ TEST_F(PcpsAcquisitionDopplerNarrowingTest /*unused*/, TwoStepAcquisitionWithNar
|
||||
// ValidationOfResultsMakeTwoStep in gps_l1_ca_pcps_acquisition_test.cc,
|
||||
// since two-step acquisition needs more samples than the 2 ms capture the
|
||||
// other tests in this file use provides.
|
||||
init(/*doppler_max=*/5000, /*doppler_step=*/6000, /*enable_assisted_doppler_narrowing=*/true, /*use_cfar=*/false);
|
||||
init(/*doppler_max=*/5000, /*doppler_step=*/6000, /*use_cfar=*/false);
|
||||
const auto assist_doppler_hz = probe_doppler_hz_4ms_capture(config, gnss_synchro);
|
||||
|
||||
gnss_synchro = Gnss_Synchro();
|
||||
@@ -433,7 +431,6 @@ TEST_F(PcpsAcquisitionDopplerNarrowingTest /*unused*/, TwoStepAcquisitionWithNar
|
||||
// set_property() is fine for these).
|
||||
config->supersede_property("Acquisition_1C.doppler_max", "5000");
|
||||
config->supersede_property("Acquisition_1C.doppler_step", "6000");
|
||||
config->supersede_property("Acquisition_1C.enable_assisted_doppler_narrowing", "true");
|
||||
config->set_property("Acquisition_1C.make_two_steps", "true");
|
||||
config->set_property("Acquisition_1C.second_nbins", "5");
|
||||
config->set_property("Acquisition_1C.second_doppler_step", "20");
|
||||
@@ -478,12 +475,12 @@ TEST_F(PcpsAcquisitionDopplerNarrowingTest /*unused*/, NarrowedDumpMetadata /*un
|
||||
// Regression test for the section 5 fix: a narrowed dump must describe
|
||||
// itself accurately (2 columns, an explicit doppler_narrowed flag) instead
|
||||
// of claiming the full grid's width/step while actually only having
|
||||
// written 2 live columns. With a single candidate bin (doppler_narrowing_num_bins
|
||||
// defaults to 1), half_span == 0, so dump_doppler_max == 0 and
|
||||
// dump_doppler_step == the real per-bin step (here == doppler_max, since
|
||||
// this test configures them equal) -- see NarrowedDumpMetadataMultipleCandidateBins
|
||||
// below for a case where doppler_max and doppler_step differ.
|
||||
init(/*doppler_max=*/5000, /*doppler_step=*/5000, /*enable_assisted_doppler_narrowing=*/true, /*use_cfar=*/false);
|
||||
// written 2 live columns. With a single (literal N == 1) candidate bin,
|
||||
// half_span == 0, so dump_doppler_max == 0 and dump_doppler_step == the
|
||||
// real per-bin step (here == doppler_max, since this test configures them
|
||||
// equal) -- see NarrowedDumpMetadataMultipleCandidateBins below for a case
|
||||
// where doppler_max and doppler_step differ.
|
||||
init(/*doppler_max=*/5000, /*doppler_step=*/5000, /*use_cfar=*/false);
|
||||
// supersede_property, not set_property: init() already called set_property
|
||||
// for "Acquisition_1C.dump" (InMemoryConfiguration::set_property() is a
|
||||
// std::map::insert, so a second set_property() with the same key is a
|
||||
@@ -539,17 +536,17 @@ TEST_F(PcpsAcquisitionDopplerNarrowingTest /*unused*/, NarrowedDumpMetadata /*un
|
||||
|
||||
TEST_F(PcpsAcquisitionDopplerNarrowingTest /*unused*/, NarrowedDumpMetadataMultipleCandidateBins /*unused*/)
|
||||
{
|
||||
// Same as NarrowedDumpMetadata, but with doppler_max != doppler_step and
|
||||
// doppler_narrowing_num_bins > 1, so a stale dump encoding (previously
|
||||
// written assuming exactly 1 candidate bin) can't pass by numeric
|
||||
// coincidence: half_span = (5-1)/2 = 2, so dump_doppler_max should be
|
||||
// 2*200 = 400 Hz, and dump_doppler_step the real per-bin step (200 Hz),
|
||||
// with 5+2 = 7 live columns (5 candidates + the opposite-sign reference
|
||||
// pair -- more than one real candidate means both +/-doppler_max
|
||||
// reference rows are computed, see d_num_reference_rows_active).
|
||||
// Same as NarrowedDumpMetadata, but with doppler_max != doppler_step and a
|
||||
// literal N == 5 request, so a stale dump encoding (previously written
|
||||
// assuming exactly 1 candidate bin) can't pass by numeric coincidence:
|
||||
// half_span = (5-1)/2 = 2, so dump_doppler_max should be 2*200 = 400 Hz,
|
||||
// and dump_doppler_step the real per-bin step (200 Hz), with 5+2 = 7 live
|
||||
// columns (5 candidates + the opposite-sign reference pair -- more than
|
||||
// one real candidate means both +/-doppler_max reference rows are
|
||||
// computed, see d_num_reference_rows_active).
|
||||
constexpr unsigned int kDopplerStep = 200;
|
||||
constexpr unsigned int kNumBins = 5;
|
||||
init(/*doppler_max=*/5000, /*doppler_step=*/kDopplerStep, /*enable_assisted_doppler_narrowing=*/true, /*use_cfar=*/false, /*doppler_narrowing_num_bins=*/kNumBins);
|
||||
init(/*doppler_max=*/5000, /*doppler_step=*/kDopplerStep, /*use_cfar=*/false);
|
||||
config->supersede_property("Acquisition_1C.dump", "true");
|
||||
config->supersede_property("Acquisition_1C.dump_filename", "./tmp-acq-narrow-dump-multi/acquisition");
|
||||
config->supersede_property("Acquisition_1C.dump_channel", "1");
|
||||
@@ -562,7 +559,7 @@ TEST_F(PcpsAcquisitionDopplerNarrowingTest /*unused*/, NarrowedDumpMetadataMulti
|
||||
fs::create_directory(data_str);
|
||||
|
||||
const int doppler_center = static_cast<int>(kTrueDopplerHz);
|
||||
const RunResult result = run_acquisition(top_block, config.get(), gnss_synchro, doppler_center, 1);
|
||||
const RunResult result = run_acquisition(top_block, config.get(), gnss_synchro, doppler_center, kNumBins);
|
||||
ASSERT_EQ(1, result.rx_message) << "Acquisition failure while producing the narrowed multi-bin dump.";
|
||||
|
||||
const std::string dump_filename = "./tmp-acq-narrow-dump-multi/acquisition_G_1C_ch_1_1_sat_1.mat";
|
||||
@@ -571,7 +568,7 @@ TEST_F(PcpsAcquisitionDopplerNarrowingTest /*unused*/, NarrowedDumpMetadataMulti
|
||||
|
||||
matvar_t *grid_var = Mat_VarRead(matfp, "acq_grid");
|
||||
ASSERT_NE(grid_var, nullptr) << "acq_grid missing from narrowed multi-bin dump";
|
||||
EXPECT_EQ(kNumBins + 2, grid_var->dims[1]) << "Narrowed acq_grid should be doppler_narrowing_num_bins + 2 columns wide (candidates plus the opposite-sign reference pair).";
|
||||
EXPECT_EQ(kNumBins + 2, grid_var->dims[1]) << "Narrowed acq_grid should be kNumBins + 2 columns wide (candidates plus the opposite-sign reference pair).";
|
||||
Mat_VarFree(grid_var);
|
||||
|
||||
matvar_t *doppler_max_var = Mat_VarRead(matfp, "doppler_max");
|
||||
@@ -591,8 +588,8 @@ TEST_F(PcpsAcquisitionDopplerNarrowingTest /*unused*/, NarrowedDumpMetadataMulti
|
||||
|
||||
TEST_F(PcpsAcquisitionDopplerNarrowingTest /*unused*/, FullGridSingleBinCfarUsesDedicatedReferenceRow /*unused*/)
|
||||
{
|
||||
// Plain full grid (enable_assisted_doppler_narrowing left off), configured
|
||||
// so doppler_step >= 2*doppler_max collapses it to exactly 1 bin, with CFAR
|
||||
// Plain full grid (the N == 0 sentinel), configured so doppler_step >=
|
||||
// 2*doppler_max collapses it to exactly 1 bin, with CFAR
|
||||
// enabled (pfa > 0, use_CFAR_algorithm_flag true). Regression coverage for
|
||||
// the sidelobe-floor fix: the generic "opposite bin" wraparound
|
||||
// (index_doppler + num_doppler_bins/2) % num_doppler_bins resolves to the
|
||||
@@ -605,7 +602,7 @@ TEST_F(PcpsAcquisitionDopplerNarrowingTest /*unused*/, FullGridSingleBinCfarUses
|
||||
// coverage of where that row lands), so CFAR detection still works, and
|
||||
// the single candidate bin, centered on doppler_center, lands on the true
|
||||
// Doppler.
|
||||
init(/*doppler_max=*/250, /*doppler_step=*/500, /*enable_assisted_doppler_narrowing=*/false, /*use_cfar=*/true);
|
||||
init(/*doppler_max=*/250, /*doppler_step=*/500, /*use_cfar=*/true);
|
||||
|
||||
const RunResult result = run_acquisition(top_block, config.get(), gnss_synchro, static_cast<int>(kTrueDopplerHz), 0);
|
||||
|
||||
@@ -628,7 +625,7 @@ TEST_F(PcpsAcquisitionDopplerNarrowingTest /*unused*/, FullGridReferenceRowClear
|
||||
// exactly the scenario this feature was built for: a grid too narrow for
|
||||
// the wraparound heuristic to be trusted, but not so narrow (N=52, not
|
||||
// N=1 or N=3) that the problem is obvious from the bin count alone.
|
||||
init(/*doppler_max=*/3200, /*doppler_step=*/125, /*enable_assisted_doppler_narrowing=*/false, /*use_cfar=*/true);
|
||||
init(/*doppler_max=*/3200, /*doppler_step=*/125, /*use_cfar=*/true);
|
||||
config->supersede_property("Acquisition_1C.dump", "true");
|
||||
config->supersede_property("Acquisition_1C.dump_filename", "./tmp-acq-full-grid-extra-row/acquisition");
|
||||
config->supersede_property("Acquisition_1C.dump_channel", "1");
|
||||
@@ -687,7 +684,7 @@ TEST_F(PcpsAcquisitionDopplerNarrowingTest /*unused*/, FullGridReferenceRowSelec
|
||||
// and picks the intended (opposite-side) row without misbehaving; it
|
||||
// would need a much stronger/pathological signal to actually flip
|
||||
// detection success/failure on a same-side vs. opposite-side reference.
|
||||
init(/*doppler_max=*/3200, /*doppler_step=*/125, /*enable_assisted_doppler_narrowing=*/false, /*use_cfar=*/true);
|
||||
init(/*doppler_max=*/3200, /*doppler_step=*/125, /*use_cfar=*/true);
|
||||
|
||||
const int doppler_center = static_cast<int>(kTrueDopplerHz) - 3250;
|
||||
const RunResult result = run_acquisition(top_block, config.get(), gnss_synchro, doppler_center, 0);
|
||||
|
||||
Reference in New Issue
Block a user