1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-20 23:05:19 +03:00

afterburner progress

This commit is contained in:
skyfpv 2023-05-01 09:31:55 -06:00
parent 6f070bbc88
commit 31cc3c4587
28 changed files with 407859 additions and 37 deletions

Binary file not shown.

View file

@ -0,0 +1,19 @@
Disclaimer:
Street League, its partners, and the authors of this software are not responsible for injury or damage to property resulting from the use of this software.
What is the RPM limiter?
The RPM limiter seeks to better equalize the performance of drone motors for spec racing purposes. A PID loop is used to limit the drone's maximum rpm to 13k rpm at 100% throttle. The limiter also linearizes the rpm of the motors such that, for example, 50% throttle will result in 50% of 13k rpm, 25% will result in 25% of the max throttle, etc. This means that battery sag will have very little effect on the rpm of the motors throughout the flight, and it won't be felt via the throttle. Please ensure voltage alarms are configured on your OSD or radio.
Which HEX do I use?
- plug your flight controller into your PC
- Open Betaflight
- In the top right corner will be displayed a dropdown menu with the COM port the FC is using
- A COM port label of "COM4 - Betaflight STM32F7x2" indicates the user should flash the STM32F7x2 HEX file.
- Note: pancake board users have a seperate hex
- If you have any questions, please reach out on our discord: https://discord.gg/C4HHYccaqk
IMPORTANT - After flashing:
After flashing, ALWAYS select "Apply Custom Defaults" when connecting for the first time!!!
If you are not prompted to apply custom defaults, you will need to make sure you either paste a dump from before flashing, or copy your custom defaults from here.
https://github.com/betaflight/unified-targets/tree/master/configs/default

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -108,4 +108,5 @@ const char * const debugModeNames[DEBUG_COUNT] = {
"VTX_MSP", "VTX_MSP",
"GPS_DOP", "GPS_DOP",
"FAILSAFE", "FAILSAFE",
"RPM_LIMITER",
}; };

View file

@ -106,6 +106,7 @@ typedef enum {
DEBUG_VTX_MSP, DEBUG_VTX_MSP,
DEBUG_GPS_DOP, DEBUG_GPS_DOP,
DEBUG_FAILSAFE, DEBUG_FAILSAFE,
DEBUG_RPM_LIMITER,
DEBUG_COUNT DEBUG_COUNT
} debugType_e; } debugType_e;

View file

@ -941,12 +941,16 @@ const clivalue_t valueTable[] = {
{ "rpm_limiter_i", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 10000 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_i) }, { "rpm_limiter_i", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 10000 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_i) },
{ "rpm_limiter_d", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 10000 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_d) }, { "rpm_limiter_d", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 10000 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_d) },
{ "rpm_limiter_rpm_limit", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 999 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_rpm_limit) }, { "rpm_limiter_rpm_limit", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 999 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_rpm_limit) },
{ "rpm_limiter_afterburner", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 999 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_rpm_afterburner) },
{ "rpm_limiter_afterburner_duration", VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 255 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_rpm_afterburner_duration) },
{ "rpm_limiter_afterburner_hold_to_use", VAR_INT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_rpm_afterburner_hold_to_use) },
{ "rpm_limiter_afterburner_tank_count", VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 255 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_rpm_afterburner_tank_count) },
{ "rpm_limiter_afterburner_reset", VAR_INT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_rpm_afterburner_reset) },
{ "rpm_limiter_acceleration_limit", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 1000 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_acceleration_limit) }, { "rpm_limiter_acceleration_limit", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 1000 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_acceleration_limit) },
{ "rpm_limiter_deceleration_limit", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 1000 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_deceleration_limit) },
//Street League customization //Street League customization
{ "rpm_limiter_idle_rpm", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 30 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_idle_rpm) }, { "rpm_limiter_idle_rpm", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 30 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_idle_rpm) },
//{ "rpm_limiter_idle_rpm", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 999 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_idle_rpm) }, //{ "rpm_limiter_idle_rpm", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 999 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_idle_rpm) },
{ "rpm_limiter_full_linearization", VAR_INT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, rpm_linearization) }, { "rpm_limiter_full_linearization", VAR_INT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_rpm_linearization) },
{ "3d_deadband_high", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { PWM_RANGE_MIDDLE, PWM_PULSE_MAX }, PG_MOTOR_3D_CONFIG, offsetof(flight3DConfig_t, deadband3d_high) }, { "3d_deadband_high", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { PWM_RANGE_MIDDLE, PWM_PULSE_MAX }, PG_MOTOR_3D_CONFIG, offsetof(flight3DConfig_t, deadband3d_high) },
{ "3d_neutral", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { PWM_PULSE_MIN, PWM_PULSE_MAX }, PG_MOTOR_3D_CONFIG, offsetof(flight3DConfig_t, neutral3d) }, { "3d_neutral", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { PWM_PULSE_MIN, PWM_PULSE_MAX }, PG_MOTOR_3D_CONFIG, offsetof(flight3DConfig_t, neutral3d) },

