Event Handlers and PID Control

C, C++, and Visual C++
eloydark

Event Handlers and PID Control

Postby eloydark » Mon Dec 19, 2011 11:52 am

I am trying to implement a simple PID position control algorithm using the 1064 and the 1047. I used the events, the EncoderPositionChangeHandler in particular, to fire the control loop every time the encoder fires the event function with this algorithm

Code: Select all

   int pos;
   CPhidgetEncoder_getPosition(ENC, Index, &pos);
   double error = usrptr.f_pos - pos;
   usrptr.integral += error * Time;
   double u1 = usrptr.Kp * error + usrptr.Kd * (error - usrptr.prev_error) / Time + usrptr.Ki * usrptr.integral * Time;
   double u2 = (u1 - usrptr.prev_u1) / Time;
   double u3 = (u2 - usrptr.prev_u2) / Time;
   usrptr.prev_u1 = u1;
   usrptr.prev_u2 = u2;
   CPhidgetMotorControl_setVelocity(motoControl, 0, u2);
   CPhidgetMotorControl_setAcceleration(motoControl, 0, u3);


Is this the correct way to implement this? Is the event handler fired continuously as long as the encoder is changing, or is it fired only once, and waits for a stop and a restart to fire it again? Will the refresh rate be adequate for control on the SBC2?
Thanks in advance,
Aris

User avatar
Patrick
Lead Developer
Posts: 3046
Joined: Mon Jun 20, 2005 8:46 am
Location: Canada
Contact:

Re: Event Handlers and PID Control

Postby Patrick » Mon Dec 19, 2011 3:02 pm

The encoder position change event only fires when the position changes, so you may want to run your pid in a separate loop.

-Patrick

andish
Fresh meat
Posts: 1
Joined: Fri May 08, 2015 11:51 am
Contact:

Re: Event Handlers and PID Control

Postby andish » Wed May 13, 2015 3:47 am

Patrick wrote:The encoder position change event only fires when the position changes, so you may want to run your pid in a separate loop.

-Patrick


Hi !

You can design a PID controller that is event based, but as the time from run to run is not equal, you have to re-calculate all terms for each "fireing".
See the event based variant of the code in
http://www.artes.uu.se/project/7/arzen1999.pdf

The advantage for me is not saving of CPU or communication in some plant network, but rather to call the PID when the event is "fresh", the encoder has just "fired" and avoid phase noise errors when doing PID asynchronously from the sensor input.

My history:
I was running in problems with a magnetic incremental encoder Infineon TLE4966-3K that gives out direction and counts, but my magnet has 12 pole changes per revolution, thought it great, but for speed measurement this is poor -my axle hopped around when it should rest.

So now I have to do some "observer" that estimates the speed _and_ the error this has, and have to keep the control cool when the error gets high. This is such a standard setup, but I can not find anyone that has implemented a PID based on the IRQ calls from the encoder event, _and_ some additional work when the counts get real low frequency (watchdog: if no event for more than ?50ms: do guesswork and go to brake / keep position mode using PWM - current - torque relation and try to stay in static friction stay-still-mode to avoid jittering around the target position.)

The Problem with the irq from encoder events is: you get called on a certain distance or angle you have travelled, but most loops want speed or frequency, and I tried to avoid the float freq=1/Period;. Do you have any idea?
If this really gets to heavy a calculus for doing it inside the irq, one could do a lookup based calculus with linear interpolation perhaps.

I have already tried to stay integer most of the time by re-writing the code atmel gave us in their Application Note on PID, http://www.atmel.com/images/doc2558.pdf . But for now I would search for some other implementation as starting point using avr-gcc right away, not their keil in AVR4.

There are moments these days where I look at the old analogue hall sensors from my torn-apart bldc motor from DVD drive (have them in old floppies, etc), and want to do Analog-to-digital on two of them, so I have my digital hall encoder for the real speedy part of the journy, and to get a clean landing, I turn on the A/D when the rate is falling below some threshold.
But there are ready solutions out there, just another 20$ or so on some distributor like rs-components, and you get quadrature decoded digital or anlogue temperature compensated robust signals from some smart IC.

Good luck & hope to hear from you

Andi


Return to “C/C++”

Who is online

Users browsing this forum: No registered users and 1 guest