FeedForward Tuning in Plane

@Leonardthall Any guidelines on how to tune Plane using FeedForward terms in Roll and Pitch?..I understand that it is actually more desirable to be dominated by FF in axis that are rate vs acceleration driven like on a Plane…

particularly, I am trying to get rid of dutch roll on TVBS in fixed wing flight due to forward motors reducing yaw stability…I have added extra fin area and that helps a bunch, but am hoping to tune out the rest for more enjoyable video on flights…unfortunately AutoTune seems to exacerbate the problem since it seems to overtune in the presence of dutch roll…I have to back the RLL2SRV P a bunch after tune to get a non-nauseating ride…

I am hoping that using FF will allow the leveling outer loop to produce quick enough rate demands directly to the servos to completely eliminate the roll wobble…but have no idea how to go about tuning this

Without the attitude controller, is it a roll or yaw dominant Dutch roll?

roll is the most noticed

Tuning session today adding in RLL2SRV_FF until it got a little jerky and backing off:

Noticeable improvement…acceptable now!

Maybe someone with a better eye on the roll controller can correct me on this. If you added in RLL2SRV_FF, then that would be equivalent to adding something to RLL2SRV_P. I might be confusing roll with the pitch kp_ff & kp_p values though.

no, FF (feedFORWARD) is a different path than P in a feedBACK controller…it goes directly from rate demand in to output…not demand compared to actual (=error) and then has P gain to apply to go to output…

iNav switched its plane controllers to PIFF (Proportional, Integral, FeedForward) controllers a long time ago… using feedforward primarily to control rate (like a pilot does on the sticks), and P/I for disturbances and long term drift/offsets

That is how FF is done traditionally done. This is the code from AP_RollController. kp_ff is just a scaled down version of k_ff that was left over to keep the tunes from the old PID controller.

_pid_info.P = desired_rate * kp_ff * scaler;
_pid_info.FF = desired_rate * k_ff * scaler;

Haven’t had time to have Tridge fully explain it, but he did say that the full pid loop calls those from higher up and those are translations, so its deceiving to look only at that code portion…

Above that at line 123 you can find the translation that is happening to for gains.P into kp_ff. Everything in this is a static value except for eas2tas which both k_ff and kp_ff have. So really ArduPlane has a FF1,FF2,I,D controller, but the FF is really what would traditionally be considered the P for rate control.

float kp_ff = MAX((gains.P - gains.I * gains.tau) * gains.tau  - gains.D , 0) / eas2tas;
float k_ff = gains.FF / eas2tas;