Files
gnss-sdr/src/core/interfaces/acquisition_interface.h
T
joebre 8f67752b9e Address review: memory safety, candidate selection, PFA, dump, naming
- Rename doppler_uncertanty -> doppler_uncertainty throughout (interface,
  adapter, block, comments, log message).

- Fix the out-of-bounds write and mis-detection in narrowed-mode
  activation: track it with an explicit d_doppler_search_narrowed flag,
  set directly in set_doppler_uncertainty() and guarded on
  d_num_doppler_bins > 1, instead of inferring it from
  "d_num_doppler_bins_active < d_num_doppler_bins". That inferred check
  broke two ways: for a 1-bin full grid (a valid, already-accepted
  config), it still forced 2 active bins, writing past the grid/wipeoff
  allocations sized to d_num_doppler_bins; for a 2-bin full grid, an
  actually-narrowed request computes the same active count as the full
  grid (2 < 2 is false), so it silently searched the full grid's own
  bin layout instead of the assisted {center, center + doppler_max}
  pair. Reproduced the out-of-bounds write directly (temporarily
  reverting to the inferred check crashes with "corrupted double-linked
  list" under the new NarrowingEnabledOneBinGrid test) and the
  mis-detection (NarrowingEnabledTwoBinGrid).

- Keep the noise-reference bin out of candidate selection: both
  max_to_input_power_statistic() and first_vs_second_peak_statistic()
  now take a separate candidate_count, used only for the peak-search
  loop bound; the CFAR path's own num_doppler_bins (used for the
  "opposite bin" reference lookup) is unchanged. In narrowed mode,
  candidate_count is 1 -- the noise-reference bin can no longer win and
  be reported as the acquisition result, regardless of its own power
  (verified against a live signal deliberately placed in the reference
  bin instead of the known/candidate bin: reverting this fix, both the
  CFAR and peak-ratio statistic mistakenly report the reference bin's
  Doppler as if it were the assisted center).

- Recalibrate the acceptance threshold for narrowed acquisition: adds
  d_threshold_narrowed, computed like d_threshold but with
  num_doppler_bins = 1 (the true candidate count in narrowed mode)
  instead of the full grid's bin count, since compute_threshold() folds
  the candidate count into the false-alarm probability and reusing the
  full-grid threshold in narrowed mode was effectively far stricter
  than the requested PFA. get_threshold() returns it whenever
  d_doppler_search_narrowed is true.

- Fix narrowed dump layout/metadata: ensure_dump_grid_allocated() now
  sizes acq_grid to d_num_doppler_bins_active (not the full grid width),
  matching what copy_magnitude_grid_to_dump_grid() actually writes each
  cycle -- this also makes narrow<->full transitions between dumps
  self-correcting. dump_results() writes accurate, mode-appropriate
  doppler_max/doppler_step (the same {0, doppler_max} encoding
  compute_statistics() uses internally when narrowed), plus new
  doppler_center and doppler_narrowed fields so offline post-processing
  can tell which encoding is in effect. Verified end to end against a
  live dump (NarrowedDumpMetadata).

- Strengthen Acq_Conf::enable_doppler_narrowing's doc comment (default,
  which implementations it applies to, its dependency on the caller
  passing doppler_uncertainty == 0) and add a commented usage example
  next to GNSS-SDR.assist_dual_frequency_acq in a dual-frequency
  Galileo E1B+E5a example config.

- Add tests/.../pcps_acquisition_doppler_narrowing_test.cc: 8 focused
  tests (narrowing enabled/disabled, 1-bin and 2-bin full-grid
  configurations, CFAR and peak-ratio statistics, a full-narrow-full
  transition, two-step acquisition with step-1 narrowing, and narrowed
  dump metadata), built on the same real-capture/known-ground-truth
  pattern as gps_l1_ca_pcps_acquisition_test.cc. Confirmed each targeted
  regression test actually fails without its corresponding fix before
  finalizing them.

Signed-off-by: joebre <joel.brenner@saphyrion.ch>
2026-08-31 09:38:13 +02:00

73 lines
2.6 KiB
C++

/*!
* \file acquisition_interface.h
* \brief Header file of the interface to an acquisition GNSS block.
* \author Carlos Aviles, 2010. carlos.avilesr(at)googlemail.com
* Luis Esteve, 2011. luis(at)epsilon-formacion.com
*
* This header file contains the interface to an abstract class
* for acquisition algorithms. Since all its methods are virtual,
* this class cannot be instantiated directly, and a subclass can only be
* instantiated directly if all inherited pure virtual methods have been
* implemented by that class or a parent class.
*
* -----------------------------------------------------------------------------
*
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
* This file is part of GNSS-SDR.
*
* Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* -----------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_ACQUISITION_INTERFACE_H
#define GNSS_SDR_ACQUISITION_INTERFACE_H
#include "gnss_block_interface.h"
#include "gnss_synchro.h"
#include <memory>
/** \addtogroup Core
* \{ */
/** \addtogroup GNSS_Block_Interfaces GNSS block interfaces
* GNSS block interfaces.
* \{ */
template <typename Data>
class Concurrent_Queue;
class ChannelFsm;
/*! \brief This abstract class represents an interface to an acquisition GNSS block.
*
* Abstract class for acquisition algorithms. Since all its methods are virtual,
* this class cannot be instantiated directly, and a subclass can only be
* instantiated directly if all inherited pure virtual methods have been
* implemented by that class or a parent class.
*/
class AcquisitionInterface : public GNSSBlockInterface
{
public:
virtual void set_gnss_synchro(Gnss_Synchro* gnss_synchro) = 0;
virtual void set_channel(unsigned int channel_id) = 0;
virtual void set_channel_fsm(std::weak_ptr<ChannelFsm> channel_fsm) = 0;
virtual void set_doppler_center(int /*doppler_center*/) {}
//! doppler_uncertainty == 0 restricts the Doppler search to a single bin
//! centered on set_doppler_center() (the Doppler is exactly known, as when
//! assisted by an already-tracked primary frequency); any other value
//! searches the full configured Doppler range.
virtual void set_doppler_uncertainty(unsigned int /*doppler_uncertainty*/) {}
virtual void set_local_code() = 0;
virtual signed int mag() = 0;
virtual void reset() = 0;
virtual void stop_acquisition() = 0;
virtual void set_resampler_latency(uint32_t latency_samples) = 0;
};
/** \} */
/** \} */
#endif // GNSS_SDR_ACQUISITION_INTERFACE */