1
0
Fork 0
mirror of https://github.com/iNavFlight/inav.git synced 2025-07-19 14:25:16 +03:00

Merge branch 'master' into sh_mixer_profile

This commit is contained in:
shota 2023-09-20 00:45:53 +09:00
commit 59e421fba2
18 changed files with 125 additions and 170 deletions

2
.gitignore vendored
View file

@ -33,3 +33,5 @@ README.pdf
# local changes only # local changes only
make/local.mk make/local.mk
launch.json launch.json
.vscode/tasks.json
.vscode/c_cpp_properties.json

View file

@ -158,7 +158,7 @@ The flight mode operands return `true` when the mode is active. These are modes
| 7 | HORIZON | `true` when you are in the **Horizon** flight mode. | | 7 | HORIZON | `true` when you are in the **Horizon** flight mode. |
| 8 | AIR | `true` when you the **Airmode** flight mode modifier is active. | | 8 | AIR | `true` when you the **Airmode** flight mode modifier is active. |
| 9 | USER1 | `true` when the **USER 1** mode is active. | | 9 | USER1 | `true` when the **USER 1** mode is active. |
| 10 | USER2 | `true` when the **USER 21** mode is active. | | 10 | USER2 | `true` when the **USER 2** mode is active. |
| 11 | COURSE_HOLD | `true` when you are in the **Course Hold** flight mode. | | 11 | COURSE_HOLD | `true` when you are in the **Course Hold** flight mode. |
| 12 | USER3 | `true` when the **USER 3** mode is active. | | 12 | USER3 | `true` when the **USER 3** mode is active. |
| 13 | USER4 | `true` when the **USER 4** mode is active. | | 13 | USER4 | `true` when the **USER 4** mode is active. |

View file

@ -4762,16 +4762,6 @@ Video system used. Possible values are `AUTO`, `PAL`, `NTSC`, `HDZERO`, 'DJIWTF'
--- ---
### output_mode
Output function assignment mode. AUTO assigns outputs according to the default mapping, SERVOS assigns all outputs to servos, MOTORS assigns all outputs to motors
| Default | Min | Max |
| --- | --- | --- |
| AUTO | | |
---
### pid_iterm_limit_percent ### pid_iterm_limit_percent
Limits max/min I-term value in stabilization PID controller. It solves the problem of servo saturation before take-off/throwing the airplane into the air. Or multirotors with low authority. By default, error accumulated in I-term can not exceed 33% of total pid throw (around 165us on deafult pidsum_limit of pitch/roll). Set 0 to disable completely. Limits max/min I-term value in stabilization PID controller. It solves the problem of servo saturation before take-off/throwing the airplane into the air. Or multirotors with low authority. By default, error accumulated in I-term can not exceed 33% of total pid throw (around 165us on deafult pidsum_limit of pitch/roll). Set 0 to disable completely.
@ -4878,7 +4868,7 @@ Selection of pitot hardware.
| Default | Min | Max | | Default | Min | Max |
| --- | --- | --- | | --- | --- | --- |
| NONE | | | | VIRTUAL | | |
--- ---

View file

@ -211,23 +211,7 @@ static bool checkPwmTimerConflicts(const timerHardware_t *timHw)
} }
static void timerHardwareOverride(timerHardware_t * timer) { static void timerHardwareOverride(timerHardware_t * timer) {
if (currentMixerConfig.outputMode == OUTPUT_MODE_SERVOS) {
//Motors are rewritten as servos
if (timer->usageFlags & (TIM_USE_MC_MOTOR|TIM_USE_FW_MOTOR)) {
timer->usageFlags &= ~(TIM_USE_MC_MOTOR | TIM_USE_FW_MOTOR);
timer->usageFlags |= TIM_USE_MC_SERVO | TIM_USE_FW_SERVO;
}
} else if (currentMixerConfig.outputMode == OUTPUT_MODE_MOTORS) {
// Servos are rewritten as motors
if (timer->usageFlags & (TIM_USE_MC_SERVO | TIM_USE_FW_SERVO)) {
timer->usageFlags &= ~(TIM_USE_MC_SERVO | TIM_USE_FW_SERVO);
timer->usageFlags |= TIM_USE_MC_MOTOR | TIM_USE_FW_MOTOR;
}
}
switch (timerOverrides(timer2id(timer->tim))->outputMode) { switch (timerOverrides(timer2id(timer->tim))->outputMode) {
case OUTPUT_MODE_MOTORS: case OUTPUT_MODE_MOTORS:
if (timer->usageFlags & (TIM_USE_MC_SERVO | TIM_USE_FW_SERVO)) { if (timer->usageFlags & (TIM_USE_MC_SERVO | TIM_USE_FW_SERVO)) {

View file

@ -834,13 +834,25 @@ void FAST_CODE taskGyro(timeUs_t currentTimeUs) {
#endif #endif
} }
static float calculateThrottleTiltCompensationFactor(uint8_t throttleTiltCompensationStrength) static void applyThrottleTiltCompensation(void)
{ {
if (throttleTiltCompensationStrength) { if (STATE(MULTIROTOR)) {
float tiltCompFactor = 1.0f / constrainf(calculateCosTiltAngle(), 0.6f, 1.0f); // max tilt about 50 deg int16_t thrTiltCompStrength = 0;
return 1.0f + (tiltCompFactor - 1.0f) * (throttleTiltCompensationStrength / 100.f);
} else { if (navigationRequiresThrottleTiltCompensation()) {
return 1.0f; thrTiltCompStrength = 100;
}
else if (systemConfig()->throttle_tilt_compensation_strength && (FLIGHT_MODE(ANGLE_MODE) || FLIGHT_MODE(HORIZON_MODE))) {
thrTiltCompStrength = systemConfig()->throttle_tilt_compensation_strength;
}
if (thrTiltCompStrength) {
const int throttleIdleValue = getThrottleIdleValue();
float tiltCompFactor = 1.0f / constrainf(calculateCosTiltAngle(), 0.6f, 1.0f); // max tilt about 50 deg
tiltCompFactor = 1.0f + (tiltCompFactor - 1.0f) * (thrTiltCompStrength / 100.f);
rcCommand[THROTTLE] = setDesiredThrottle(throttleIdleValue + (rcCommand[THROTTLE] - throttleIdleValue) * tiltCompFactor, false);
}
} }
} }
@ -892,26 +904,7 @@ void taskMainPidLoop(timeUs_t currentTimeUs)
applyWaypointNavigationAndAltitudeHold(); applyWaypointNavigationAndAltitudeHold();
// Apply throttle tilt compensation // Apply throttle tilt compensation
if (!STATE(FIXED_WING_LEGACY)) { applyThrottleTiltCompensation();
int16_t thrTiltCompStrength = 0;
if (navigationRequiresThrottleTiltCompensation()) {
thrTiltCompStrength = 100;
}
else if (systemConfig()->throttle_tilt_compensation_strength && (FLIGHT_MODE(ANGLE_MODE) || FLIGHT_MODE(HORIZON_MODE))) {
thrTiltCompStrength = systemConfig()->throttle_tilt_compensation_strength;
}
if (thrTiltCompStrength) {
rcCommand[THROTTLE] = constrain(getThrottleIdleValue()
+ (rcCommand[THROTTLE] - getThrottleIdleValue()) * calculateThrottleTiltCompensationFactor(thrTiltCompStrength),
getThrottleIdleValue(),
motorConfig()->maxthrottle);
}
}
else {
// FIXME: throttle pitch comp for FW
}
#ifdef USE_POWER_LIMITS #ifdef USE_POWER_LIMITS
powerLimiterApply(&rcCommand[THROTTLE]); powerLimiterApply(&rcCommand[THROTTLE]);

View file

@ -112,9 +112,6 @@ tables:
enum: smartportFuelUnit_e enum: smartportFuelUnit_e
- name: platform_type - name: platform_type
values: ["MULTIROTOR", "AIRPLANE", "HELICOPTER", "TRICOPTER", "ROVER", "BOAT"] values: ["MULTIROTOR", "AIRPLANE", "HELICOPTER", "TRICOPTER", "ROVER", "BOAT"]
- name: output_mode
values: ["AUTO", "MOTORS", "SERVOS"]
enum: outputMode_e
- name: tz_automatic_dst - name: tz_automatic_dst
values: ["OFF", "EU", "USA"] values: ["OFF", "EU", "USA"]
enum: tz_automatic_dst_e enum: tz_automatic_dst_e
@ -588,7 +585,7 @@ groups:
members: members:
- name: pitot_hardware - name: pitot_hardware
description: "Selection of pitot hardware." description: "Selection of pitot hardware."
default_value: "NONE" default_value: "VIRTUAL"
table: pitot_hardware table: pitot_hardware
- name: pitot_lpf_milli_hz - name: pitot_lpf_milli_hz
min: 0 min: 0
@ -1164,11 +1161,6 @@ groups:
field: mixer_config.appliedMixerPreset field: mixer_config.appliedMixerPreset
min: -1 min: -1
max: INT16_MAX max: INT16_MAX
- name: output_mode
description: "Output function assignment mode. AUTO assigns outputs according to the default mapping, SERVOS assigns all outputs to servos, MOTORS assigns all outputs to motors"
default_value: "AUTO"
field: mixer_config.outputMode
table: output_mode
- name: motorstop_on_low - name: motorstop_on_low
description: "If enabled, motor will stop when throttle is low on this mixer_profile" description: "If enabled, motor will stop when throttle is low on this mixer_profile"
default_value: OFF default_value: OFF

View file

@ -146,6 +146,10 @@ static const failsafeProcedureLogic_t failsafeProcedureLogic[] = {
*/ */
void failsafeReset(void) void failsafeReset(void)
{ {
if (failsafeState.active) { // can't reset if still active
return;
}
failsafeState.rxDataFailurePeriod = PERIOD_RXDATA_FAILURE + failsafeConfig()->failsafe_delay * MILLIS_PER_TENTH_SECOND; failsafeState.rxDataFailurePeriod = PERIOD_RXDATA_FAILURE + failsafeConfig()->failsafe_delay * MILLIS_PER_TENTH_SECOND;
failsafeState.rxDataRecoveryPeriod = PERIOD_RXDATA_RECOVERY + failsafeConfig()->failsafe_recovery_delay * MILLIS_PER_TENTH_SECOND; failsafeState.rxDataRecoveryPeriod = PERIOD_RXDATA_RECOVERY + failsafeConfig()->failsafe_recovery_delay * MILLIS_PER_TENTH_SECOND;
failsafeState.validRxDataReceivedAt = 0; failsafeState.validRxDataReceivedAt = 0;
@ -157,6 +161,7 @@ void failsafeReset(void)
failsafeState.phase = FAILSAFE_IDLE; failsafeState.phase = FAILSAFE_IDLE;
failsafeState.rxLinkState = FAILSAFE_RXLINK_DOWN; failsafeState.rxLinkState = FAILSAFE_RXLINK_DOWN;
failsafeState.activeProcedure = failsafeConfig()->failsafe_procedure; failsafeState.activeProcedure = failsafeConfig()->failsafe_procedure;
failsafeState.controlling = false;
failsafeState.lastGoodRcCommand[ROLL] = 0; failsafeState.lastGoodRcCommand[ROLL] = 0;
failsafeState.lastGoodRcCommand[PITCH] = 0; failsafeState.lastGoodRcCommand[PITCH] = 0;
@ -211,14 +216,6 @@ bool failsafeRequiresAngleMode(void)
failsafeProcedureLogic[failsafeState.activeProcedure].forceAngleMode; failsafeProcedureLogic[failsafeState.activeProcedure].forceAngleMode;
} }
bool failsafeRequiresMotorStop(void)
{
return failsafeState.active &&
failsafeState.activeProcedure == FAILSAFE_PROCEDURE_AUTO_LANDING &&
posControl.flags.estAltStatus < EST_USABLE &&
currentBatteryProfile->failsafe_throttle < getThrottleIdleValue();
}
void failsafeStartMonitoring(void) void failsafeStartMonitoring(void)
{ {
failsafeState.monitoring = true; failsafeState.monitoring = true;

View file

@ -170,7 +170,6 @@ void failsafeOnRxResume(void);
bool failsafeMayRequireNavigationMode(void); bool failsafeMayRequireNavigationMode(void);
void failsafeApplyControlInput(void); void failsafeApplyControlInput(void);
bool failsafeRequiresAngleMode(void); bool failsafeRequiresAngleMode(void);
bool failsafeRequiresMotorStop(void);
bool failsafeShouldApplyControlInput(void); bool failsafeShouldApplyControlInput(void);
bool failsafeBypassNavigation(void); bool failsafeBypassNavigation(void);
void failsafeUpdateRcCommandValues(void); void failsafeUpdateRcCommandValues(void);

View file

@ -83,7 +83,7 @@ PG_RESET_TEMPLATE(reversibleMotorsConfig_t, reversibleMotorsConfig,
.neutral = SETTING_3D_NEUTRAL_DEFAULT .neutral = SETTING_3D_NEUTRAL_DEFAULT
); );
PG_REGISTER_WITH_RESET_TEMPLATE(motorConfig_t, motorConfig, PG_MOTOR_CONFIG, 9); PG_REGISTER_WITH_RESET_TEMPLATE(motorConfig_t, motorConfig, PG_MOTOR_CONFIG, 10);
PG_RESET_TEMPLATE(motorConfig_t, motorConfig, PG_RESET_TEMPLATE(motorConfig_t, motorConfig,
.motorPwmProtocol = SETTING_MOTOR_PWM_PROTOCOL_DEFAULT, .motorPwmProtocol = SETTING_MOTOR_PWM_PROTOCOL_DEFAULT,
@ -230,6 +230,7 @@ void mixerInit(void)
void mixerResetDisarmedMotors(void) void mixerResetDisarmedMotors(void)
{ {
getThrottleIdleValue();
if (feature(FEATURE_REVERSIBLE_MOTORS)) { if (feature(FEATURE_REVERSIBLE_MOTORS)) {
motorZeroCommand = reversibleMotorsConfig()->neutral; motorZeroCommand = reversibleMotorsConfig()->neutral;
@ -237,7 +238,7 @@ void mixerResetDisarmedMotors(void)
throttleRangeMax = motorConfig()->maxthrottle; throttleRangeMax = motorConfig()->maxthrottle;
} else { } else {
motorZeroCommand = motorConfig()->mincommand; motorZeroCommand = motorConfig()->mincommand;
throttleRangeMin = getThrottleIdleValue(); throttleRangeMin = throttleIdleValue;
throttleRangeMax = motorConfig()->maxthrottle; throttleRangeMax = motorConfig()->maxthrottle;
} }
@ -246,7 +247,7 @@ void mixerResetDisarmedMotors(void)
if (ifMotorstopFeatureEnabled()) { if (ifMotorstopFeatureEnabled()) {
motorValueWhenStopped = motorZeroCommand; motorValueWhenStopped = motorZeroCommand;
} else { } else {
motorValueWhenStopped = getThrottleIdleValue(); motorValueWhenStopped = throttleIdleValue;
} }
// set disarmed motor values // set disarmed motor values
@ -491,6 +492,19 @@ void FAST_CODE mixTable(void)
return; return;
} }
#endif #endif
#ifdef USE_DEV_TOOLS
bool isDisarmed = !ARMING_FLAG(ARMED) || systemConfig()->groundTestMode;
#else
bool isDisarmed = !ARMING_FLAG(ARMED);
#endif
bool motorStopIsActive = getMotorStatus() != MOTOR_RUNNING && !isDisarmed;
if (isDisarmed || motorStopIsActive) {
for (int i = 0; i < motorCount; i++) {
motor[i] = isDisarmed ? motor_disarmed[i] : motorValueWhenStopped;
}
mixerThrottleCommand = motor[0];
return;
}
int16_t input[3]; // RPY, range [-500:+500] int16_t input[3]; // RPY, range [-500:+500]
// Allow direct stick input to motors in passthrough mode on airplanes // Allow direct stick input to motors in passthrough mode on airplanes
@ -573,11 +587,11 @@ void FAST_CODE mixTable(void)
throttleRangeMax = motorConfig()->maxthrottle; throttleRangeMax = motorConfig()->maxthrottle;
// Throttle scaling to limit max throttle when battery is full // Throttle scaling to limit max throttle when battery is full
#ifdef USE_PROGRAMMING_FRAMEWORK #ifdef USE_PROGRAMMING_FRAMEWORK
mixerThrottleCommand = ((mixerThrottleCommand - throttleRangeMin) * getThrottleScale(currentBatteryProfile->motor.throttleScale)) + throttleRangeMin; mixerThrottleCommand = ((mixerThrottleCommand - throttleRangeMin) * getThrottleScale(currentBatteryProfile->motor.throttleScale)) + throttleRangeMin;
#else #else
mixerThrottleCommand = ((mixerThrottleCommand - throttleRangeMin) * currentBatteryProfile->motor.throttleScale) + throttleRangeMin; mixerThrottleCommand = ((mixerThrottleCommand - throttleRangeMin) * currentBatteryProfile->motor.throttleScale) + throttleRangeMin;
#endif #endif
// Throttle compensation based on battery voltage // Throttle compensation based on battery voltage
if (feature(FEATURE_THR_VBAT_COMP) && isAmperageConfigured() && feature(FEATURE_VBAT)) { if (feature(FEATURE_THR_VBAT_COMP) && isAmperageConfigured() && feature(FEATURE_VBAT)) {
mixerThrottleCommand = MIN(throttleRangeMin + (mixerThrottleCommand - throttleRangeMin) * calculateThrottleCompensationFactor(), throttleRangeMax); mixerThrottleCommand = MIN(throttleRangeMin + (mixerThrottleCommand - throttleRangeMin) * calculateThrottleCompensationFactor(), throttleRangeMax);
@ -586,7 +600,6 @@ void FAST_CODE mixTable(void)
throttleMin = throttleRangeMin; throttleMin = throttleRangeMin;
throttleMax = throttleRangeMax; throttleMax = throttleRangeMax;
throttleRange = throttleMax - throttleMin; throttleRange = throttleMax - throttleMin;
#define THROTTLE_CLIPPING_FACTOR 0.33f #define THROTTLE_CLIPPING_FACTOR 0.33f
@ -606,64 +619,53 @@ void FAST_CODE mixTable(void)
// Now add in the desired throttle, but keep in a range that doesn't clip adjusted // Now add in the desired throttle, but keep in a range that doesn't clip adjusted
// roll/pitch/yaw. This could move throttle down, but also up for those low throttle flips. // roll/pitch/yaw. This could move throttle down, but also up for those low throttle flips.
if (ARMING_FLAG(ARMED)) { for (int i = 0; i < motorCount; i++) {
const motorStatus_e currentMotorStatus = getMotorStatus(); motor[i] = rpyMix[i] + constrain(mixerThrottleCommand * currentMixer[i].throttle, throttleMin, throttleMax);
for (int i = 0; i < motorCount; i++) {
motor[i] = rpyMix[i] + constrain(mixerThrottleCommand * currentMixer[i].throttle, throttleMin, throttleMax);
if (failsafeIsActive()) { if (failsafeIsActive()) {
motor[i] = constrain(motor[i], motorConfig()->mincommand, motorConfig()->maxthrottle); motor[i] = constrain(motor[i], motorConfig()->mincommand, motorConfig()->maxthrottle);
} else { } else {
motor[i] = constrain(motor[i], throttleRangeMin, throttleRangeMax); motor[i] = constrain(motor[i], throttleRangeMin, throttleRangeMax);
}
//stop motors
if (currentMixer[i].throttle <= 0.0f) {
motor[i] = motorZeroCommand;
}
//spin stopped motors only in mixer transition mode
if (isMixerTransitionMixing && currentMixer[i].throttle <= -1.05f && currentMixer[i].throttle >= -2.0f && (!feature(FEATURE_REVERSIBLE_MOTORS))) {
motor[i] = -currentMixer[i].throttle * 1000;
motor[i] = constrain(motor[i], throttleRangeMin, throttleRangeMax);
}
// Motor stop handling
if (currentMotorStatus != MOTOR_RUNNING) {
motor[i] = motorValueWhenStopped;
}
#ifdef USE_DEV_TOOLS
if (systemConfig()->groundTestMode) {
motor[i] = motorZeroCommand;
}
#endif
} }
} else {
for (int i = 0; i < motorCount; i++) { //stop motors
motor[i] = motor_disarmed[i]; if (currentMixer[i].throttle <= 0.0f) {
motor[i] = motorZeroCommand;
}
//spin stopped motors only in mixer transition mode
if (isMixerTransitionMixing && currentMixer[i].throttle <= -1.05f && currentMixer[i].throttle >= -2.0f && (!feature(FEATURE_REVERSIBLE_MOTORS))) {
motor[i] = -currentMixer[i].throttle * 1000;
motor[i] = constrain(motor[i], throttleRangeMin, throttleRangeMax);
} }
} }
} }
int16_t getThrottlePercent(bool useScaled) int16_t getThrottlePercent(bool useScaled)
{ {
int16_t thr = constrain(rcCommand[THROTTLE], PWM_RANGE_MIN, PWM_RANGE_MAX); int16_t thr = constrain(mixerThrottleCommand, PWM_RANGE_MIN, PWM_RANGE_MAX);
const int idleThrottle = getThrottleIdleValue();
if (useScaled) { if (useScaled) {
thr = (thr - idleThrottle) * 100 / (motorConfig()->maxthrottle - idleThrottle); thr = (thr - throttleIdleValue) * 100 / (motorConfig()->maxthrottle - throttleIdleValue);
} else { } else {
thr = (rxGetChannelValue(THROTTLE) - PWM_RANGE_MIN) * 100 / (PWM_RANGE_MAX - PWM_RANGE_MIN); thr = (rxGetChannelValue(THROTTLE) - PWM_RANGE_MIN) * 100 / (PWM_RANGE_MAX - PWM_RANGE_MIN);
} }
return thr; return thr;
} }
uint16_t setDesiredThrottle(uint16_t throttle, bool allowMotorStop)
{
const uint16_t throttleIdleValue = getThrottleIdleValue();
if (allowMotorStop && throttle < throttleIdleValue) {
ENABLE_STATE(NAV_MOTOR_STOP_OR_IDLE);
return throttle;
}
return constrain(throttle, throttleIdleValue, motorConfig()->maxthrottle);
}
motorStatus_e getMotorStatus(void) motorStatus_e getMotorStatus(void)
{ {
if (failsafeRequiresMotorStop()) { if (STATE(NAV_MOTOR_STOP_OR_IDLE)) {
return MOTOR_STOPPED_AUTO;
}
if (!failsafeIsActive() && STATE(NAV_MOTOR_STOP_OR_IDLE)) {
return MOTOR_STOPPED_AUTO; return MOTOR_STOPPED_AUTO;
} }

View file

@ -110,6 +110,7 @@ extern int mixerThrottleCommand;
bool ifMotorstopFeatureEnabled(void); bool ifMotorstopFeatureEnabled(void);
int getThrottleIdleValue(void); int getThrottleIdleValue(void);
int16_t getThrottlePercent(bool); int16_t getThrottlePercent(bool);
uint16_t setDesiredThrottle(uint16_t throttle, bool allowMotorStop);
uint8_t getMotorCount(void); uint8_t getMotorCount(void);
float getMotorMixRange(void); float getMotorMixRange(void);
bool mixerIsOutputSaturated(void); bool mixerIsOutputSaturated(void);

View file

@ -48,7 +48,6 @@ void pgResetFn_mixerProfiles(mixerProfile_t *instance)
.platformType = SETTING_PLATFORM_TYPE_DEFAULT, .platformType = SETTING_PLATFORM_TYPE_DEFAULT,
.hasFlaps = SETTING_HAS_FLAPS_DEFAULT, .hasFlaps = SETTING_HAS_FLAPS_DEFAULT,
.appliedMixerPreset = SETTING_MODEL_PREVIEW_TYPE_DEFAULT, // This flag is not available in CLI and used by Configurator only .appliedMixerPreset = SETTING_MODEL_PREVIEW_TYPE_DEFAULT, // This flag is not available in CLI and used by Configurator only
.outputMode = SETTING_OUTPUT_MODE_DEFAULT,
.motorstopOnLow = SETTING_MOTORSTOP_ON_LOW_DEFAULT, .motorstopOnLow = SETTING_MOTORSTOP_ON_LOW_DEFAULT,
.PIDProfileLinking = SETTING_MIXER_PID_PROFILE_LINKING_DEFAULT, .PIDProfileLinking = SETTING_MIXER_PID_PROFILE_LINKING_DEFAULT,
.automated_switch = SETTING_MIXER_AUTOMATED_SWITCH_DEFAULT, .automated_switch = SETTING_MIXER_AUTOMATED_SWITCH_DEFAULT,

View file

@ -831,13 +831,14 @@ static const char * osdArmingDisabledReasonMessage(void)
// See handling of FAILSAFE_RX_LOSS_MONITORING in failsafe.c // See handling of FAILSAFE_RX_LOSS_MONITORING in failsafe.c
if (failsafePhase() == FAILSAFE_RX_LOSS_MONITORING) { if (failsafePhase() == FAILSAFE_RX_LOSS_MONITORING) {
if (failsafeIsReceivingRxData()) { if (failsafeIsReceivingRxData()) {
// If we're not using sticks, it means the ARM switch // reminder to disarm to exit FAILSAFE_RX_LOSS_MONITORING once timeout period ends
// hasn't been off since entering FAILSAFE_RX_LOSS_MONITORING if (IS_RC_MODE_ACTIVE(BOXARM)) {
// yet return OSD_MESSAGE_STR(OSD_MSG_TURN_ARM_SW_OFF);
return OSD_MESSAGE_STR(OSD_MSG_TURN_ARM_SW_OFF); }
} else {
// Not receiving RX data
return OSD_MESSAGE_STR(OSD_MSG_RC_RX_LINK_LOST);
} }
// Not receiving RX data
return OSD_MESSAGE_STR(OSD_MSG_RC_RX_LINK_LOST);
} }
return OSD_MESSAGE_STR(OSD_MSG_DISABLED_BY_FS); return OSD_MESSAGE_STR(OSD_MSG_DISABLED_BY_FS);
case ARMING_DISABLED_NOT_LEVEL: case ARMING_DISABLED_NOT_LEVEL:
@ -991,10 +992,10 @@ static const char * osdFailsafeInfoMessage(void)
#if defined(USE_SAFE_HOME) #if defined(USE_SAFE_HOME)
static const char * divertingToSafehomeMessage(void) static const char * divertingToSafehomeMessage(void)
{ {
if (NAV_Status.state != MW_NAV_STATE_HOVER_ABOVE_HOME && posControl.safehomeState.isApplied) { if (NAV_Status.state != MW_NAV_STATE_HOVER_ABOVE_HOME && posControl.safehomeState.isApplied) {
return OSD_MESSAGE_STR(OSD_MSG_DIVERT_SAFEHOME); return OSD_MESSAGE_STR(OSD_MSG_DIVERT_SAFEHOME);
} }
return NULL; return NULL;
} }
#endif #endif
@ -1116,11 +1117,7 @@ bool osdUsingScaledThrottle(void)
**/ **/
static void osdFormatThrottlePosition(char *buff, bool useScaled, textAttributes_t *elemAttr) static void osdFormatThrottlePosition(char *buff, bool useScaled, textAttributes_t *elemAttr)
{ {
if (useScaled) { buff[0] = SYM_BLANK;
buff[0] = SYM_SCALE;
} else {
buff[0] = SYM_BLANK;
}
buff[1] = SYM_THR; buff[1] = SYM_THR;
if (navigationIsControllingThrottle()) { if (navigationIsControllingThrottle()) {
buff[0] = SYM_AUTO_THR0; buff[0] = SYM_AUTO_THR0;
@ -1135,7 +1132,14 @@ static void osdFormatThrottlePosition(char *buff, bool useScaled, textAttributes
TEXT_ATTRIBUTES_ADD_BLINK(*elemAttr); TEXT_ATTRIBUTES_ADD_BLINK(*elemAttr);
} }
#endif #endif
tfp_sprintf(buff + 2, "%3d", getThrottlePercent(useScaled)); int8_t throttlePercent = getThrottlePercent(useScaled);
if ((useScaled && throttlePercent <= 0) || !ARMING_FLAG(ARMED)) {
const char* message = ARMING_FLAG(ARMED) ? throttlePercent == 0 ? "IDLE" : "STOP" : "DARM";
buff[0] = SYM_THR;
strcpy(buff + 1, message);
return;
}
tfp_sprintf(buff + 2, "%3d", throttlePercent);
} }
/** /**
@ -4445,14 +4449,14 @@ static void osdShowArmed(void)
if (posControl.safehomeState.distance) { // safehome found during arming if (posControl.safehomeState.distance) { // safehome found during arming
if (navConfig()->general.flags.safehome_usage_mode == SAFEHOME_USAGE_OFF) { if (navConfig()->general.flags.safehome_usage_mode == SAFEHOME_USAGE_OFF) {
strcpy(buf, "SAFEHOME FOUND; MODE OFF"); strcpy(buf, "SAFEHOME FOUND; MODE OFF");
} else { } else {
char buf2[12]; // format the distance first char buf2[12]; // format the distance first
osdFormatDistanceStr(buf2, posControl.safehomeState.distance); osdFormatDistanceStr(buf2, posControl.safehomeState.distance);
tfp_sprintf(buf, "%c - %s -> SAFEHOME %u", SYM_HOME, buf2, posControl.safehomeState.index); tfp_sprintf(buf, "%c - %s -> SAFEHOME %u", SYM_HOME, buf2, posControl.safehomeState.index);
} }
textAttributes_t elemAttr = _TEXT_ATTRIBUTES_BLINK_BIT; textAttributes_t elemAttr = _TEXT_ATTRIBUTES_BLINK_BIT;
// write this message above the ARMED message to make it obvious // write this message above the ARMED message to make it obvious
displayWriteWithAttr(osdDisplayPort, (osdDisplayPort->cols - strlen(buf)) / 2, y - 8, buf, elemAttr); displayWriteWithAttr(osdDisplayPort, (osdDisplayPort->cols - strlen(buf)) / 2, y - 8, buf, elemAttr);
} }
#endif #endif
} else { } else {

View file

@ -1874,8 +1874,6 @@ static navigationFSMEvent_t navOnEnteringState_NAV_STATE_EMERGENCY_LANDING_FINIS
{ {
UNUSED(previousState); UNUSED(previousState);
disarm(DISARM_NAVIGATION);
return NAV_FSM_EVENT_NONE; return NAV_FSM_EVENT_NONE;
} }
@ -2972,7 +2970,7 @@ void updateLandingStatus(timeMs_t currentTimeMs)
} }
} else if (STATE(LANDING_DETECTED)) { } else if (STATE(LANDING_DETECTED)) {
pidResetErrorAccumulators(); pidResetErrorAccumulators();
if (navConfig()->general.flags.disarm_on_landing) { if (navConfig()->general.flags.disarm_on_landing && !FLIGHT_MODE(FAILSAFE_MODE)) {
ENABLE_ARMING_FLAG(ARMING_DISABLED_LANDING_DETECTED); ENABLE_ARMING_FLAG(ARMING_DISABLED_LANDING_DETECTED);
disarm(DISARM_LANDING); disarm(DISARM_LANDING);
} else if (!navigationInAutomaticThrottleMode()) { } else if (!navigationInAutomaticThrottleMode()) {

View file

@ -651,7 +651,7 @@ void applyFixedWingPitchRollThrottleController(navigationFSMStateFlags_t navStat
isAutoThrottleManuallyIncreased = false; isAutoThrottleManuallyIncreased = false;
} }
rcCommand[THROTTLE] = constrain(correctedThrottleValue, getThrottleIdleValue(), motorConfig()->maxthrottle); rcCommand[THROTTLE] = setDesiredThrottle(correctedThrottleValue, false);
} }
#ifdef NAV_FIXED_WING_LANDING #ifdef NAV_FIXED_WING_LANDING
@ -666,7 +666,6 @@ void applyFixedWingPitchRollThrottleController(navigationFSMStateFlags_t navStat
(posControl.flags.estAglStatus == EST_TRUSTED && posControl.actualState.agl.pos.z <= navConfig()->general.land_slowdown_minalt)) { (posControl.flags.estAglStatus == EST_TRUSTED && posControl.actualState.agl.pos.z <= navConfig()->general.land_slowdown_minalt)) {
// Set motor to min. throttle and stop it when MOTOR_STOP feature is enabled // Set motor to min. throttle and stop it when MOTOR_STOP feature is enabled
rcCommand[THROTTLE] = getThrottleIdleValue();
ENABLE_STATE(NAV_MOTOR_STOP_OR_IDLE); ENABLE_STATE(NAV_MOTOR_STOP_OR_IDLE);
// Stabilize ROLL axis on 0 degrees banking regardless of loiter radius and position // Stabilize ROLL axis on 0 degrees banking regardless of loiter radius and position
@ -766,7 +765,7 @@ bool isFixedWingLandingDetected(void)
*-----------------------------------------------------------*/ *-----------------------------------------------------------*/
void applyFixedWingEmergencyLandingController(timeUs_t currentTimeUs) void applyFixedWingEmergencyLandingController(timeUs_t currentTimeUs)
{ {
rcCommand[THROTTLE] = currentBatteryProfile->failsafe_throttle; rcCommand[THROTTLE] = setDesiredThrottle(currentBatteryProfile->failsafe_throttle, true);
if (posControl.flags.estAltStatus >= EST_USABLE) { if (posControl.flags.estAltStatus >= EST_USABLE) {
// target min descent rate 10m above takeoff altitude // target min descent rate 10m above takeoff altitude

View file

@ -234,19 +234,12 @@ static void setCurrentState(fixedWingLaunchState_t nextState, timeUs_t currentTi
/* Wing control Helpers */ /* Wing control Helpers */
static bool isThrottleIdleEnabled(void)
{
return currentBatteryProfile->nav.fw.launch_idle_throttle > getThrottleIdleValue();
}
static void applyThrottleIdleLogic(bool forceMixerIdle) static void applyThrottleIdleLogic(bool forceMixerIdle)
{ {
if (isThrottleIdleEnabled() && !forceMixerIdle) { if (forceMixerIdle) {
rcCommand[THROTTLE] = currentBatteryProfile->nav.fw.launch_idle_throttle; ENABLE_STATE(NAV_MOTOR_STOP_OR_IDLE); // If MOTOR_STOP is enabled mixer will keep motor stopped, otherwise motor will run at idle
} } else {
else { rcCommand[THROTTLE] = setDesiredThrottle(currentBatteryProfile->nav.fw.launch_idle_throttle, true);
ENABLE_STATE(NAV_MOTOR_STOP_OR_IDLE); // If MOTOR_STOP is enabled mixer will keep motor stopped
rcCommand[THROTTLE] = getThrottleIdleValue(); // If MOTOR_STOP is disabled, motors will spin given throttle value
} }
} }
@ -290,7 +283,7 @@ static fixedWingLaunchEvent_t fwLaunchState_FW_LAUNCH_STATE_WAIT_THROTTLE(timeUs
UNUSED(currentTimeUs); UNUSED(currentTimeUs);
if (!throttleStickIsLow()) { if (!throttleStickIsLow()) {
if (isThrottleIdleEnabled()) { if (currentBatteryProfile->nav.fw.launch_idle_throttle > getThrottleIdleValue()) {
return FW_LAUNCH_EVENT_SUCCESS; return FW_LAUNCH_EVENT_SUCCESS;
} }
else { else {
@ -404,7 +397,7 @@ static fixedWingLaunchEvent_t fwLaunchState_FW_LAUNCH_STATE_MOTOR_SPINUP(timeUs_
const timeMs_t elapsedTimeMs = currentStateElapsedMs(currentTimeUs); const timeMs_t elapsedTimeMs = currentStateElapsedMs(currentTimeUs);
const uint16_t motorSpinUpMs = navConfig()->fw.launch_motor_spinup_time; const uint16_t motorSpinUpMs = navConfig()->fw.launch_motor_spinup_time;
const uint16_t launchThrottle = constrain(currentBatteryProfile->nav.fw.launch_throttle, getThrottleIdleValue(), motorConfig()->maxthrottle); const uint16_t launchThrottle = setDesiredThrottle(currentBatteryProfile->nav.fw.launch_throttle, false);
if (elapsedTimeMs > motorSpinUpMs) { if (elapsedTimeMs > motorSpinUpMs) {
rcCommand[THROTTLE] = launchThrottle; rcCommand[THROTTLE] = launchThrottle;
@ -438,7 +431,7 @@ static fixedWingLaunchEvent_t fwLaunchState_FW_LAUNCH_STATE_IN_PROGRESS(timeUs_t
} }
} else { } else {
initialTime = navConfig()->fw.launch_motor_timer + navConfig()->fw.launch_motor_spinup_time; initialTime = navConfig()->fw.launch_motor_timer + navConfig()->fw.launch_motor_spinup_time;
rcCommand[THROTTLE] = constrain(currentBatteryProfile->nav.fw.launch_throttle, getThrottleIdleValue(), motorConfig()->maxthrottle); rcCommand[THROTTLE] = setDesiredThrottle(currentBatteryProfile->nav.fw.launch_throttle, false);
} }
if (isLaunchMaxAltitudeReached()) { if (isLaunchMaxAltitudeReached()) {
@ -468,7 +461,7 @@ static fixedWingLaunchEvent_t fwLaunchState_FW_LAUNCH_STATE_FINISH(timeUs_t curr
// Make a smooth transition from the launch state to the current state for pitch angle // Make a smooth transition from the launch state to the current state for pitch angle
// Do the same for throttle when manual launch throttle isn't used // Do the same for throttle when manual launch throttle isn't used
if (!navConfig()->fw.launch_manual_throttle) { if (!navConfig()->fw.launch_manual_throttle) {
const uint16_t launchThrottle = constrain(currentBatteryProfile->nav.fw.launch_throttle, getThrottleIdleValue(), motorConfig()->maxthrottle); const uint16_t launchThrottle = setDesiredThrottle(currentBatteryProfile->nav.fw.launch_throttle, false);
rcCommand[THROTTLE] = scaleRangef(elapsedTimeMs, 0.0f, endTimeMs, launchThrottle, rcCommand[THROTTLE]); rcCommand[THROTTLE] = scaleRangef(elapsedTimeMs, 0.0f, endTimeMs, launchThrottle, rcCommand[THROTTLE]);
} }
fwLaunch.pitchAngle = scaleRangef(elapsedTimeMs, 0.0f, endTimeMs, navConfig()->fw.launch_climb_angle, rcCommand[PITCH]); fwLaunch.pitchAngle = scaleRangef(elapsedTimeMs, 0.0f, endTimeMs, navConfig()->fw.launch_climb_angle, rcCommand[PITCH]);

View file

@ -121,7 +121,7 @@ static void updateAltitudeThrottleController_MC(timeDelta_t deltaMicros)
int16_t rcThrottleCorrection = pt1FilterApply4(&altholdThrottleFilterState, velocity_controller, NAV_THROTTLE_CUTOFF_FREQENCY_HZ, US2S(deltaMicros)); int16_t rcThrottleCorrection = pt1FilterApply4(&altholdThrottleFilterState, velocity_controller, NAV_THROTTLE_CUTOFF_FREQENCY_HZ, US2S(deltaMicros));
rcThrottleCorrection = constrain(rcThrottleCorrection, thrCorrectionMin, thrCorrectionMax); rcThrottleCorrection = constrain(rcThrottleCorrection, thrCorrectionMin, thrCorrectionMax);
posControl.rcAdjustment[THROTTLE] = constrain(currentBatteryProfile->nav.mc.hover_throttle + rcThrottleCorrection, getThrottleIdleValue(), motorConfig()->maxthrottle); posControl.rcAdjustment[THROTTLE] = setDesiredThrottle(currentBatteryProfile->nav.mc.hover_throttle + rcThrottleCorrection, false);
} }
bool adjustMulticopterAltitudeFromRCInput(void) bool adjustMulticopterAltitudeFromRCInput(void)
@ -914,13 +914,14 @@ static void applyMulticopterEmergencyLandingController(timeUs_t currentTimeUs)
rcCommand[YAW] = 0; rcCommand[YAW] = 0;
rcCommand[ROLL] = 0; rcCommand[ROLL] = 0;
rcCommand[PITCH] = 0; rcCommand[PITCH] = 0;
rcCommand[THROTTLE] = currentBatteryProfile->failsafe_throttle;
/* Altitude sensors gone haywire, attempt to land regardless */ /* Altitude sensors gone haywire, attempt to land regardless */
if (posControl.flags.estAltStatus < EST_USABLE) { if (posControl.flags.estAltStatus < EST_USABLE) {
if (failsafeConfig()->failsafe_procedure == FAILSAFE_PROCEDURE_DROP_IT) { if (failsafeConfig()->failsafe_procedure == FAILSAFE_PROCEDURE_DROP_IT) {
rcCommand[THROTTLE] = getThrottleIdleValue(); rcCommand[THROTTLE] = getThrottleIdleValue();
return;
} }
rcCommand[THROTTLE] = setDesiredThrottle(currentBatteryProfile->failsafe_throttle, true);
return; return;
} }

View file

@ -138,7 +138,7 @@ void applyRoverBoatNavigationController(navigationFSMStateFlags_t navStateFlags,
rcCommand[ROLL] = 0; rcCommand[ROLL] = 0;
rcCommand[PITCH] = 0; rcCommand[PITCH] = 0;
rcCommand[YAW] = 0; rcCommand[YAW] = 0;
rcCommand[THROTTLE] = currentBatteryProfile->failsafe_throttle; rcCommand[THROTTLE] = setDesiredThrottle(currentBatteryProfile->failsafe_throttle, true);
} else if (navStateFlags & NAV_CTL_POS) { } else if (navStateFlags & NAV_CTL_POS) {
applyRoverBoatPositionController(currentTimeUs); applyRoverBoatPositionController(currentTimeUs);
applyRoverBoatPitchRollThrottleController(navStateFlags, currentTimeUs); applyRoverBoatPitchRollThrottleController(navStateFlags, currentTimeUs);

View file

@ -55,6 +55,7 @@
#define USE_BARO_BMP280 #define USE_BARO_BMP280
#define USE_BARO_MS5611 #define USE_BARO_MS5611
#define USE_BARO_DPS310
//*********** Magnetometer / Compass ************* //*********** Magnetometer / Compass *************
#define USE_MAG #define USE_MAG