View file

@ -79,6 +79,7 @@ typedef enum {
BOXBEEPERMUTE, BOXBEEPERMUTE,
BOXREADY, BOXREADY,
CHECKBOX_ITEM_COUNT CHECKBOX_ITEM_COUNT
} boxId_e; } boxId_e;
typedef enum { typedef enum {

View file

@ -344,34 +344,71 @@ static void applyFlipOverAfterCrashModeToMotors(void)
} }
} }
static void applyRPMLimiter(void) static void applyRPMLimiter(void)
{ {
//Street League spec settings if (mixerRuntime.govenorEnabled) {
float forcedRPMLimit = 130.0f;
bool forcedLinearization = true;
int forcedMotorPoleCount = 14;
bool forceGovenor = true;
//Unlocked spec settings
//float forcedRPMLimit = mixerConfig()->govenor_rpm_limit;
//bool forcedLinearization = mixerConfig()->rpm_linearization;
//int forcedMotorPoleCount = motorConfig()->motorPoleCount;
//bool forceGovenor = mixerConfig()->govenor && motorConfig()->dev.useDshotTelemetry;
if (forceGovenor) {
float RPM_GOVENOR_LIMIT = 0; float RPM_GOVENOR_LIMIT = 0;
float averageRPM = 0; float averageRPM = 0;
float averageRPM_smoothed = 0; float averageRPM_smoothed = 0;
float PIDOutput = 0; float PIDOutput = 0;
float rcCommandThrottle = (rcCommand[THROTTLE]-1000)/1000.0f; float rcCommandThrottle = (rcCommand[THROTTLE]-1000)/1000.0f;
float maxRPMLimit = 0;
maxRPMLimit = mixerRuntime.RPMLimit;
//afterburner code
//if drone is armed
if (ARMING_FLAG(ARMED)) {
//if the afterburner switch is enguaged
if(IS_RC_MODE_ACTIVE(BOXUSER4)) {
//if the afterburner isn't initiated
if(mixerRuntime.afterburnerInitiated == false) {
//if there's charge in the tank
if(mixerRuntime.afterburnerTankPercent>0.0f) {
//if we have another tank left
if(mixerRuntime.afterburnerTanksRemaining>0) {
mixerRuntime.afterburnerInitiated = true;
}
}
}
//if the afterburner switch is NOT enguaged
} else {
//if hold to boost is enabled
if(mixerRuntime.afterburnerHoldToBoost) {
mixerRuntime.afterburnerInitiated = false;
}
//if the tank is empty, reset
if(mixerRuntime.afterburnerTankPercent<=0.0f) {
mixerRuntime.afterburnerInitiated = false;
mixerRuntime.afterburnerTankPercent = 100.0f;
mixerRuntime.afterburnerTanksRemaining -= 1;
}
}
//use afterburner
if(mixerRuntime.afterburnerInitiated) {
//tank percent decreases linearly
mixerRuntime.afterburnerTankPercent -= (pidGetDT()/(mixerRuntime.afterburnerDuration))*100.0f;
//tank percent can never be above 100%
mixerRuntime.afterburnerTankPercent = MAX(mixerRuntime.afterburnerTankPercent,0.0f);
//increase the rpm limit
maxRPMLimit = mixerRuntime.RPMLimit+(mixerRuntime.afterburnerRPM*mixerRuntime.afterburnerTankPercent*0.01f);
}
}else{
if(mixerRuntime.afterburnerReset) {
mixerRuntime.afterburnerTankPercent = 100.0f;
mixerRuntime.afterburnerTanksRemaining = mixerConfig()->govenor_rpm_afterburner_tank_count;
}
}
//Street League customization //Street League customization
if (forcedLinearization) { if (mixerRuntime.rpmLinearization) {
//scales rpm setpoint between idle rpm and rpm limit based on throttle percent //scales rpm setpoint between idle rpm and max rpm limit based on throttle percent
RPM_GOVENOR_LIMIT = ((forcedRPMLimit - mixerConfig()->govenor_idle_rpm))*100.0f*(rcCommandThrottle) + mixerConfig()->govenor_idle_rpm * 100.0f; RPM_GOVENOR_LIMIT = ((maxRPMLimit - mixerConfig()->govenor_idle_rpm))*100.0f*(rcCommandThrottle) + mixerConfig()->govenor_idle_rpm * 100.0f;
//limit the speed with which the rpm setpoint can increase based on the rpm_limiter_acceleration_limit cli command //limit the speed with which the rpm setpoint can change based on the rpm_limiter_acceleration_limit cli command
float acceleration = RPM_GOVENOR_LIMIT - mixerRuntime.govenorPreviousRPMLimit; float acceleration = RPM_GOVENOR_LIMIT - mixerRuntime.govenorPreviousRPMLimit;
if(acceleration > 0) { if(acceleration > 0) {
acceleration = MIN(acceleration, mixerRuntime.govenorAccelerationLimit); acceleration = MIN(acceleration, mixerRuntime.govenorAccelerationLimit);
@ -381,21 +418,24 @@ static void applyRPMLimiter(void)
acceleration = MAX(acceleration, -mixerRuntime.govenorDecelerationLimit); acceleration = MAX(acceleration, -mixerRuntime.govenorDecelerationLimit);
RPM_GOVENOR_LIMIT = mixerRuntime.govenorPreviousRPMLimit + acceleration; RPM_GOVENOR_LIMIT = mixerRuntime.govenorPreviousRPMLimit + acceleration;
} }
} } else {
else {
throttle = throttle * mixerRuntime.govenorExpectedThrottleLimit; throttle = throttle * mixerRuntime.govenorExpectedThrottleLimit;
RPM_GOVENOR_LIMIT = ((forcedRPMLimit))*100.0f; RPM_GOVENOR_LIMIT = ((maxRPMLimit))*100.0f;
} }
//get the rpm averaged across the motors //get the rpm averaged across the motors
bool motorsSaturated = false; bool motorsSaturated = false;
//bool motorsDesaturated = false;
for (int i = 0; i < getMotorCount(); i++) { for (int i = 0; i < getMotorCount(); i++) {
averageRPM += getDshotTelemetry(i); averageRPM += getDshotTelemetry(i);
if (motor[i] >= motorConfig()->maxthrottle) { if (motor[i] >= motorConfig()->maxthrottle) {
motorsSaturated = true; motorsSaturated = true;
} }
/*if (motor[i] <= motorConfig()->minthrottle) {
motorsDesaturated = true;
}*/
} }
averageRPM = 100 * averageRPM / (getMotorCount()*forcedMotorPoleCount/2.0f); averageRPM = 100 * averageRPM / (getMotorCount()*mixerRuntime.motorPoleCount/2.0f);
//get the smoothed rpm to avoid d term noise //get the smoothed rpm to avoid d term noise
averageRPM_smoothed = mixerRuntime.govenorPreviousSmoothedRPM + mixerRuntime.govenorDelayK * (averageRPM - mixerRuntime.govenorPreviousSmoothedRPM); //kinda braindead to convert to rps then back averageRPM_smoothed = mixerRuntime.govenorPreviousSmoothedRPM + mixerRuntime.govenorDelayK * (averageRPM - mixerRuntime.govenorPreviousSmoothedRPM); //kinda braindead to convert to rps then back
@ -404,7 +444,8 @@ static void applyRPMLimiter(void)
float govenorP = smoothedRPMError * mixerRuntime.govenorPGain; //+ when overspped float govenorP = smoothedRPMError * mixerRuntime.govenorPGain; //+ when overspped
float govenorD = (smoothedRPMError-mixerRuntime.govenorPreviousSmoothedRPMError) * mixerRuntime.govenorDGain; // + when quickly going overspeed float govenorD = (smoothedRPMError-mixerRuntime.govenorPreviousSmoothedRPMError) * mixerRuntime.govenorDGain; // + when quickly going overspeed
if (forcedLinearization) { if (mixerRuntime.rpmLinearization) {
/*
//don't let I term wind up if throttle is below the motor idle //don't let I term wind up if throttle is below the motor idle
if (rcCommandThrottle < motorConfig()->digitalIdleOffsetValue / 10000.0f) { if (rcCommandThrottle < motorConfig()->digitalIdleOffsetValue / 10000.0f) {
mixerRuntime.govenorI *= 1.0f/(1.0f+(pidGetDT()*10.0f)); //slowly ramp down i term instead of resetting to avoid throttle pulsing cheats mixerRuntime.govenorI *= 1.0f/(1.0f+(pidGetDT()*10.0f)); //slowly ramp down i term instead of resetting to avoid throttle pulsing cheats
@ -414,7 +455,20 @@ static void applyRPMLimiter(void)
{ {
mixerRuntime.govenorI += smoothedRPMError * mixerRuntime.govenorIGain; // + when overspeed mixerRuntime.govenorI += smoothedRPMError * mixerRuntime.govenorIGain; // + when overspeed
} }
}*/
//don't let I term wind up if throttle is below the motor idle
if (rcCommandThrottle < motorConfig()->digitalIdleOffsetValue / 10000.0f) {
//mixerRuntime.govenorI *= 1.0f/(1.0f+(pidGetDT()*10.0f)); //slowly ramp down i term instead of resetting to avoid throttle pulsing cheats
mixerRuntime.govenorI = 0.0f;
} else {
//don't let I term wind up if motors are saturated. Otherwise, motors may stay at high throttle even after low throttle is commanded
if(!motorsSaturated)
{
mixerRuntime.govenorI += smoothedRPMError * mixerRuntime.govenorIGain; // + when overspeed
} }
}
//sum our pid terms //sum our pid terms
PIDOutput = govenorP + mixerRuntime.govenorI + govenorD; //more + when overspeed, should be subtracted from throttle PIDOutput = govenorP + mixerRuntime.govenorI + govenorD; //more + when overspeed, should be subtracted from throttle
@ -435,7 +489,7 @@ static void applyRPMLimiter(void)
} }
if (mixerRuntime.govenor_init) { if (mixerRuntime.govenor_init) {
if (forcedLinearization) { if (mixerRuntime.rpmLinearization) {
throttle = constrainf(-PIDOutput, 0.0f, 1.0f); throttle = constrainf(-PIDOutput, 0.0f, 1.0f);
} else { } else {
throttle = constrainf(throttle-PIDOutput, 0.0f, 1.0f); throttle = constrainf(throttle-PIDOutput, 0.0f, 1.0f);
@ -449,10 +503,15 @@ static void applyRPMLimiter(void)
mixerRuntime.govenorPreviousSmoothedRPMError = smoothedRPMError; mixerRuntime.govenorPreviousSmoothedRPMError = smoothedRPMError;
mixerRuntime.govenorPreviousRPMLimit = RPM_GOVENOR_LIMIT; mixerRuntime.govenorPreviousRPMLimit = RPM_GOVENOR_LIMIT;
//DEBUG_SET(DEBUG_RPM_LIMITER, 0, averageRPM); DEBUG_SET(DEBUG_RPM_LIMITER, 0, averageRPM);
//DEBUG_SET(DEBUG_RPM_LIMITER, 1, smoothedRPMError); DEBUG_SET(DEBUG_RPM_LIMITER, 1, smoothedRPMError);
//DEBUG_SET(DEBUG_RPM_LIMITER, 2, mixerRuntime.govenorI*100.0f); DEBUG_SET(DEBUG_RPM_LIMITER, 2, mixerRuntime.govenorI*100.0f);
//DEBUG_SET(DEBUG_RPM_LIMITER, 3, govenorD*10000.0f); DEBUG_SET(DEBUG_RPM_LIMITER, 3, govenorD*10000.0f);
/*DEBUG_SET(DEBUG_RPM_LIMITER, 0, mixerRuntime.afterburnerInitiated);
DEBUG_SET(DEBUG_RPM_LIMITER, 1, mixerRuntime.afterburnerTankPercent);
DEBUG_SET(DEBUG_RPM_LIMITER, 2, mixerRuntime.afterburnerTanksRemaining);
DEBUG_SET(DEBUG_RPM_LIMITER, 3, maxRPMLimit);*/
} }
} }

View file

@ -94,9 +94,14 @@ typedef struct mixerConfig_s {
uint16_t govenor_i; uint16_t govenor_i;
uint16_t govenor_d; uint16_t govenor_d;
uint16_t govenor_rpm_limit; uint16_t govenor_rpm_limit;
uint16_t govenor_rpm_afterburner;
uint8_t govenor_rpm_afterburner_duration;
bool govenor_rpm_afterburner_reset;
bool govenor_rpm_afterburner_hold_to_use;
uint8_t govenor_rpm_afterburner_tank_count;
uint16_t govenor_acceleration_limit; uint16_t govenor_acceleration_limit;
uint16_t govenor_deceleration_limit; uint16_t govenor_deceleration_limit;
bool rpm_linearization; bool govenor_rpm_linearization;
uint16_t govenorThrottleLimitLearningTimeMS; uint16_t govenorThrottleLimitLearningTimeMS;
uint16_t govenor_idle_rpm; uint16_t govenor_idle_rpm;
uint8_t mixer_type; uint8_t mixer_type;

View file

@ -55,11 +55,16 @@ PG_RESET_TEMPLATE(mixerConfig_t, mixerConfig,
.govenor_p = 20, .govenor_p = 20,
.govenor_i = 15, .govenor_i = 15,
.govenor_d = 10, .govenor_d = 10,
.rpm_linearization = true, .govenor_rpm_linearization = true,
.govenor_idle_rpm = 17, .govenor_idle_rpm = 17,
.govenor_acceleration_limit = 60, .govenor_acceleration_limit = 60,
.govenor_deceleration_limit = 60, .govenor_deceleration_limit = 60,
.govenor_rpm_limit = 130, .govenor_rpm_limit = 130,
.govenor_rpm_afterburner = 20,
.govenor_rpm_afterburner_duration = 5,
.govenor_rpm_afterburner_reset = true,
.govenor_rpm_afterburner_hold_to_use = false,
.govenor_rpm_afterburner_tank_count = 3,
.mixer_type = MIXER_LEGACY, .mixer_type = MIXER_LEGACY,
); );
@ -320,18 +325,44 @@ void mixerInitProfile(void)
} }
#endif #endif
mixerRuntime.govenorExpectedThrottleLimit = 1.0f; mixerRuntime.govenorExpectedThrottleLimit = 1.0f;
//Street League customization
mixerRuntime.govenorPGain = 20.0f * 0.0000015f; //Street League spec settigns
/*mixerRuntime.govenorPGain = 20.0f * 0.0000015f;
mixerRuntime.govenorIGain = 15.0f * 0.0001f * pidGetDT(); mixerRuntime.govenorIGain = 15.0f * 0.0001f * pidGetDT();
mixerRuntime.govenorDGain = 10.0f * 0.00000003f * pidGetPidFrequency(); mixerRuntime.govenorDGain = 10.0f * 0.00000003f * pidGetPidFrequency();
mixerRuntime.govenorAccelerationLimit = 60.0f * 1000.0f * pidGetDT(); mixerRuntime.govenorAccelerationLimit = 60.0f * 1000.0f * pidGetDT();
mixerRuntime.govenorDecelerationLimit = 60.0f * 1000.0f * pidGetDT(); mixerRuntime.govenorDecelerationLimit = 60.0f * 1000.0f * pidGetDT();
/*mixerRuntime.govenorPGain = mixerConfig()->govenor_p * 0.0000015f; mixerRuntime.afterburnerRPM = mixerConfig()->govenor_rpm_afterburner;
mixerRuntime.afterburnerReset = mixerConfig()->govenor_rpm_afterburner_reset;
mixerRuntime.afterburnerDuration = mixerConfig()->govenor_rpm_afterburner_duration;
mixerRuntime.afterburnerTanksRemaining = mixerConfig()->govenor_rpm_afterburner_tank_count;
mixerRuntime.afterburnerHoldToBoost = mixerConfig()->govenor_rpm_afterburner_hold_to_use;
mixerRuntime.rpmLinearization = true;
mixerRuntime.RPMLimit = 130.0f;
mixerRuntime.motorPoleCount = 14;
mixerRuntime.govenorEnabled = true;
mixerRuntime.afterburnerInitiated = false;*/
//Unlocked rpm settings
mixerRuntime.govenorPGain = mixerConfig()->govenor_p * 0.0000015f;
mixerRuntime.govenorIGain = mixerConfig()->govenor_i * 0.0001f * pidGetDT(); mixerRuntime.govenorIGain = mixerConfig()->govenor_i * 0.0001f * pidGetDT();
mixerRuntime.govenorDGain = mixerConfig()->govenor_d * 0.00000003f * pidGetPidFrequency(); mixerRuntime.govenorDGain = mixerConfig()->govenor_d * 0.00000003f * pidGetPidFrequency();
mixerRuntime.govenorAccelerationLimit = mixerConfig()->govenor_acceleration_limit * 1000.0f * pidGetDT(); mixerRuntime.govenorAccelerationLimit = mixerConfig()->govenor_acceleration_limit * 1000.0f * pidGetDT();
mixerRuntime.govenorDecelerationLimit = mixerConfig()->govenor_deceleration_limit * 1000.0f * pidGetDT();*/ mixerRuntime.govenorDecelerationLimit = mixerConfig()->govenor_deceleration_limit * 1000.0f * pidGetDT();
mixerRuntime.afterburnerRPM = mixerConfig()->govenor_rpm_afterburner;
mixerRuntime.afterburnerReset = mixerConfig()->govenor_rpm_afterburner_reset;
mixerRuntime.afterburnerDuration = mixerConfig()->govenor_rpm_afterburner_duration;
mixerRuntime.afterburnerTanksRemaining = mixerConfig()->govenor_rpm_afterburner_tank_count;
mixerRuntime.afterburnerHoldToBoost = mixerConfig()->govenor_rpm_afterburner_hold_to_use;
mixerRuntime.rpmLinearization = mixerConfig()->govenor_rpm_linearization;
mixerRuntime.RPMLimit = mixerConfig()->govenor_rpm_limit;
mixerRuntime.motorPoleCount = motorConfig()->motorPoleCount;
mixerRuntime.govenorEnabled = mixerConfig()->govenor;
mixerRuntime.govenorI = 0; mixerRuntime.govenorI = 0;
mixerRuntime.afterburnerTankPercent = 100.0f;
mixerRuntime.afterburnerInitiated = false;
// mixerRuntime.govenorPrevThrottle = 0; // mixerRuntime.govenorPrevThrottle = 0;
// mixerRuntime.govenorFFGain = 0.05f * (float)(mixerConfig()->govenor_ff) * 0.001f; // mixerRuntime.govenorFFGain = 0.05f * (float)(mixerConfig()->govenor_ff) * 0.001f;
// mixerRuntime.govenorAverageAverageRPM = 0; // mixerRuntime.govenorAverageAverageRPM = 0;

