mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-05-23 22:58:10 +08:00
refactor(gpsRedundancyCheck): address code review feedback
This commit is contained in:
@@ -138,11 +138,14 @@ parameters:
|
||||
reboot_required: true
|
||||
SYS_HAS_NUM_GNSS:
|
||||
description:
|
||||
short: Control if and how many GNSS receivers are expected
|
||||
short: Control if and how many GNSS receivers are required
|
||||
long: |-
|
||||
0: Disable GNSS redundancy check (any number of GNSS receivers is acceptable).
|
||||
0: No minimum receiver count required. Position divergence between two receivers
|
||||
and loss of a GNSS receiver still produce a warning but never trigger the
|
||||
COM_GPS_LOSS_ACT failsafe action.
|
||||
1-N: Require the presence of N GNSS receivers for arming and during flight.
|
||||
If the active count drops below this value in flight, COM_GPS_LOSS_ACT is triggered.
|
||||
When set to 2, position divergence between the two receivers also triggers COM_GPS_LOSS_ACT.
|
||||
type: int32
|
||||
default: 0
|
||||
min: 0
|
||||
|
||||
@@ -136,6 +136,20 @@ public:
|
||||
& (uint64_t)events::px4::enums::health_component_t::gps) != 0;
|
||||
}
|
||||
|
||||
// Runs one check cycle and returns true if gnss_lost was set (failsafe would trigger)
|
||||
bool hasGnssLost(bool armed)
|
||||
{
|
||||
vehicle_status_s status{};
|
||||
status.arming_state = armed
|
||||
? vehicle_status_s::ARMING_STATE_ARMED
|
||||
: vehicle_status_s::ARMING_STATE_DISARMED;
|
||||
Context context{status};
|
||||
failsafe_flags_s failsafe_flags{};
|
||||
Report reporter{failsafe_flags, 0_s};
|
||||
_check->checkAndReport(context, reporter);
|
||||
return failsafe_flags.gnss_lost;
|
||||
}
|
||||
|
||||
static orb_advert_t _pub0;
|
||||
static orb_advert_t _pub1;
|
||||
GpsRedundancyChecks *_check{nullptr};
|
||||
@@ -198,6 +212,41 @@ TEST_F(GpsRedundancyCheckTest, FixTypeBelow3TreatedAsInactive)
|
||||
EXPECT_FALSE(hasDivergenceWarning(false));
|
||||
}
|
||||
|
||||
// Divergence with SYS_HAS_NUM_GNSS=2 and COM_GPS_LOSS_ACT>0 → gnss_lost set (failsafe fires)
|
||||
TEST_F(GpsRedundancyCheckTest, DivergenceWithRedundancyRequiredSetsGnssLost)
|
||||
{
|
||||
int i = 2;
|
||||
param_set(param_find("SYS_HAS_NUM_GNSS"), &i);
|
||||
i = 1; // Return
|
||||
param_set(param_find("COM_GPS_LOSS_ACT"), &i);
|
||||
delete _check;
|
||||
_check = new GpsRedundancyChecks();
|
||||
|
||||
sensor_gps_s gps0 = makeGps(BASE_LAT, BASE_LON);
|
||||
sensor_gps_s gps1 = makeGps(DIVERGING_LAT, BASE_LON);
|
||||
orb_publish(ORB_ID(sensor_gps), _pub0, &gps0);
|
||||
orb_publish(ORB_ID(sensor_gps), _pub1, &gps1);
|
||||
EXPECT_TRUE(hasGnssLost(false));
|
||||
}
|
||||
|
||||
// Divergence with SYS_HAS_NUM_GNSS=0 and COM_GPS_LOSS_ACT>0 → warning only, gnss_lost not set
|
||||
TEST_F(GpsRedundancyCheckTest, DivergenceWithoutRedundancyRequiredWarnsOnly)
|
||||
{
|
||||
int i = 0;
|
||||
param_set(param_find("SYS_HAS_NUM_GNSS"), &i);
|
||||
i = 1; // Return
|
||||
param_set(param_find("COM_GPS_LOSS_ACT"), &i);
|
||||
delete _check;
|
||||
_check = new GpsRedundancyChecks();
|
||||
|
||||
sensor_gps_s gps0 = makeGps(BASE_LAT, BASE_LON);
|
||||
sensor_gps_s gps1 = makeGps(DIVERGING_LAT, BASE_LON);
|
||||
orb_publish(ORB_ID(sensor_gps), _pub0, &gps0);
|
||||
orb_publish(ORB_ID(sensor_gps), _pub1, &gps1);
|
||||
EXPECT_FALSE(hasGnssLost(false));
|
||||
EXPECT_TRUE(hasDivergenceWarning(false));
|
||||
}
|
||||
|
||||
// Divergence then recovery: timer resets and warning stops
|
||||
TEST_F(GpsRedundancyCheckTest, DivergenceClearsAfterRecovery)
|
||||
{
|
||||
|
||||
@@ -75,12 +75,16 @@ void GpsRedundancyChecks::checkAndReport(const Context &context, Report &reporte
|
||||
}
|
||||
}
|
||||
|
||||
const int required = _param_sys_has_num_gnss.get();
|
||||
|
||||
// Position divergence check: warn if two fixed receivers disagree beyond their combined
|
||||
// uncertainty. The gate is: lever-arm separation + GNSS_DIVERGENCE_SIGMA * RMS(eph0, eph1).
|
||||
// Using RMS(eph) means the gate tightens when both receivers are accurate and widens
|
||||
// automatically when one degrades, avoiding false alarms without a hard-coded threshold.
|
||||
// Pre-arm: warn immediately. In-flight: require GPS_DIVERGENCE_SUSTAIN to suppress
|
||||
// transient multipath spikes.
|
||||
// The failsafe action is only triggered when SYS_HAS_NUM_GNSS >= 2; otherwise divergence
|
||||
// is reported as a warning only.
|
||||
bool divergence_active = false;
|
||||
|
||||
if (fixed_count >= 2) {
|
||||
@@ -106,8 +110,8 @@ void GpsRedundancyChecks::checkAndReport(const Context &context, Report &reporte
|
||||
}
|
||||
|
||||
if (hrt_elapsed_time(&_divergence_since) >= sustain) {
|
||||
divergence_active = true;
|
||||
const bool act = (_param_com_gnss_loss_act.get() > 0);
|
||||
const bool act = (_param_com_gnss_loss_act.get() > 0) && (required >= 2);
|
||||
divergence_active = act;
|
||||
|
||||
/* EVENT
|
||||
* @description
|
||||
@@ -115,6 +119,7 @@ void GpsRedundancyChecks::checkAndReport(const Context &context, Report &reporte
|
||||
*
|
||||
* <profile name="dev">
|
||||
* Configure the failsafe action with <param>COM_GPS_LOSS_ACT</param>.
|
||||
* The failsafe action is only triggered when <param>SYS_HAS_NUM_GNSS</param> is set to 2.
|
||||
* </profile>
|
||||
*/
|
||||
reporter.healthFailure<float, float>(act ? NavModes::All : NavModes::None,
|
||||
@@ -135,7 +140,6 @@ void GpsRedundancyChecks::checkAndReport(const Context &context, Report &reporte
|
||||
_peak_fixed_count = fixed_count;
|
||||
}
|
||||
|
||||
const int required = _param_sys_has_num_gnss.get();
|
||||
const bool below_required = (required > 0 && fixed_count < required);
|
||||
const bool dropped_below_peak = (_peak_fixed_count > 1 && fixed_count < _peak_fixed_count);
|
||||
|
||||
|
||||
@@ -136,8 +136,9 @@ parameters:
|
||||
short: GNSS loss failsafe mode
|
||||
long: |-
|
||||
Action the system takes when a GNSS failure is detected during flight.
|
||||
Triggers when the active GNSS count drops below SYS_HAS_NUM_GNSS or when
|
||||
two receivers report positions inconsistent with their reported accuracy.
|
||||
Triggers when the active GNSS count drops below SYS_HAS_NUM_GNSS (disabled
|
||||
when SYS_HAS_NUM_GNSS=0), or when two receivers report positions inconsistent
|
||||
with their reported accuracy and SYS_HAS_NUM_GNSS=2 (otherwise warning only).
|
||||
Any value above Warning also blocks arming.
|
||||
type: enum
|
||||
values:
|
||||
|
||||
Reference in New Issue
Block a user