-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Add airspeed TPA support (backport from #11042) via merge from master #11197
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d691333
6bc321b
c1e2112
4c44d5f
9603361
00c9db0
54f437a
68546a2
89850d7
4690775
7f9da38
31a5cbe
65fdd6a
253cd41
4d3ee07
2747993
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -126,7 +126,7 @@ static EXTENDED_FASTRAM pt1Filter_t headingHoldRateFilter; | |||||||||||||||||||||||||||||||||
| static EXTENDED_FASTRAM pt1Filter_t fixedWingTpaFilter; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| // Thrust PID Attenuation factor. 0.0f means fully attenuated, 1.0f no attenuation is applied | ||||||||||||||||||||||||||||||||||
| STATIC_FASTRAM bool pidGainsUpdateRequired; | ||||||||||||||||||||||||||||||||||
| STATIC_FASTRAM bool pidGainsUpdateRequired= true; | ||||||||||||||||||||||||||||||||||
| FASTRAM int16_t axisPID[FLIGHT_DYNAMICS_INDEX_COUNT]; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| #ifdef USE_BLACKBOX | ||||||||||||||||||||||||||||||||||
|
|
@@ -442,6 +442,14 @@ float pidRcCommandToRate(int16_t stick, uint8_t rate) | |||||||||||||||||||||||||||||||||
| return scaleRangef((float) stick, -500.0f, 500.0f, -maxRateDPS, maxRateDPS); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| static float calculateFixedWingAirspeedTPAFactor(void){ | ||||||||||||||||||||||||||||||||||
| const float airspeed = getAirspeedEstimate(); // in cm/s | ||||||||||||||||||||||||||||||||||
| const float referenceAirspeed = pidProfile()->fixedWingReferenceAirspeed; // in cm/s | ||||||||||||||||||||||||||||||||||
| float tpaFactor= powf(referenceAirspeed/(airspeed+0.01f), currentControlProfile->throttle.apa_pow/100.0f); | ||||||||||||||||||||||||||||||||||
| tpaFactor= constrainf(tpaFactor, 0.3f, 2.0f); | ||||||||||||||||||||||||||||||||||
| return tpaFactor; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| static float calculateFixedWingTPAFactor(uint16_t throttle) | ||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||
| float tpaFactor; | ||||||||||||||||||||||||||||||||||
|
|
@@ -452,16 +460,15 @@ static float calculateFixedWingTPAFactor(uint16_t throttle) | |||||||||||||||||||||||||||||||||
| if (throttle > getThrottleIdleValue()) { | ||||||||||||||||||||||||||||||||||
| // Calculate TPA according to throttle | ||||||||||||||||||||||||||||||||||
| tpaFactor = 0.5f + ((float)(currentControlProfile->throttle.pa_breakpoint - getThrottleIdleValue()) / (throttle - getThrottleIdleValue()) / 2.0f); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| // Limit to [0.5; 2] range | ||||||||||||||||||||||||||||||||||
| tpaFactor = constrainf(tpaFactor, 0.5f, 2.0f); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| else { | ||||||||||||||||||||||||||||||||||
| tpaFactor = 2.0f; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| // Attenuate TPA curve according to configured amount | ||||||||||||||||||||||||||||||||||
| tpaFactor = 1.0f + (tpaFactor - 1.0f) * (currentControlProfile->throttle.dynPID / 100.0f); | ||||||||||||||||||||||||||||||||||
| // Limit to [0.5; 2] range | ||||||||||||||||||||||||||||||||||
| tpaFactor = constrainf(tpaFactor, 0.3f, 2.0f); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| else { | ||||||||||||||||||||||||||||||||||
| tpaFactor = 1.0f; | ||||||||||||||||||||||||||||||||||
|
|
@@ -470,45 +477,48 @@ static float calculateFixedWingTPAFactor(uint16_t throttle) | |||||||||||||||||||||||||||||||||
| return tpaFactor; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| static float calculateMultirotorTPAFactor(void) | ||||||||||||||||||||||||||||||||||
| static float calculateMultirotorTPAFactor(uint16_t throttle) | ||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||
| float tpaFactor; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| // TPA should be updated only when TPA is actually set | ||||||||||||||||||||||||||||||||||
| if (currentControlProfile->throttle.dynPID == 0 || rcCommand[THROTTLE] < currentControlProfile->throttle.pa_breakpoint) { | ||||||||||||||||||||||||||||||||||
| if (currentControlProfile->throttle.dynPID == 0 || throttle < currentControlProfile->throttle.pa_breakpoint) { | ||||||||||||||||||||||||||||||||||
| tpaFactor = 1.0f; | ||||||||||||||||||||||||||||||||||
| } else if (rcCommand[THROTTLE] < getMaxThrottle()) { | ||||||||||||||||||||||||||||||||||
| tpaFactor = (100 - (uint16_t)currentControlProfile->throttle.dynPID * (rcCommand[THROTTLE] - currentControlProfile->throttle.pa_breakpoint) / (float)(getMaxThrottle() - currentControlProfile->throttle.pa_breakpoint)) / 100.0f; | ||||||||||||||||||||||||||||||||||
| } else if (throttle < getMaxThrottle()) { | ||||||||||||||||||||||||||||||||||
| tpaFactor = (100 - (uint16_t)currentControlProfile->throttle.dynPID * (throttle - currentControlProfile->throttle.pa_breakpoint) / (float)(getMaxThrottle() - currentControlProfile->throttle.pa_breakpoint)) / 100.0f; | ||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||
| tpaFactor = (100 - currentControlProfile->throttle.dynPID) / 100.0f; | ||||||||||||||||||||||||||||||||||
| tpaFactor = (100 - constrain(currentControlProfile->throttle.dynPID, 0, 100)) / 100.0f; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+487
to
491
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: Clamp the multirotor
Suggested change
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| return tpaFactor; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| static float calculateTPAThtrottle(void) | ||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||
| uint16_t tpaThrottle = 0; | ||||||||||||||||||||||||||||||||||
| static const fpVector3_t vDown = { .v = { 0.0f, 0.0f, 1.0f } }; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| if (usedPidControllerType == PID_TYPE_PIFF && (currentControlProfile->throttle.fixedWingTauMs > 0)) { //fixed wing TPA with filtering | ||||||||||||||||||||||||||||||||||
| fpVector3_t vForward = { .v = { HeadVecEFFiltered.x, -HeadVecEFFiltered.y, -HeadVecEFFiltered.z } }; | ||||||||||||||||||||||||||||||||||
| float groundCos = vectorDotProduct(&vForward, &vDown); | ||||||||||||||||||||||||||||||||||
| int16_t throttleAdjustment = currentControlProfile->throttle.tpa_pitch_compensation * groundCos * 90.0f / 1.57079632679f; //when 1deg pitch up, increase throttle by pitch(deg)_to_throttle. cos(89 deg)*90/(pi/2)=0.99995,cos(80 deg)*90/(pi/2)=9.9493, | ||||||||||||||||||||||||||||||||||
| uint16_t throttleAdjusted = rcCommand[THROTTLE] + constrain(throttleAdjustment, -1000, 1000); | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+503
to
+505
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion:
Suggested change
|
||||||||||||||||||||||||||||||||||
| tpaThrottle = pt1FilterApply(&fixedWingTpaFilter, constrain(throttleAdjusted, 1000, 2000)); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| else { | ||||||||||||||||||||||||||||||||||
| tpaThrottle = rcCommand[THROTTLE]; //multirotor TPA without filtering | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| return tpaThrottle; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| void schedulePidGainsUpdate(void) | ||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||
| pidGainsUpdateRequired = true; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| void updatePIDCoefficients(void) | ||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||
| STATIC_FASTRAM uint16_t prevThrottle = 0; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| // Check if throttle changed. Different logic for fixed wing vs multirotor | ||||||||||||||||||||||||||||||||||
| if (usedPidControllerType == PID_TYPE_PIFF && (currentControlProfile->throttle.fixedWingTauMs > 0)) { | ||||||||||||||||||||||||||||||||||
| uint16_t filteredThrottle = pt1FilterApply(&fixedWingTpaFilter, rcCommand[THROTTLE]); | ||||||||||||||||||||||||||||||||||
| if (filteredThrottle != prevThrottle) { | ||||||||||||||||||||||||||||||||||
| prevThrottle = filteredThrottle; | ||||||||||||||||||||||||||||||||||
| pidGainsUpdateRequired = true; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| else { | ||||||||||||||||||||||||||||||||||
| if (rcCommand[THROTTLE] != prevThrottle) { | ||||||||||||||||||||||||||||||||||
| prevThrottle = rcCommand[THROTTLE]; | ||||||||||||||||||||||||||||||||||
| pidGainsUpdateRequired = true; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| STATIC_FASTRAM float tpaFactorprev=-1.0f; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| #ifdef USE_ANTIGRAVITY | ||||||||||||||||||||||||||||||||||
| if (usedPidControllerType == PID_TYPE_PID) { | ||||||||||||||||||||||||||||||||||
|
|
@@ -523,14 +533,29 @@ void updatePIDCoefficients(void) | |||||||||||||||||||||||||||||||||
| for (int axis = 0; axis < 3; axis++) { | ||||||||||||||||||||||||||||||||||
| pidState[axis].stickPosition = constrain(rxGetChannelValue(axis) - PWM_RANGE_MIDDLE, -500, 500) / 500.0f; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| float tpaFactor=1.0f; | ||||||||||||||||||||||||||||||||||
| if(usedPidControllerType == PID_TYPE_PIFF){ // Fixed wing TPA calculation | ||||||||||||||||||||||||||||||||||
| if(currentControlProfile->throttle.apa_pow>0 && pitotValidForAirspeed()){ | ||||||||||||||||||||||||||||||||||
| tpaFactor = calculateFixedWingAirspeedTPAFactor(); | ||||||||||||||||||||||||||||||||||
| }else{ | ||||||||||||||||||||||||||||||||||
| tpaFactor = calculateFixedWingTPAFactor(calculateTPAThtrottle()); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||
| tpaFactor = calculateMultirotorTPAFactor(calculateTPAThtrottle()); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| if (tpaFactor != tpaFactorprev) { | ||||||||||||||||||||||||||||||||||
| pidGainsUpdateRequired = true; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| tpaFactorprev = tpaFactor; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| // If nothing changed - don't waste time recalculating coefficients | ||||||||||||||||||||||||||||||||||
| if (!pidGainsUpdateRequired) { | ||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| const float tpaFactor = usedPidControllerType == PID_TYPE_PIFF ? calculateFixedWingTPAFactor(prevThrottle) : calculateMultirotorTPAFactor(); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| // PID coefficients can be update only with THROTTLE and TPA or inflight PID adjustments | ||||||||||||||||||||||||||||||||||
| //TODO: Next step would be to update those only at THROTTLE or inflight adjustments change | ||||||||||||||||||||||||||||||||||
| for (int axis = 0; axis < 3; axis++) { | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: Validate
airspeedandreferenceAirspeedare positive (andapa_powis in-range) and return a safe neutral factor (1.0) when invalid, instead of relying on an arbitrary epsilon that can still yield extreme results. [Learned best practice, importance: 6]