View file

@ -59,6 +59,17 @@ typedef struct mixerRuntime_s {
float prevAverageRPM; float prevAverageRPM;
float govenorPreviousSmoothedRPMError; float govenorPreviousSmoothedRPMError;
float minRPMDelayK; float minRPMDelayK;
float afterburnerRPM;
bool afterburnerReset;
bool afterburnerHoldToBoost;
float afterburnerDuration;
float afterburnerTankPercent;
bool afterburnerInitiated;
int afterburnerTanksRemaining;
bool rpmLinearization;
float RPMLimit;
int motorPoleCount;
bool govenorEnabled;
float govenorI; float govenorI;
float govenorPGain; float govenorPGain;
float govenorIGain; float govenorIGain;

View file

@ -49,6 +49,7 @@
#include "flight/gps_rescue.h" #include "flight/gps_rescue.h"
#include "flight/imu.h" #include "flight/imu.h"
#include "flight/mixer.h" #include "flight/mixer.h"
#include "flight/mixer_init.h"
#include "flight/pid.h" #include "flight/pid.h"
#include "io/beeper.h" #include "io/beeper.h"
@ -375,7 +376,11 @@ void renderOsdWarning(char *warningText, bool *blinking, uint8_t *displayAttr)
*displayAttr = DISPLAYPORT_ATTR_WARNING; *displayAttr = DISPLAYPORT_ATTR_WARNING;
*blinking = true; *blinking = true;
return; return;
} }/*else if (mixerRuntime.afterburnerInitiated) {
tfp_sprintf(warningText, "BOOST ENGAGED");
*displayAttr = DISPLAYPORT_ATTR_CRITICAL;
return;
}*/
#ifdef USE_RC_SMOOTHING_FILTER #ifdef USE_RC_SMOOTHING_FILTER
// Show warning if rc smoothing hasn't initialized the filters // Show warning if rc smoothing hasn't initialized the filters

Binary file not shown.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff