One thing is setting the throttle PID attenuation. However, in downward flight oscillations happened anyway because of the high speed even without WOT.
As i didnt want to add a speed sensor, I changed the software instead to adapt the PIDs depending on the plane's angle:
Nose pointing upwards -> increase PIDs, downwards -> decrease PIDs.
As of first quick and dirty test I tried modification of 50% for vertical down and 150% for vertical up (and 100%, of course, for horizontal flight).
It appears to work quite fine. Oscillations now happen only after transition from downward to horizontal flight, when speed is still high.
I have hacked it into the dynamic PID routine. I am not so sure about what typecasts are required, maybe one of the real developers wants to add it to the plane branch (is there actually still a plane branch?)?
My mod is based on an older version of PatrikE's plane code. The actual change is in the #if ACC -> #endif section.
Code: Select all
// PITCH & ROLL only dynamic PID adjustemnt, depending on throttle value
if (rcData[THROTTLE]<BREAKPOINT) {
prop2 = 100;
} else {
if (rcData[THROTTLE]<2000) {
prop2 = 100 - (uint16_t)conf.dynThrPID*(rcData[THROTTLE]-BREAKPOINT)/(2000-BREAKPOINT);
} else {
prop2 = 100 - conf.dynThrPID;
}
}
// ChW Plane Stabi 2.5: make PID dependant of angle: nose up -> higher PID, nose down -> lower PID
// to avoid oszillations at high speed and aloow easy hovering
#if ACC
int16_t angle_prop2_factor; // percentage to change prop2; target range 50 to 150
angle_prop2_factor = 100-(angle[PITCH]/9)*0.5; // change here: compute factor from nose up angle
prop2 = (uint8_t)(prop2*(float)angle_prop2_factor/100.0);
#endif
// End mod ChW Plane Stabi 2.5: make PID dependant of angle: nose up -> higher PID, nose down -> lower PID
for(axis=0;axis<3;axis++) {
tmp = min(abs(rcData[axis]-conf.midrc),500);
#if defined(DEADBAND)
if (tmp>DEADBAND) { tmp -= DEADBAND; }
else { tmp=0; }
#endif
if(axis!=2) { //ROLL & PITCH
tmp2 = tmp/100;
rcCommand[axis] = lookupPitchRollRC[tmp2] + (tmp-tmp2*100) * (lookupPitchRollRC[tmp2+1]-lookupPitchRollRC[tmp2]) / 100;
prop1 = 100-(uint16_t)conf.rollPitchRate*tmp/500;
prop1 = (uint16_t)prop1*prop2/100;
} else { // YAW
rcCommand[axis] = tmp;
prop1 = 100-(uint16_t)conf.yawRate*tmp/500;
}
dynP8[axis] = (uint16_t)conf.P8[axis]*prop1/100;
dynD8[axis] = (uint16_t)conf.D8[axis]*prop1/100;
if (rcData[axis]<conf.midrc) rcCommand[axis] = -rcCommand[axis];
}