mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-26 01:35:41 +03:00
Block yaw, allow in CLI, option to apply yaw correction code
This commit is contained in:
parent
5e81ff6977
commit
c856485727
6 changed files with 68 additions and 34 deletions
|
@ -278,6 +278,13 @@ bool positionControl(void) {
|
|||
const float pitchP = pitchProportion * posHold.distanceCm * positionPidCoeffs.Kp;
|
||||
|
||||
// derivative and acceleration
|
||||
// note: velocity sign reverses when moving away, vs moving towards, the target
|
||||
// and the proportioning factor reverses on overshooting
|
||||
// net effect is that the sign of the correction stays correct
|
||||
// accumulated velocity on one axis can only go to zero if velocity on that axis goes to zero
|
||||
// hence we don't rotate the filtered D and A, only the input
|
||||
// the delayed component of the filtered output should be rotated if the quad yaws (not done yet)
|
||||
|
||||
// roll
|
||||
float velocityRoll = rollProportion * velocity;
|
||||
float accelerationRoll = rollProportion * acceleration;
|
||||
|
@ -302,44 +309,59 @@ bool positionControl(void) {
|
|||
float pitchA = accelerationPitch * positionPidCoeffs.Kf;
|
||||
|
||||
// iTerm
|
||||
// Note: accumulated iTerm opposes wind.
|
||||
// The accumulated amount of iTerm on each axis does not care about bearing error
|
||||
// But accumulated iTerm should be rotated if the craft yaws (not done yet)
|
||||
// For that I think we need to accumulate iTerm with an iTerm vector angle to North
|
||||
// then we get separate pitch and roll values by comparing craft heading and iTerm vector
|
||||
// current code assumes no yaw input and does not rotate the accumulated iTerm to preserve its direction
|
||||
if (!posHold.isStarting){
|
||||
// hold previous iTerm while starting up
|
||||
// don't change accumulated iTerm while adjusting position or during startup phase
|
||||
posHold.rollI += rollProportion * posHold.distanceCm * positionPidCoeffs.Ki * gpsDataIntervalS;
|
||||
posHold.pitchI += pitchProportion * posHold.distanceCm * positionPidCoeffs.Ki * gpsDataIntervalS;
|
||||
}
|
||||
|
||||
// calculate rotation change from the initial heading, and rotate the roll and pitch proportions accordingly
|
||||
const float currentHeadingDeg = attitude.values.yaw * 0.1f;
|
||||
float deltaHeading = currentHeadingDeg - posHold.initialHeadingDeg;
|
||||
// ** test code to handle user yaw inputs ** //
|
||||
|
||||
// Normalize deltaHeading
|
||||
if (deltaHeading > 180.0f) {
|
||||
deltaHeading -= 360.0f; // Wrap around if greater than 180
|
||||
} else if (deltaHeading < -180.0f) {
|
||||
deltaHeading += 360.0f; // Wrap around if less than -180
|
||||
if (autopilotConfig()->position_allow_yaw) {
|
||||
// code that we know is effective for fixing user yaw inputs (none at present lol)
|
||||
if (autopilotConfig()->position_test_yaw_fix) {
|
||||
// test code that might fix user yaw inputs
|
||||
|
||||
// calculate rotation change from the initial heading
|
||||
const float currentHeadingDeg = attitude.values.yaw * 0.1f;
|
||||
float deltaHeading = currentHeadingDeg - posHold.initialHeadingDeg;
|
||||
|
||||
// Normalize deltaHeading
|
||||
if (deltaHeading > 180.0f) {
|
||||
deltaHeading -= 360.0f; // Wrap around if greater than 180
|
||||
} else if (deltaHeading < -180.0f) {
|
||||
deltaHeading += 360.0f; // Wrap around if less than -180
|
||||
}
|
||||
const float deltaHeadingRadians = deltaHeading * RAD;
|
||||
|
||||
float cosDeltaHeading = cos_approx(deltaHeadingRadians);
|
||||
float sinDeltaHeading = sin_approx(deltaHeadingRadians);
|
||||
|
||||
// rotate iTerm if heading changes from original heading
|
||||
const float rotatedRollI = posHold.rollI * cosDeltaHeading + posHold.pitchI * sinDeltaHeading;
|
||||
const float rotatedPitchI = posHold.pitchI * cosDeltaHeading - posHold.rollI * sinDeltaHeading;
|
||||
|
||||
posHold.rollI = rotatedRollI;
|
||||
posHold.pitchI = rotatedPitchI;
|
||||
|
||||
// rotate smoothed DA factors (doesn't work since inverts D sign inappropriately)
|
||||
// const float rotatedRollD = rollD * cosDeltaHeading + pitchD * sinDeltaHeading;
|
||||
// const float rotatedPitchD = pitchD * cosDeltaHeading - rollD * sinDeltaHeading;
|
||||
// rollD = rotatedRollD;
|
||||
// pitchD = rotatedPitchD;
|
||||
//
|
||||
// const float rotatedRollA = rollA * cosDeltaHeading + pitchA * sinDeltaHeading;
|
||||
// const float rotatedPitchA = pitchA * cosDeltaHeading - rollA * sinDeltaHeading;
|
||||
// rollA = rotatedRollA;
|
||||
// pitchA = rotatedPitchA;
|
||||
}
|
||||
}
|
||||
const float deltaHeadingRadians = deltaHeading * RAD;
|
||||
|
||||
float cosDeltaHeading = cos_approx(deltaHeadingRadians);
|
||||
float sinDeltaHeading = sin_approx(deltaHeadingRadians);
|
||||
|
||||
// rotate iTerm if heading changes from original heading
|
||||
const float rotatedRollI = posHold.rollI * cosDeltaHeading + posHold.pitchI * sinDeltaHeading;
|
||||
const float rotatedPitchI = posHold.pitchI * cosDeltaHeading - posHold.rollI * sinDeltaHeading;
|
||||
|
||||
posHold.rollI = rotatedRollI;
|
||||
posHold.pitchI = rotatedPitchI;
|
||||
|
||||
// rotate smoothed DA factors
|
||||
// const float rotatedRollD = rollD * cosDeltaHeading + pitchD * sinDeltaHeading;
|
||||
// const float rotatedPitchD = pitchD * cosDeltaHeading - rollD * sinDeltaHeading;
|
||||
// rollD = rotatedRollD;
|
||||
// pitchD = rotatedPitchD;
|
||||
//
|
||||
// const float rotatedRollA = rollA * cosDeltaHeading + pitchA * sinDeltaHeading;
|
||||
// const float rotatedPitchA = pitchA * cosDeltaHeading - rollA * sinDeltaHeading;
|
||||
// rollA = rotatedRollA;
|
||||
// pitchA = rotatedPitchA;
|
||||
|
||||
// limit sum of D and A because otherwise too aggressive if entering at speed
|
||||
float rollDA = rollD + rollA;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue