Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   Programming (http://www.chiefdelphi.com/forums/forumdisplay.php?f=51)
-   -   PID control loop/Encoder question (http://www.chiefdelphi.com/forums/showthread.php?t=24463)

Zee 28-01-2004 17:43

PID control loop/Encoder question
 
Hey guys, I'm a programmer for a rookie team. We're going to try to use Digikey encoders to help with velocity control. I've seen a few websites that help, like:

http://www.barello.net/Papers/Motion_Control/index.htm

http://nrg.chaosnet.org/repository/viewcode?id=0

Once I've figured out the error between requested speed and actual speed, I don't really understand what commands I would send to the motors to make the proper adjustments. Could anyone explain how that would work? Any help is appreciated.

Guest 28-01-2004 18:12

Re: PID control loop/Encoder question
 
If you use my code at the repository that you mentioned above, all that you have to do is call this function from your Default_Routine(). As in:
Code:

/* set actualLeft and actualRight to values from two encoders */
/* all other default routine code here */
pwm01=PID(left,actualLeft,&actualLeftLast,&sumLeft);
pwm02=PID(right,actualRight,&actualRightLast,&sumRight);

Then, place this in the global vars section:
Code:

int left=127, right=127;
int actualLeft,actualRight;
int actualRightLast=127,actualLeftLast=127;
int sumLeft=0,sumRight=0;

All code above assumes that left motors are pwm01, and right are pwm02.

I'm in the middle of writing an "Advanced Programming Guide" and when I'm done it'll be at the NRG website (see my sig), under "Resources." I'll be sure to include details about PID and encoders.

deltacoder1020 28-01-2004 18:13

Re: PID control loop/Encoder question
 
well, the PID control loop code you saw on the NRG repository essentially accepts a requested (nominal) PWM value, and the actual PWM value (in your case, from the encoder) - the second two variables are just for storage (note, you could just declare these in the function as static variables instead of declaring them elsewhere and passing them as arguments). It then returns the value that the PWM should be set to. It's essentially that simple - call it with those two values, and set the pwm variable to the return value of the function.

Larry Barello 28-01-2004 22:51

Re: PID control loop/Encoder question
 
Quote:

Originally Posted by Zee
Hey guys, I'm a programmer for a rookie team. We're going to try to use Digikey encoders to help with velocity control. I've seen a few websites that help, like:

http://www.barello.net/Papers/Motion_Control/index.htm

http://nrg.chaosnet.org/repository/viewcode?id=0

Once I've figured out the error between requested speed and actual speed, I don't really understand what commands I would send to the motors to make the proper adjustments. Could anyone explain how that would work? Any help is appreciated.

Typically the output of the PID loop is a signed number representing the power delivered to the motor. Unfortunately for IFI they don't use a signed number: they use 0 through 127 for 100% to 0% reverse and 127 through 255 for 0% to 100% forward.

So, if you have a signed number (e.g. -127 to 0 to 127) just add 127 to that to get an IFI compatible number. The reverse can be done to convert Joystick readings into signed numbers.

Beware, you need to explicitely declare variables as signed with the Microchip C compiler. I recommend working with 'int' values to avoid overflow problems, then clipping to +/- 127 then converting for output to IFI controllers.

Figuring out the function to transform error into output power can be tricky. Simple proportional and integral terms are all you need, but, check the results. If the output is being clipped (e.g. you have hit the stops) stop accumulating integral errors!

Figuring out the constants is also tricky. It depends upon your loop rate (fixed in IFI stuff) encoder resolution, velocity, etc. The integral term usually has a fractional gain while the proportional one usually has a fairly small number (1-30) - but again, it all depends.

Rickertsen2 28-01-2004 23:37

Re: PID control loop/Encoder question
 
Be careful. Even with the new controller, you may run into processor speed limitations if you try to use encoders with a resolution that is too high.

Larry Barello 29-01-2004 00:00

Re: PID control loop/Encoder question
 
Quote:

Originally Posted by Rickertsen2
Be careful. Even with the new controller, you may run into processor speed limitations if you try to use encoders with a resolution that is too high.

The 2004 controller seems capable of handling at least 5000 counts/sec with two encoders. I am using PORTB interrupt lines (change of state interrupt) and two four stripe encoders (home made) on the shaft of the Bosch. At ~20krpm the encoders give about 5000 counts/sec.

I did some experiments with a super fine resolution encoder and at about 100k counts/sec the IFI system locked up :)

Anyway, 5k/sec is about right. It gives ~150 counts/26ms loop at top speed.

Rickertsen2 29-01-2004 00:01

Re: PID control loop/Encoder question
 
Quote:

Originally Posted by Larry Barello
The 2004 controller seems capable of handling at least 5000 counts/sec with two encoders. I am using PORTB interrupt lines (change of state interrupt) and two four stripe encoders (home made) on the shaft of the Bosch. At ~20krpm the encoders give about 5000 counts/sec.

I did some experiments with a super fine resolution encoder and at about 100k counts/sec the IFI system locked up :)

Anyway, 5k/sec is about right. It gives ~150 counts/26ms loop at top speed.

Yes, but what else are you doing in the background?

Larry Barello 29-01-2004 00:19

Re: PID control loop/Encoder question
 
Quote:

Originally Posted by Rickertsen2
Yes, but what else are you doing in the background?

