mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-13 19:40:31 +03:00
Merge pull request #2 from StreetLeagueSpec/sl-4.4.0
added adjustable k-factor
This commit is contained in:
commit
c6939297ab
9 changed files with 67 additions and 49 deletions
|
@ -1,2 +1 @@
|
|||
HOBBYWING_XROTORF7CONV
|
||||
|
||||
BetafpvF411RX
|
||||
|
|
|
|
@ -28,6 +28,8 @@
|
|||
#define FC_VERSION_MINOR 4 // increment when a minor release is made (small new feature, change etc)
|
||||
#define FC_VERSION_PATCH_LEVEL 2 // increment when a bug is fixed
|
||||
|
||||
#define SPEC_VERSION "SL-1.3.0"
|
||||
|
||||
#define FC_VERSION_STRING STR(FC_VERSION_MAJOR) "." STR(FC_VERSION_MINOR) "." STR(FC_VERSION_PATCH_LEVEL)
|
||||
|
||||
extern const char* const targetName;
|
||||
|
|
|
@ -4951,6 +4951,7 @@ static void printVersion(const char *cmdName, bool printBoardInfo)
|
|||
|
||||
cliPrintf("# %s / %s (%s) %s %s / %s (%s) MSP API: %s",
|
||||
FC_FIRMWARE_NAME,
|
||||
SPEC_VERSION,
|
||||
targetName,
|
||||
systemConfig()->boardIdentifier,
|
||||
FC_VERSION_STRING,
|
||||
|
|
|
@ -936,6 +936,26 @@ const clivalue_t valueTable[] = {
|
|||
{ "mixer_type", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_MIXER_TYPE }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, mixer_type) },
|
||||
{ "crashflip_motor_percent", VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 100 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, crashflip_motor_percent) },
|
||||
{ "crashflip_expo", VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 100 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, crashflip_expo) },
|
||||
//Street League customization
|
||||
{ "rpm_limiter_idle_rpm", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 999 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_idle_rpm) },
|
||||
|
||||
//street league locked
|
||||
// { "rpm_limiter", VAR_INT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor) },
|
||||
// { "rpm_limiter_p", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 20, 20 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_p) },
|
||||
// { "rpm_limiter_i", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 15, 15 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_i) },
|
||||
// { "rpm_limiter_d", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 10, 10 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_d) },
|
||||
// { "rpm_limiter_rpm_limit", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 130, 130 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_rpm_limit) },
|
||||
// { "rpm_limiter_afterburner", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 16, 16 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_rpm_afterburner) },
|
||||
// { "rpm_limiter_afterburner_duration", VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { 5, 5 }, 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 = { 3, 3 }, 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 = { 60, 60 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_acceleration_limit) },
|
||||
// { "rpm_limiter_deceleration_limit", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 60, 60 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_deceleration_limit) },
|
||||
// { "rpm_limiter_k_factor", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 1000, 1000 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_k_factor) },
|
||||
// { "rpm_limiter_full_linearization", VAR_INT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_rpm_linearization) },
|
||||
|
||||
//street league unlocked
|
||||
{ "rpm_limiter", VAR_INT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor) },
|
||||
{ "rpm_limiter_p", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 10000 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_p) },
|
||||
{ "rpm_limiter_i", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 10000 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_i) },
|
||||
|
@ -946,9 +966,9 @@ const clivalue_t valueTable[] = {
|
|||
{ "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) },
|
||||
//Street League customization
|
||||
{ "rpm_limiter_idle_rpm", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 999 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_idle_rpm) },
|
||||
{ "rpm_limiter_acceleration_limit", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 50000 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_acceleration_limit) },
|
||||
{ "rpm_limiter_deceleration_limit", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 50000 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_deceleration_limit) },
|
||||
{ "rpm_limiter_k_factor", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 1, 50000 }, PG_MIXER_CONFIG, offsetof(mixerConfig_t, govenor_k_factor) },
|
||||
{ "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) },
|
||||
|
|
|
@ -357,12 +357,12 @@ float getAfterburnerTankPercent(void)
|
|||
static void applyRPMLimiter(void)
|
||||
{
|
||||
if (mixerRuntime.govenorEnabled) {
|
||||
float RPM_GOVENOR_LIMIT = 0;
|
||||
float averageRPM = 0;
|
||||
float averageRPM_smoothed = 0;
|
||||
float PIDOutput = 0;
|
||||
float RPM_GOVENOR_LIMIT = 0.0f;
|
||||
float averageRPM = 0.0f;
|
||||
float averageRPM_smoothed = 0.0f;
|
||||
float PIDOutput = 0.0f;
|
||||
float rcCommandThrottle = (rcCommand[THROTTLE]-1000)/1000.0f;
|
||||
float maxRPMLimit = 0;
|
||||
float maxRPMLimit = 0.0f;
|
||||
|
||||
maxRPMLimit = mixerRuntime.RPMLimit;
|
||||
|
||||
|
@ -444,7 +444,7 @@ static void applyRPMLimiter(void)
|
|||
bool motorsSaturated = false;
|
||||
bool motorsDesaturated = false;
|
||||
for (int i = 0; i < getMotorCount(); i++) {
|
||||
averageRPM += getDshotTelemetry(i);
|
||||
averageRPM += (float)getDshotTelemetry(i);
|
||||
if (motor[i] >= motorConfig()->maxthrottle) {
|
||||
motorsSaturated = true;
|
||||
}
|
||||
|
@ -452,10 +452,10 @@ static void applyRPMLimiter(void)
|
|||
motorsDesaturated = false;
|
||||
}
|
||||
}
|
||||
averageRPM = 100 * averageRPM / (getMotorCount()*mixerRuntime.motorPoleCount/2.0f);
|
||||
averageRPM = 100.0f * averageRPM / (float)(getMotorCount()*mixerRuntime.motorPoleCount/2.0f);
|
||||
|
||||
//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 + (float)mixerRuntime.govenorDelayK * (averageRPM - mixerRuntime.govenorPreviousSmoothedRPM); //kinda braindead to convert to rps then back
|
||||
|
||||
float smoothedRPMError = averageRPM_smoothed - RPM_GOVENOR_LIMIT;
|
||||
float govenorP = smoothedRPMError * mixerRuntime.govenorPGain; //+ when overspped
|
||||
|
@ -527,10 +527,11 @@ static void applyRPMLimiter(void)
|
|||
mixerRuntime.govenorPreviousSmoothedRPMError = smoothedRPMError;
|
||||
mixerRuntime.govenorPreviousRPMLimit = RPM_GOVENOR_LIMIT;
|
||||
|
||||
DEBUG_SET(DEBUG_RPM_LIMITER, 0, averageRPM);
|
||||
DEBUG_SET(DEBUG_RPM_LIMITER, 1, smoothedRPMError);
|
||||
DEBUG_SET(DEBUG_RPM_LIMITER, 2, mixerRuntime.govenorI*100.0f);
|
||||
DEBUG_SET(DEBUG_RPM_LIMITER, 3, govenorD*10000.0f);
|
||||
DEBUG_SET(DEBUG_RPM_LIMITER, 0, averageRPM);//unfiltered average rpm
|
||||
DEBUG_SET(DEBUG_RPM_LIMITER, 1, averageRPM_smoothed); //filtered average rpm
|
||||
DEBUG_SET(DEBUG_RPM_LIMITER, 2, smoothedRPMError); //P term
|
||||
DEBUG_SET(DEBUG_RPM_LIMITER, 3, mixerRuntime.govenorI*100.0f); // I term
|
||||
DEBUG_SET(DEBUG_RPM_LIMITER, 4, govenorD*10000.0f); // D term
|
||||
|
||||
/*DEBUG_SET(DEBUG_RPM_LIMITER, 0, mixerRuntime.afterburnerInitiated);
|
||||
DEBUG_SET(DEBUG_RPM_LIMITER, 1, mixerRuntime.afterburnerTankPercent);
|
||||
|
|
|
@ -101,6 +101,7 @@ typedef struct mixerConfig_s {
|
|||
uint8_t govenor_rpm_afterburner_tank_count;
|
||||
uint16_t govenor_acceleration_limit;
|
||||
uint16_t govenor_deceleration_limit;
|
||||
uint16_t govenor_k_factor;
|
||||
bool govenor_rpm_linearization;
|
||||
uint16_t govenorThrottleLimitLearningTimeMS;
|
||||
uint16_t govenor_idle_rpm;
|
||||
|
|
|
@ -59,6 +59,7 @@ PG_RESET_TEMPLATE(mixerConfig_t, mixerConfig,
|
|||
.govenor_idle_rpm = 17,
|
||||
.govenor_acceleration_limit = 60,
|
||||
.govenor_deceleration_limit = 60,
|
||||
.govenor_k_factor = 1000,
|
||||
.govenor_rpm_limit = 130.0f,
|
||||
.govenor_rpm_afterburner = 16,
|
||||
.govenor_rpm_afterburner_duration = 5,
|
||||
|
@ -327,48 +328,38 @@ void mixerInitProfile(void)
|
|||
mixerRuntime.govenorExpectedThrottleLimit = 1.0f;
|
||||
|
||||
//Street League spec settings
|
||||
mixerRuntime.govenorPGain = 20.0f * 0.0000015f;
|
||||
mixerRuntime.govenorIGain = 15.0f * 0.0001f * pidGetDT();
|
||||
mixerRuntime.govenorDGain = 10.0f * 0.00000003f * pidGetPidFrequency();
|
||||
mixerRuntime.govenorAccelerationLimit = 60.0f * 1000.0f * pidGetDT();
|
||||
mixerRuntime.govenorDecelerationLimit = 60.0f * 1000.0f * pidGetDT();
|
||||
mixerRuntime.afterburnerRPM = 16;
|
||||
mixerRuntime.afterburnerReset = false;
|
||||
mixerRuntime.afterburnerDuration = 5;
|
||||
mixerRuntime.afterburnerTanksRemaining = 3;
|
||||
mixerRuntime.afterburnerHoldToBoost = false;
|
||||
mixerRuntime.rpmLinearization = true;
|
||||
mixerRuntime.RPMLimit = 130.0f;
|
||||
mixerRuntime.motorPoleCount = 14;
|
||||
mixerRuntime.govenorEnabled = true;
|
||||
|
||||
//Locked rpm settings
|
||||
// mixerRuntime.govenorEnabled = true;
|
||||
// mixerRuntime.rpmLinearization = true;
|
||||
// mixerRuntime.motorPoleCount = 14;
|
||||
// mixerRuntime.afterburnerReset = false;
|
||||
// mixerRuntime.afterburnerHoldToBoost = false;
|
||||
|
||||
//Unlocked rpm settings
|
||||
mixerRuntime.govenorEnabled = mixerConfig()->govenor;
|
||||
mixerRuntime.rpmLinearization = mixerConfig()->govenor_rpm_linearization;
|
||||
mixerRuntime.motorPoleCount = motorConfig()->motorPoleCount;
|
||||
mixerRuntime.afterburnerReset = mixerConfig()->govenor_rpm_afterburner_reset;
|
||||
mixerRuntime.afterburnerHoldToBoost = mixerConfig()->govenor_rpm_afterburner_hold_to_use;
|
||||
|
||||
|
||||
mixerRuntime.govenorPGain = mixerConfig()->govenor_p * 0.0000015f;
|
||||
mixerRuntime.govenorIGain = mixerConfig()->govenor_i * 0.0001f * pidGetDT();
|
||||
mixerRuntime.govenorDGain = mixerConfig()->govenor_d * 0.00000003f * pidGetPidFrequency();
|
||||
mixerRuntime.govenorAccelerationLimit = mixerConfig()->govenor_acceleration_limit * 1000.0f * pidGetDT();
|
||||
mixerRuntime.govenorDecelerationLimit = mixerConfig()->govenor_deceleration_limit * 1000.0f * pidGetDT();
|
||||
mixerRuntime.govenorKFactor = mixerConfig()->govenor_k_factor;
|
||||
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.afterburnerTankPercent = 100.0f;
|
||||
mixerRuntime.afterburnerInitiated = false;
|
||||
// mixerRuntime.govenorPrevThrottle = 0;
|
||||
// mixerRuntime.govenorFFGain = 0.05f * (float)(mixerConfig()->govenor_ff) * 0.001f;
|
||||
// mixerRuntime.govenorAverageAverageRPM = 0;
|
||||
// mixerRuntime.govenorAverageStickThrottle = 0;
|
||||
mixerRuntime.govenorPreviousSmoothedRPMError = 0;
|
||||
// mixerRuntime.govenorIterationStep = 1.0f/(pidGetPidFrequency() * mixerConfig()->govenor_learning_threshold_window); // 3 is the averaging
|
||||
mixerRuntime.govenorDelayK = 800 * pidGetDT() / 20.0f;
|
||||
mixerRuntime.govenorDelayK = mixerRuntime.govenorKFactor * pidGetDT() / 20.0f;
|
||||
mixerRuntime.govenorLearningThrottleK = 0.5 / (pidGetPidFrequency() * mixerConfig()->govenorThrottleLimitLearningTimeMS / 1000); // 0.5 = value ^ (4000 * time) 0.99^(4000*(20/1000))
|
||||
mixerRuntime.govenor_init = false;
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ typedef struct mixerRuntime_s {
|
|||
float govenorExpectedThrottleLimit;
|
||||
float govenorAccelerationLimit;
|
||||
float govenorDecelerationLimit;
|
||||
float govenorKFactor;
|
||||
float prevAverageRPM;
|
||||
float govenorPreviousSmoothedRPMError;
|
||||
float minRPMDelayK;
|
||||
|
|
|
@ -370,17 +370,19 @@ void renderOsdWarning(char *warningText, bool *blinking, uint8_t *displayAttr)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mixerRuntime.afterburnerInitiated) {
|
||||
tfp_sprintf(warningText, "BOOST ENGAGED");
|
||||
*displayAttr = DISPLAYPORT_SEVERITY_WARNING;
|
||||
*blinking = true;
|
||||
return;
|
||||
}
|
||||
if (osdWarnGetState(OSD_WARNING_BATTERY_WARNING) && batteryState == BATTERY_WARNING) {
|
||||
tfp_sprintf(warningText, "LOW BATTERY");
|
||||
*displayAttr = DISPLAYPORT_SEVERITY_WARNING;
|
||||
*blinking = true;
|
||||
return;
|
||||
}/*else if (mixerRuntime.afterburnerInitiated) {
|
||||
tfp_sprintf(warningText, "BOOST ENGAGED");
|
||||
*displayAttr = DISPLAYPORT_ATTR_CRITICAL;
|
||||
return;
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_RC_SMOOTHING_FILTER
|
||||
// Show warning if rc smoothing hasn't initialized the filters
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue