1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-22 07:45:29 +03:00

Only allow arming when valid Rx signals are received (#13033)

* Only allow arming when failsafe criteria are cleared

* 500ms RXLOSS period with 100ms minimum
This commit is contained in:
ctzsnooze 2023-09-01 23:58:26 +10:00 committed by GitHub
parent d1025bd1f5
commit a35a5af16c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 23 additions and 27 deletions

View file

@ -880,7 +880,7 @@ const clivalue_t valueTable[] = {
{ "failsafe_switch_mode", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_FAILSAFE_SWITCH_MODE }, PG_FAILSAFE_CONFIG, offsetof(failsafeConfig_t, failsafe_switch_mode) },
{ "failsafe_throttle_low_delay",VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 300 }, PG_FAILSAFE_CONFIG, offsetof(failsafeConfig_t, failsafe_throttle_low_delay) },
{ "failsafe_procedure", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_FAILSAFE }, PG_FAILSAFE_CONFIG, offsetof(failsafeConfig_t, failsafe_procedure) },
{ "failsafe_recovery_delay", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 200 }, PG_FAILSAFE_CONFIG, offsetof(failsafeConfig_t, failsafe_recovery_delay) },
{ "failsafe_recovery_delay", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 1, 200 }, PG_FAILSAFE_CONFIG, offsetof(failsafeConfig_t, failsafe_recovery_delay) },
{ "failsafe_stick_threshold", VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 50 }, PG_FAILSAFE_CONFIG, offsetof(failsafeConfig_t, failsafe_stick_threshold) },
// PG_BOARDALIGNMENT_CONFIG

View file

@ -297,10 +297,10 @@ void updateArmingStatus(void)
if (justGotRxBack && IS_RC_MODE_ACTIVE(BOXARM)) {
// If the RX has just started to receive a signal again and the arm switch is on, apply arming restriction
setArmingDisabled(ARMING_DISABLED_BAD_RX_RECOVERY);
setArmingDisabled(ARMING_DISABLED_NOT_DISARMED);
} else if (haveRx && !IS_RC_MODE_ACTIVE(BOXARM)) {
// If RX signal is OK and the arm switch is off, remove arming restriction
unsetArmingDisabled(ARMING_DISABLED_BAD_RX_RECOVERY);
unsetArmingDisabled(ARMING_DISABLED_NOT_DISARMED);
}
hadRx = haveRx;

View file

@ -37,7 +37,7 @@ const char *armingDisableFlagNames[]= {
"NOGYRO",
"FAILSAFE",
"RXLOSS",
"BADRX",
"NOT_DISARMED",
"BOXFAILSAFE",
"RUNAWAY",
"CRASH",

View file

@ -43,7 +43,7 @@ typedef enum {
ARMING_DISABLED_NO_GYRO = (1 << 0),
ARMING_DISABLED_FAILSAFE = (1 << 1),
ARMING_DISABLED_RX_FAILSAFE = (1 << 2),
ARMING_DISABLED_BAD_RX_RECOVERY = (1 << 3),
ARMING_DISABLED_NOT_DISARMED = (1 << 3),
ARMING_DISABLED_BOXFAILSAFE = (1 << 4),
ARMING_DISABLED_RUNAWAY_TAKEOFF = (1 << 5),
ARMING_DISABLED_CRASH_DETECTED = (1 << 6),

View file

@ -69,7 +69,7 @@ PG_RESET_TEMPLATE(failsafeConfig_t, failsafeConfig,
.failsafe_off_delay = 10, // 1 sec in landing phase, if enabled
.failsafe_switch_mode = FAILSAFE_SWITCH_MODE_STAGE1, // default failsafe switch action is identical to rc link loss
.failsafe_procedure = FAILSAFE_PROCEDURE_DROP_IT, // default full failsafe procedure is 0: auto-landing
.failsafe_recovery_delay = 10, // 1 sec of valid rx data needed to allow recovering from failsafe procedure
.failsafe_recovery_delay = 5, // 500ms of valid rx data needed to allow recovery from failsafe and arming block
.failsafe_stick_threshold = 30 // 30 percent of stick deflection to exit GPS Rescue procedure
);
@ -88,12 +88,12 @@ void failsafeReset(void)
{
failsafeState.rxDataFailurePeriod = failsafeConfig()->failsafe_delay * MILLIS_PER_TENTH_SECOND;
if (failsafeState.rxDataFailurePeriod < PERIOD_RXDATA_RECOVERY){
// avoid transients and ensure reliable arming for minimum of PERIOD_RXDATA_RECOVERY (200ms)
// avoid transients and ensure reliable arming for minimum of PERIOD_RXDATA_RECOVERY (100ms)
failsafeState.rxDataFailurePeriod = PERIOD_RXDATA_RECOVERY;
}
failsafeState.rxDataRecoveryPeriod = failsafeConfig()->failsafe_recovery_delay * MILLIS_PER_TENTH_SECOND;
if (failsafeState.rxDataRecoveryPeriod < PERIOD_RXDATA_RECOVERY) {
// PERIOD_RXDATA_RECOVERY (200ms) is the minimum allowed RxData recovery time
// PERIOD_RXDATA_RECOVERY (100ms) is the minimum allowed RxData recovery time
failsafeState.rxDataRecoveryPeriod = PERIOD_RXDATA_RECOVERY;
}
failsafeState.validRxDataReceivedAt = 0;
@ -160,25 +160,20 @@ void failsafeOnRxResume(void)
}
void failsafeOnValidDataReceived(void)
// enters stage 2
// runs, after prior a signal loss, immediately when packets are received or the BOXFAILSAFE switch is reverted
// rxLinkState will go RXLINK_UP immediately if BOXFAILSAFE goes back ON since receivingRxDataPeriodPreset is set to zero in that case
// otherwise RXLINK_UP is delayed for the recovery period (failsafe_recovery_delay, default 1s, 0-20, min 0.2s)
// otherwise RXLINK_UP is delayed for the recovery period (failsafe_recovery_delay, default 500ms, 1-20, min 0.1s)
{
unsetArmingDisabled(ARMING_DISABLED_RX_FAILSAFE);
// clear RXLOSS in OSD immediately we get a good packet, and un-set its arming block
failsafeState.validRxDataReceivedAt = millis();
if (failsafeState.validRxDataFailedAt == 0) {
// after initialisation, we sometimes only receive valid packets,
// then we don't know how long the signal has been valid for
// in this setting, the time the signal first valid is also time it was last valid, so
// after initialisation, we sometimes only receive valid packets, so validRxDataFailedAt will remain unset (0)
// in this setting, the time the signal is first valid is also time it was last valid, so
// initialise validRxDataFailedAt to the time of the first valid data
failsafeState.validRxDataFailedAt = failsafeState.validRxDataReceivedAt;
setArmingDisabled(ARMING_DISABLED_BST);
// prevent arming until we have valid data for rxDataRecoveryPeriod after initialisation
// using the BST flag since no other suitable name....
// show RXLOSS in OSD to indicate reason we cannot arm
setArmingDisabled(ARMING_DISABLED_RX_FAILSAFE);
}
if (cmp32(failsafeState.validRxDataReceivedAt, failsafeState.validRxDataFailedAt) > (int32_t)failsafeState.receivingRxDataPeriodPreset) {
@ -186,7 +181,8 @@ void failsafeOnValidDataReceived(void)
// rxDataRecoveryPeriod defaults to 1.0s with minimum of PERIOD_RXDATA_RECOVERY (200ms)
// link is not considered 'up', after it has been 'down', until that recovery period has expired
failsafeState.rxLinkState = FAILSAFE_RXLINK_UP;
unsetArmingDisabled(ARMING_DISABLED_BST);
// after the rxDataRecoveryPeriod, typically 1s after receiving valid data, clear RXLOSS in OSD and permit arming
unsetArmingDisabled(ARMING_DISABLED_RX_FAILSAFE);
}
}
@ -195,12 +191,12 @@ void failsafeOnValidDataFailed(void)
// after the stage 1 delay has expired, sets the rxLinkState to RXLINK_DOWN, ie not up, causing failsafeIsReceivingRxData to become false
// if failsafe is configured to go direct to stage 2, this is emulated immediately in failsafeUpdateState()
{
// set RXLOSS in OSD and block arming after 100ms of signal loss
setArmingDisabled(ARMING_DISABLED_RX_FAILSAFE);
// set RXLOSS in OSD and block arming after 100ms of signal loss (is restored in rx.c immediately signal returns)
failsafeState.validRxDataFailedAt = millis();
if ((cmp32(failsafeState.validRxDataFailedAt, failsafeState.validRxDataReceivedAt) > (int32_t)failsafeState.rxDataFailurePeriod)) {
// sets rxLinkState = DOWN to initiate stage 2 failsafe
// sets rxLinkState = DOWN to initiate stage 2 failsafe after expiry of the Stage 1 period
failsafeState.rxLinkState = FAILSAFE_RXLINK_DOWN;
// show RXLOSS and block arming
}

View file

@ -29,7 +29,7 @@
#define PERIOD_OF_3_SECONDS 3 * MILLIS_PER_SECOND
#define PERIOD_OF_30_SECONDS 30 * MILLIS_PER_SECOND
#define PERIOD_RXDATA_FAILURE 10 // millis
#define PERIOD_RXDATA_RECOVERY 200 // millis
#define PERIOD_RXDATA_RECOVERY 100 // millis
typedef struct failsafeConfig_s {
uint16_t failsafe_throttle; // Throttle level used for landing - specify value between 1000..2000 (pwm pulse width for slightly below hover). center throttle = 1500.
@ -38,7 +38,7 @@ typedef struct failsafeConfig_s {
uint8_t failsafe_off_delay; // Time for Landing before motors stop in 0.1sec. 1 step = 0.1sec - 20sec in example (200)
uint8_t failsafe_switch_mode; // failsafe switch action is 0: Stage 1, 1: Disarms instantly, 2: Stage 2
uint8_t failsafe_procedure; // selected full failsafe procedure is 0: auto-landing, 1: Drop it
uint16_t failsafe_recovery_delay; // Time (in 0.1sec) of valid rx data (min 200ms PERIOD_RXDATA_RECOVERY) to allow recovering from failsafe procedure
uint16_t failsafe_recovery_delay; // Time (in 0.1sec) of valid rx data (min 100ms PERIOD_RXDATA_RECOVERY) to allow recovering from failsafe procedure
uint8_t failsafe_stick_threshold; // Stick deflection percentage to exit GPS Rescue procedure
} failsafeConfig_t;

View file

@ -750,7 +750,7 @@ void detectAndApplySignalLossBehaviour(void)
// --> start the timer to exit stage 2 failsafe 100ms after losing all packets or the BOXFAILSAFE switch is actioned
} else {
failsafeOnValidDataFailed();
// -> start timer to enter stage2 failsafe the instant we get a good packet or the BOXFAILSAFE switch is reverted
// -> start stage 1 timer to enter stage2 failsafe the instant we get a good packet or the BOXFAILSAFE switch is reverted
}
DEBUG_SET(DEBUG_RX_SIGNAL_LOSS, 3, rcData[THROTTLE]);

View file

@ -372,7 +372,7 @@ TEST(ArmingPreventionTest, RadioTurnedOnAtAnyTimeArmed)
// expect
EXPECT_FALSE(isUsingSticksForArming());
EXPECT_TRUE(isArmingDisabled());
EXPECT_EQ(ARMING_DISABLED_BAD_RX_RECOVERY | ARMING_DISABLED_ARM_SWITCH, getArmingDisableFlags());
EXPECT_EQ(ARMING_DISABLED_NOT_DISARMED | ARMING_DISABLED_ARM_SWITCH, getArmingDisableFlags());
// given
// arm switch turned off by user
@ -1083,7 +1083,7 @@ extern "C" {
void failsafeStartMonitoring(void) {}
void failsafeUpdateState(void) {}
bool failsafeIsActive(void) { return false; }
bool failsafeIsReceivingRxData(void) { return false; }
bool failsafeIsReceivingRxData(void) { return true; }
bool rxAreFlightChannelsValid(void) { return false; }
void pidResetIterm(void) {}
void updateAdjustmentStates(void) {}

View file

@ -86,7 +86,7 @@ void configureFailsafe(void)
failsafeConfigMutable()->failsafe_throttle = 1200;
failsafeConfigMutable()->failsafe_throttle_low_delay = 100; // 10 seconds
failsafeConfigMutable()->failsafe_procedure = FAILSAFE_PROCEDURE_AUTO_LANDING;
// NB we don't have failsafe_recovery_delay so use PERIOD_RXDATA_RECOVERY (200ms)
// NB we don't have failsafe_recovery_delay so use PERIOD_RXDATA_RECOVERY (100ms)
sysTickUptime = 0;
}