2 * This file is part of Cleanflight.
4 * Cleanflight is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Cleanflight is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
21 #include "blackbox/blackbox.h"
22 #include "build/debug.h"
23 #include "common/maths.h"
24 #include "config/feature.h"
27 #include "pg/pg_ids.h"
29 #include "config/config.h"
30 #include "fc/controlrate_profile.h"
32 #include "fc/rc_controls.h"
33 #include "fc/rc_modes.h"
34 #include "fc/runtime_config.h"
35 #include "flight/failsafe.h"
36 #include "flight/imu.h"
37 #include "flight/mixer.h"
38 #include "flight/pid.h"
39 #include "flight/servos.h"
40 #include "io/beeper.h"
43 #include "scheduler/scheduler.h"
44 #include "sensors/acceleration.h"
45 #include "sensors/gyro.h"
46 #include "telemetry/telemetry.h"
47 #include "flight/gps_rescue.h"
49 PG_REGISTER(accelerometerConfig_t
, accelerometerConfig
, PG_ACCELEROMETER_CONFIG
, 0);
50 PG_REGISTER(blackboxConfig_t
, blackboxConfig
, PG_BLACKBOX_CONFIG
, 0);
51 PG_REGISTER(gyroConfig_t
, gyroConfig
, PG_GYRO_CONFIG
, 0);
52 PG_REGISTER(mixerConfig_t
, mixerConfig
, PG_MIXER_CONFIG
, 0);
53 PG_REGISTER(pidConfig_t
, pidConfig
, PG_PID_CONFIG
, 0);
54 PG_REGISTER(rxConfig_t
, rxConfig
, PG_RX_CONFIG
, 0);
55 PG_REGISTER(servoConfig_t
, servoConfig
, PG_SERVO_CONFIG
, 0);
56 PG_REGISTER(systemConfig_t
, systemConfig
, PG_SYSTEM_CONFIG
, 0);
57 PG_REGISTER(telemetryConfig_t
, telemetryConfig
, PG_TELEMETRY_CONFIG
, 0);
58 PG_REGISTER(failsafeConfig_t
, failsafeConfig
, PG_FAILSAFE_CONFIG
, 0);
59 PG_REGISTER(motorConfig_t
, motorConfig
, PG_MOTOR_CONFIG
, 0);
62 float rcData
[MAX_SUPPORTED_RC_CHANNEL_COUNT
];
63 uint16_t averageSystemLoadPercent
= 0;
65 uint8_t debugMode
= 0;
66 int16_t debug
[DEBUG16_VALUE_COUNT
];
67 pidProfile_t
*currentPidProfile
;
68 controlRateConfig_t
*currentControlRateProfile
;
69 attitudeEulerAngles_t attitude
;
70 gpsSolutionData_t gpsSol
;
71 uint32_t targetPidLooptime
;
72 bool cmsInMenu
= false;
73 float axisPID_P
[3], axisPID_I
[3], axisPID_D
[3], axisPIDSum
[3];
74 rxRuntimeState_t rxRuntimeState
= {};
75 uint16_t GPS_distanceToHome
= 0;
76 int16_t GPS_directionToHome
= 0;
78 bool mockIsUpright
= false;
79 uint8_t activePidLoopDenom
= 1;
82 uint32_t simulationFeatureFlags
= 0;
83 uint32_t simulationTime
= 0;
84 bool gyroCalibDone
= false;
85 bool simulationHaveRx
= false;
87 #include "gtest/gtest.h"
89 TEST(ArmingPreventionTest
, CalibrationPowerOnGraceAngleThrottleArmSwitch
)
93 gyroCalibDone
= false;
94 sensorsSet(SENSOR_GYRO
);
97 modeActivationConditionsMutable(0)->auxChannelIndex
= 0;
98 modeActivationConditionsMutable(0)->modeId
= BOXARM
;
99 modeActivationConditionsMutable(0)->range
.startStep
= CHANNEL_VALUE_TO_STEP(1750);
100 modeActivationConditionsMutable(0)->range
.endStep
= CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MAX
);
104 rxConfigMutable()->mincheck
= 1050;
107 // default channel positions
108 rcData
[THROTTLE
] = 1400;
112 systemConfigMutable()->powerOnArmingGraceTime
= 5;
113 setArmingDisabled(ARMING_DISABLED_BOOT_GRACE_TIME
);
116 updateActivatedModes();
117 updateArmingStatus();
120 EXPECT_TRUE(isArmingDisabled());
121 EXPECT_EQ(ARMING_DISABLED_BOOT_GRACE_TIME
| ARMING_DISABLED_CALIBRATING
| ARMING_DISABLED_ANGLE
| ARMING_DISABLED_ARM_SWITCH
| ARMING_DISABLED_THROTTLE
, getArmingDisableFlags());
124 // gyro calibration is done
125 gyroCalibDone
= true;
128 updateActivatedModes();
129 updateArmingStatus();
132 EXPECT_TRUE(isArmingDisabled());
133 EXPECT_EQ(ARMING_DISABLED_BOOT_GRACE_TIME
| ARMING_DISABLED_ANGLE
| ARMING_DISABLED_ARM_SWITCH
| ARMING_DISABLED_THROTTLE
, getArmingDisableFlags());
137 mockIsUpright
= true;
140 updateArmingStatus();
143 EXPECT_TRUE(isArmingDisabled());
144 EXPECT_EQ(ARMING_DISABLED_BOOT_GRACE_TIME
| ARMING_DISABLED_ARM_SWITCH
| ARMING_DISABLED_THROTTLE
, getArmingDisableFlags());
147 rcData
[THROTTLE
] = 1000;
150 updateArmingStatus();
153 EXPECT_TRUE(isArmingDisabled());
154 EXPECT_EQ(ARMING_DISABLED_BOOT_GRACE_TIME
| ARMING_DISABLED_ARM_SWITCH
, getArmingDisableFlags());
157 // arming grace time has elapsed
158 simulationTime
+= systemConfig()->powerOnArmingGraceTime
* 1e6
;
161 updateArmingStatus();
164 EXPECT_TRUE(isArmingDisabled());
165 EXPECT_EQ(ARMING_DISABLED_ARM_SWITCH
, getArmingDisableFlags());
171 // arm guard time elapses
172 updateActivatedModes();
173 updateArmingStatus();
176 EXPECT_EQ(0, getArmingDisableFlags());
177 EXPECT_FALSE(isArmingDisabled());
180 TEST(ArmingPreventionTest
, ArmingGuardRadioLeftOnAndArmed
)
184 gyroCalibDone
= false;
185 sensorsSet(SENSOR_GYRO
);
188 modeActivationConditionsMutable(0)->auxChannelIndex
= 0;
189 modeActivationConditionsMutable(0)->modeId
= BOXARM
;
190 modeActivationConditionsMutable(0)->range
.startStep
= CHANNEL_VALUE_TO_STEP(1750);
191 modeActivationConditionsMutable(0)->range
.endStep
= CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MAX
);
195 rxConfigMutable()->mincheck
= 1050;
198 rcData
[THROTTLE
] = 1000;
199 mockIsUpright
= true;
202 updateActivatedModes();
203 updateArmingStatus();
206 EXPECT_FALSE(isUsingSticksForArming());
207 EXPECT_TRUE(isArmingDisabled());
208 EXPECT_EQ(ARMING_DISABLED_CALIBRATING
, getArmingDisableFlags());
211 // arm channel takes a safe default value from the RX after power on
215 // a short time passes while calibration is in progress
216 simulationTime
+= 1e6
;
219 // during calibration RF link is established and ARM switch is on
223 updateActivatedModes();
224 updateArmingStatus();
227 EXPECT_TRUE(isArmingDisabled());
228 EXPECT_EQ(ARMING_DISABLED_CALIBRATING
| ARMING_DISABLED_ARM_SWITCH
, getArmingDisableFlags());
231 // calibration is done
232 gyroCalibDone
= true;
235 updateActivatedModes();
236 updateArmingStatus();
239 EXPECT_TRUE(isArmingDisabled());
240 EXPECT_EQ(ARMING_DISABLED_ARM_SWITCH
, getArmingDisableFlags());
243 // arm switch is switched off by user
247 updateActivatedModes();
248 updateArmingStatus();
251 // arming enabled as arm switch has been off for sufficient time
252 EXPECT_EQ(0, getArmingDisableFlags());
253 EXPECT_FALSE(isArmingDisabled());
256 TEST(ArmingPreventionTest
, Prearm
)
262 modeActivationConditionsMutable(0)->auxChannelIndex
= 0;
263 modeActivationConditionsMutable(0)->modeId
= BOXARM
;
264 modeActivationConditionsMutable(0)->range
.startStep
= CHANNEL_VALUE_TO_STEP(1750);
265 modeActivationConditionsMutable(0)->range
.endStep
= CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MAX
);
266 modeActivationConditionsMutable(1)->auxChannelIndex
= 1;
267 modeActivationConditionsMutable(1)->modeId
= BOXPREARM
;
268 modeActivationConditionsMutable(1)->range
.startStep
= CHANNEL_VALUE_TO_STEP(1750);
269 modeActivationConditionsMutable(1)->range
.endStep
= CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MAX
);
273 rxConfigMutable()->mincheck
= 1050;
276 rcData
[THROTTLE
] = 1000;
277 mockIsUpright
= true;
280 updateActivatedModes();
281 updateArmingStatus();
284 EXPECT_FALSE(isUsingSticksForArming());
285 EXPECT_TRUE(isArmingDisabled());
286 EXPECT_EQ(ARMING_DISABLED_NOPREARM
, getArmingDisableFlags());
293 updateActivatedModes();
294 updateArmingStatus();
297 // arming enabled as arm switch has been off for sufficient time
298 EXPECT_EQ(0, getArmingDisableFlags());
299 EXPECT_FALSE(isArmingDisabled());
302 TEST(ArmingPreventionTest
, RadioTurnedOnAtAnyTimeArmed
)
305 simulationTime
= 30e6
; // 30 seconds after boot
306 gyroCalibDone
= true;
309 modeActivationConditionsMutable(0)->auxChannelIndex
= 0;
310 modeActivationConditionsMutable(0)->modeId
= BOXARM
;
311 modeActivationConditionsMutable(0)->range
.startStep
= CHANNEL_VALUE_TO_STEP(1750);
312 modeActivationConditionsMutable(0)->range
.endStep
= CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MAX
);
316 rxConfigMutable()->mincheck
= 1050;
319 rcData
[THROTTLE
] = 1000;
320 mockIsUpright
= true;
323 // RX has no link to radio
324 simulationHaveRx
= false;
327 // arm channel has a safe default value
331 updateActivatedModes();
332 updateArmingStatus();
335 EXPECT_FALSE(isUsingSticksForArming());
336 EXPECT_FALSE(isArmingDisabled());
337 EXPECT_EQ(0, getArmingDisableFlags());
340 // RF link is established and arm switch is turned on on radio
341 simulationHaveRx
= true;
345 updateActivatedModes();
346 updateArmingStatus();
349 EXPECT_FALSE(isUsingSticksForArming());
350 EXPECT_TRUE(isArmingDisabled());
351 EXPECT_EQ(ARMING_DISABLED_BAD_RX_RECOVERY
| ARMING_DISABLED_ARM_SWITCH
, getArmingDisableFlags());
354 // arm switch turned off by user
358 updateActivatedModes();
359 updateArmingStatus();
362 EXPECT_FALSE(isUsingSticksForArming());
363 EXPECT_FALSE(isArmingDisabled());
364 EXPECT_EQ(0, getArmingDisableFlags());
367 TEST(ArmingPreventionTest
, In3DModeAllowArmingWhenEnteringThrottleDeadband
)
370 simulationFeatureFlags
= FEATURE_3D
; // Using 3D mode
371 simulationTime
= 30e6
; // 30 seconds after boot
372 gyroCalibDone
= true;
375 modeActivationConditionsMutable(0)->auxChannelIndex
= 0;
376 modeActivationConditionsMutable(0)->modeId
= BOXARM
;
377 modeActivationConditionsMutable(0)->range
.startStep
= CHANNEL_VALUE_TO_STEP(1750);
378 modeActivationConditionsMutable(0)->range
.endStep
= CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MAX
);
382 rxConfigMutable()->midrc
= 1500;
383 flight3DConfigMutable()->deadband3d_throttle
= 5;
386 rcData
[THROTTLE
] = 1400;
387 mockIsUpright
= true;
388 simulationHaveRx
= true;
391 // arm channel has a safe default value
395 updateActivatedModes();
396 updateArmingStatus();
399 EXPECT_FALSE(isUsingSticksForArming());
400 EXPECT_TRUE(isArmingDisabled());
401 EXPECT_EQ(ARMING_DISABLED_THROTTLE
, getArmingDisableFlags());
408 updateActivatedModes();
409 updateArmingStatus();
412 EXPECT_FALSE(isUsingSticksForArming());
413 EXPECT_TRUE(isArmingDisabled());
414 EXPECT_EQ(ARMING_DISABLED_THROTTLE
, getArmingDisableFlags());
417 // throttle moved to centre
418 rcData
[THROTTLE
] = 1496;
421 updateActivatedModes();
422 updateArmingStatus();
425 EXPECT_FALSE(isUsingSticksForArming());
426 EXPECT_FALSE(isArmingDisabled());
427 EXPECT_EQ(0, getArmingDisableFlags());
430 TEST(ArmingPreventionTest
, When3DModeDisabledThenNormalThrottleArmingConditionApplies
)
433 simulationFeatureFlags
= FEATURE_3D
; // Using 3D mode
434 simulationTime
= 30e6
; // 30 seconds after boot
435 gyroCalibDone
= true;
438 modeActivationConditionsMutable(0)->auxChannelIndex
= 0;
439 modeActivationConditionsMutable(0)->modeId
= BOXARM
;
440 modeActivationConditionsMutable(0)->range
.startStep
= CHANNEL_VALUE_TO_STEP(1750);
441 modeActivationConditionsMutable(0)->range
.endStep
= CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MAX
);
442 modeActivationConditionsMutable(1)->auxChannelIndex
= 1;
443 modeActivationConditionsMutable(1)->modeId
= BOX3D
;
444 modeActivationConditionsMutable(1)->range
.startStep
= CHANNEL_VALUE_TO_STEP(1750);
445 modeActivationConditionsMutable(1)->range
.endStep
= CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MAX
);
449 rxConfigMutable()->mincheck
= 1050;
450 rxConfigMutable()->midrc
= 1500;
451 flight3DConfigMutable()->deadband3d_throttle
= 5;
454 // safe throttle value for 3D mode
455 rcData
[THROTTLE
] = 1500;
456 mockIsUpright
= true;
457 simulationHaveRx
= true;
460 // arm channel has a safe default value
464 // disable 3D mode is off (i.e. 3D mode is on)
468 updateActivatedModes();
469 updateArmingStatus();
472 // ok to arm in 3D mode
473 EXPECT_FALSE(isUsingSticksForArming());
474 EXPECT_FALSE(isArmingDisabled());
475 EXPECT_EQ(0, getArmingDisableFlags());
482 updateActivatedModes();
483 updateArmingStatus();
486 // ok to arm in 3D mode
487 EXPECT_FALSE(isUsingSticksForArming());
488 EXPECT_TRUE(isArmingDisabled());
489 EXPECT_EQ(ARMING_DISABLED_THROTTLE
, getArmingDisableFlags());
496 updateActivatedModes();
497 updateArmingStatus();
500 EXPECT_FALSE(isUsingSticksForArming());
501 EXPECT_TRUE(isArmingDisabled());
502 EXPECT_EQ(ARMING_DISABLED_THROTTLE
| ARMING_DISABLED_ARM_SWITCH
, getArmingDisableFlags());
505 // throttle moved low
506 rcData
[THROTTLE
] = 1000;
509 updateActivatedModes();
510 updateArmingStatus();
513 EXPECT_FALSE(isUsingSticksForArming());
514 EXPECT_TRUE(isArmingDisabled());
515 EXPECT_EQ(ARMING_DISABLED_ARM_SWITCH
, getArmingDisableFlags());
518 // arm switch turned off
522 updateActivatedModes();
523 updateArmingStatus();
526 EXPECT_FALSE(isUsingSticksForArming());
527 EXPECT_FALSE(isArmingDisabled());
528 EXPECT_EQ(0, getArmingDisableFlags());
531 TEST(ArmingPreventionTest
, WhenUsingSwitched3DModeThenNormalThrottleArmingConditionApplies
)
534 simulationFeatureFlags
= FEATURE_3D
; // Using 3D mode
535 simulationTime
= 30e6
; // 30 seconds after boot
536 gyroCalibDone
= true;
539 modeActivationConditionsMutable(0)->auxChannelIndex
= 0;
540 modeActivationConditionsMutable(0)->modeId
= BOXARM
;
541 modeActivationConditionsMutable(0)->range
.startStep
= CHANNEL_VALUE_TO_STEP(1750);
542 modeActivationConditionsMutable(0)->range
.endStep
= CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MAX
);
543 modeActivationConditionsMutable(1)->auxChannelIndex
= 1;
544 modeActivationConditionsMutable(1)->modeId
= BOX3D
;
545 modeActivationConditionsMutable(1)->range
.startStep
= CHANNEL_VALUE_TO_STEP(1750);
546 modeActivationConditionsMutable(1)->range
.endStep
= CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MAX
);
550 rxConfigMutable()->mincheck
= 1050;
553 rcData
[THROTTLE
] = 1000;
554 mockIsUpright
= true;
555 simulationHaveRx
= true;
558 // arm channel has a safe default value
562 updateActivatedModes();
563 updateArmingStatus();
566 // ok to arm in 3D mode
567 EXPECT_FALSE(isUsingSticksForArming());
568 EXPECT_FALSE(isArmingDisabled());
569 EXPECT_EQ(0, getArmingDisableFlags());
572 // raise throttle to unsafe position
573 rcData
[THROTTLE
] = 1500;
576 updateActivatedModes();
577 updateArmingStatus();
580 // ok to arm in 3D mode
581 EXPECT_FALSE(isUsingSticksForArming());
582 EXPECT_TRUE(isArmingDisabled());
583 EXPECT_EQ(ARMING_DISABLED_THROTTLE
, getArmingDisableFlags());
590 updateActivatedModes();
591 updateArmingStatus();
594 EXPECT_FALSE(isUsingSticksForArming());
595 EXPECT_TRUE(isArmingDisabled());
596 EXPECT_EQ(ARMING_DISABLED_THROTTLE
| ARMING_DISABLED_ARM_SWITCH
, getArmingDisableFlags());
599 // throttle moved low
600 rcData
[THROTTLE
] = 1000;
603 updateActivatedModes();
604 updateArmingStatus();
607 EXPECT_FALSE(isUsingSticksForArming());
608 EXPECT_TRUE(isArmingDisabled());
609 EXPECT_EQ(ARMING_DISABLED_ARM_SWITCH
, getArmingDisableFlags());
612 // arm switch turned off
616 updateActivatedModes();
617 updateArmingStatus();
620 EXPECT_FALSE(isUsingSticksForArming());
621 EXPECT_FALSE(isArmingDisabled());
622 EXPECT_EQ(0, getArmingDisableFlags());
625 TEST(ArmingPreventionTest
, GPSRescueWithoutFixPreventsArm
)
628 simulationFeatureFlags
= 0;
630 gyroCalibDone
= true;
633 modeActivationConditionsMutable(0)->auxChannelIndex
= 0;
634 modeActivationConditionsMutable(0)->modeId
= BOXARM
;
635 modeActivationConditionsMutable(0)->range
.startStep
= CHANNEL_VALUE_TO_STEP(1750);
636 modeActivationConditionsMutable(0)->range
.endStep
= CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MAX
);
637 modeActivationConditionsMutable(1)->auxChannelIndex
= 1;
638 modeActivationConditionsMutable(1)->modeId
= BOXGPSRESCUE
;
639 modeActivationConditionsMutable(1)->range
.startStep
= CHANNEL_VALUE_TO_STEP(1750);
640 modeActivationConditionsMutable(1)->range
.endStep
= CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MAX
);
644 rxConfigMutable()->mincheck
= 1050;
647 rcData
[THROTTLE
] = 1000;
650 mockIsUpright
= true;
653 updateActivatedModes();
654 updateArmingStatus();
657 EXPECT_FALSE(ARMING_FLAG(ARMED
));
658 EXPECT_TRUE(isArmingDisabled());
659 EXPECT_EQ(ARMING_DISABLED_GPS
, getArmingDisableFlags());
660 EXPECT_FALSE(IS_RC_MODE_ACTIVE(BOXGPSRESCUE
));
668 updateActivatedModes();
669 updateArmingStatus();
672 EXPECT_FALSE(ARMING_FLAG(ARMED
));
673 EXPECT_TRUE(isArmingDisabled());
674 EXPECT_EQ(ARMING_DISABLED_ARM_SWITCH
|ARMING_DISABLED_GPS
, getArmingDisableFlags());
675 EXPECT_FALSE(IS_RC_MODE_ACTIVE(BOXGPSRESCUE
));
682 disarm(DISARM_REASON_SYSTEM
);
683 updateActivatedModes();
684 updateArmingStatus();
687 EXPECT_FALSE(ARMING_FLAG(ARMED
));
688 EXPECT_TRUE(isArmingDisabled());
689 EXPECT_EQ(ARMING_DISABLED_GPS
, getArmingDisableFlags());
690 EXPECT_FALSE(IS_RC_MODE_ACTIVE(BOXGPSRESCUE
));
694 ENABLE_STATE(GPS_FIX
);
697 updateActivatedModes();
698 updateArmingStatus();
701 EXPECT_FALSE(ARMING_FLAG(ARMED
));
702 EXPECT_FALSE(isArmingDisabled());
703 EXPECT_EQ(0, getArmingDisableFlags());
704 EXPECT_FALSE(IS_RC_MODE_ACTIVE(BOXGPSRESCUE
));
712 updateActivatedModes();
713 updateArmingStatus();
716 EXPECT_TRUE(ARMING_FLAG(ARMED
));
717 EXPECT_FALSE(isArmingDisabled());
718 EXPECT_EQ(0, getArmingDisableFlags());
719 EXPECT_FALSE(IS_RC_MODE_ACTIVE(BOXGPSRESCUE
));
726 disarm(DISARM_REASON_SYSTEM
);
727 updateActivatedModes();
728 updateArmingStatus();
731 EXPECT_FALSE(ARMING_FLAG(ARMED
));
732 EXPECT_FALSE(isArmingDisabled());
733 EXPECT_EQ(0, getArmingDisableFlags());
734 EXPECT_FALSE(IS_RC_MODE_ACTIVE(BOXGPSRESCUE
));
737 TEST(ArmingPreventionTest
, GPSRescueSwitchPreventsArm
)
740 simulationFeatureFlags
= 0;
742 gyroCalibDone
= true;
744 ENABLE_STATE(GPS_FIX
);
747 modeActivationConditionsMutable(0)->auxChannelIndex
= 0;
748 modeActivationConditionsMutable(0)->modeId
= BOXARM
;
749 modeActivationConditionsMutable(0)->range
.startStep
= CHANNEL_VALUE_TO_STEP(1750);
750 modeActivationConditionsMutable(0)->range
.endStep
= CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MAX
);
751 modeActivationConditionsMutable(1)->auxChannelIndex
= 1;
752 modeActivationConditionsMutable(1)->modeId
= BOXGPSRESCUE
;
753 modeActivationConditionsMutable(1)->range
.startStep
= CHANNEL_VALUE_TO_STEP(1750);
754 modeActivationConditionsMutable(1)->range
.endStep
= CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MAX
);
758 rxConfigMutable()->mincheck
= 1050;
761 rcData
[THROTTLE
] = 1000;
763 rcData
[AUX2
] = 1800; // Start out with rescue enabled
764 mockIsUpright
= true;
767 updateActivatedModes();
768 updateArmingStatus();
771 EXPECT_FALSE(ARMING_FLAG(ARMED
));
772 EXPECT_TRUE(isArmingDisabled());
773 EXPECT_EQ(ARMING_DISABLED_RESC
, getArmingDisableFlags());
774 EXPECT_TRUE(IS_RC_MODE_ACTIVE(BOXGPSRESCUE
));
782 updateActivatedModes();
783 updateArmingStatus();
786 EXPECT_FALSE(ARMING_FLAG(ARMED
));
787 EXPECT_TRUE(isArmingDisabled());
788 EXPECT_EQ(ARMING_DISABLED_ARM_SWITCH
|ARMING_DISABLED_RESC
, getArmingDisableFlags());
789 EXPECT_TRUE(IS_RC_MODE_ACTIVE(BOXGPSRESCUE
));
796 disarm(DISARM_REASON_SYSTEM
);
797 updateActivatedModes();
798 updateArmingStatus();
801 EXPECT_FALSE(ARMING_FLAG(ARMED
));
802 EXPECT_TRUE(isArmingDisabled());
803 EXPECT_EQ(ARMING_DISABLED_RESC
, getArmingDisableFlags());
804 EXPECT_TRUE(IS_RC_MODE_ACTIVE(BOXGPSRESCUE
));
811 updateActivatedModes();
812 updateArmingStatus();
815 EXPECT_FALSE(ARMING_FLAG(ARMED
));
816 EXPECT_FALSE(isArmingDisabled());
817 EXPECT_EQ(0, getArmingDisableFlags());
818 EXPECT_FALSE(IS_RC_MODE_ACTIVE(BOXGPSRESCUE
));
826 updateActivatedModes();
827 updateArmingStatus();
830 EXPECT_TRUE(ARMING_FLAG(ARMED
));
831 EXPECT_FALSE(isArmingDisabled());
832 EXPECT_EQ(0, getArmingDisableFlags());
833 EXPECT_FALSE(IS_RC_MODE_ACTIVE(BOXGPSRESCUE
));
840 disarm(DISARM_REASON_SYSTEM
);
841 updateActivatedModes();
842 updateArmingStatus();
845 EXPECT_FALSE(ARMING_FLAG(ARMED
));
846 EXPECT_FALSE(isArmingDisabled());
847 EXPECT_EQ(0, getArmingDisableFlags());
848 EXPECT_FALSE(IS_RC_MODE_ACTIVE(BOXGPSRESCUE
));
851 TEST(ArmingPreventionTest
, ParalyzeOnAtBoot
)
854 simulationFeatureFlags
= 0;
856 gyroCalibDone
= true;
859 modeActivationConditionsMutable(0)->auxChannelIndex
= 0;
860 modeActivationConditionsMutable(0)->modeId
= BOXARM
;
861 modeActivationConditionsMutable(0)->range
.startStep
= CHANNEL_VALUE_TO_STEP(1750);
862 modeActivationConditionsMutable(0)->range
.endStep
= CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MAX
);
863 modeActivationConditionsMutable(1)->auxChannelIndex
= 1;
864 modeActivationConditionsMutable(1)->modeId
= BOXPARALYZE
;
865 modeActivationConditionsMutable(1)->range
.startStep
= CHANNEL_VALUE_TO_STEP(1750);
866 modeActivationConditionsMutable(1)->range
.endStep
= CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MAX
);
870 rxConfigMutable()->mincheck
= 1050;
873 rcData
[THROTTLE
] = 1000;
875 rcData
[AUX2
] = 1800; // Paralyze on at boot
876 mockIsUpright
= true;
879 updateActivatedModes();
880 updateArmingStatus();
883 EXPECT_FALSE(ARMING_FLAG(ARMED
));
884 EXPECT_FALSE(isArmingDisabled());
885 EXPECT_EQ(0, getArmingDisableFlags());
886 EXPECT_FALSE(IS_RC_MODE_ACTIVE(BOXPARALYZE
));
889 updateActivatedModes();
892 EXPECT_FALSE(IS_RC_MODE_ACTIVE(BOXPARALYZE
));
895 TEST(ArmingPreventionTest
, Paralyze
)
898 simulationFeatureFlags
= 0;
900 gyroCalibDone
= true;
903 modeActivationConditionsMutable(0)->auxChannelIndex
= 0;
904 modeActivationConditionsMutable(0)->modeId
= BOXARM
;
905 modeActivationConditionsMutable(0)->range
.startStep
= CHANNEL_VALUE_TO_STEP(1750);
906 modeActivationConditionsMutable(0)->range
.endStep
= CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MAX
);
907 modeActivationConditionsMutable(1)->auxChannelIndex
= 1;
908 modeActivationConditionsMutable(1)->modeId
= BOXPARALYZE
;
909 modeActivationConditionsMutable(1)->range
.startStep
= CHANNEL_VALUE_TO_STEP(1750);
910 modeActivationConditionsMutable(1)->range
.endStep
= CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MAX
);
911 modeActivationConditionsMutable(2)->auxChannelIndex
= 2;
912 modeActivationConditionsMutable(2)->modeId
= BOXBEEPERON
;
913 modeActivationConditionsMutable(2)->range
.startStep
= CHANNEL_VALUE_TO_STEP(1750);
914 modeActivationConditionsMutable(2)->range
.endStep
= CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MAX
);
915 modeActivationConditionsMutable(3)->modeId
= BOXVTXPITMODE
;
916 modeActivationConditionsMutable(3)->linkedTo
= BOXPARALYZE
;
920 rxConfigMutable()->mincheck
= 1050;
923 rcData
[THROTTLE
] = 1000;
925 rcData
[AUX2
] = 1800; // Start out with paralyze enabled
927 mockIsUpright
= true;
930 updateActivatedModes();
931 updateArmingStatus();
934 EXPECT_FALSE(ARMING_FLAG(ARMED
));
935 EXPECT_FALSE(isArmingDisabled());
936 EXPECT_EQ(0, getArmingDisableFlags());
944 updateActivatedModes();
945 updateArmingStatus();
948 EXPECT_TRUE(ARMING_FLAG(ARMED
));
949 EXPECT_FALSE(isArmingDisabled());
950 EXPECT_EQ(0, getArmingDisableFlags());
957 disarm(DISARM_REASON_SYSTEM
);
958 updateActivatedModes();
959 updateArmingStatus();
962 EXPECT_FALSE(ARMING_FLAG(ARMED
));
963 EXPECT_FALSE(isArmingDisabled());
964 EXPECT_EQ(0, getArmingDisableFlags());
965 EXPECT_FALSE(IS_RC_MODE_ACTIVE(BOXPARALYZE
));
968 simulationTime
= 10e6
; // 10 seconds after boot
971 updateActivatedModes();
974 EXPECT_FALSE(ARMING_FLAG(ARMED
));
975 EXPECT_FALSE(isArmingDisabled());
976 EXPECT_EQ(0, getArmingDisableFlags());
977 EXPECT_FALSE(IS_RC_MODE_ACTIVE(BOXPARALYZE
));
980 // disable paralyze once after the startup timer
984 updateActivatedModes();
986 // enable paralyze again
990 updateActivatedModes();
991 updateArmingStatus();
994 EXPECT_TRUE(isArmingDisabled());
995 EXPECT_EQ(ARMING_DISABLED_PARALYZE
, getArmingDisableFlags());
996 EXPECT_TRUE(IS_RC_MODE_ACTIVE(BOXPARALYZE
));
997 EXPECT_TRUE(IS_RC_MODE_ACTIVE(BOXVTXPITMODE
));
998 EXPECT_FALSE(IS_RC_MODE_ACTIVE(BOXBEEPERON
));
1002 rcData
[AUX3
] = 1800;
1005 updateActivatedModes();
1008 EXPECT_TRUE(IS_RC_MODE_ACTIVE(BOXVTXPITMODE
));
1009 EXPECT_TRUE(IS_RC_MODE_ACTIVE(BOXBEEPERON
));
1012 // try exiting paralyze mode and ensure arming and pit mode are still disabled
1013 rcData
[AUX2
] = 1000;
1016 updateActivatedModes();
1017 updateArmingStatus();
1020 EXPECT_TRUE(isArmingDisabled());
1021 EXPECT_EQ(ARMING_DISABLED_PARALYZE
, getArmingDisableFlags());
1022 EXPECT_TRUE(IS_RC_MODE_ACTIVE(BOXPARALYZE
));
1023 EXPECT_TRUE(IS_RC_MODE_ACTIVE(BOXVTXPITMODE
));
1028 uint32_t micros(void) { return simulationTime
; }
1029 uint32_t millis(void) { return micros() / 1000; }
1030 bool rxIsReceivingSignal(void) { return simulationHaveRx
; }
1032 bool featureIsEnabled(uint32_t f
) { return simulationFeatureFlags
& f
; }
1033 void warningLedFlash(void) {}
1034 void warningLedDisable(void) {}
1035 void warningLedUpdate(void) {}
1036 void beeper(beeperMode_e
) {}
1037 void beeperConfirmationBeeps(uint8_t) {}
1038 void beeperWarningBeeps(uint8_t) {}
1039 void beeperSilence(void) {}
1040 void systemBeep(bool) {}
1041 void saveConfigAndNotify(void) {}
1042 void blackboxFinish(void) {}
1043 bool accIsCalibrationComplete(void) { return true; }
1044 bool baroIsCalibrationComplete(void) { return true; }
1045 bool gyroIsCalibrationComplete(void) { return gyroCalibDone
; }
1046 void gyroStartCalibration(bool) {}
1047 bool isFirstArmingGyroCalibrationRunning(void) { return false; }
1048 void pidController(const pidProfile_t
*, timeUs_t
) {}
1049 void pidStabilisationState(pidStabilisationState_e
) {}
1050 void mixTable(timeUs_t
) {};
1051 void writeMotors(void) {};
1052 void writeServos(void) {};
1053 bool calculateRxChannelsAndUpdateFailsafe(timeUs_t
) { return true; }
1054 bool isMixerUsingServos(void) { return false; }
1055 void gyroUpdate(void) {}
1056 timeDelta_t
getTaskDeltaTimeUs(taskId_e
) { return 0; }
1057 void updateRSSI(timeUs_t
) {}
1058 bool failsafeIsMonitoring(void) { return false; }
1059 void failsafeStartMonitoring(void) {}
1060 void failsafeUpdateState(void) {}
1061 bool failsafeIsActive(void) { return false; }
1062 void pidResetIterm(void) {}
1063 void updateAdjustmentStates(void) {}
1064 void processRcAdjustments(controlRateConfig_t
*) {}
1065 void updateGpsWaypointsAndMode(void) {}
1066 void mspSerialReleaseSharedTelemetryPorts(void) {}
1067 void telemetryCheckState(void) {}
1068 void mspSerialAllocatePorts(void) {}
1069 void gyroReadTemperature(void) {}
1070 void updateRcCommands(void) {}
1071 void applyAltHold(void) {}
1072 void resetYawAxis(void) {}
1073 int16_t calculateThrottleAngleCorrection(uint8_t) { return 0; }
1074 void processRcCommand(void) {}
1075 void updateGpsStateForHomeAndHoldMode(void) {}
1076 void blackboxUpdate(timeUs_t
) {}
1077 void transponderUpdate(timeUs_t
) {}
1078 void GPS_reset_home_position(void) {}
1079 void accStartCalibration(void) {}
1080 bool accHasBeenCalibrated(void) { return true; }
1081 void baroSetGroundLevel(void) {}
1082 void changePidProfile(uint8_t) {}
1083 void changeControlRateProfile(uint8_t) {}
1084 void dashboardEnablePageCycling(void) {}
1085 void dashboardDisablePageCycling(void) {}
1086 bool imuQuaternionHeadfreeOffsetSet(void) { return true; }
1087 void rescheduleTask(taskId_e
, timeDelta_t
) {}
1088 bool usbCableIsInserted(void) { return false; }
1089 bool usbVcpIsConnected(void) { return false; }
1090 void pidSetAntiGravityState(bool) {}
1091 void osdSuppressStats(bool) {}
1092 float scaleRangef(float, float, float, float, float) { return 0.0f
; }
1093 bool crashRecoveryModeActive(void) { return false; }
1094 int32_t getEstimatedAltitudeCm(void) { return 0; }
1095 bool gpsIsHealthy() { return false; }
1096 bool isAltitudeOffset(void) { return false; }
1097 float getCosTiltAngle(void) { return 0.0f
; }
1098 void pidSetItermReset(bool) {}
1099 void applyAccelerometerTrimsDelta(rollAndPitchTrims_t
*) {}
1100 bool isFixedWing(void) { return false; }
1101 void compassStartCalibration(void) {}
1102 bool compassIsCalibrationComplete(void) { return true; }
1103 bool isUpright(void) { return mockIsUpright
; }
1104 void blackboxLogEvent(FlightLogEvent
, union flightLogEventData_u
*) {};
1105 void gyroFiltering(timeUs_t
) {};
1106 timeDelta_t
rxGetFrameDelta(timeDelta_t
*) { return 0; }
1107 void updateRcRefreshRate(timeUs_t
) {};
1108 uint16_t getAverageSystemLoadPercent(void) { return 0; }
1109 bool isMotorProtocolEnabled(void) { return true; }
1110 void pinioBoxTaskControl(void) {}
1111 void schedulerSetNextStateTime(timeDelta_t
) {}