What do you mean?

I use the change of state interrupt for my encoders and Timer2 to increment a counter at 1khz. That is all that is done in the background. Everything else is done in the user code. Mostly in the high speed loop, running my gyro integration stuff at 100hz and a menu interface task at 10hz. All direct robot control stuff occurs in the 26ms main loop.

Even at 10k interrupts/sec (two encoders going full tilt), that is 1000 machine instructions per interrupt. It only takes a couple dozen to service the interrupt and decode the inputs. Lets say 100 to be generous. That is only 10% load. That leaves 9mips for the rest of the system.

Caleb Fulton 29-01-2004 01:01

Re: PID control loop/Encoder question
 
I think we've all just gotten so used to slow BASIC stuff that we're unconsciously limiting what we think we can do with the new controller...

Astronouth7303 29-01-2004 13:43

Re: PID control loop/Encoder question
 
He means "What are you doing BESIDES counting ticks?"

virusmirusne 29-01-2004 19:48

Re: PID control loop/Encoder question
 
Mr. Barello:
Have you successfully read quatrature encoders with the IFI?
The super high resolution with the wheel encoders is nice... but our team is having difficulties reading the second output pin on the wheel encoders. Do we not have access to these input pins? What would be the purpose of Process_Data_From_Local_IO() if it weren't to make it so as we could read digital io real-time. Why no real-time input reads if interrupts? We only seem to be able to read the direction of the wheel encoder if we spin the encoder shaft really, really slowly.

Any suggestions?

Larry Barello 29-01-2004 22:39

Re: PID control loop/Encoder question
 
Quote:

Originally Posted by virusmirusne
Mr. Barello:
Have you successfully read quatrature encoders with the IFI?
The super high resolution with the wheel encoders is nice... but our team is having difficulties reading the second output pin on the wheel encoders. Do we not have access to these input pins? What would be the purpose of Process_Data_From_Local_IO() if it weren't to make it so as we could read digital io real-time. Why no real-time input reads if interrupts? We only seem to be able to read the direction of the wheel encoder if we spin the encoder shaft really, really slowly.

Any suggestions?

The local io loop is very fast. I think I clocked it at a mere 29 cycles (doing nothing else, of course) which is many hundred thousand times per second.

HOWEVER, that isn't guarenteed! Once every 26.2 ms the main loop fires off and who knows how long that will take.

So I ran my encoder stuff off the PORTB 4-7 interrupt lines (IFI digital inputs 2-5), enabled the port B change interrupt so it interrupts whever any line changes.

When choosing encoders & such, keep in mind that the IFI CPU can only handle around 5-8 thousand counts/sec each for two encoders. So figure out how many RPM, how many slots (multiply by four for quadrature) and do the math. If you are substantially higher than 10k/sec total, then re-think.

I posted my quadrature code (including interrupt setup) in the thread about Yaw sensors.

Mike Rozar 30-01-2004 00:35

Re: PID control loop/Encoder question
 
Quote:

Originally Posted by Larry Barello
The local io loop is very fast. I think I clocked it at a mere 29 cycles (doing nothing else, of course) which is many hundred thousand times per second.

HOWEVER, that isn't guarenteed! Once every 26.2 ms the main loop fires off and who knows how long that will take.

So I ran my encoder stuff off the PORTB 4-7 interrupt lines (IFI digital inputs 2-5), enabled the port B change interrupt so it interrupts whever any line changes.

When choosing encoders & such, keep in mind that the IFI CPU can only handle around 5-8 thousand counts/sec each for two encoders. So figure out how many RPM, how many slots (multiply by four for quadrature) and do the math. If you are substantially higher than 10k/sec total, then re-think.

I posted my quadrature code (including interrupt setup) in the thread about Yaw sensors.

Our team has assumed that since we are controlling the direction of the motors, we would not need quadrature for directional counting. Are we missing something?

Zee 30-01-2004 00:42

Re: PID control loop/Encoder question
 
Quote:

Originally Posted by SilverStar
If you use my code at the repository that you mentioned above, all that you have to do is call this function from your Default_Routine(). As in:
Code:

/* set actualLeft and actualRight to values from two encoders */
/* all other default routine code here */
pwm01=PID(left,actualLeft,&actualLeftLast,&sumLeft);
pwm02=PID(right,actualRight,&actualRightLast,&sumRight);

Then, place this in the global vars section:
Code:

int left=127, right=127;
int actualLeft,actualRight;
int actualRightLast=127,actualLeftLast=127;
int sumLeft=0,sumRight=0;

All code above assumes that left motors are pwm01, and right are pwm02.

I'm in the middle of writing an "Advanced Programming Guide" and when I'm done it'll be at the NRG website (see my sig), under "Resources." I'll be sure to include details about PID and encoders.

This answers my question completely. Thanks for clearing it up and thanks to everyone else for the responses.

Mr. Lim 30-01-2004 00:42

Re: PID control loop/Encoder question
 
Quote:

Originally Posted by Mike Rozar
Our team has assumed that since we are controlling the direction of the motors, we would not need quadrature for directional counting. Are we missing something?

You're good, as long as whatever you're moving won't get moved by forces other than your motor. If you have to put up with gravity and robots hitting said object, then quadrature may be the way to go.


All times are GMT -5. The time now is 13:53.

Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi