mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-20 06:45:16 +03:00
Add ACC_CALIB arming disabled reason if ACC is required but not calibrated
Checks various features, modes, and OSD elements to determine if ACC is needed. Generates an arming disabled warning if ACC calibration has never been completed.
This commit is contained in:
parent
2888bdd2b8
commit
565f1f4db5
9 changed files with 122 additions and 1 deletions
|
@ -214,6 +214,61 @@ void resetArmingDisabled(void)
|
||||||
lastArmingDisabledReason = 0;
|
lastArmingDisabledReason = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_ACC
|
||||||
|
static bool accNeedsCalibration(void)
|
||||||
|
{
|
||||||
|
if (sensors(SENSOR_ACC)) {
|
||||||
|
|
||||||
|
// Check to see if the ACC has already been calibrated
|
||||||
|
if (accelerometerConfig()->calibrationCompleted ||
|
||||||
|
accelerometerConfig()->accZero.values.roll != 0 ||
|
||||||
|
accelerometerConfig()->accZero.values.pitch != 0 ||
|
||||||
|
accelerometerConfig()->accZero.values.yaw != 0) {
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We've determined that there's a detected ACC that has not
|
||||||
|
// yet been calibrated. Check to see if anything is using the
|
||||||
|
// ACC that would be affected by the lack of calibration.
|
||||||
|
|
||||||
|
// Check for any configured modes that use the ACC
|
||||||
|
if (isModeActivationConditionPresent(BOXANGLE) ||
|
||||||
|
isModeActivationConditionPresent(BOXHORIZON) ||
|
||||||
|
isModeActivationConditionPresent(BOXGPSRESCUE) ||
|
||||||
|
isModeActivationConditionPresent(BOXCAMSTAB) ||
|
||||||
|
isModeActivationConditionPresent(BOXCALIB) ||
|
||||||
|
isModeActivationConditionPresent(BOXACROTRAINER)) {
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Launch Control only requires the ACC if a angle limit is set
|
||||||
|
if (isModeActivationConditionPresent(BOXLAUNCHCONTROL) && currentPidProfile->launchControlAngleLimit) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_OSD
|
||||||
|
// Check for any enabled OSD elements that need the ACC
|
||||||
|
if (featureIsEnabled(FEATURE_OSD)) {
|
||||||
|
if (osdNeedsAccelerometer()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_GPS_RESCUE
|
||||||
|
// Check if failsafe will use GPS Rescue
|
||||||
|
if (failsafeConfig()->failsafe_procedure == FAILSAFE_PROCEDURE_GPS_RESCUE) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void updateArmingStatus(void)
|
void updateArmingStatus(void)
|
||||||
{
|
{
|
||||||
if (ARMING_FLAG(ARMED)) {
|
if (ARMING_FLAG(ARMED)) {
|
||||||
|
@ -328,6 +383,14 @@ void updateArmingStatus(void)
|
||||||
setArmingDisabled(ARMING_DISABLED_PARALYZE);
|
setArmingDisabled(ARMING_DISABLED_PARALYZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_ACC
|
||||||
|
if (accNeedsCalibration()) {
|
||||||
|
setArmingDisabled(ARMING_DISABLED_ACC_CALIBRATION);
|
||||||
|
} else {
|
||||||
|
unsetArmingDisabled(ARMING_DISABLED_ACC_CALIBRATION);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!isUsingSticksForArming()) {
|
if (!isUsingSticksForArming()) {
|
||||||
/* Ignore ARMING_DISABLED_CALIBRATING if we are going to calibrate gyro on first arm */
|
/* Ignore ARMING_DISABLED_CALIBRATING if we are going to calibrate gyro on first arm */
|
||||||
bool ignoreGyro = armingConfig()->gyro_cal_on_first_arm
|
bool ignoreGyro = armingConfig()->gyro_cal_on_first_arm
|
||||||
|
|
|
@ -57,6 +57,7 @@ const char *armingDisableFlagNames[]= {
|
||||||
"RPMFILTER",
|
"RPMFILTER",
|
||||||
"REBOOT_REQD",
|
"REBOOT_REQD",
|
||||||
"DSHOT_BBANG",
|
"DSHOT_BBANG",
|
||||||
|
"ACC_CALIB",
|
||||||
"ARMSWITCH",
|
"ARMSWITCH",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,8 @@ typedef enum {
|
||||||
ARMING_DISABLED_RPMFILTER = (1 << 20),
|
ARMING_DISABLED_RPMFILTER = (1 << 20),
|
||||||
ARMING_DISABLED_REBOOT_REQUIRED = (1 << 21),
|
ARMING_DISABLED_REBOOT_REQUIRED = (1 << 21),
|
||||||
ARMING_DISABLED_DSHOT_BITBANG = (1 << 22),
|
ARMING_DISABLED_DSHOT_BITBANG = (1 << 22),
|
||||||
ARMING_DISABLED_ARM_SWITCH = (1 << 23), // Needs to be the last element, since it's always activated if one of the others is active when arming
|
ARMING_DISABLED_ACC_CALIBRATION = (1 << 23),
|
||||||
|
ARMING_DISABLED_ARM_SWITCH = (1 << 24), // Needs to be the last element, since it's always activated if one of the others is active when arming
|
||||||
} armingDisableFlags_e;
|
} armingDisableFlags_e;
|
||||||
|
|
||||||
#define ARMING_DISABLE_FLAGS_COUNT (LOG2(ARMING_DISABLED_ARM_SWITCH) + 1)
|
#define ARMING_DISABLE_FLAGS_COUNT (LOG2(ARMING_DISABLED_ARM_SWITCH) + 1)
|
||||||
|
|
|
@ -136,6 +136,10 @@ PG_REGISTER_WITH_RESET_FN(osdConfig_t, osdConfig, PG_OSD_CONFIG, 6);
|
||||||
// be shown on the the post-flight statistics page.
|
// be shown on the the post-flight statistics page.
|
||||||
// If you reorder the stats it's likely that you'll need to make likewise updates
|
// If you reorder the stats it's likely that you'll need to make likewise updates
|
||||||
// to the unit tests.
|
// to the unit tests.
|
||||||
|
|
||||||
|
// If adding new stats, please add to the osdStatsNeedAccelerometer() function
|
||||||
|
// if the statistic utilizes the accelerometer.
|
||||||
|
//
|
||||||
const osd_stats_e osdStatsDisplayOrder[OSD_STAT_COUNT] = {
|
const osd_stats_e osdStatsDisplayOrder[OSD_STAT_COUNT] = {
|
||||||
OSD_STAT_RTC_DATE_TIME,
|
OSD_STAT_RTC_DATE_TIME,
|
||||||
OSD_STAT_TIMER_1,
|
OSD_STAT_TIMER_1,
|
||||||
|
@ -950,4 +954,20 @@ statistic_t *osdGetStats(void)
|
||||||
{
|
{
|
||||||
return &stats;
|
return &stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_ACC
|
||||||
|
// Determine if there are any enabled stats that need
|
||||||
|
// the ACC (currently only MAX_G_FORCE).
|
||||||
|
static bool osdStatsNeedAccelerometer(void)
|
||||||
|
{
|
||||||
|
return osdStatGetState(OSD_STAT_MAX_G_FORCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if any enabled elements or stats need the ACC
|
||||||
|
bool osdNeedsAccelerometer(void)
|
||||||
|
{
|
||||||
|
return osdStatsNeedAccelerometer() || osdElementsNeedAccelerometer();
|
||||||
|
}
|
||||||
|
#endif // USE_ACC
|
||||||
|
|
||||||
#endif // USE_OSD
|
#endif // USE_OSD
|
||||||
|
|
|
@ -316,3 +316,4 @@ void changeOsdProfileIndex(uint8_t profileIndex);
|
||||||
bool osdElementVisible(uint16_t value);
|
bool osdElementVisible(uint16_t value);
|
||||||
bool osdGetVisualBeeperState(void);
|
bool osdGetVisualBeeperState(void);
|
||||||
statistic_t *osdGetStats(void);
|
statistic_t *osdGetStats(void);
|
||||||
|
bool osdNeedsAccelerometer(void);
|
||||||
|
|
|
@ -36,6 +36,8 @@
|
||||||
Add the mapping from the element ID added in the first step to the function
|
Add the mapping from the element ID added in the first step to the function
|
||||||
created in the third step to the osdElementDrawFunction array.
|
created in the third step to the osdElementDrawFunction array.
|
||||||
|
|
||||||
|
If the new element utilizes the accelerometer, add it to the osdElementsNeedAccelerometer() function.
|
||||||
|
|
||||||
Finally add a CLI parameter for the new element in cli/settings.c.
|
Finally add a CLI parameter for the new element in cli/settings.c.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1779,4 +1781,27 @@ void osdUpdateAlarms(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_ACC
|
||||||
|
static bool osdElementIsActive(osd_items_e element)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < activeOsdElementCount; i++) {
|
||||||
|
if (activeOsdElementArray[i] == element) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine if any active elements need the ACC
|
||||||
|
bool osdElementsNeedAccelerometer(void)
|
||||||
|
{
|
||||||
|
return osdElementIsActive(OSD_ARTIFICIAL_HORIZON) ||
|
||||||
|
osdElementIsActive(OSD_PITCH_ANGLE) ||
|
||||||
|
osdElementIsActive(OSD_ROLL_ANGLE) ||
|
||||||
|
osdElementIsActive(OSD_G_FORCE) ||
|
||||||
|
osdElementIsActive(OSD_FLIP_ARROW);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // USE_ACC
|
||||||
|
|
||||||
#endif // USE_OSD
|
#endif // USE_OSD
|
||||||
|
|
|
@ -49,3 +49,4 @@ void osdAnalyzeActiveElements(void);
|
||||||
void osdDrawActiveElements(displayPort_t *osdDisplayPort, timeUs_t currentTimeUs);
|
void osdDrawActiveElements(displayPort_t *osdDisplayPort, timeUs_t currentTimeUs);
|
||||||
void osdResetAlarms(void);
|
void osdResetAlarms(void);
|
||||||
void osdUpdateAlarms(void);
|
void osdUpdateAlarms(void);
|
||||||
|
bool osdElementsNeedAccelerometer(void);
|
||||||
|
|
|
@ -96,6 +96,11 @@ void resetRollAndPitchTrims(rollAndPitchTrims_t *rollAndPitchTrims)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setConfigCalibrationCompleted(void)
|
||||||
|
{
|
||||||
|
accelerometerConfigMutable()->calibrationCompleted = true;
|
||||||
|
}
|
||||||
|
|
||||||
void accResetRollAndPitchTrims(void)
|
void accResetRollAndPitchTrims(void)
|
||||||
{
|
{
|
||||||
resetRollAndPitchTrims(&accelerometerConfigMutable()->accelerometerTrims);
|
resetRollAndPitchTrims(&accelerometerConfigMutable()->accelerometerTrims);
|
||||||
|
@ -119,6 +124,7 @@ void pgResetFn_accelerometerConfig(accelerometerConfig_t *instance)
|
||||||
.acc_lpf_hz = 10,
|
.acc_lpf_hz = 10,
|
||||||
.acc_hardware = ACC_DEFAULT,
|
.acc_hardware = ACC_DEFAULT,
|
||||||
.acc_high_fsr = false,
|
.acc_high_fsr = false,
|
||||||
|
.calibrationCompleted = false,
|
||||||
);
|
);
|
||||||
resetRollAndPitchTrims(&instance->accelerometerTrims);
|
resetRollAndPitchTrims(&instance->accelerometerTrims);
|
||||||
resetFlightDynamicsTrims(&instance->accZero);
|
resetFlightDynamicsTrims(&instance->accZero);
|
||||||
|
@ -405,6 +411,7 @@ static void performAcclerationCalibration(rollAndPitchTrims_t *rollAndPitchTrims
|
||||||
accelerationTrims->raw[Z] = (a[Z] + (CALIBRATING_ACC_CYCLES / 2)) / CALIBRATING_ACC_CYCLES - acc.dev.acc_1G;
|
accelerationTrims->raw[Z] = (a[Z] + (CALIBRATING_ACC_CYCLES / 2)) / CALIBRATING_ACC_CYCLES - acc.dev.acc_1G;
|
||||||
|
|
||||||
resetRollAndPitchTrims(rollAndPitchTrims);
|
resetRollAndPitchTrims(rollAndPitchTrims);
|
||||||
|
setConfigCalibrationCompleted();
|
||||||
|
|
||||||
saveConfigAndNotify();
|
saveConfigAndNotify();
|
||||||
}
|
}
|
||||||
|
@ -459,6 +466,7 @@ static void performInflightAccelerationCalibration(rollAndPitchTrims_t *rollAndP
|
||||||
accelerationTrims->raw[Z] = b[Z] / 50 - acc.dev.acc_1G; // for nunchuck 200=1G
|
accelerationTrims->raw[Z] = b[Z] / 50 - acc.dev.acc_1G; // for nunchuck 200=1G
|
||||||
|
|
||||||
resetRollAndPitchTrims(rollAndPitchTrims);
|
resetRollAndPitchTrims(rollAndPitchTrims);
|
||||||
|
setConfigCalibrationCompleted();
|
||||||
|
|
||||||
saveConfigAndNotify();
|
saveConfigAndNotify();
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,7 @@ typedef struct accelerometerConfig_s {
|
||||||
bool acc_high_fsr;
|
bool acc_high_fsr;
|
||||||
flightDynamicsTrims_t accZero;
|
flightDynamicsTrims_t accZero;
|
||||||
rollAndPitchTrims_t accelerometerTrims;
|
rollAndPitchTrims_t accelerometerTrims;
|
||||||
|
bool calibrationCompleted; // has ACC calibration been performed (should not be exposed in settings)
|
||||||
} accelerometerConfig_t;
|
} accelerometerConfig_t;
|
||||||
|
|
||||||
PG_DECLARE(accelerometerConfig_t, accelerometerConfig);
|
PG_DECLARE(accelerometerConfig_t, accelerometerConfig);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue