mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-15 12:25:20 +03:00
Auto-disarm on landing impact (#13803)
* Disarm on landing * Changes from review comments, thanks PL * Sorry missed that one * calculate Acc magnitude once only, not multiple times * Include gyro factors as in crashRecovery * Fix bug in CrashRecovery delta gains Add temporary debugs to monitor error and delta inputs * remove 1G subtraction for accMagnitude thanks Karate * Use AccDelta or Jerk - thanks Karate * Revert using Gyro Setpoint and Delta * Fix typo, thanks Mark * increment PG version to 9
This commit is contained in:
parent
8f10f17245
commit
f890287598
16 changed files with 72 additions and 25 deletions
|
@ -1412,6 +1412,7 @@ static bool blackboxWriteSysinfo(void)
|
|||
BLACKBOX_PRINT_HEADER_LINE(PARAM_NAME_EZ_LANDING_THRESHOLD, "%d", currentPidProfile->ez_landing_threshold);
|
||||
BLACKBOX_PRINT_HEADER_LINE(PARAM_NAME_EZ_LANDING_LIMIT, "%d", currentPidProfile->ez_landing_limit);
|
||||
BLACKBOX_PRINT_HEADER_LINE(PARAM_NAME_EZ_LANDING_SPEED, "%d", currentPidProfile->ez_landing_speed);
|
||||
BLACKBOX_PRINT_HEADER_LINE(PARAM_NAME_EZ_DISARM_THRESHOLD, "%d", currentPidProfile->ez_landing_disarm_threshold);
|
||||
|
||||
#ifdef USE_WING
|
||||
BLACKBOX_PRINT_HEADER_LINE(PARAM_NAME_SPA_ROLL_CENTER, "%d", currentPidProfile->spa_center[FD_ROLL]);
|
||||
|
|
|
@ -1276,6 +1276,7 @@ const clivalue_t valueTable[] = {
|
|||
{ PARAM_NAME_EZ_LANDING_THRESHOLD, VAR_UINT8 | PROFILE_VALUE, .config.minmaxUnsigned = { 0, 200 }, PG_PID_PROFILE, offsetof(pidProfile_t, ez_landing_threshold) },
|
||||
{ PARAM_NAME_EZ_LANDING_LIMIT, VAR_UINT8 | PROFILE_VALUE, .config.minmaxUnsigned = { 0, 75 }, PG_PID_PROFILE, offsetof(pidProfile_t, ez_landing_limit) },
|
||||
{ PARAM_NAME_EZ_LANDING_SPEED, VAR_UINT8 | PROFILE_VALUE, .config.minmaxUnsigned = { 0, 250 }, PG_PID_PROFILE, offsetof(pidProfile_t, ez_landing_speed) },
|
||||
{ PARAM_NAME_EZ_DISARM_THRESHOLD, VAR_UINT8 | PROFILE_VALUE, .config.minmaxUnsigned = { 0, 250 }, PG_PID_PROFILE, offsetof(pidProfile_t, ez_landing_disarm_threshold) },
|
||||
|
||||
#ifdef USE_WING
|
||||
{ PARAM_NAME_SPA_ROLL_CENTER, VAR_UINT16 | PROFILE_VALUE, .config.minmaxUnsigned = { 0, UINT16_MAX }, PG_PID_PROFILE, offsetof(pidProfile_t, spa_center[FD_ROLL]) },
|
||||
|
|
|
@ -266,6 +266,7 @@ static uint16_t cmsx_tpa_breakpoint;
|
|||
static int8_t cmsx_tpa_low_rate;
|
||||
static uint16_t cmsx_tpa_low_breakpoint;
|
||||
static uint8_t cmsx_tpa_low_always;
|
||||
static uint8_t cmsx_ez_landing_disarm_threshold;
|
||||
|
||||
static const void *cmsx_simplifiedTuningOnEnter(displayPort_t *pDisp)
|
||||
{
|
||||
|
@ -610,7 +611,7 @@ static const void *cmsx_profileOtherOnEnter(displayPort_t *pDisp)
|
|||
cmsx_tpa_low_rate = pidProfile->tpa_low_rate;
|
||||
cmsx_tpa_low_breakpoint = pidProfile->tpa_low_breakpoint;
|
||||
cmsx_tpa_low_always = pidProfile->tpa_low_always;
|
||||
|
||||
cmsx_ez_landing_disarm_threshold = pidProfile->ez_landing_disarm_threshold;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -668,6 +669,7 @@ static const void *cmsx_profileOtherOnExit(displayPort_t *pDisp, const OSD_Entry
|
|||
pidProfile->tpa_low_rate = cmsx_tpa_low_rate;
|
||||
pidProfile->tpa_low_breakpoint = cmsx_tpa_low_breakpoint;
|
||||
pidProfile->tpa_low_always = cmsx_tpa_low_always;
|
||||
pidProfile->ez_landing_disarm_threshold = cmsx_ez_landing_disarm_threshold;
|
||||
|
||||
initEscEndpoints();
|
||||
return NULL;
|
||||
|
@ -728,6 +730,7 @@ static const OSD_Entry cmsx_menuProfileOtherEntries[] = {
|
|||
{ "TPA LOW RATE", OME_INT8, NULL, &(OSD_INT8_t) { &cmsx_tpa_low_rate, TPA_LOW_RATE_MIN, TPA_MAX , 1} },
|
||||
{ "TPA LOW BRKPT", OME_UINT16, NULL, &(OSD_UINT16_t){ &cmsx_tpa_low_breakpoint, 1000, 2000, 10} },
|
||||
{ "TPA LOW ALWYS", OME_Bool, NULL, &cmsx_tpa_low_always },
|
||||
{ "EZDISARM THR", OME_UINT8, NULL, &(OSD_UINT8_t) { &cmsx_ez_landing_disarm_threshold, 0, 150, 1} },
|
||||
|
||||
{ "BACK", OME_Back, NULL, NULL },
|
||||
{ NULL, OME_END, NULL, NULL}
|
||||
|
|
|
@ -55,6 +55,7 @@ typedef enum {
|
|||
DISARM_REASON_RUNAWAY_TAKEOFF = 6,
|
||||
DISARM_REASON_GPS_RESCUE = 7,
|
||||
DISARM_REASON_SERIAL_COMMAND = 8,
|
||||
DISARM_REASON_LANDING = 9,
|
||||
#ifdef UNIT_TEST
|
||||
DISARM_REASON_SYSTEM = 255,
|
||||
#endif
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
#define PARAM_NAME_EZ_LANDING_THRESHOLD "ez_landing_threshold"
|
||||
#define PARAM_NAME_EZ_LANDING_LIMIT "ez_landing_limit"
|
||||
#define PARAM_NAME_EZ_LANDING_SPEED "ez_landing_speed"
|
||||
#define PARAM_NAME_EZ_DISARM_THRESHOLD "ez_landing_disarm_threshold"
|
||||
#define PARAM_NAME_SPA_ROLL_CENTER "spa_roll_center"
|
||||
#define PARAM_NAME_SPA_ROLL_WIDTH "spa_roll_width"
|
||||
#define PARAM_NAME_SPA_ROLL_MODE "spa_roll_mode"
|
||||
|
|
|
@ -101,7 +101,6 @@ typedef struct {
|
|||
float distanceToHomeM;
|
||||
uint16_t groundSpeedCmS;
|
||||
int16_t directionToHome;
|
||||
float accMagnitude;
|
||||
bool healthy;
|
||||
float errorAngle;
|
||||
float gpsDataIntervalSeconds;
|
||||
|
@ -564,12 +563,6 @@ static void sensorUpdate(void)
|
|||
DEBUG_SET(DEBUG_GPS_RESCUE_HEADING, 3, rescueState.sensor.directionToHome); // computed from current GPS position in relation to home
|
||||
rescueState.sensor.healthy = gpsIsHealthy();
|
||||
|
||||
if (rescueState.phase == RESCUE_LANDING) {
|
||||
// do this at sensor update rate, not the much slower GPS rate, for quick disarm
|
||||
rescueState.sensor.accMagnitude = (float) sqrtf(sq(acc.accADC[Z] - acc.dev.acc_1G) + sq(acc.accADC[X]) + sq(acc.accADC[Y])) * acc.dev.acc_1G_rec;
|
||||
// Note: subtracting 1G from Z assumes the quad is 'flat' with respect to the horizon. A true non-gravity acceleration value, regardless of attitude, may be better.
|
||||
}
|
||||
|
||||
rescueState.sensor.directionToHome = GPS_directionToHome; // extern value from gps.c using current position relative to home
|
||||
rescueState.sensor.errorAngle = (attitude.values.yaw - rescueState.sensor.directionToHome) / 10.0f;
|
||||
// both attitude and direction are in degrees * 10, errorAngle is degrees
|
||||
|
@ -702,7 +695,7 @@ static bool checkGPSRescueIsAvailable(void)
|
|||
|
||||
void disarmOnImpact(void)
|
||||
{
|
||||
if (rescueState.sensor.accMagnitude > rescueState.intent.disarmThreshold) {
|
||||
if (acc.accMagnitude > rescueState.intent.disarmThreshold) {
|
||||
setArmingDisabled(ARMING_DISABLED_ARM_SWITCH);
|
||||
disarm(DISARM_REASON_GPS_RESCUE);
|
||||
rescueStop();
|
||||
|
|
|
@ -323,18 +323,10 @@ STATIC_UNIT_TESTED void imuUpdateEulerAngles(void)
|
|||
}
|
||||
}
|
||||
|
||||
static bool imuIsAccelerometerHealthy(const float *accAverage)
|
||||
static bool imuIsAccelerometerHealthy(void)
|
||||
{
|
||||
float accMagnitudeSq = 0;
|
||||
for (int axis = 0; axis < 3; axis++) {
|
||||
const float a = accAverage[axis];
|
||||
accMagnitudeSq += a * a;
|
||||
}
|
||||
|
||||
accMagnitudeSq = accMagnitudeSq * sq(acc.dev.acc_1G_rec);
|
||||
|
||||
// Accept accel readings only in range 0.9g - 1.1g
|
||||
return (0.81f < accMagnitudeSq) && (accMagnitudeSq < 1.21f);
|
||||
return (0.9f < acc.accMagnitude) && (acc.accMagnitude < 1.1f);
|
||||
}
|
||||
|
||||
// Calculate the dcmKpGain to use. When armed, the gain is imuRuntimeConfig.imuDcmKp, i.e., the default value
|
||||
|
@ -687,8 +679,7 @@ static void imuCalculateEstimatedAttitude(timeUs_t currentTimeUs)
|
|||
gyroAverage[axis] = gyroGetFilteredDownsampled(axis);
|
||||
}
|
||||
|
||||
const bool useAcc = imuIsAccelerometerHealthy(acc.accADC); // all smoothed accADC values are within 20% of 1G
|
||||
|
||||
const bool useAcc = imuIsAccelerometerHealthy(); // all smoothed accADC values are within 10% of 1G
|
||||
imuMahonyAHRSupdate(dt,
|
||||
DEGREES_TO_RADIANS(gyroAverage[X]), DEGREES_TO_RADIANS(gyroAverage[Y]), DEGREES_TO_RADIANS(gyroAverage[Z]),
|
||||
useAcc, acc.accADC[X], acc.accADC[Y], acc.accADC[Z],
|
||||
|
|
|
@ -100,6 +100,7 @@ void stopMotors(void)
|
|||
}
|
||||
|
||||
static FAST_DATA_ZERO_INIT float throttle = 0;
|
||||
static FAST_DATA_ZERO_INIT float rcThrottle = 0;
|
||||
static FAST_DATA_ZERO_INIT float mixerThrottle = 0;
|
||||
static FAST_DATA_ZERO_INIT float motorOutputMin;
|
||||
static FAST_DATA_ZERO_INIT float motorRangeMin;
|
||||
|
@ -264,6 +265,7 @@ static void calculateThrottleAndCurrentMotorEndpoints(timeUs_t currentTimeUs)
|
|||
}
|
||||
|
||||
throttle = constrainf(throttle / currentThrottleInputRange, 0.0f, 1.0f);
|
||||
rcThrottle = throttle;
|
||||
}
|
||||
|
||||
#define CRASH_FLIP_DEADBAND 20
|
||||
|
@ -771,3 +773,8 @@ float mixerGetThrottle(void)
|
|||
{
|
||||
return mixerThrottle;
|
||||
}
|
||||
|
||||
float mixerGetRcThrottle(void)
|
||||
{
|
||||
return rcThrottle;
|
||||
}
|
||||
|
|
|
@ -140,6 +140,7 @@ bool mixerIsTricopter(void);
|
|||
|
||||
void mixerSetThrottleAngleCorrection(int correctionValue);
|
||||
float mixerGetThrottle(void);
|
||||
float mixerGetRcThrottle(void);
|
||||
mixerMode_e getMixerMode(void);
|
||||
bool mixerModeIsFixedWing(mixerMode_e mixerMode);
|
||||
bool isFixedWing(void);
|
||||
|
|
|
@ -116,7 +116,7 @@ PG_RESET_TEMPLATE(pidConfig_t, pidConfig,
|
|||
|
||||
#define LAUNCH_CONTROL_YAW_ITERM_LIMIT 50 // yaw iterm windup limit when launch mode is "FULL" (all axes)
|
||||
|
||||
PG_REGISTER_ARRAY_WITH_RESET_FN(pidProfile_t, PID_PROFILE_COUNT, pidProfiles, PG_PID_PROFILE, 8);
|
||||
PG_REGISTER_ARRAY_WITH_RESET_FN(pidProfile_t, PID_PROFILE_COUNT, pidProfiles, PG_PID_PROFILE, 9);
|
||||
|
||||
void resetPidProfile(pidProfile_t *pidProfile)
|
||||
{
|
||||
|
@ -236,6 +236,7 @@ void resetPidProfile(pidProfile_t *pidProfile)
|
|||
.spa_center = { 0, 0, 0 },
|
||||
.spa_width = { 0, 0, 0 },
|
||||
.spa_mode = { 0, 0, 0 },
|
||||
.ez_landing_disarm_threshold = 0 ,
|
||||
);
|
||||
|
||||
#ifndef USE_D_MIN
|
||||
|
@ -774,6 +775,20 @@ float pidGetAirmodeThrottleOffset(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
static FAST_CODE_NOINLINE void disarmOnImpact(void)
|
||||
{
|
||||
// if all sticks are within 5% of center, and throttle low, check accDelta for impacts
|
||||
// threshold should be high enough to avoid unwanted disarms in the air on throttle chops
|
||||
if (isAirmodeActivated() && getMaxRcDeflectionAbs() < 0.05f && mixerGetRcThrottle() < 0.05f &&
|
||||
fabsf(acc.accDelta) > pidRuntime.ezLandingDisarmThreshold) {
|
||||
// disarm on accDelta transients
|
||||
setArmingDisabled(ARMING_DISABLED_ARM_SWITCH);
|
||||
disarm(DISARM_REASON_LANDING);
|
||||
}
|
||||
DEBUG_SET(DEBUG_EZLANDING, 6, lrintf(getMaxRcDeflectionAbs() * 100.0f));
|
||||
DEBUG_SET(DEBUG_EZLANDING, 7, lrintf(acc.accDelta));
|
||||
}
|
||||
|
||||
#ifdef USE_LAUNCH_CONTROL
|
||||
#define LAUNCH_CONTROL_MAX_RATE 100.0f
|
||||
#define LAUNCH_CONTROL_MIN_RATE 5.0f
|
||||
|
@ -974,6 +989,10 @@ void FAST_CODE pidController(const pidProfile_t *pidProfile, timeUs_t currentTim
|
|||
rpmFilterUpdate();
|
||||
#endif
|
||||
|
||||
if (pidRuntime.useEzDisarm) {
|
||||
disarmOnImpact();
|
||||
}
|
||||
|
||||
// ----------PID controller----------
|
||||
for (int axis = FD_ROLL; axis <= FD_YAW; ++axis) {
|
||||
|
||||
|
@ -1043,6 +1062,7 @@ void FAST_CODE pidController(const pidProfile_t *pidProfile, timeUs_t currentTim
|
|||
|
||||
const float previousIterm = pidData[axis].I;
|
||||
float itermErrorRate = errorRate;
|
||||
|
||||
#ifdef USE_ABSOLUTE_CONTROL
|
||||
const float uncorrectedSetpoint = currentPidSetpoint;
|
||||
#endif
|
||||
|
@ -1081,12 +1101,14 @@ void FAST_CODE pidController(const pidProfile_t *pidProfile, timeUs_t currentTim
|
|||
}
|
||||
|
||||
float iTermChange = (Ki + pidRuntime.itermAccelerator) * dynCi * pidRuntime.dT * itermErrorRate;
|
||||
|
||||
#ifdef USE_WING
|
||||
if (pidProfile->spa_mode[axis] != SPA_MODE_OFF) {
|
||||
// slowing down I-term change, or even making it zero if setpoint is high enough
|
||||
iTermChange *= pidRuntime.spa[axis];
|
||||
}
|
||||
#endif // #ifdef USE_WING
|
||||
|
||||
pidData[axis].I = constrainf(previousIterm + iTermChange, -pidRuntime.itermLimit, pidRuntime.itermLimit);
|
||||
|
||||
// -----calculate D component
|
||||
|
@ -1151,6 +1173,7 @@ void FAST_CODE pidController(const pidProfile_t *pidProfile, timeUs_t currentTim
|
|||
// Apply the dMinFactor
|
||||
preTpaD *= dMinFactor;
|
||||
#endif
|
||||
|
||||
pidData[axis].D = preTpaD * pidRuntime.tpaFactor;
|
||||
|
||||
// Log the value of D pre application of TPA
|
||||
|
|
|
@ -261,6 +261,8 @@ typedef struct pidProfile_s {
|
|||
uint8_t ez_landing_threshold; // Threshold stick position below which motor output is limited
|
||||
uint8_t ez_landing_limit; // Maximum motor output when all sticks centred and throttle zero
|
||||
uint8_t ez_landing_speed; // Speed below which motor output is limited
|
||||
uint8_t ez_landing_disarm_threshold; // Accelerometer vector threshold which disarms if exceeded
|
||||
|
||||
uint16_t tpa_delay_ms; // TPA delay for fixed wings using pt2 filter (time constant)
|
||||
uint16_t spa_center[XYZ_AXIS_COUNT]; // RPY setpoint at which PIDs are reduced to 50% (setpoint PID attenuation)
|
||||
uint16_t spa_width[XYZ_AXIS_COUNT]; // Width of smooth transition around spa_center
|
||||
|
@ -358,6 +360,8 @@ typedef struct pidRuntime_s {
|
|||
float tpaLowBreakpoint;
|
||||
float tpaLowMultiplier;
|
||||
bool tpaLowAlways;
|
||||
bool useEzDisarm;
|
||||
float ezLandingDisarmThreshold;
|
||||
|
||||
#ifdef USE_ITERM_RELAX
|
||||
pt1Filter_t windupLpf[XYZ_AXIS_COUNT];
|
||||
|
|
|
@ -316,8 +316,8 @@ void pidInitConfig(const pidProfile_t *pidProfile)
|
|||
pidRuntime.crashTimeDelayUs = pidProfile->crash_delay * 1000;
|
||||
pidRuntime.crashRecoveryAngleDeciDegrees = pidProfile->crash_recovery_angle * 10;
|
||||
pidRuntime.crashRecoveryRate = pidProfile->crash_recovery_rate;
|
||||
pidRuntime.crashGyroThreshold = pidProfile->crash_gthreshold;
|
||||
pidRuntime.crashDtermThreshold = pidProfile->crash_dthreshold;
|
||||
pidRuntime.crashGyroThreshold = pidProfile->crash_gthreshold; // error in deg/s
|
||||
pidRuntime.crashDtermThreshold = pidProfile->crash_dthreshold * 1000.0f; // gyro delta in deg/s/s * 1000 to match original 2017 intent
|
||||
pidRuntime.crashSetpointThreshold = pidProfile->crash_setpoint_threshold;
|
||||
pidRuntime.crashLimitYaw = pidProfile->crash_limit_yaw;
|
||||
pidRuntime.itermLimit = pidProfile->itermLimit;
|
||||
|
@ -441,6 +441,10 @@ void pidInitConfig(const pidProfile_t *pidProfile)
|
|||
pidRuntime.tpaLowBreakpoint = MIN(pidRuntime.tpaLowBreakpoint, pidRuntime.tpaBreakpoint);
|
||||
pidRuntime.tpaLowMultiplier = pidProfile->tpa_low_rate / (100.0f * pidRuntime.tpaLowBreakpoint);
|
||||
pidRuntime.tpaLowAlways = pidProfile->tpa_low_always;
|
||||
|
||||
pidRuntime.useEzDisarm = pidProfile->ez_landing_disarm_threshold > 0;
|
||||
pidRuntime.ezLandingDisarmThreshold = pidProfile->ez_landing_disarm_threshold * 10.0f;
|
||||
|
||||
}
|
||||
|
||||
void pidCopyProfile(uint8_t dstPidProfileIndex, uint8_t srcPidProfileIndex)
|
||||
|
|
|
@ -47,7 +47,7 @@ PG_RESET_TEMPLATE(gpsRescueConfig_t, gpsRescueConfig,
|
|||
.descentDistanceM = 20,
|
||||
.descendRate = 150, // cm/s, minimum for descent and landing phase, or for descending if starting high ascent
|
||||
.targetLandingAltitudeM = 4,
|
||||
.disarmThreshold = 20,
|
||||
.disarmThreshold = 30,
|
||||
|
||||
.throttleMin = 1100,
|
||||
.throttleMax = 1700,
|
||||
|
|
|
@ -51,6 +51,7 @@ static void applyAccelerationTrims(const flightDynamicsTrims_t *accelerationTrim
|
|||
void accUpdate(timeUs_t currentTimeUs)
|
||||
{
|
||||
UNUSED(currentTimeUs);
|
||||
static float previousAccMagnitude;
|
||||
|
||||
if (!acc.dev.readFn(&acc.dev)) {
|
||||
return;
|
||||
|
@ -78,10 +79,15 @@ void accUpdate(timeUs_t currentTimeUs)
|
|||
|
||||
applyAccelerationTrims(accelerationRuntime.accelerationTrims);
|
||||
|
||||
float accAdcSquaredSum = 0.0f;
|
||||
for (int axis = 0; axis < XYZ_AXIS_COUNT; axis++) {
|
||||
const float val = acc.accADC[axis];
|
||||
acc.accADC[axis] = accelerationRuntime.accLpfCutHz ? pt2FilterApply(&accelerationRuntime.accFilter[axis], val) : val;
|
||||
accAdcSquaredSum += sq(acc.accADC[axis]);
|
||||
}
|
||||
acc.accMagnitude = sqrtf(accAdcSquaredSum) * acc.dev.acc_1G_rec; // normally 1.0; used for disarm on impact detection
|
||||
acc.accDelta = (acc.accMagnitude - previousAccMagnitude) * acc.sampleRateHz;
|
||||
previousAccMagnitude = acc.accMagnitude;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -56,6 +56,8 @@ typedef struct acc_s {
|
|||
uint16_t sampleRateHz;
|
||||
float accADC[XYZ_AXIS_COUNT];
|
||||
bool isAccelUpdatedAtLeastOnce;
|
||||
float accMagnitude;
|
||||
float accDelta;
|
||||
} acc_t;
|
||||
|
||||
extern acc_t acc;
|
||||
|
|
|
@ -28,6 +28,8 @@ bool simulatedAirmodeEnabled = true;
|
|||
float simulatedSetpointRate[3] = { 0,0,0 };
|
||||
float simulatedPrevSetpointRate[3] = { 0,0,0 };
|
||||
float simulatedRcDeflection[3] = { 0,0,0 };
|
||||
float simulatedMaxRcDeflectionAbs = 0;
|
||||
float simulatedMixerGetRcThrottle = 0;
|
||||
float simulatedRcCommandDelta[3] = { 1,1,1 };
|
||||
float simulatedRawSetpoint[3] = { 0,0,0 };
|
||||
float simulatedMaxRate[3] = { 670,670,670 };
|
||||
|
@ -72,6 +74,7 @@ extern "C" {
|
|||
#include "sensors/gyro.h"
|
||||
#include "sensors/acceleration.h"
|
||||
|
||||
acc_t acc;
|
||||
gyro_t gyro;
|
||||
attitudeEulerAngles_t attitude;
|
||||
|
||||
|
@ -85,6 +88,12 @@ extern "C" {
|
|||
float getSetpointRate(int axis) { return simulatedSetpointRate[axis]; }
|
||||
bool isAirmodeActivated(void) { return simulatedAirmodeEnabled; }
|
||||
float getRcDeflectionAbs(int axis) { return fabsf(simulatedRcDeflection[axis]); }
|
||||
|
||||
// for ezLanding auto-disarm
|
||||
// note that there is no test to check that this code works.
|
||||
float getMaxRcDeflectionAbs() { return fabsf(simulatedMaxRcDeflectionAbs); }
|
||||
float mixerGetRcThrottle() { return fabsf(simulatedMixerGetRcThrottle); }
|
||||
|
||||
void systemBeep(bool) { }
|
||||
bool gyroOverflowDetected(void) { return false; }
|
||||
float getRcDeflection(int axis) { return simulatedRcDeflection[axis]; }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue