mirror of https://github.com/gnss-sdr/gnss-sdr
Generic ephemeris validator
Implement generic ephemeris validator: Keep previous and last valid ephemeris. Compare received ephemeris to previous and last valid. Count successful comparisions. Update last valid ephemeris if count reaches threshold. Add telemetry decoder configuration parameters: int32_t TelemetryDecoder_B1.ecc_reject - reject ephemeris if the ECC error counter reaches this value int32_t TelemetryDecoder_B1.ecc_resync - resync telemetry decoder if the ECC error counter reaches this value int32_t TelemetryDecoder_B1.validator_thr - number of equal ephemeris received, after that the ephemeris would be passed to observable. Set to 1 to disable validation bool TelemetryDecoder_B1.validator_accept_first - an option to always pass the first received ephemeris, bypassing the validator for one time. This may speed up first PVT solution at cost of higher probability of getting incorrect PVT in case, the first epehemeris would be corrupt. Signed-off-by: Vladislav P <vladisslav2011@gmail.com>
This commit is contained in:
parent
f09da3ded6
commit
0282e61ac0
|
@ -34,4 +34,10 @@ void Tlm_Conf::SetFromConfiguration(const ConfigurationInterface *configuration,
|
|||
{
|
||||
there_are_e6_channels = true;
|
||||
}
|
||||
ecc_errors_reject = configuration->property(role + ".ecc_reject", 1);
|
||||
ecc_errors_reject = (ecc_errors_reject < 1) ? 1 : ecc_errors_reject;
|
||||
ecc_errors_resync = configuration->property(role + ".ecc_resync", 6);
|
||||
ecc_errors_resync = (ecc_errors_resync < 1) ? 1 : ecc_errors_resync;
|
||||
validator_thr = configuration->property(role + ".validator_thr", 2);
|
||||
validator_accept_first = configuration->property(role + ".validator_accept_first", true);
|
||||
}
|
||||
|
|
|
@ -43,6 +43,10 @@ public:
|
|||
bool dump_crc_stats{false}; // telemetry CRC statistics
|
||||
bool enable_navdata_monitor{false};
|
||||
bool there_are_e6_channels{false};
|
||||
int32_t ecc_errors_reject{1};
|
||||
int32_t ecc_errors_resync{6};
|
||||
uint32_t validator_thr{2};
|
||||
bool validator_accept_first{true};
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
|
||||
set(SYSTEM_PARAMETERS_SOURCES
|
||||
common_ephemeris.cc
|
||||
gnss_almanac.cc
|
||||
gnss_ephemeris.cc
|
||||
gnss_satellite.cc
|
||||
|
@ -31,6 +32,7 @@ set(SYSTEM_PARAMETERS_SOURCES
|
|||
)
|
||||
|
||||
set(SYSTEM_PARAMETERS_HEADERS
|
||||
common_ephemeris.h
|
||||
gnss_almanac.h
|
||||
gnss_ephemeris.h
|
||||
gnss_satellite.h
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
/*!
|
||||
* \file common_ephemeris.cc
|
||||
* \brief Base class for GNSS Ephemeris
|
||||
* \author Vladislav P, 2022. vladisslav2011(at)gmail.com
|
||||
*
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "common_ephemeris.h"
|
||||
#include <cmath>
|
||||
#include <numeric>
|
||||
|
||||
bool Common_Ephemeris::validate(history_set &hist, const std::shared_ptr<Common_Ephemeris> &eph, const int thr, const bool first_pass)
|
||||
{
|
||||
double dev_last = -1.0;
|
||||
double dev_val = -1.0;
|
||||
const int prn = eph->PRN - 1;
|
||||
bool ret = false;
|
||||
if (thr == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (hist[prn].last_eph.get())
|
||||
{
|
||||
dev_last = hist[prn].last_eph->max_deviation(*eph.get());
|
||||
#ifdef EPHEMERIS_VALIDATOR_DEBUG
|
||||
if (hist[prn].last_eph.get() == eph.get())
|
||||
{
|
||||
std::cout << "\nhist[prn].last_eph.get() == eph.get()\n\n";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (hist[prn].valid_eph.get())
|
||||
{
|
||||
dev_val = hist[prn].valid_eph->max_deviation(*eph.get());
|
||||
#ifdef EPHEMERIS_VALIDATOR_DEBUG
|
||||
if (hist[prn].valid_eph.get() == eph.get())
|
||||
{
|
||||
std::cout << "\nhist[prn].last_eph.get() == eph.get()\n\n";
|
||||
}
|
||||
#endif
|
||||
if (dev_last < dev_val)
|
||||
{
|
||||
if (dev_last < DEVIATION_THRESHOLD)
|
||||
{
|
||||
hist[prn].valid_eph = eph;
|
||||
hist[prn].valid_eph_count = 2;
|
||||
ret = hist[prn].valid_eph_count >= hist[prn].valid_eph_thr;
|
||||
hist[prn].valid_eph_thr = (thr > 2) ? thr : 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dev_val < DEVIATION_THRESHOLD)
|
||||
{
|
||||
hist[prn].valid_eph_count++;
|
||||
hist[prn].valid_eph_thr = (thr > 2) ? thr : 2;
|
||||
ret = hist[prn].valid_eph_count >= hist[prn].valid_eph_thr;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hist[prn].valid_eph = eph;
|
||||
hist[prn].valid_eph_count = 1;
|
||||
hist[prn].valid_eph_thr = thr;
|
||||
ret = first_pass || hist[prn].valid_eph_count >= hist[prn].valid_eph_thr;
|
||||
}
|
||||
hist[prn].last_eph = eph;
|
||||
#ifdef EPHEMERIS_VALIDATOR_DEBUG
|
||||
std::cout << "PRN " << eph->PRN << " dev_last = " << dev_last << " dev_val = " << dev_val << " count = " << hist[prn].valid_eph_count << "\n";
|
||||
#endif
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*!
|
||||
* \file common_ephemeris.h
|
||||
* \brief Base class for GNSS Ephemeris
|
||||
* \author Vladislav P, 2022. vladisslav2011(at)gmail.com
|
||||
*
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GNSS_SDR_COMMON_EPHEMERIS_H
|
||||
#define GNSS_SDR_COMMON_EPHEMERIS_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#ifdef EPHEMERIS_VALIDATOR_DEBUG
|
||||
#include <iostream>
|
||||
#define update_eph_deviation(NN) \
|
||||
{ \
|
||||
if (std::fabs((NN)-tmp.NN) > dev) \
|
||||
{ \
|
||||
dev = std::fabs((NN)-tmp.NN); \
|
||||
std::cout << "Gnss_Ephemeris::max_deviation " #NN << ": " << (NN) << "-" << tmp.NN << "=" << std::fabs((NN)-tmp.NN) << "\n"; \
|
||||
} \
|
||||
}
|
||||
#else
|
||||
#define update_eph_deviation(NN) \
|
||||
{ \
|
||||
if (std::fabs((NN)-tmp.NN) > dev) \
|
||||
{ \
|
||||
dev = std::fabs((NN)-tmp.NN); \
|
||||
} \
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
class Common_Ephemeris
|
||||
{
|
||||
private:
|
||||
using last_valid = struct
|
||||
{
|
||||
std::shared_ptr<Common_Ephemeris> last_eph;
|
||||
std::shared_ptr<Common_Ephemeris> valid_eph;
|
||||
int valid_eph_count;
|
||||
int valid_eph_thr;
|
||||
};
|
||||
|
||||
protected:
|
||||
static constexpr double DEVIATION_THRESHOLD = 0.00001;
|
||||
|
||||
public:
|
||||
using history_set = std::vector<last_valid>;
|
||||
Common_Ephemeris() = default;
|
||||
virtual ~Common_Ephemeris() = default;
|
||||
virtual double max_deviation(Common_Ephemeris &from) = 0; //!< Compare a set of ephemeris to another one
|
||||
static bool validate(history_set &hist, const std::shared_ptr<Common_Ephemeris> &eph, const int thr, const bool first_pass);
|
||||
uint32_t PRN{}; //!< SV ID
|
||||
};
|
||||
|
||||
|
||||
#endif // GNSS_SDR_COMMON_EPHEMERIS_H
|
|
@ -21,10 +21,10 @@
|
|||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <numeric>
|
||||
#include <vector>
|
||||
|
||||
|
||||
double Gnss_Ephemeris::sv_clock_drift(double transmitTime)
|
||||
{
|
||||
const double dt = check_t(transmitTime - this->toc);
|
||||
|
@ -165,8 +165,37 @@ void Gnss_Ephemeris::satellitePosition(double transmitTime)
|
|||
this->dtr = pos_vel_dtr[6];
|
||||
}
|
||||
|
||||
double Gnss_Ephemeris::max_deviation(Common_Ephemeris &from)
|
||||
{
|
||||
const Gnss_Ephemeris &tmp = dynamic_cast<Gnss_Ephemeris &>(from);
|
||||
double dev = 0.0;
|
||||
update_eph_deviation(PRN);
|
||||
update_eph_deviation(M_0);
|
||||
update_eph_deviation(delta_n);
|
||||
update_eph_deviation(ecc);
|
||||
update_eph_deviation(sqrtA);
|
||||
update_eph_deviation(OMEGA_0);
|
||||
update_eph_deviation(i_0);
|
||||
update_eph_deviation(omega);
|
||||
update_eph_deviation(OMEGAdot);
|
||||
update_eph_deviation(idot);
|
||||
update_eph_deviation(Cuc);
|
||||
update_eph_deviation(Cus);
|
||||
update_eph_deviation(Crc);
|
||||
update_eph_deviation(Crs);
|
||||
update_eph_deviation(Cic);
|
||||
update_eph_deviation(Cis);
|
||||
// update_eph_deviation(toe);
|
||||
// update_eph_deviation(toc);
|
||||
update_eph_deviation(af0);
|
||||
update_eph_deviation(af1);
|
||||
update_eph_deviation(af2);
|
||||
update_eph_deviation(satClkDrift);
|
||||
update_eph_deviation(dtr);
|
||||
return dev;
|
||||
}
|
||||
|
||||
void Gnss_Ephemeris::satellitePosVelComputation(double transmitTime, std::array<double, 7>& pos_vel_dtr) const
|
||||
void Gnss_Ephemeris::satellitePosVelComputation(double transmitTime, std::array<double, 7> &pos_vel_dtr) const
|
||||
{
|
||||
// Restore semi-major axis
|
||||
const double a = this->sqrtA * this->sqrtA;
|
||||
|
|
|
@ -19,13 +19,16 @@
|
|||
#ifndef GNSS_SDR_GNSS_EPHEMERIS_H
|
||||
#define GNSS_SDR_GNSS_EPHEMERIS_H
|
||||
|
||||
#include "common_ephemeris.h"
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
/*!
|
||||
* \brief Base class for GNSS ephemeris storage
|
||||
*/
|
||||
class Gnss_Ephemeris
|
||||
class Gnss_Ephemeris : public Common_Ephemeris
|
||||
{
|
||||
public:
|
||||
Gnss_Ephemeris() = default;
|
||||
|
@ -65,9 +68,9 @@ public:
|
|||
*/
|
||||
double predicted_doppler(double rx_time_s, double lat, double lon, double h, double ve, double vn, double vu, int band) const;
|
||||
|
||||
void satellitePosition(double transmitTime); //!< Computes the ECEF SV coordinates and ECEF velocity
|
||||
void satellitePosition(double transmitTime); //!< Computes the ECEF SV coordinates and ECEF velocity
|
||||
double max_deviation(Common_Ephemeris &from) override; //!< Compare a set of ephemeris to another one
|
||||
|
||||
uint32_t PRN{}; //!< SV ID
|
||||
double M_0{}; //!< Mean anomaly at reference time [rad]
|
||||
double delta_n{}; //!< Mean motion difference from computed value [rad/sec]
|
||||
double ecc{}; //!< Eccentricity
|
||||
|
@ -112,7 +115,7 @@ protected:
|
|||
char System{}; //!< Character ID of the GNSS system. 'G': GPS. 'E': Galileo. 'B': BeiDou
|
||||
|
||||
private:
|
||||
void satellitePosVelComputation(double transmitTime, std::array<double, 7>& pos_vel_dtr) const;
|
||||
void satellitePosVelComputation(double transmitTime, std::array<double, 7> &pos_vel_dtr) const;
|
||||
double check_t(double time) const;
|
||||
double sv_clock_relativistic_term(double transmitTime) const;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue