diff --git a/src/main/cli/settings.c b/src/main/cli/settings.c index 10a36d891c..a563ed8423 100644 --- a/src/main/cli/settings.c +++ b/src/main/cli/settings.c @@ -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 diff --git a/src/main/fc/core.c b/src/main/fc/core.c index d7bf901a06..dd52b05663 100644 --- a/src/main/fc/core.c +++ b/src/main/fc/core.c @@ -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; diff --git a/src/main/fc/runtime_config.c b/src/main/fc/runtime_config.c index 290482454d..8185ed4bd7 100644 --- a/src/main/fc/runtime_config.c +++ b/src/main/fc/runtime_config.c @@ -37,7 +37,7 @@ const char *armingDisableFlagNames[]= { "NOGYRO", "FAILSAFE", "RXLOSS", - "BADRX", + "NOT_DISARMED", "BOXFAILSAFE", "RUNAWAY", "CRASH", diff --git a/src/main/fc/runtime_config.h b/src/main/fc/runtime_config.h index 1a41b13153..c8d250bfd7 100644 --- a/src/main/fc/runtime_config.h +++ b/src/main/fc/runtime_config.h @@ -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), diff --git a/src/main/flight/failsafe.c b/src/main/flight/failsafe.c index d1a9aac1cc..5a628996f5 100644 --- a/src/main/flight/failsafe.c +++ b/src/main/flight/failsafe.c @@ -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 } diff --git a/src/main/flight/failsafe.h b/src/main/flight/failsafe.h index 959ab9644f..7e97cdc417 100644 --- a/src/main/flight/failsafe.h +++ b/src/main/flight/failsafe.h @@ -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; diff --git a/src/main/rx/rx.c b/src/main/rx/rx.c index 237b8c4f17..d61ff9bb59 100644 --- a/src/main/rx/rx.c +++ b/src/main/rx/rx.c @@ -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]); diff --git a/src/test/unit/arming_prevention_unittest.cc b/src/test/unit/arming_prevention_unittest.cc index 2fceb23724..8fcaa2c679 100644 --- a/src/test/unit/arming_prevention_unittest.cc +++ b/src/test/unit/arming_prevention_unittest.cc @@ -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) {} diff --git a/src/test/unit/flight_failsafe_unittest.cc b/src/test/unit/flight_failsafe_unittest.cc index 6296bcc253..3f6ce0f082 100644 --- a/src/test/unit/flight_failsafe_unittest.cc +++ b/src/test/unit/flight_failsafe_unittest.cc @@ -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; }