mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-23 16:25:31 +03:00
Launch Control
Adds a race start assistance system that allows the pilot to pitch forward and then release the sticks with the quad holding position for the race start.
This commit is contained in:
parent
8609346f21
commit
e4dc93b128
14 changed files with 377 additions and 17 deletions
|
@ -101,7 +101,8 @@ enum {
|
|||
enum {
|
||||
ARMING_DELAYED_DISARMED = 0,
|
||||
ARMING_DELAYED_NORMAL = 1,
|
||||
ARMING_DELAYED_CRASHFLIP = 2
|
||||
ARMING_DELAYED_CRASHFLIP = 2,
|
||||
ARMING_DELAYED_LAUNCH_CONTROL = 3
|
||||
};
|
||||
|
||||
#define GYRO_WATCHDOG_DELAY 80 // delay for gyro sync
|
||||
|
@ -145,6 +146,20 @@ static timeUs_t runawayTakeoffTriggerUs = 0;
|
|||
static bool runawayTakeoffTemporarilyDisabled = false;
|
||||
#endif
|
||||
|
||||
#ifdef USE_LAUNCH_CONTROL
|
||||
static launchControlState_e launchControlState = LAUNCH_CONTROL_DISABLED;
|
||||
|
||||
const char * const osdLaunchControlModeNames[] = {
|
||||
"NORMAL",
|
||||
"PITCHONLY",
|
||||
"FULL"
|
||||
};
|
||||
const char * const osdLaunchControlTriggerModeNames[] = {
|
||||
"MULTIPLE",
|
||||
"SINGLE"
|
||||
};
|
||||
#endif
|
||||
|
||||
PG_REGISTER_WITH_RESET_TEMPLATE(throttleCorrectionConfig_t, throttleCorrectionConfig, PG_THROTTLE_CORRECTION_CONFIG, 0);
|
||||
|
||||
PG_RESET_TEMPLATE(throttleCorrectionConfig_t, throttleCorrectionConfig,
|
||||
|
@ -173,6 +188,23 @@ static bool isCalibrating(void)
|
|||
return (!accIsCalibrationComplete() && sensors(SENSOR_ACC)) || (!isGyroCalibrationComplete());
|
||||
}
|
||||
|
||||
#ifdef USE_LAUNCH_CONTROL
|
||||
bool canUseLaunchControl(void)
|
||||
{
|
||||
if (!STATE(FIXED_WING)
|
||||
&& !isUsingSticksForArming() // require switch arming for safety
|
||||
&& IS_RC_MODE_ACTIVE(BOXLAUNCHCONTROL)
|
||||
&& (!featureIsEnabled(FEATURE_MOTOR_STOP) || airmodeIsEnabled()) // can't use when motors are stopped
|
||||
&& !featureIsEnabled(FEATURE_3D) // pitch control is not 3D aware
|
||||
&& (flightModeFlags == 0)) { // don't want to use unless in acro mode
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void resetArmingDisabled(void)
|
||||
{
|
||||
lastArmingDisabledReason = 0;
|
||||
|
@ -346,6 +378,10 @@ void tryArm(void)
|
|||
if (tryingToArm == ARMING_DELAYED_DISARMED) {
|
||||
if (isModeActivationConditionPresent(BOXFLIPOVERAFTERCRASH) && IS_RC_MODE_ACTIVE(BOXFLIPOVERAFTERCRASH)) {
|
||||
tryingToArm = ARMING_DELAYED_CRASHFLIP;
|
||||
#ifdef USE_LAUNCH_CONTROL
|
||||
} else if (canUseLaunchControl()) {
|
||||
tryingToArm = ARMING_DELAYED_LAUNCH_CONTROL;
|
||||
#endif
|
||||
} else {
|
||||
tryingToArm = ARMING_DELAYED_NORMAL;
|
||||
}
|
||||
|
@ -370,6 +406,14 @@ void tryArm(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_LAUNCH_CONTROL
|
||||
if (!flipOverAfterCrashMode && (canUseLaunchControl() || (tryingToArm == ARMING_DELAYED_LAUNCH_CONTROL))) {
|
||||
if (launchControlState == LAUNCH_CONTROL_DISABLED) { // only activate if it hasn't already been triggered
|
||||
launchControlState = LAUNCH_CONTROL_ACTIVE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ENABLE_ARMING_FLAG(ARMED);
|
||||
ENABLE_ARMING_FLAG(WAS_EVER_ARMED);
|
||||
|
||||
|
@ -577,8 +621,10 @@ bool processRx(timeUs_t currentTimeUs)
|
|||
|
||||
const throttleStatus_e throttleStatus = calculateThrottleStatus();
|
||||
const uint8_t throttlePercent = calculateThrottlePercent();
|
||||
|
||||
const bool launchControlActive = isLaunchControlActive();
|
||||
|
||||
if (airmodeIsEnabled() && ARMING_FLAG(ARMED)) {
|
||||
if (airmodeIsEnabled() && ARMING_FLAG(ARMED) && !launchControlActive) {
|
||||
if (throttlePercent >= rxConfig()->airModeActivateThreshold) {
|
||||
airmodeIsActivated = true; // Prevent iterm from being reset
|
||||
}
|
||||
|
@ -588,7 +634,7 @@ bool processRx(timeUs_t currentTimeUs)
|
|||
|
||||
/* In airmode iterm should be prevented to grow when Low thottle and Roll + Pitch Centered.
|
||||
This is needed to prevent iterm winding on the ground, but keep full stabilisation on 0 throttle while in air */
|
||||
if (throttleStatus == THROTTLE_LOW && !airmodeIsActivated) {
|
||||
if (throttleStatus == THROTTLE_LOW && !airmodeIsActivated && !launchControlActive) {
|
||||
pidResetIterm();
|
||||
if (currentPidProfile->pidAtMinThrottle)
|
||||
pidStabilisationState(PID_STABILISATION_ON);
|
||||
|
@ -666,6 +712,29 @@ bool processRx(timeUs_t currentTimeUs)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_LAUNCH_CONTROL
|
||||
if (ARMING_FLAG(ARMED)) {
|
||||
if (launchControlActive && (throttlePercent > currentPidProfile->launchControlThrottlePct)) {
|
||||
// throttle limit trigger reached, launch triggered
|
||||
// reset the iterms as they may be at high values from holding the launch position
|
||||
launchControlState = LAUNCH_CONTROL_TRIGGERED;
|
||||
pidResetIterm();
|
||||
}
|
||||
} else {
|
||||
if (launchControlState == LAUNCH_CONTROL_TRIGGERED) {
|
||||
// If trigger mode is MULTIPLE then reset the state when disarmed
|
||||
// and the mode switch is turned off.
|
||||
// For trigger mode SINGLE we never reset the state and only a single
|
||||
// launch is allowed until a reboot.
|
||||
if ((currentPidProfile->launchControlTriggerMode == LAUNCH_CONTROL_TRIGGER_MODE_MULTIPLE) && !IS_RC_MODE_ACTIVE(BOXLAUNCHCONTROL)) {
|
||||
launchControlState = LAUNCH_CONTROL_DISABLED;
|
||||
}
|
||||
} else {
|
||||
launchControlState = LAUNCH_CONTROL_DISABLED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// When armed and motors aren't spinning, do beeps and then disarm
|
||||
// board after delay so users without buzzer won't lose fingers.
|
||||
// mixTable constrains motor commands, so checking throttleStatus is enough
|
||||
|
@ -1044,3 +1113,12 @@ void resetTryingToArm()
|
|||
{
|
||||
tryingToArm = ARMING_DELAYED_DISARMED;
|
||||
}
|
||||
|
||||
bool isLaunchControlActive(void)
|
||||
{
|
||||
#ifdef USE_LAUNCH_CONTROL
|
||||
return launchControlState == LAUNCH_CONTROL_ACTIVE;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue