Skip to content

Commit d9c60d9

Browse files
authored
Merge pull request #4623 from iNavFlight/agh_nav_extra_arming_safety_bypass
Add support for bypassing extra arming safety
2 parents 82784a9 + 20fac46 commit d9c60d9

File tree

7 files changed

+87
-30
lines changed

7 files changed

+87
-30
lines changed

docs/Cli.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ A shorter form is also supported to enable and disable functions using `serial <
177177
| name | Empty string | Craft name |
178178
| nav_disarm_on_landing | OFF | If set to ON, iNav disarms the FC after landing |
179179
| nav_use_midthr_for_althold | OFF | If set to OFF, the FC remembers your throttle stick position when enabling ALTHOLD and treats it as a neutral midpoint for holding altitude |
180-
| nav_extra_arming_safety | ON | If set to ON drone won't arm if no GPS fix and any navigation mode like RTH or POSHOLD is configured |
180+
| nav_extra_arming_safety | ON | If set to ON drone won't arm if no GPS fix and any navigation mode like RTH or POSHOLD is configured. ALLOW_BYPASS allows the user to momentarily disable this check by holding yaw high (left stick held at the bottom right in mode 2) when switch arming is used |
181181
| nav_user_control_mode | ATTI | Defines how Pitch/Roll input from RC receiver affects flight in POSHOLD mode: ATTI - right stick controls attitude like in ANGLE mode; CRUISE - right stick controls velocity in forward and right direction. |
182182
| nav_position_timeout | 5 | If GPS fails wait for this much seconds before switching to emergency landing mode (0 - disable) |
183183
| nav_wp_radius | 100 | Waypoint radius [cm]. Waypoint would be considered reached if machine is within this radius |

src/main/fc/fc_core.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ static void updateArmingStatus(void)
215215

216216
#if defined(USE_NAV)
217217
/* CHECK: Navigation safety */
218-
if (navigationBlockArming()) {
218+
if (navigationIsBlockingArming(NULL) != NAV_ARMING_BLOCKER_NONE) {
219219
ENABLE_ARMING_FLAG(ARMING_DISABLED_NAVIGATION_UNSAFE);
220220
}
221221
else {
@@ -374,6 +374,18 @@ void tryArm(void)
374374
return;
375375
}
376376

377+
#if defined(USE_NAV)
378+
// If nav_extra_arming_safety was bypassed we always
379+
// allow bypassing it even without the sticks set
380+
// in the correct position to allow re-arming quickly
381+
// in case of a mid-air accidental disarm.
382+
bool usedBypass = false;
383+
navigationIsBlockingArming(&usedBypass);
384+
if (usedBypass) {
385+
ENABLE_STATE(NAV_EXTRA_ARMING_SAFETY_BYPASSED);
386+
}
387+
#endif
388+
377389
lastDisarmReason = DISARM_NONE;
378390

379391
ENABLE_ARMING_FLAG(ARMED);

src/main/fc/runtime_config.h

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -89,20 +89,21 @@ extern uint32_t flightModeFlags;
8989
#define FLIGHT_MODE(mask) (flightModeFlags & (mask))
9090

9191
typedef enum {
92-
GPS_FIX_HOME = (1 << 0),
93-
GPS_FIX = (1 << 1),
94-
CALIBRATE_MAG = (1 << 2),
95-
SMALL_ANGLE = (1 << 3),
96-
FIXED_WING = (1 << 4), // set when in flying_wing or airplane mode. currently used by althold selection code
97-
ANTI_WINDUP = (1 << 5),
98-
FLAPERON_AVAILABLE = (1 << 6),
99-
NAV_MOTOR_STOP_OR_IDLE = (1 << 7), // navigation requests MOTOR_STOP or motor idle regardless of throttle stick, will only activate if MOTOR_STOP feature is available
100-
COMPASS_CALIBRATED = (1 << 8),
101-
ACCELEROMETER_CALIBRATED = (1 << 9),
102-
PWM_DRIVER_AVAILABLE = (1 << 10),
103-
NAV_CRUISE_BRAKING = (1 << 11),
104-
NAV_CRUISE_BRAKING_BOOST = (1 << 12),
105-
NAV_CRUISE_BRAKING_LOCKED = (1 << 13),
92+
GPS_FIX_HOME = (1 << 0),
93+
GPS_FIX = (1 << 1),
94+
CALIBRATE_MAG = (1 << 2),
95+
SMALL_ANGLE = (1 << 3),
96+
FIXED_WING = (1 << 4), // set when in flying_wing or airplane mode. currently used by althold selection code
97+
ANTI_WINDUP = (1 << 5),
98+
FLAPERON_AVAILABLE = (1 << 6),
99+
NAV_MOTOR_STOP_OR_IDLE = (1 << 7), // navigation requests MOTOR_STOP or motor idle regardless of throttle stick, will only activate if MOTOR_STOP feature is available
100+
COMPASS_CALIBRATED = (1 << 8),
101+
ACCELEROMETER_CALIBRATED = (1 << 9),
102+
PWM_DRIVER_AVAILABLE = (1 << 10),
103+
NAV_CRUISE_BRAKING = (1 << 11),
104+
NAV_CRUISE_BRAKING_BOOST = (1 << 12),
105+
NAV_CRUISE_BRAKING_LOCKED = (1 << 13),
106+
NAV_EXTRA_ARMING_SAFETY_BYPASSED = (1 << 14), // nav_extra_arming_safey was bypassed. Keep it until power cycle.
106107
} stateFlags_t;
107108

108109
#define DISABLE_STATE(mask) (stateFlags &= ~(mask))

src/main/fc/settings.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ tables:
120120
- name: iterm_relax_type
121121
values: ["GYRO", "SETPOINT"]
122122
enum: itermRelaxType_e
123+
- name: nav_extra_arming_safety
124+
values: ["OFF", "ON", "ALLOW_BYPASS"]
125+
enum: navExtraArmingSafety_e
123126

124127
groups:
125128
- name: PG_GYRO_CONFIG
@@ -1244,7 +1247,7 @@ groups:
12441247
type: bool
12451248
- name: nav_extra_arming_safety
12461249
field: general.flags.extra_arming_safety
1247-
type: bool
1250+
table: nav_extra_arming_safety
12481251
- name: nav_user_control_mode
12491252
field: general.flags.user_control_mode
12501253
table: nav_user_control_mode

src/main/io/osd.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,20 @@ static const char * osdArmingDisabledReasonMessage(void)
616616
case ARMING_DISABLED_SYSTEM_OVERLOADED:
617617
return OSD_MESSAGE_STR("SYSTEM OVERLOADED");
618618
case ARMING_DISABLED_NAVIGATION_UNSAFE:
619-
return OSD_MESSAGE_STR("NAVIGATION IS UNSAFE");
619+
#if defined(USE_NAV)
620+
// Check the exact reason
621+
switch (navigationIsBlockingArming(NULL)) {
622+
case NAV_ARMING_BLOCKER_NONE:
623+
break;
624+
case NAV_ARMING_BLOCKER_MISSING_GPS_FIX:
625+
return OSD_MESSAGE_STR("WAITING FOR GPS FIX");
626+
case NAV_ARMING_BLOCKER_NAV_IS_ALREADY_ACTIVE:
627+
return OSD_MESSAGE_STR("DISABLE NAVIGATION FIRST");
628+
case NAV_ARMING_BLOCKER_FIRST_WAYPOINT_TOO_FAR:
629+
return OSD_MESSAGE_STR("FIRST WAYPOINT IS TOO FAR");
630+
}
631+
#endif
632+
break;
620633
case ARMING_DISABLED_COMPASS_NOT_CALIBRATED:
621634
return OSD_MESSAGE_STR("COMPASS NOT CALIBRATED");
622635
case ARMING_DISABLED_ACCELEROMETER_NOT_CALIBRATED:

src/main/navigation/navigation.c

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
#include "navigation/navigation.h"
5151
#include "navigation/navigation_private.h"
5252

53+
#include "rx/rx.h"
54+
5355
#include "sensors/sensors.h"
5456
#include "sensors/acceleration.h"
5557
#include "sensors/boardalignment.h"
@@ -83,7 +85,7 @@ PG_RESET_TEMPLATE(navConfig_t, navConfig,
8385

8486
.flags = {
8587
.use_thr_mid_for_althold = 0,
86-
.extra_arming_safety = 1,
88+
.extra_arming_safety = NAV_EXTRA_ARMING_SAFETY_ON,
8789
.user_control_mode = NAV_GPS_ATTI,
8890
.rth_alt_control_mode = NAV_RTH_AT_LEAST_ALT,
8991
.rth_climb_first = 1, // Climb first, turn after reaching safe altitude
@@ -2919,23 +2921,34 @@ bool navigationTerrainFollowingEnabled(void)
29192921
return posControl.flags.isTerrainFollowEnabled;
29202922
}
29212923

2922-
bool navigationBlockArming(void)
2924+
navArmingBlocker_e navigationIsBlockingArming(bool *usedBypass)
29232925
{
29242926
const bool navBoxModesEnabled = IS_RC_MODE_ACTIVE(BOXNAVRTH) || IS_RC_MODE_ACTIVE(BOXNAVWP) || IS_RC_MODE_ACTIVE(BOXNAVPOSHOLD) || (STATE(FIXED_WING) && IS_RC_MODE_ACTIVE(BOXNAVALTHOLD)) || (STATE(FIXED_WING) && IS_RC_MODE_ACTIVE(BOXNAVCRUISE));
29252927
const bool navLaunchComboModesEnabled = isNavLaunchEnabled() && (IS_RC_MODE_ACTIVE(BOXNAVRTH) || IS_RC_MODE_ACTIVE(BOXNAVWP) || IS_RC_MODE_ACTIVE(BOXNAVALTHOLD) || IS_RC_MODE_ACTIVE(BOXNAVCRUISE));
2926-
bool shouldBlockArming = false;
29272928

2928-
if (!navConfig()->general.flags.extra_arming_safety)
2929-
return false;
2929+
if (usedBypass) {
2930+
*usedBypass = false;
2931+
}
2932+
2933+
if (navConfig()->general.flags.extra_arming_safety == NAV_EXTRA_ARMING_SAFETY_OFF) {
2934+
return NAV_ARMING_BLOCKER_NONE;
2935+
}
29302936

29312937
// Apply extra arming safety only if pilot has any of GPS modes configured
29322938
if ((isUsingNavigationModes() || failsafeMayRequireNavigationMode()) && !((posControl.flags.estPosStatus >= EST_USABLE) && STATE(GPS_FIX_HOME))) {
2933-
shouldBlockArming = true;
2939+
if (navConfig()->general.flags.extra_arming_safety == NAV_EXTRA_ARMING_SAFETY_ALLOW_BYPASS &&
2940+
(STATE(NAV_EXTRA_ARMING_SAFETY_BYPASSED) || rxGetChannelValue(YAW) > 1750)) {
2941+
if (usedBypass) {
2942+
*usedBypass = true;
2943+
}
2944+
return NAV_ARMING_BLOCKER_NONE;
2945+
}
2946+
return NAV_ARMING_BLOCKER_MISSING_GPS_FIX;
29342947
}
29352948

29362949
// Don't allow arming if any of NAV modes is active
29372950
if (!ARMING_FLAG(ARMED) && navBoxModesEnabled && !navLaunchComboModesEnabled) {
2938-
shouldBlockArming = true;
2951+
return NAV_ARMING_BLOCKER_NAV_IS_ALREADY_ACTIVE;
29392952
}
29402953

29412954
// Don't allow arming if first waypoint is farther than configured safe distance
@@ -2946,14 +2959,13 @@ bool navigationBlockArming(void)
29462959
const bool navWpMissionStartTooFar = calculateDistanceToDestination(&startingWaypointPos) > navConfig()->general.waypoint_safe_distance;
29472960

29482961
if (navWpMissionStartTooFar) {
2949-
shouldBlockArming = true;
2962+
return NAV_ARMING_BLOCKER_FIRST_WAYPOINT_TOO_FAR;
29502963
}
29512964
}
29522965

2953-
return shouldBlockArming;
2966+
return NAV_ARMING_BLOCKER_NONE;
29542967
}
29552968

2956-
29572969
bool navigationPositionEstimateIsHealthy(void)
29582970
{
29592971
return (posControl.flags.estPosStatus >= EST_USABLE) && STATE(GPS_FIX_HOME);

src/main/navigation/navigation.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,19 @@ typedef enum {
8888
NAV_RTH_ALLOW_LANDING_FS_ONLY = 2, // Allow landing only if RTH was triggered by failsafe
8989
} navRTHAllowLanding_e;
9090

91+
typedef enum {
92+
NAV_EXTRA_ARMING_SAFETY_OFF = 0,
93+
NAV_EXTRA_ARMING_SAFETY_ON = 1,
94+
NAV_EXTRA_ARMING_SAFETY_ALLOW_BYPASS = 2, // Allow disabling by holding THR+YAW low
95+
} navExtraArmingSafety_e;
96+
97+
typedef enum {
98+
NAV_ARMING_BLOCKER_NONE = 0,
99+
NAV_ARMING_BLOCKER_MISSING_GPS_FIX = 1,
100+
NAV_ARMING_BLOCKER_NAV_IS_ALREADY_ACTIVE = 2,
101+
NAV_ARMING_BLOCKER_FIRST_WAYPOINT_TOO_FAR = 3,
102+
} navArmingBlocker_e;
103+
91104
typedef struct positionEstimationConfig_s {
92105
uint8_t automatic_mag_declination;
93106
uint8_t reset_altitude_type; // from nav_reset_type_e
@@ -128,7 +141,7 @@ typedef struct navConfig_s {
128141
struct {
129142
struct {
130143
uint8_t use_thr_mid_for_althold; // Don't remember throttle when althold was initiated, assume that throttle is at Thr Mid = zero climb rate
131-
uint8_t extra_arming_safety; // Forcibly apply 100% throttle tilt compensation
144+
uint8_t extra_arming_safety; // from navExtraArmingSafety_e
132145
uint8_t user_control_mode; // NAV_GPS_ATTI or NAV_GPS_CRUISE
133146
uint8_t rth_alt_control_mode; // Controls the logic for choosing the RTH altitude
134147
uint8_t rth_climb_first; // Controls the logic for initial RTH climbout
@@ -352,7 +365,10 @@ bool navigationRequiresAngleMode(void);
352365
bool navigationRequiresThrottleTiltCompensation(void);
353366
bool navigationRequiresTurnAssistance(void);
354367
int8_t navigationGetHeadingControlState(void);
355-
bool navigationBlockArming(void);
368+
// Returns wether arming is blocked by the navigation system.
369+
// If usedBypass is provided, it will indicate wether any checks
370+
// were bypassed due to user input.
371+
navArmingBlocker_e navigationIsBlockingArming(bool *usedBypass);
356372
bool navigationPositionEstimateIsHealthy(void);
357373
bool navIsCalibrationComplete(void);
358374
bool navigationTerrainFollowingEnabled(void);

0 commit comments

Comments
 (0)