From ad540d8ad8e11bddfc7866772633b743bf0da427 Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Sun, 13 Aug 2017 16:05:48 +0100 Subject: [PATCH] Add prevention for turning radio on at any time with arm switch on --- src/main/fc/fc_core.c | 18 ++++++ src/main/fc/runtime_config.c | 6 +- src/main/fc/runtime_config.h | 27 ++++---- src/test/unit/arming_prevention_unittest.cc | 69 ++++++++++++++++++++- 4 files changed, 102 insertions(+), 18 deletions(-) diff --git a/src/main/fc/fc_core.c b/src/main/fc/fc_core.c index 05853d1a3f..ae1b0bb065 100644 --- a/src/main/fc/fc_core.c +++ b/src/main/fc/fc_core.c @@ -158,6 +158,24 @@ void updateArmingStatus(void) unsetArmingDisabled(ARMING_DISABLED_BOOT_GRACE_TIME); } + // If switch is used for arming then check it is not defaulting to on when the RX link recovers from a fault + if (!isUsingSticksForArming()) { + static bool hadRx = false; + const bool haveRx = rxIsReceivingSignal(); + + const bool justGotRxBack = !hadRx && haveRx; + + 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); + } 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); + } + + hadRx = haveRx; + } + if (IS_RC_MODE_ACTIVE(BOXFAILSAFE)) { setArmingDisabled(ARMING_DISABLED_BOXFAILSAFE); } else { diff --git a/src/main/fc/runtime_config.c b/src/main/fc/runtime_config.c index dbffafdc27..fe1cbe3337 100644 --- a/src/main/fc/runtime_config.c +++ b/src/main/fc/runtime_config.c @@ -31,9 +31,9 @@ static uint32_t enabledSensors = 0; #if defined(OSD) || !defined(MINIMAL_CLI) const char *armingDisableFlagNames[]= { - "NOGYRO", "FAILSAFE", "RX LOSS", "BOXFAILSAFE", "THROTTLE", - "ANGLE", "BOOT GRACE", "NO PREARM", "ARM SWITCH", "LOAD", - "CALIB", "CLI", "CMS", "OSD", "BST" + "NOGYRO", "FAILSAFE", "RX LOSS", "BAD RX", "BOXFAILSAFE", + "THROTTLE", "ANGLE", "BOOT GRACE", "NO PREARM", "ARM SWITCH", + "LOAD", "CALIB", "CLI", "CMS", "OSD", "BST" }; #endif diff --git a/src/main/fc/runtime_config.h b/src/main/fc/runtime_config.h index 109e0442e7..d6a123965d 100644 --- a/src/main/fc/runtime_config.h +++ b/src/main/fc/runtime_config.h @@ -38,21 +38,22 @@ typedef enum { ARMING_DISABLED_NO_GYRO = (1 << 0), ARMING_DISABLED_FAILSAFE = (1 << 1), ARMING_DISABLED_RX_FAILSAFE = (1 << 2), - ARMING_DISABLED_BOXFAILSAFE = (1 << 3), - ARMING_DISABLED_THROTTLE = (1 << 4), - ARMING_DISABLED_ANGLE = (1 << 5), - ARMING_DISABLED_BOOT_GRACE_TIME = (1 << 6), - ARMING_DISABLED_NOPREARM = (1 << 7), - ARMING_DISABLED_ARM_SWITCH = (1 << 8), - ARMING_DISABLED_LOAD = (1 << 9), - ARMING_DISABLED_CALIBRATING = (1 << 10), - ARMING_DISABLED_CLI = (1 << 11), - ARMING_DISABLED_CMS_MENU = (1 << 12), - ARMING_DISABLED_OSD_MENU = (1 << 13), - ARMING_DISABLED_BST = (1 << 14) + ARMING_DISABLED_BAD_RX_RECOVERY = (1 << 3), + ARMING_DISABLED_BOXFAILSAFE = (1 << 4), + ARMING_DISABLED_THROTTLE = (1 << 5), + ARMING_DISABLED_ANGLE = (1 << 6), + ARMING_DISABLED_BOOT_GRACE_TIME = (1 << 7), + ARMING_DISABLED_NOPREARM = (1 << 8), + ARMING_DISABLED_ARM_SWITCH = (1 << 9), + ARMING_DISABLED_LOAD = (1 << 10), + ARMING_DISABLED_CALIBRATING = (1 << 11), + ARMING_DISABLED_CLI = (1 << 12), + ARMING_DISABLED_CMS_MENU = (1 << 13), + ARMING_DISABLED_OSD_MENU = (1 << 14), + ARMING_DISABLED_BST = (1 << 15) } armingDisableFlags_e; -#define NUM_ARMING_DISABLE_FLAGS 15 +#define NUM_ARMING_DISABLE_FLAGS 16 #if defined(OSD) || !defined(MINIMAL_CLI) extern const char *armingDisableFlagNames[NUM_ARMING_DISABLE_FLAGS]; diff --git a/src/test/unit/arming_prevention_unittest.cc b/src/test/unit/arming_prevention_unittest.cc index 893d70cf2e..d6bd09d8ad 100644 --- a/src/test/unit/arming_prevention_unittest.cc +++ b/src/test/unit/arming_prevention_unittest.cc @@ -67,6 +67,7 @@ extern "C" { uint32_t simulationTime = 0; bool gyroCalibDone = false; +bool simulationHaveRx = false; #include "gtest/gtest.h" @@ -159,7 +160,6 @@ TEST(ArmingPreventionTest, CalibrationPowerOnGraceAngleThrottleArmSwitch) EXPECT_EQ(0, getArmingDisableFlags()); EXPECT_FALSE(isArmingDisabled()); } - TEST(ArmingPreventionTest, ArmingGuardRadioLeftOnAndArmed) { // given @@ -281,11 +281,76 @@ TEST(ArmingPreventionTest, Prearm) EXPECT_FALSE(isArmingDisabled()); } +TEST(ArmingPreventionTest, RadioTurnedOnAtAnyTimeArmed) +{ + // given + simulationTime = 30e6; // 30 seconds after boot + gyroCalibDone = true; + + // and + modeActivationConditionsMutable(0)->auxChannelIndex = 0; + modeActivationConditionsMutable(0)->modeId = BOXARM; + modeActivationConditionsMutable(0)->range.startStep = CHANNEL_VALUE_TO_STEP(1750); + modeActivationConditionsMutable(0)->range.endStep = CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MAX); + useRcControlsConfig(NULL); + + // and + rxConfigMutable()->mincheck = 1050; + + // and + rcData[THROTTLE] = 1000; + ENABLE_STATE(SMALL_ANGLE); + + // and + // RX has no link to radio + simulationHaveRx = false; + + // and + // arm channel has a safe default value + rcData[4] = 1100; + + // when + updateActivatedModes(); + updateArmingStatus(); + + // expect + EXPECT_FALSE(isUsingSticksForArming()); + EXPECT_FALSE(isArmingDisabled()); + EXPECT_EQ(0, getArmingDisableFlags()); + + // given + // RF link is established and arm switch is turned on on radio + simulationHaveRx = true; + rcData[4] = 1800; + + // when + updateActivatedModes(); + updateArmingStatus(); + + // expect + EXPECT_FALSE(isUsingSticksForArming()); + EXPECT_TRUE(isArmingDisabled()); + EXPECT_EQ(ARMING_DISABLED_BAD_RX_RECOVERY | ARMING_DISABLED_ARM_SWITCH, getArmingDisableFlags()); + + // given + // arm switch turned off by user + rcData[4] = 1100; + + // when + updateActivatedModes(); + updateArmingStatus(); + + // expect + EXPECT_FALSE(isUsingSticksForArming()); + EXPECT_FALSE(isArmingDisabled()); + EXPECT_EQ(0, getArmingDisableFlags()); +} + // STUBS extern "C" { uint32_t micros(void) { return simulationTime; } uint32_t millis(void) { return micros() / 1000; } - bool rxIsReceivingSignal(void) { return false; } + bool rxIsReceivingSignal(void) { return simulationHaveRx; } bool feature(uint32_t) { return false; } void warningLedFlash(void) {}