PID for motion control
Mickster
Posts: 2,694
Just looking at the various PID routines in the OBEX and I wonder if there is any reason why a purely integer solution is not feasible?
I'm probably missing something but at first glance, I don't see why not.
Mickster.
I'm probably missing something but at first glance, I don't see why not.
Mickster.
Comments
People generally use floating point because they have not thought about what they really need and they hope floating point will cover all eventualities.
Being an oddity here... But I used floating point for my PID routines so that it would work with the floating point batch processor that I wrote. Otherwise, my code would have a delay while the Spin overseer did the math: floating point turned out to be faster. Again, probably not the common case.
I've used an interger PID algorithm. I was a pain to keep the numbers from overflowing. Instead of a single multiplier for P, I and D, I used a "numerator" and "denominator" portion for each multiplier. The error would would be multiplied by the numerator and then divided by denominator portion of the "multiplier". IIRC, some of the multipliers needed to be less than one which is why I used the factional multiplier. I never ended up using a full PID integer solution (but I did try it) since PI worked well enough. Usually proportional control is enough for the projects I've done.
Here are these "multipliers" I used in one of my programs.
Here's the PID section.
I was never really satisfied with this attempt. I'm sure there are better ways of implimenting an integer PID algorithm.
I didn't have a "dt" variable since each loop took the same about of time (a delay was added if needed).
I'm not sure if the above code was the one that worked the best or not. I tried several variations.
I've written PID routines for my brushless servo controller. I've used a "custom format" floating point math, 8 bits for the mantissa and 8 bit exponent. This way I can use the same mul/add routine for all coefficients although P, I and D coefficients have a different order of magnitude, which would be difficult to handle with fixed point math. 8x24 bit multiplication is also much faster than 32x32 bit multiplication on the propeller.
Only the coefficients are floting point, in and output is fixed (constant exponent for in, one shift operation for out). As the coefficients don't change very often this saves time for conversions.
In actual fact, my intention is to run one "real" and several virtual motion profiles in the same cog along with the PID for the "real" axis.
Some rough numbers, are 1000 quad counts/mm and I can, based on my performance criteria and under hard acceleration expect up to 10mm lag (aka: following error). Beyond this, my process is deemed out-of-control and I will shut the system down. This is only 10,000 counts of error so it seems to me that I have plenty of room to "SHL" for the calcs and later "SHR" when it comes to writing to the DAC(?)
Have I over-simplified the problem?
Thanks for the input, guys.
Mickster
When I wrote my Spin inverse kinematics I planned to use fixed point arithmetic for the trig functions, but I found F32 was faster and used floating point instead.
This is where PBasic’s */ and ** operators are really handy. They do the multiply and divide at the same time with a 32 bit intermediate quantity. If Spin had similar operators with a 64 bit intermediate, that would really help the fixed point arithmetic cause.
UPDATE: I checked the Propeller manual and Spin does contain the ** operator..
Very interesting. Did you publish details regarding this? Was this for an articulated arm? How many axes?
Regards,
Mickster
The actual PID code line looks like this:
Output := (Kp ** PError) + (Kd ** DError) + (Ki ** IError)
The source of the input value PError is just accumulated with more precision than necessary, and the K factors are chosen such that they scale the result back down into the appropriate range for the control output.