PIDs model a linear system without having to know all the factors which may affect the system, nor what effect they may have, as long as the affect is linear.

But there’s a non-linearity in the code at the moment (and a bug actually that became cler as I gave the none linearity some thought:

The velocity PIDs’ output is essentially a number representing the desired corrective acceleration.  The bigger the velocity error, the bigger the acceleration required to fix it; they are proportional.

For constant acceleration:

v = a * t

Or if the acceleration is not constant:

v = ∫ a dt

Similarly the rotation PID’s input is essentially representing the desired change in angle, and the output is the desired rotation rate applied to the ESCs / motors to carry out that change; again they are proportional.

For a fixed rotation rate, R:

θ = R * t

Or if the rotation rate is not constant:

θ = ∫ R dt

But there’s a problem turning the corrective acceleration (the output from the velocity PID) into the desired angle (the input to the rotation rate PID).  Here’s the current code.

 pr_target = qvx_out
 rr_target = -qvy_out

There’s two problems with the code above.  It’s mapping the qv*_out accelerations to a rotation rate.  But the acceleration in the quad X and Y axes is not proportional to the angle (for examply 0º change gives 0 change in acceleration; 45° gives 1/√2 acceleration change and 90° gives full power acceleration change.  Notice the underlined above – they don’t match and that’s the bug.  To add to the complexity, it’s not actually known what the angle change actually is – it’s not an absolute angle wrt the earth gravity; it’s the change in angle since last time so an integration of the gyro output or the gyro change since the last set of motion processing. But currently that’s not what is fed into that PID – it’s a rotation rate.

So once more, I have a rewrite of the code shown above to allow for the non-linearity, and the result is fed into the inner PID as a desired angle change and compared to the integrated gyro angle change to come up with the rotation rate.

A good thing then that the weather has gone lousy again, so I have plenty of time to think it through properly and implement the changes.

P.S I’m going to apply these changes to the thread + signal code as although its use of threads provided no performance improvement in data collection rate, the code is a lot cleaner / tidier both in allocation / ownership and freeing of variables, and has a nice clean split between locally owned and global variables.