Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   Technical Discussion (http://www.chiefdelphi.com/forums/forumdisplay.php?f=22)
-   -   PID control loops - closed loop feedback (http://www.chiefdelphi.com/forums/showthread.php?t=24340)

KenWittlief 24-01-2004 21:45

PID control loops - feedback is our friend!!!
 
I've been talking (ranting:c) about this topic on and off on CD for a while, and a couple people have asked questions about it.

I went into some detail in a thread about castors, but thought this subject desirves its own thread.

Feedback is one of the most power tools you learn about in engineering - I stuck this thread here because it involves SW and HW and your controller and sensors, and it can get pretty technical.

I started talking about it in this thread:

http://www.chiefdelphi.com/forums/sh...751#post212751

but for the sake of the rest of the forum, I like to continue the discussion here - it applies to more than just using castors on your robot - it can be used if you turn your wheels to steer, to postion a robot arm, to control your robots speed, how fast it turns - you could even set up a control algorythm to drive your bot with a steering wheel, so that, when you turn the wheel ten degrees, your bot turns ten degrees...

if you take engineering in college you will learn about feedback and PID control systems - but I think we can use enough of a subset for what we do in FIRST to really make a difference in how well your bot responds to your drivers commands.

(PS. I searched before I posted this, the only threads I could find on PID loops were from previous years, and they are closed now)

mtrawls 25-01-2004 12:12

Re: PID control loops - closed loop feedback
 
For another site that may prove interesting, you can try here [barello.net]. It includes an implementation of PID control in C, along with a description about it, for those interested.

Guest 25-01-2004 23:20

Re: PID control loops - feedback is our friend!!!
 
http://nrg.chaosnet.org/repository/viewcode?id=0

Some sample PID code I wrote.

mightywombat 11-03-2004 21:47

Re: PID control loops - feedback is our friend!!!
 
PID control loops.... ahh. They seem to make sense sometimes but other times they don't... Here is the control loop that I have written up. Please take a look at it and critique it. The constants have not been tuned at all. I finally got to plug it into our second arm (with working pots!!) and somehow it was outputting numbers in the 400's....

Any help???

The two scaled values are pot values, one from our arm and one from the model. They are both scaled from 0 to 255 and are declared as unsigned longs... (don't ask, it has to do with how we scale them...)

sint = signed int

THIS IS WHERE IT IS CALLED:

//call the control loop to set the pwm values
Arm_Upper_Out = PID(scaled_highjoint_req, scaled_highjoint_act, lasthighjoint_act, sint_highjoint_errorsum);

//keep track of the error for the control loop
sint_highjoint_errorsum = sint_highjoint_errorsum + (scaled_highjoint_req - scaled_highjoint_act);

//keep track of the last position to be able to tell how fast it is moving for the control loop
lasthighjoint_act = scaled_highjoint_act;


THIS IS THE CONTROL LOOP:


unsigned char PID(signed int request, signed int actual, signed int lastactual, signed int sumerror)
{
#define PID_PROP 2
#define PID_DER 1
#define PID_INT 1

signed int pid, error;

request = request - 127;
actual = actual - 127;
lastactual = lastactual - 127;


pid = request;

error = request - actual; //find the difference of the two values

pid = pid + (error/PID_PROP); //add the proportional part of the error

pid = pid + ((actual - lastactual)/PID_DER); // add the derivative part of the error

pid = pid + (sumerror/PID_INT); //integral part of the pid

pid = pid + 127;

return(pid);
}

Guest 11-03-2004 21:50

Re: PID control loops - feedback is our friend!!!
 
This might be the problem (it had been screwing up a lot of my code 'till I realized it).

Try casting all your constants to (signed int).

Also, try casting your return value to (unsigned char) both in the return statement and in calling code.

mightywombat 11-03-2004 21:52

Re: PID control loops - feedback is our friend!!!
 
So like:

#define (signed int) PID_PROP 2

?

Joe Ross 11-03-2004 21:52

Re: PID control loops - feedback is our friend!!!
 
Quote:

Originally Posted by mightywombat
I finally got to plug it into our second arm (with working pots!!) and somehow it was outputting numbers in the 400's....

If you didn't know already, the analog inputs this year are 10 bit numbers, not 8 bit like previous years. There is a lot of important information about the analog inputs on page 16 of the 2004 programming guide from innovation first.

Joe Ross 11-03-2004 21:54

Re: PID control loops - feedback is our friend!!!
 
Quote:

Originally Posted by mightywombat
So like:

#define (signed int) PID_PROP 2

#define PID_PROP (signed int)2

mightywombat 11-03-2004 22:12

Re: PID control loops - feedback is our friend!!!
 
Yeah. I read up on that and I think I'm safe there.
I'm able to print out the scaled and pre-scaled actual pot values from the arm and they output correctly/as expected, so I don't think I have a problem there.

velocipenguin 12-03-2004 02:18

Re: PID control loops - closed loop feedback
 
Have you made sure that you're calling the PID function at a consistent time interval? If there's code that occurs before that in the main loop that might vary in execution time, you might want to consider using an interrupt-driven timing scheme to make sure you're calling the function at precisely the right time interval. Are the excessive output values appearing as soon as the control loop starts, or are they occurring gradually? If they're occurring after you move the arm, particularly if you move it rapidly, try reducing Ki to make sure you're not saturating the integral term of the PID equation.

mightywombat 12-03-2004 07:03

Re: PID control loops - closed loop feedback
 
What kind of time interval would you recommend? Every 25 ms or so?

kevinw 12-03-2004 10:07

Re: PID control loops - feedback is our friend!!!
 
Quote:

Originally Posted by mightywombat

pid = request;

error = request - actual; //find the difference of the two values

pid = pid + (error/PID_PROP); //add the proportional part of the error

pid = pid + ((actual - lastactual)/PID_DER); // add the derivative part of the error

pid = pid + (sumerror/PID_INT); //integral part of the pid

pid = pid + 127;

return(pid);
}

What is the reason for adding the requested position to the PID control output? Is there a need for a feed-forward term in the control loop? Are you scaling the output after pid is returned?

Also, you might want to add overflow checking, just in case.

ChrisA 12-03-2004 10:54

Re: PID control loops - feedback is our friend!!!
 
Quote:

Originally Posted by kevin_308
What is the reason for adding the requested position to the PID control output? Is there a need for a feed-forward term in the control loop? Are you scaling the output after pid is returned?

Also, you might want to add overflow checking, just in case.

Overflow will be added as soon as the code itself is working. No scaling is being done to the output of the above code.

mightywombat 13-03-2004 02:20

Re: PID control loops - feedback is our friend!!!
 
So I should initially set pid to zero?

After testing the code this evening I found that the arm model that we are using was behaving more like a joystick than a model. I'd move it forward and the arm would move forward - but never stop at a certain place, move it back to neutral and it would stop, move it backward from neutral and the arm would go the opposite direction - once again not stopping at the desired position.
Any pointers?

kevinw 14-03-2004 21:15

Re: PID control loops - closed loop feedback
 
I believe the integral control portion should offset the initial setting of pid, but I would set it to 0, as this will most likely reduce settling time, overshoot, etc.

As for the digital response, my team saw something similar until we realized we were reading the wrong potentiometer value on the robot. We were reading a centered potentiometer, so when the input was neutral, the motor would not move. When the input was forward, the arm went forward, but the feedback wasn't in place to slow the arm down as it approached it's desired position because we were monitoring the wrong joint. I would recommend adding some debugging code to display both your arm pot value and your joystick value - this will also help you check to make sure the scaling is the same.

It may also be a function of the gain settings. One suggestion is to comment out the integral and derivative control inputs, leaving only the proportional control effort and attempt to tune it so that it's satisfactory. This is the simplest loop, and often is enough to get the job done well. If you find you have error that can not be overcome (due to gravity, etc.), then you may have to add in integral control back in, or go back to a full PID. Either way, I try to start as simple as possible and add in complexity only as needed.

Hope this helps.

Max Lobovsky 21-03-2004 14:47

Re: PID control loops - feedback is our friend!!!
 
All the code for PID feedback loops i have seen posted on CD has used only the current and last measured values for the derivative and integral part. Has anyone tried using 3 or more frames? Is the result better?

KenWittlief 21-03-2004 15:06

Re: PID control loops - closed loop feedback
 
going back more than 2 loops is only useful for the intergral part - if the arm is not moving you keep adding a small part of the error - so the control signal can actually build up over several loops before the motor move enough to eliminate the error

but for the differential part you only want this reading and the last one - the D is like giving the system a swift kick for a loop or two, so it needs to be very responsive to the most recent action of the system.

There is another type of PID control that does keep track of several previous commands and positions- its an adaptive algorythm - one that responsed differently if the mass of the system changes (like if you pick up a ball with your arm) or it the friction of the system changes (like if you move from carpet to smooth surface) and it adjusts the gains of the feedback accordingly. But I think thats really too fancy for what we need.

so far on our drivetrain and our arm motion, we are only using proportional feedback this year - its works well so we dont want to get lost in complexity.

Larry Barello 21-03-2004 19:31

Re: PID control loops - closed loop feedback
 
For the typical low performance robot (I think FIRST robots count here), PD is needed for position control (proportional/derivative) and PI is needed for velocity control.

Usually with positioning servos, the control is sloppy and there is a lot of friction, so you can get away with just P term. Adding the D term allows stiffer snappier control, but, again, with the typical chain driven arm snappy isn't the image that comes to mind.

W/velocity control, often folks get away with just the I term. Something like:

output += SomeFudgeFactor * VelocityError;

So if you are slow, the output is built up until you are at the right speed, etc.

Team #492 had a arm for manipulating the 2x ball which was pretty sloppy and oscillated terribly when overhead (chain slop). So we simply checked for range and divided the output by 16 (or some other large number) when overhead. Worked great. That is an example of "gain scheduling" where you change the gain based upon position (or some other external factor).

Max Lobovsky 21-03-2004 20:44

Re: PID control loops - closed loop feedback
 
Quote:

Originally Posted by KenWittlief
going back more than 2 loops is only useful for the intergral part - if the arm is not moving you keep adding a small part of the error - so the control signal can actually build up over several loops before the motor move enough to eliminate the error

but for the differential part you only want this reading and the last one - the D is like giving the system a swift kick for a loop or two, so it needs to be very responsive to the most recent action of the system.

There is another type of PID control that does keep track of several previous commands and positions- its an adaptive algorythm - one that responsed differently if the mass of the system changes (like if you pick up a ball with your arm) or it the friction of the system changes (like if you move from carpet to smooth surface) and it adjusts the gains of the feedback accordingly. But I think thats really too fancy for what we need.

so far on our drivetrain and our arm motion, we are only using proportional feedback this year - its works well so we dont want to get lost in complexity.

ah, sorry, i do understand what a derivative is, just didn't think about the fact that previous values wont affect it.

Max Lobovsky 21-03-2004 20:48

Re: PID control loops - closed loop feedback
 
Quote:

Originally Posted by Larry Barello
For the typical low performance robot (I think FIRST robots count here), PD is needed for position control (proportional/derivative) and PI is needed for velocity control.

Wouldn't it be vice-versa? I thought that the integral is neccesary for reaching the right value.

Quote:

Originally Posted by Larry Barello
W/velocity control, often folks get away with just the I term. Something like:

output += SomeFudgeFactor * VelocityError;

So if you are slow, the output is built up until you are at the right speed, etc.

how is this the integral? This looks proportional to me, just the current error.

Jay Lundy 21-03-2004 21:50

Re: PID control loops - closed loop feedback
 
We use 2 PI loops to maintain target velocities on our 2 arm joints. The integral is essential for our loop because it is what keeps the arms from falling due to gravity. For the proportional to work, it needs to have a speed error. So in order for the proportional to prevent the arm from dropping, the arm needs to drop a little first. The integral is non-zero when the arm is stationary, which is what keeps the motor at stall torque.

Here's the code for the PI loop for our elbow.

Code:

//Joystick dead zone
 ELBOW_CONTROL = (ELBOW_CONTROL >= 127 - ELBOW_CONTROL_DEAD_ZONE && ELBOW_CONTROL <= 127 + ELBOW_CONTROL_DEAD_ZONE) ? 127 : ELBOW_CONTROL;       
 
  //Calculate velocities
  elbowVelocity = (long)(elbowCurrPosition - elbowPrevPosition) * 1000 / (long)(elbowCurrTime - elbowPrevTime);
  targetVelocity = ((int)ELBOW_CONTROL - 127) * ELBOW_MAX_POT_SPEED / 127;
 
  //Check for target position mode
  if (elbowPositionMode) {
          targetVelocity = RepositionElbow();
  }
 
  //Calculate speed error
  speedError = targetVelocity - elbowVelocity;
 
  //Calculate proportional and integral
  proportional = speedError * ELBOW_PROPORTIONAL;
  elbowIntegral += speedError * ELBOW_INTEGRAL;
 
  //Limit integral
  elbowIntegral = MIN_MAX(elbowIntegral, -127, 127);
 
  //Output to motors
  ELBOW_MOTORS = 254 - MIN_MAX(127 + (proportional + elbowIntegral), 0, 254);       
 
  //Set prev values to current values
  elbowPrevPosition = elbowCurrPosition;
  elbowPrevTime = elbowCurrTime;

The thing is, none of our programmers had any prior experience with PID loops. We just had an engineer come in for 2 hours one day and explain the theory to us, but he didn't provide any code. I'm curious if our implementation is correct, or if there are any improvements we should make.

By the way, our P and I constants are both 1 / 8 on our competition robot, and our elbow loop runs at 10 Hz.

Oh we also have a target position mode which feeds a target velocity into our PI loop. That's the RepositionElbow() function that you see in there.

KenWittlief 21-03-2004 22:05

Re: PID control loops - closed loop feedback
 
thats pretty cool - I dont see any obvious mistakes in it.

have you been able to test it on your bot?

the one thing Im curious about, why did you close the loop on arm velocity instead of arm position?

for our arm control we integrate the joystick input and it creates a desired arm position - then we use a straight proportional desired-actual postion with a gain constant to create the motor drive

the arm sags a little bit if its holding a ball, but thats a function of the gain- the more gain you use, the less it will sag (before the error signal is enough to hold it)

closing the loop on position makes it easier to deal with the up and down limits - you just dont let the desired position exceed the limits.

Jay Lundy 21-03-2004 23:06

Re: PID control loops - closed loop feedback
 
Yeah the elbow loop works really well. It took us a lot of testing to get the right constants but 1/8 and 1/8 works best for us.

The wrist loop was a little more difficult to get working because of chain slack. Our wrist chain runs from the base of the robot up 5 ft to the joint so we can maintain a low CG by keeping all the motors in the base. What happened was when we moved the arm down it would overshoot a lot and be really bouncy, even though it worked perfectly on the way up. To fix that we reduced the constants on the way down.

We did target velocity because that's basically what was coming out of the joysticks -- a target velocity. With target position, if something is holding back your arm, and your joystick is full forward, your target position is changing, but the actual position never changes. Then if you bring the joystick back to neutral and allow the arm to move again, it will shoot forward to its target position, even though that isn't necessarily what you wanted.

Our arms sag a little bit when a ball is placed in them, but not much and the integral adjusts accordingly pretty quickly. In fact, we tested once with the robot at 90 deg (we were hanging from the bar) and the arm fully extended to 10 feet, and we placed a ball in it and it sagged about 3 inches with a huge lever arm before the integral picked up the change.

10intheCrunch 21-03-2004 23:18

Re: PID control loops - closed loop feedback
 
The PI loop on the wrist was immensely successful for us (I ran the arms at the Sacramento regional this weekend). The only problem it has, other than the bounciness on the way down Jay described (in actuallity that is a small problem, we only *fold* the arm once or twice in a match, to stow a ball or to stow when hanging), is that it can be slow to react when holding a ball. The integral has to get pretty high to move the arm up from extended to vertical (say, when we pick up a ball from a goal), and until I learned to correct, it would overshoot vertical (if thats when I moved the joystick to neutral) and fly down the other side. After about four rounds on Friday, though, I got that worked out and it worked really well for the rest of the tournament.

We had tried to build a PID loop earlier in the year, and didn't really end up with a workable solution. The important thing, it seems, was the engineer who came down and helped us map out the logic of the process. Once we knew what we wanted to do, it was actually only took about a half hour to write the function (and update as needed later).

By the way, you can see the pictures of the arm straight out on our website, in my signature =).

edit: The Reposition functions for the arms came from our old code for the arm, before we implemented the PI loop. It takes the distance from the desired position to generate a velocity. Pretty much, we only use it for the preset buttons on our control box and autonomous mode.

KenWittlief 21-03-2004 23:25

Re: PID control loops - closed loop feedback
 
wow that arm looks huge - now that you mention it, we did the same thing with our arm - used a much smaller gain going down than up - didnt want the arm to slam into the roller on the front of our bot.

if your arm goes over the top and down the other side, that does make it tricky. In general the way to get a feedback loop working is to start with low gains and increase them until you start getting overshoot - then back off a little.

(or goto engineering school for 4 years and learn all the math :c)

Max Lobovsky 21-03-2004 23:34

Re: PID control loops - closed loop feedback
 
Quote:

Originally Posted by Jay Lundy
We use 2 PI loops to maintain target velocities on our 2 arm joints. The integral is essential for our loop because it is what keeps the arms from falling due to gravity. For the proportional to work, it needs to have a speed error. So in order for the proportional to prevent the arm from dropping, the arm needs to drop a little first. The integral is non-zero when the arm is stationary, which is what keeps the motor at stall torque.

Here's the code for the PI loop for our elbow.

Code:

//Joystick dead zone
 ELBOW_CONTROL = (ELBOW_CONTROL >= 127 - ELBOW_CONTROL_DEAD_ZONE && ELBOW_CONTROL <= 127 + ELBOW_CONTROL_DEAD_ZONE) ? 127 : ELBOW_CONTROL;       
 
  //Calculate velocities
  elbowVelocity = (long)(elbowCurrPosition - elbowPrevPosition) * 1000 / (long)(elbowCurrTime - elbowPrevTime);
  targetVelocity = ((int)ELBOW_CONTROL - 127) * ELBOW_MAX_POT_SPEED / 127;
 
  //Check for target position mode
  if (elbowPositionMode) {
          targetVelocity = RepositionElbow();
  }
 
  //Calculate speed error
  speedError = targetVelocity - elbowVelocity;
 
  //Calculate proportional and integral
  proportional = speedError * ELBOW_PROPORTIONAL;
  elbowIntegral += speedError * ELBOW_INTEGRAL;
 
  //Limit integral
  elbowIntegral = MIN_MAX(elbowIntegral, -127, 127);
 
  //Output to motors
  ELBOW_MOTORS = 254 - MIN_MAX(127 + (proportional + elbowIntegral), 0, 254);       
 
  //Set prev values to current values
  elbowPrevPosition = elbowCurrPosition;
  elbowPrevTime = elbowCurrTime;

The thing is, none of our programmers had any prior experience with PID loops. We just had an engineer come in for 2 hours one day and explain the theory to us, but he didn't provide any code. I'm curious if our implementation is correct, or if there are any improvements we should make.

By the way, our P and I constants are both 1 / 8 on our competition robot, and our elbow loop runs at 10 Hz.

Oh we also have a target position mode which feeds a target velocity into our PI loop. That's the RepositionElbow() function that you see in there.

as i understand it, the code sums the integral from start to finish, but every iteration of the loop it limits the integral. This seems like a very bad idea. essentially, the effective length of time that sum occurs is changing as the integral is being limited when it grows large. Also, for errors that continue in one direction, the integral error will not change because it will reach its max and keep trying to exceed that. This brings me back to my first question in this post. how long in iterations or in time should the integral sum over?

Larry Barello 21-03-2004 23:40

Re: PID control loops - closed loop feedback
 
Quote:

Originally Posted by maxlobovsky
Wouldn't it be vice-versa? I thought that the integral is neccesary for reaching the right value.



how is this the integral? This looks proportional to me, just the current error.

Note the "+=" that says add the right hand side to the left hand side. Which is an integral

e.g.

Foo += Something

is equivalent to

Foo = Foo + Something;

Therefore Foo is accumulating the integral of Something.

You are correct that the integral is needed to drive the error term to zero, but for position stuff that is rarely needed (particularly in low performance systems like what we are working on). WHat is really needed is to drive the servo *close* enough to the correct position that you don't care about the residual error. Integral terms are hard to get right and lead to a lot of instability and are really useless in a dynamic environment as they are fighting your ability to change the setpoint. They only make sense if your servo is relatively static or has a constant force in one direction that needs to be compensated for with the integral term. But if the error amount is dynamic and changing sign, the integral term just gets in the way.

Larry Barello 21-03-2004 23:41

Re: PID control loops - closed loop feedback
 
Quote:

Originally Posted by maxlobovsky
as i understand it, the code sums the integral from start to finish, but every iteration of the loop it limits the integral. This seems like a very bad idea. essentially, the effective length of time that sum occurs is changing as the integral is being limited when it grows large. Also, for errors that continue in one direction, the integral error will not change because it will reach its max and keep trying to exceed that. This brings me back to my first question in this post. how long in iterations or in time should the integral sum over?

You must limit the integral term: what happens when your output is at 100% and you STILL have an error term? DO you really want to continue accumulating errors? It is a bad idea and will cause excessive delays in working out the integral term (the official name for this is Integral Windup) when you regain control.

Larry Barello 21-03-2004 23:47

Re: PID control loops - closed loop feedback
 
Quote:

Originally Posted by Jay Lundy
We use 2 PI loops to maintain target velocities on our 2 arm joints. The integral is essential for our loop because it is what keeps the arms from falling due to gravity. For the proportional to work, it needs to have a speed error. So in order for the proportional to prevent the arm from dropping, the arm needs to drop a little first. The integral is non-zero when the arm is stationary, which is what keeps the motor at stall torque.
...

There is nothing wrong with your code, but terminology is a little hashed.

You state you are controlling velocity, yet what you are really controlling is position, but by a round-about way.

Velocity is the first derivative of position. Your code takes the velocity error + the integral of the velocity error. Well, that can also read as: The first derivative of position error + Position error. Hence, in fact, you have a classic PD controller for position.

As your controller integrates the velocity error, you get, essentially, an error term that grows as the position error grows. That is the "proportional" error term.

Cheers!

Max Lobovsky 21-03-2004 23:47

Re: PID control loops - closed loop feedback
 
Quote:

Originally Posted by Larry Barello
You must limit the integral term: what happens when your output is at 100% and you STILL have an error term? DO you really want to continue accumulating errors? It is a bad idea and will cause excessive delays in working out the integral term (the official name for this is Integral Windup) when you regain control.

ok, but i thought the solution to that is to sum over a shorter period of time and use a small enough coeffecient. The integral term just becomes an additional proportional term in the code posted above when the error is large enough.

.... on second though, that isnt really a problem as the integral term isn't needed when the error is large. And i was presumptious enough to think that years of science and engineering could be faulty.... :)

So what this means is that if one limits the integral each iteration, one can integrate for the entire time the robot functions? I understand this would work now, but it still seems a little odd, id rather just integrate for a shorter period of time. Is this common practice?

10intheCrunch 21-03-2004 23:51

Re: PID control loops - closed loop feedback
 
Before we limited the integral, we found that it could wind itself up into the thousands if we weren't *very* careful. That could happen if the OI was off, the robot was on, and the arm moved, or if a velocity went in and the arm was held down. An integral that high means that when the arm is allowed to move, it will smash all the way over and ram into itself, or do other nasty things to itself.

We found that the integral never actually gets higher than 30-50, and thats very rare too. Usually it is under 20.

We run the elbow loop at 10hz, and the wrist loop at 5hz. That leaves enough time to create a speed error we can actually work with...too much faster and we get mostly 0 speed with intermittant high speed as it actually moves. Very bad.

edit: To the above poster: You're right. The proportional is supposed to be the major factor when the speed error is large, and the integral builds up to balance it out and hold steady as the speed error decreases (ie the integral maintains the speed the proportional generates). It just so happened that the arm worked best for us when the proportional and integral were both 1/8. It took a lot of testing and frustration to find the right values.

Larry Barello 22-03-2004 00:00

Re: PID control loops - closed loop feedback
 
Quote:

Originally Posted by maxlobovsky
ok, but i thought the solution to that is to sum over a shorter period of time and use a small enough coeffecient. The integral term just becomes an additional proportional term in the code posted above when the error is large enough.

.... on second though, that isnt really a problem as the integral term isn't needed when the error is large. And i was presumptious enough to think that years of science and engineering could be faulty.... :)

The PID controller is a vast simplification. It takes a while to get a handle on all the things going on and why it works, or, more importantly, doesn't work.

The best way to think of the integral term is that it, eventually, will compensate for all those unknown things that prevent you from getting to your goal (position or velocity). The problem is that if your position setpoint is moving all the time (plus & minus, typical for an arm) the integral needed going forward is precisely the wrong thing for moving in reverse! Best to just leave out.

10intheCrunch 22-03-2004 02:49

Re: PID control loops - closed loop feedback
 
Quote:

Originally Posted by Larry Barello
The problem is that if your position setpoint is moving all the time (plus & minus, typical for an arm) the integral needed going forward is precisely the wrong thing for moving in reverse! Best to just leave out.

True, the integral is going to be in the wrong direction at times, and you are going to have a slower response time because your joystick is not hooked directly to the motor values coming from your program. But best to leave out? No...

Without an integral in our program there would be no way for us to control our arm, much less control it with a ball. The integral needs to build up to maintain zero velocity when the lever arm and torque is great, or the arm will simply fall. There really is no way to manage it dynamically otherwise.

We suggest you use the PID loop to control velocity, because that's what's coming out of your joystick. Position may be very tricky, and as Jay and I said, the position system just generates its own velocity value. Don't knock PI loops until you've tried them! We would never have done so well without it.

Rickertsen2 22-03-2004 20:34

Re: PID control loops - closed loop feedback
 
Quote:

Originally Posted by 10intheCrunch
True, the integral is going to be in the wrong direction at times, and you are going to have a slower response time because your joystick is not hooked directly to the motor values coming from your program. But best to leave out? No...

Without an integral in our program there would be no way for us to control our arm, much less control it with a ball. The integral needs to build up to maintain zero velocity when the lever arm and torque is great, or the arm will simply fall. There really is no way to manage it dynamically otherwise.

We suggest you use the PID loop to control velocity, because that's what's coming out of your joystick. Position may be very tricky, and as Jay and I said, the position system just generates its own velocity value. Don't knock PI loops until you've tried them! We would never have done so well without it.

I was thinking about PID loops in situation with rapidly changing w, and the phase lag time of the I term causing problems when this occured to me, and i was wondering if anybody had any input, wanted to tell my why i'm wrong, or if they had tried this before:

The PI algorithm that we use for everything uses a data element we invented called a CSStack for the I term. Its basically a dynamic variable lenght mutable circular buffer. It seems to me that response could be improved by dropping certian old values from the buffer in times of rapid w change. What about dynamically changing Ki according to the derivitave of w? Any input? What other sorts of optimizations have people made to the basic PID algorithm? Is anybody using somethign other than some variation of a PID controller?

Max Lobovsky 22-03-2004 22:27

Re: PID control loops - closed loop feedback
 
Quote:

Originally Posted by Rickertsen2
I was thinking about PID loops in situation with rapidly changing w, and the phase lag time of the I term causing problems when this occured to me, and i was wondering if anybody had any input, wanted to tell my why i'm wrong, or if they had tried this before:

The PI algorithm that we use for everything uses a data element we invented called a CSStack for the I term. Its basically a dynamic variable lenght mutable circular buffer. It seems to me that response could be improved by dropping certian old values from the buffer in times of rapid w change. What about dynamically changing Ki according to the derivitave of w? Any input? What other sorts of optimizations have people made to the basic PID algorithm? Is anybody using somethign other than some variation of a PID controller?

well this buffer was what i was invisioning when i was asking about having the integral last over a certain length of time rather than from initialization. I didnt think about changing this length of time dynamically, but that could make for a pretty complex, if not effective, control. I have been doing a lot of research and some loops do have dynamic coefficients. Regardless, it seems to me that when you are dealing with 8 bit or less precisions and when the systems are so full of unpredicted forces that Larry Barello was right when he described FIRST as being classified as low performance. If you do implement anything this advanced, please post some data comparing it to simpler algorithms. IE response times, or even better, response curves.

10intheCrunch 22-03-2004 22:39

Re: PID control loops - closed loop feedback
 
If you start dropping values off of your integral, you are going to have a hard time keeping a steady state (ie velocity = 0) for any amount of time. You won't have a speed error, and so your integral won't change, but you still want it to hold still.

Rick is probably right in that you can increase your performance by dropping values off during times of high theta change (high omega), but the complexity of performing that may become difficult in C--I would think an object oriented language would assist much more in this (dynamically sized queues are also really difficult to program on our tiny little memory block on the robot...). Conceivably you could make another PID loop feed into your main one to change the constant's values, but just the straight loop works quite well with a little driver knowledge. I think that inputting another loop or trying to dynamically drop values will either make it far too jumpy or unstable.

One last (though possibly minor) problem is drawing too hard on the battery and overheating the motors. We considered zeroing the integral if the direction of the motion was opposite the target direction but concluded it would draw too hard and be harder to control in the long run.

Rickertsen2 23-03-2004 11:53

Re: PID control loops - closed loop feedback
 
Quote:

Originally Posted by maxlobovsky
If you do implement anything this advanced, please post some data comparing it to simpler algorithms. IE response times, or even better, response curves.

Alright i will. Once we get our robot back, this is the sort of thing i will be messing with the rest of the year. Also, who says that jsut because you have an 8-bit processor you are limited to 8 bit precision. There are other data types that arn't 8-bit. We needed something that could handle decimal values, but didn't want to use floating point, so we invinted our own fixed point system. I may publish that at some later time. I mean in the end we are limited to 8-bit motor control, but that shouldn't be too much of a problem. It seems like thats plenty. As far as input resolution goes we arn't really limited. We can add whatever sensors we want, and higher precision ADC, etc to support them.

Btw, you say you have been doing research on variable coeff algorithms, do you have any links? Any books i might read? I have wanted to learn more about feedback control loops, particulary adaptive ones, but havn't really known where to look. A freind of mine gave me a book on feedback control, but its more about analyzing the effectiveness of control loops rather than designing them.

KenWittlief 23-03-2004 12:03

Re: PID control loops - closed loop feedback
 
any college library would have a shelf full of books on control systems - only problem is they require you to understand the math they use - most of it is worked out in the frequency domain - convolution - imaginary numbers

lots of fun at first, but once you get your head into that way of thinking it becomes intuitive.

another good source is to seach the web for companies that sell control system hardware - stepper motors and servo motors - linear amps and feedback sensors - lots of them put out application books and white papers on how to use their stuff- and its all based on PID control loops.

TedP 30-03-2004 03:44

Re: PID control loops - closed loop feedback
 
Because this thread is so long, I haven't had a chance to read it all, but I see some common themes coming up... some people fighting for using PID... some people fighting to understand the math behind it... some people just looking for examples. I do a great deal of linear and non-linear control applications when I'm not doing FIRST, so I was thrilled this year to have some time to help the team build in some simple feedback controls systems to control not only our drive train but a two-jointed articulated arm.

And so I want to comment on a few things... But first, as a reference, if you would like some examples of PID (actually PIID, notice the second I) feedback loops as well as some other important modifications, take a look at our code for this year's Pittsburgh regional:

http://www.osufirst.org/twiki/bin/vi...04RegionalCode

To give some background, the robot is driven by one joystick out of the box, a number of buttons and switches, and a mock-up of our actual two-jointed arm. This mock-up has potentiometers built into each joint just like our big arm. Our big arm tracks the position of the small arm. Additionally, our drive train wheels have Banner sensors encoding every 36 degrees of their rotations into "ticks" that can be handled by interrupt handlers tied to digital inputs 1 and 2. If we had our ticks spaced correctly, we could run the Banner "normally closed" input into two more digital inputs to get double the resolution. There are some other software tricks to increase resolution, but they need speed first... and we need speed first anyway...


Use Speed Control for Actual Motor Control Whenever Possible

So my first comment is on speed control. Because motors inherently output speed and not position, even though you have position sensors (effectively), it's much easier to control speed. However, it's not trivial to calculate speed on such a robot with all of these quantization issues. For example, it's tempting to calculate speed by counting the number of ticks that pass by your encoder in a particular time. If you have lots and lots of ticks and are not sampling that fast, this works fine. However, if you're sampling fast with respect to the tick changes and you don't have that much resolution so the ticks take a long time to get noticed, you need a new way to calculate speed.


How to Calculate Speed in Software Quickly

On our robot, we have a clock running that keeps track of the number of 100ths of a second (centiseconds) that have passed. This is an "elapsedTime" variable. This is setup using interrupts, as is explained on IFI as well as many places here. Now, the interesting part is that our interrupt handler that catches the tick transitions of each wheel doesn't just increment a counter; it also calculates the time difference between the current tick and the last tick and also stores the current time. This time difference allows for the current speed to be easily calculated (in our code, in inches per second), except the problem is that if the robot stops turning, it will never register that we've slowed down to 0. So in our fast code, we calculate the difference between the current time and the previous tick time, and if that grows too large for our slowest speed (slowest speed is found by ramping up input until the robot moves and recording that speed), then we assume we've stopped.


Calculate Acceleration Too: This is Important Later

At each tick, calculate a new acceleration based on the change in speed over the time it took to move from tick to tick. This is much simpler than the speed calculation, but you should do it here rather than anywhere else so that it stays constant from tick to tick. Again, you should have some way of bringing the acceleration to 0 if the robot is stopped.


Use Constant Time Sampling

It doesn't always pay to do things as fast as you can. In these applications, sampling your actual data at 100 times a second is probably enough. So even though you are calculating speed very quickly from those interrupt handlers, actually create "speed samples" that will be known to be constant over the whole sample. This will become more important later when implementing the PID controller.


System Identification: Keep It Linear!

While a great deal in engineering is random, unknown, and often unsolvable, nothing in engineering is black magic. Once you can capture speed being outputted each 100th of a second to the program port, it is easy to characterize your system (or a linear approximation of it). This can be done by software encoding an input which sits at 0 for a small time and then immediately jumps up to some value (otherwise known as a "step" input). The input speed from the wheel turning due to such an input can actually give you the PID coefficients almost directly. (REMEMBER TO USE CONSTANT TIME SAMPLING!!) If you are not familiar with this compensation process or have no one around you who is familiar with root locus and/or Ziegler-Nichols methods, then you can bypass this section entirely.

However, if you do do system identification on your robot, be sure that your step is not too large!! Having your robot jump into a speed that is approaching its saturation point will unfortunately cause your response to characterize a particular point on a very non-linear side of the motor. If you want to approximate your motor as a simple second-order linear time-invariant system, you probably should do it in the region where the change in output over change in input is still fairly constant.

Note that in the 1014 code, we actually took a step and implemented it, but unfortunately our drive train changed substantially after the step was taken and we weren't able to use our optimized coefficients in time for competition. We resulted to setting these coefficients heuristically, and things worked very well during competition.


Before Implementing: Condition Inputs and Outputs

Create functions that will take in a value from -128 to 127 and output a PWM signal that has had a dead-zone applied (and possibly a hold-over zone) that goes from 0 to 255. Keeping your code in terms of -128 to 127 will simplify things GREATLY. This makes things all "linear" rather than "affine."


The Basic PID Controller

PID is simple to implement. The basic pseudocode goes something like this. Keep in mind the last note about conditioning inputs and outputs to be centered around 0. Also remember that both actual_seed and actual_accel are available as they have been calculated already. NOTICE THE USE OF Ts. This is the time between samples. If you sample 100 times a second, this is thus 0.01. THIS IS VERY IMPORTANT. It will help make your Ki gains much more reasonable. It is needed to approximate an integrator. It is the "width" of each rectangle that is being integrated.

error = desired_speed - actual_seed;
output = Kp * error + Ki * Ts * sum_error + Kd * actual_accel;
sum_error += error; // Don't actually do this!!! SEE NEXT NOTE!!!

The goal is then to set the Kp, Ki, and Kd coefficients properly. If you have identified your system, this is easy to do. If you have not, keep this in mind, and BE CAREFUL as you can EASILY CREATE OSCILLATIONS:

Kp: Proportional Gain - Sets the shape of the output to generally match the input

Ki: Creates a lag in the output that helps smooth transitions. This also causes overshoot due to this lag. However, a great thing it does is that it gaurantees no steady-state error. After some sufficiently long period of time, if enough of this term is added in, the output will match the input exactly.

Kd: Speeds up the response. This reduces the lag caused by the Ki control. However, not only does it couple in lots of noise into the system, but it can actually cause steady-state error problems (because derivatives of constants are 0).


Dealing with Integer Overflow: SATURATE

If that sum_error term just keeps getting added to over and over again, it will very quickly overflow. This will turn a VERY LARGE POSITIVE NUMBER quickly into a VERY LARGE NEGATIVE NUMBER. Integral control can on its own cause nasty oscillations just due to its delay/lag. However, adding this fun roll-over effect creates even worse ones.

To fix this, wrap something around the addition that prevents it from ever rolling over. Something like:

sum_error = safe_add( sum_error, error );

Where safe_add makes sure that if a positive is added to a positive, a positive comes out, and if a negative is added to a negative, a negative comes out.

You can see our PIID code in user_routines_fast.c. There is an additional integrator to allow us the freedom to tune our second order (ramp) input response. There are reasons for this additional I, but I am placing them outside the scope of this message. This controller does show all of the points above, including some more.


Be Careful: Literals are BYTES by Default

In this process, if you use ANY literals, be sure you explicitly cast them as, for example, int if they are negative or over 127. Otherwise your 255 looks like a -1 to the PIC.

In general, be careful about your signed/unsigned conversions. Things may not be as you think they seem.


Use State Machines in Autonomous Mode Once Good Controllers are Built

Once good speed and position controllers are built (position controllers can be built on top of speed controllers), use state machines to move from one state (motors driving forward) to another state (motors turning robot left) to another state (motors driving forward again) to...... The only time you should have to look at your feedback in autonomous mode is thus when to CHANGE STATES. Otherwise, you let the speed controller do all the hard work for you.

See the 1014 code for an example of this.

Additionally, it is possible to build "steering controllers" that are PID based in themselves. These can take angles and forward velocities and turn them into left and right motor CONTROLS which then get fed into the left and right motor PID controllers which then turn them into motor commands.


Some Simple Benefits (and Cons) of Feedback Control

Being able to count on a controller to deliver a very simple task is so important. This allows the driver to simply "suggest" a speed with his or her joystick and the robot will handle all the rest. The driver can then get up the step at a slow speed, for example. Rather than running straight into the step, the driver holds the joystick constant and the feedback controller figures out how to get up the step to maintain its own speed.

Additionally, for that same reason, a real feedback controller actually makes the torque-speed curve of a motor almost entirely horizontal (within a certain range). This actually can be dangerous because the robot will perform CONSISTENTLY under ANY BATTERY POWER and it may be easy to forget to monitor it's battery life.

Plus, these controllers are extremely robust. People spend hours dealing with open-loop filters on joystick inputs and often come up with odd non-linear controllers which have no easy way to optimize. The linear feedback control system uses the motors own natural low-pass effects to smooth out its own input. The linear feedback control system needs very little tweaking to be operational, and will do its hardest to perform as close to optimally as possible even on a low battery or when facing an odd load.

However, there is a much stronger dependence on hardware. There is a tremendous increase in complexity. There simply are costs for all the things that the feedback gains you.


Anyway, I hope that code might help some people. I'm afraid my post might be too long to help pepole directly, but hopefully some will read it. The system works great on our robot; I hope it can help yours.

10intheCrunch 30-03-2004 10:40

Re: PID control loops - closed loop feedback
 
Wow, great post!

A few questions, though: first, how high a resolution encoder are you using? You spoke about sampling at 100hz, which is *much* higher than our sample rate (5 and 10hz)--we found that anything higher didn't allow for much change at all during one tick and as a result operated inproperly. We use a potentiometer on the motor with 1024 ticks on it (10 turns), using about 900 in the actual arm scope.

Two, just as general practice, make sure to use 254 instead of 255 (and -127 instead of -128, or you're adding too much); you can get into trouble with the speed controllers with 255.

Three, what circumstances are you dealing with integer overflow? We've never had anything close to that high an integral, much less wanted it (it would cause the motor to swing all the way over and jam the arm into the robot...). Perhaps we have radically different output systems, but our integral never really gets higher than 30-50 (and that can be dangerous).

Hey but thanks for this! Now I gotta sit down and try to understand the part about linearizing it... :ahh:

KenWittlief 30-03-2004 10:58

Re: PID control loops - closed loop feedback
 
Great post by TedP - only thing I would add is the motor speed is not the only way to go

for our auton mode we were more concerned with robot heading, so using a yaw rate sensor was the easiest solution - for most driving situtaions getting the robot pointed in the right direction is the trick, how fast it move (preciesly) is of less concern

you can calculate how fast your bot is turning by having speed sensors on both wheels, but its much simpler to plant a yaw rate sensor on your frame somewhere and read it directly.

BTW - if anyone is wondering if this stuff is worth the trouble- yes! our auton mode worked very well when our team coach remembered which 'left' to set the switch to (left or the other left)

and at Buckeye our team won the Johnson & Johnson quality in controls award - I think not so much because of the PID closed loop feedback we had on our steering, arm elevation and arm extension, and the use of IR sensors - but because our students could explain so well to the judges how it all works.

sophestication is good - understanding is excellent :^)

Larry Barello 30-03-2004 11:09

Re: PID control loops - closed loop feedback
 
1 Attachment(s)
I am very cuious, why do you use the double integration? What was the issue with leaving it out?

For team #492, we only used PI for our velocity control and PD for our arm had excellent results. Attached is our servo code. It is considerably different from the typical examples and I will be publishing (sometime) a white paper on the subject out at http://www.titanrobotics.net on the subject. Highlights:

1. we modeled the drive motors and compensated for the back-EMF with some posative velocity driven feedback. By moving this large, known error, outside of the control loop, we were able to remove most of the integral term and vastly improve the stability of the system while keeping tight control.

When properly implemented, back-EMF compensation (when in "torque" control mode) makes the robot feels "frictionless". Very cool to be able to push the robot and have it glide across the floor... In fact, that is how I tuned it: pushed the robot back and forth and adjusted the kemf values (left, right, forward, reverse) until the robot glided without speeding up or slowing down, in a straight line. This has obvious control implications: speed errors generate a torque command, when up to speed, the torque command goes to zero (no integral term needed!) yet the robot continues to zoom along.

2. We used gain scheduling on our arm. Actually, all we did was divide the K term by 16 when overhead because of the drive slop and lack of gravity keeping things taut. Still, gain scheduling sounds cooler :)

3. We also limited the maximum torque (current) to our motors. Rather than using the FIRST supplied current sensors (which would have been the precise way to do this) we used the back-EMF technique. Anyway, by limiting the maximum torque we avoided all issues of overheating our motors and popping circuit breakers. With a dual motor, simple gearbox (no shifting) design we still had plenty of power to push goals and robots around :D

Larry Barello 30-03-2004 11:19

Re: PID control loops - closed loop feedback
 
Quote:

Originally Posted by 10intheCrunch
...
Three, what circumstances are you dealing with integer overflow? We've never had anything close to that high an integral, much less wanted it (it would cause the motor to swing all the way over and jam the arm into the robot...). Perhaps we have radically different output systems, but our integral never really gets higher than 30-50 (and that can be dangerous).

Typically, if you are running near the edge of your control abilities (pushing your hardware to the limits, which I am *always* doing), when the output saturates (e.g. ->254 in IFI systems) and you have not made your setpoint (velocity or position) the error term grows without bounds. The solution is simple: stop accumulating errors if the output saturates.

In the code I posted (above), we have a torque limit and stop accumulating the integral error when that has been hit.

Cheers!

TedP 30-03-2004 14:18

Re: PID control loops - closed loop feedback
 
Quote:

Originally Posted by 10intheCrunch
A few questions, though: first, how high a resolution encoder are you using? You spoke about sampling at 100hz, which is *much* higher than our sample rate (5 and 10hz)--we found that anything higher didn't allow for much change at all during one tick and as a result operated inproperly. We use a potentiometer on the motor with 1024 ticks on it (10 turns), using about 900 in the actual arm scope.

Re-read some of the notes I made. We don't calculate speed the same way you do. Rather than looking for the amount of ticks that go by every sample, we look at the amount of time that goes by evey tick. This is much more asynchronous and updates the speed whenever it CAN rather than whenever I want it. (and we had to add something to force the speed to go to 0, but that was a simple fix -- all of this is documented in my note and is in the code)

To answer your question directly, we only had TEN ticks per revolution on our drive wheels (unfortunately that was about 4 to 5 inches per tick) and our maximum velocity for this robot wasn't any higher than around 50 inches per second. So we were ticking very very slowly... But we didn't calculate speed every sampling period, we calculated it every tick by recording time rather than recording ticks.

Quote:

Originally Posted by 10intheCrunch
Two, just as general practice, make sure to use 254 instead of 255 (and -127 instead of -128, or you're adding too much); you can get into trouble with the speed controllers with 255.

Every year I always hear that... but I never pay attention to it... and I'm always too lazy to see the reason why. I figured that 255 was some special mode that the speed controllers got in... perhaps an OFF mode or something... and I THOUGHT one year I found out why there was so much commotion about it and that particular year they removed the reason for that commotion... but I don't remember. Anyway, I've never had a problem going full scale... but that's definitely something that could easiliy be fixed.

Quote:

Originally Posted by 10intheCrunch
Three, what circumstances are you dealing with integer overflow? We've never had anything close to that high an integral, much less wanted it (it would cause the motor to swing all the way over and jam the arm into the robot...). Perhaps we have radically different output systems, but our integral never really gets higher than 30-50 (and that can be dangerous).

There are lots of reasons why you would have large integral, though they don't necessarily apply to everyone's robots.

For one, an uncompensated steady state output may simply have an output offset. As you sit "still" you'll sit there and churn integral error. The integrator is what brings you back to 0.

The otherwise, in very slow moving systems, the error adds up VERY quickly since it takes you so long to get to your set point. In other words, IF YOUR SYSTEM ALREADY HAS LOTS OF LAG, then your integral term, which is supposed to ADD LAG, will explode.

Of course, we saturate when we get too high. This protection is built into the code. It's a standard technique.

Additionally, the reason you may not see much of that integral term is because you may multiply by your sampling time period immediately during the sum. We sum without that factor (0.01) and then multiply the whole sum later.

And regardless, this is hardly dangerous. If the integral term gets large, that's fine. Just make sure your integral coefficient is set moderately correctly.


Quote:

Originally Posted by 10intheCrunch
Hey but thanks for this! Now I gotta sit down and try to understand the part about linearizing it... :ahh:

PID with constant coefficients already IS a linear controller. However, many of our systems are highly non-linear and not necessarily time-invariant. PID controllers have the strength to control such systems in many cases. It's important to understand the cases when this is not the case, but in most of FIRST's cases, a simple PID controller will work fine.

To understand where the non-linearities come from, I'll give two examples. The drive train moves from stopped to moderately slow in appoximately a straight line. That is, a little change in input causes a change in output proportional to that change in input, and that proportion doesn't change as long as you're moving moderately slow. Note that there is a jump from 0 to some velocity that is a non-linear jump, but I'm assuming we're over that hump.

But eventually those motors have to saturate. Eventually they can't drive your robot any faster. This may happen when your joystick is only halfway through its travel. Even though your joystick can increase the signal going out to the motor, the motor simply cannot turn any faster. This is probably going to an extreme, but the point is that even a large change in input won't necessarily cause a large change in output. I know I see this with our robot as it easily moves from 0 to 45 inches per second and then creeps up toward 50 or 55 inches per second at a much slower rate.

This sort of non-linearity causes all sorts of problems. However, without getting into them, the biggest issue is that your robot USUALLY is in the linear range. Your compensator should be built for the slower range where changes in input ACTUALLY CAUSE changes in output. If you build a compensator EXPECTING a very STUBBORN motor, then it will be FAR TOO HARSH during the rest of the motor's travel. It's better for the compensator to be gentle than harsh.

The other non-linearity, a much more interesting one, involves our two-jointed articulated arm. Assuming the shoulder is holding the arm straight up into the air, the elbow joint may be moving the arm with gravity or against gravity depending on its direction AND its position. As it crosses vertical, the role of gravity will switch. In fact, as it moves toward vertical, the role of gravity drastically changes. Additionally, as weight is added onto the end of the arm when it picks up a ball, things change quite a bit.

On top of this, the shoulder's position greatly affects how gravity will affect the elbow. If the shoulder is near horiztonal, we expect different gravity effects at the elbow based on its position. So in short, now position is a major variable in the control.

However, things get more complicated when you consider shoulder movement. The shoulder has a gravity component too, but its own center of gravity changes depending on the elbow position, and that changes how fast it can move along with all the problems associated with the elbow joint. So now the elbow joint's dynamics are coupled to both its position and the shoulder's position and the SHOULDER'S DYNAMICS, and the shoulder's dynamics are coupled to the elbow's position, the shoulder's position, and the elbow's dynamics (is the elbow moving or not? and where is the elbow while it's moving?). This is a much more complicated system, and traditional approaches to the two-jointed arm problem involve forms of gravitational linearizing and other methods.

However, our arm was so slow and had such a major gear reduction from motor to output joint (1250 reduction on the shoulder), we were able to use the simple PID controller on both joints fairly well.

BUT... we did add an integral term to both joints. We didn't want to slow things down, but we wanted to make sure that as the robot sat idle, it would correct any offset errors which were produced during its movement.

The topic of linear time-invariant systems is worth a whole career. The top of linear controllers fits into there. However, non-linear systems is an entirely different topic, and often does not benefit at all from linear system theory. Lukcilly, most FIRST systems are simple enough to not require such sophistication.

And, of course, the thing that won our Engineering Inspiration Award in Pittsburgh was less of the technical stuff we did here, but more of the ability of our students to use it to aid in their understanding of engineering. When our STUDENTS said that we had no error because the integral term compensated for it, the judges really appreciated that. When our students explained that a system can be characterized by its ideal PID coefficients and thus the PID coefficients need to be traded off from one to the other to find the right equilibirum, that's what impressed the judges. How well we did enforced that, and that we were able to help other teams with similar mechanical systems but very different controls surely helped... but I hope it's what the students portrayed that got us recognized.

Larry Barello 30-03-2004 15:25

Re: PID control loops - closed loop feedback
 
Quote:

Originally Posted by TedP
...

Every year I always hear that... but I never pay attention to it... and I'm always too lazy to see the reason why. I figured that 255 was some special mode that the speed controllers got in... perhaps an OFF mode or something... and I THOUGHT one year I found out why there was so much commotion about it and that particular year they removed the reason for that commotion... but I don't remember. Anyway, I've never had a problem going full scale... but that's definitely something that could easiliy be fixed.

The 255 issue is a holdover from the old PBasic days. The packet sent between the the user processor and the control processor used two "255" in a row to delimit the end of a packet. If you sent out a bunch of 255 as PWM values the packet would be truncated. This happened to us in 2001: at stick extremes the two PWMs went to 255 and got the packets out of synch and all heck broke loose.

The current system still uses the 2x255 but hides it from you by "adjusting" 255 to 254 before sending it to the control processor. We discovered this when trying to send telemetry data back. We were using some of the unused PWM slots for the dashport, so we could get data back each cycle. Well, no such luck. So we limited the data to 7 bits and used two slots to pass 14 bits of data back. (it was gyro angle in .1 deg so it needed to be an int).

Now that IFI has given us a real processor, it is time to give a real radio without these limitations.

Salik Syed 23-04-2004 23:16

Re: PID control loops - closed loop feedback
 
I am planning to use PID on the arm for our end of year mini-game bot
(we make a mini game w/ the robotic class (sadly only 7 students one being a moderator) split into 2 teams w/ a 2X2X3'
80 lbs robot its really cool)
any ways for ours (i'm not sure if this will work)
I will basically just put a gyro on the arm and
compare the "wanted speed" to the real speed and
then just add a bit to the PWM (dependent on how close real is to wanted)
to calibrate it just move the gyro away from or closer to the joint!
to get the real speed i'm just going to multiply the accel*time/looptime + previous...that
should probly give me speed..
Will this work? Also i'm using the PBasic controller so i'll have to learn that a bit...
do i have to keep loop time constant or not...does it really matter that mucH?
This part really bugs me out because i read about everyone keeping loop times constant and
what not but on the Edubot controller I just wrote the code...heck to loop time and
everything worked (for our little autonomous gyro guidance thing)
IF it does matter a LOT
i might take a educontroller and connect it to the maincontroller so it can receive
gyro inputs and then simply output the amount to add to the PWM through dig_out which
plugs into dig in on the RC

Also can someone explain why it matters so much (in reality ) do the loop times really
vary by so much that it would greatly affect operation (i imagine if it loops so quickly
it wouldn't matter...the differences would be averaged out to a menial number??)

Thanks!

KenWittlief 23-04-2004 23:27

Re: PID control loops - closed loop feedback
 
if you are matching rotational speed then the amount of time the loop takes doenst matter

its when you are integrating it to get angles that the loop time alters the output - and even that averages out if the loop is not the same every time

I wouldnt worry about the loop speed - PID loops always have some trial and error testing to get the constants right

sounds like fun.

Salik Syed 24-04-2004 23:52

Re: PID control loops - closed loop feedback
 
Also...this is kind of a side question...if i integrate twice...wouldn't i get a 0-254 value? (from the gyro) ...that is Total V? ....i guess it wouldn't be so hard to convert to an angle given that its 150 deg/sec...but i don't really trust that so I'm thinking i'll not convert to degrees (useless anyways)...
just wondeing...

KenWittlief 25-04-2004 12:24

Re: PID control loops - closed loop feedback
 
Im not sure what you mean by integrating the sensor twice?

the output of a yaw rate sensor is degrees/second

when you integrate its somewhat like multipling by seconds, so you end up with degrees (in units that do not directly read out in degrees, you would need a constant added in if you want actually degrees, or radians, or whatever standard unit you want

but if you integrate that again? Im not sure what that gives you? degreeSeconds?!

I dont know what that would be measuring?

Salik Syed 25-04-2004 17:59

Re: PID control loops - closed loop feedback
 
degree seconds? i thought it would give the degree angle of the arm ...like a potentiometer... (degree/seconds * seconds = degrees ) right?



btw this is the actual code it hasn't been compiled or tested yet just theory...just notepad:
Code:

p2_y=armin;
targetv=armin;  //just temporary...

//////get gyro input conv to 8bit

(int)gyroin10bit=Get_Analog_Value(rc_anlg_in01);
gyroval=gyroin10bit/4;

////convert gyro values to usable values....
armaccel=gyroval-127;


///integrate
realv=(armaccel+realv)/time;
time++;
//////////////



if((hicutoff+targetv)>realv>(locutoff+targetv))
        {
        armout=(targetv-realv)/proportion;
        }
pwm03=pwm03+armout;

One more thing... What is this about integral and derivative.... I get the proportional part (basically multiplying by how much change the input produces.."Gain" )
but why integrate the error....i don't get this and how it works ? i read some stuff about how it is an automatic reset which doesn't quite make sense to me...... Also can someone explain the derivative...part... :)

Salik Syed 25-04-2004 18:16

Re: PID control loops - closed loop feedback
 
OKay...nevermind...i figured out what it does......now for the derivative ....the longer an error has stayed the more it adds... :cool:

KenWittlief 25-04-2004 18:22

Re: PID control loops - closed loop feedback
 
I think I understand your statements now.

when you intergrate the sensor output you are changing the 'signal' from degrees/second to degrees

so now you can create an error signal by subtracting that from what the operator is commanding (desired angle)

and do a PID feedback with intergral, proprotional and deriviative (or differentail) components

so you would not really be intergating the sensor single twice - you would be integrating it once to get the angle

then if you wanted tight feedback you could integrate the error signal over time.

Salik Syed 25-04-2004 20:40

Re: PID control loops - closed loop feedback
 
yeah...i know i'm not gonna integrate twice...just once..(see code) but i was just wondering...
I've tweaked the code to include an integral term, now i'm wondering how to do the derivative...its hard because i'm trying to read ahead in the textbook...(we haven't learned derivitves yet!) ..... and then apply it to this....all the articles I find on PID are a bit too complex...
btw... we also did the whole tape interpolation thing for autonomous..we didn't use it because we didn't need the precision, we used a gyro to track heading, then tape for distance, we didn't have a legal gyro at times so i also implemented a timer that would measure time between the tape being seen and calculate dist to a much finer degree then 1/6 wheel circumfrence...alot like what u did...

KenWittlief 26-04-2004 09:06

Re: PID control loops - closed loop feedback
 
derivative is easy. its the delta or change since the last loop

create a new variable to keep track of the 'last_error' signal - then compair the current error signal to the last one - thats the derivate - you are interested in how fast the error signal is changing

which can be due to the driver making a sudden change, or the bot moving suddenly.

Salik Syed 26-04-2004 11:01

Re: PID control loops - closed loop feedback
 
okay....i get it now
Thanks!

Salik Syed 26-04-2004 21:05

Re: PID control loops - closed loop feedback
 
Heres our PID code so far...the constants u multiply by really have to be tweaked once the actual robot is built :D! ... P+I+D should not be over 127 or under -127...so i'll have to definitely calibrate it A LOT
IF( any one spots obvious mistakes ...(not like syntax error type mistakes) ){please tell me...}

Code:

////get joystick input///////////////
p2_y=armin;
targetv=armin;  //just temporary...

//////get gyro input conv to 8bit

(int)gyroin10bit=Get_Analog_Value(rc_anlg_in01);
gyroval=gyroin10bit/4;

////convert gyro values to usable values....
armaccel=gyroval-127;


///integrate
realv=(armaccel+realv)/time;

//////////////


//////////Calculate the proportional.....
if((hicutoff+targetv)>realv>(locutoff+targetv))
        {
        armout=(targetv-realv)*proportion; /// as the real gets closer to target pwm addition is lowered...
/// this is basically "Gain"
        }

/////////////calculate the integral of the error....
error=realv-targetv;
errorint=(error+errorint/time)*intprop;

/////calculate  the derivative of the error;
derivative=(lasterror-error)*devprop;


///////////////////Output;////////////////////

if(tripped!=1)
{
pwm03=armout+errorint+derivative+127;
}

///////update time
time++;

////update error
lasterror=error;


////motor heating control....
///basically take current sensor values and make sure not too much
//is being drawn or else it will let down on the motors


(int)current=(Get_Analog_Value(rc_anlg_in02))/4;
///+127 = 100 amps...... so + or - 50 = 40 AMPS!!! I set it to "trip" at 27 amps
/// since we have 30 amps breakers ... so that you don't trip the actual breaker.!
//// divide current by .79 to get anlgreading-127~!  so 100/.79+127=254!

if(current>161 || <93)
{
pwm03=p2_y;
tripped=1;
}

I also added some code in to ensure that if we have a large weight on the arm at a not so great angle the motors won't over heat and trip the breaker....
Am I doing the Proportional correctly? It says Gain= Input / Ouput ... but in stead i just compare the target to the actual...thats not exactly the same but should give me the result i'm looking for (to lower speed when target is closer to actual)?? Correct me if i'm wrong please....

Max Lobovsky 26-04-2004 21:27

Re: PID control loops - closed loop feedback
 
Quote:

Originally Posted by TedP
Some Simple Benefits (and Cons) of Feedback Control

Being able to count on a controller to deliver a very simple task is so important. This allows the driver to simply "suggest" a speed with his or her joystick and the robot will handle all the rest. The driver can then get up the step at a slow speed, for example. Rather than running straight into the step, the driver holds the joystick constant and the feedback controller figures out how to get up the step to maintain its own speed.

Additionally, for that same reason, a real feedback controller actually makes the torque-speed curve of a motor almost entirely horizontal (within a certain range). This actually can be dangerous because the robot will perform CONSISTENTLY under ANY BATTERY POWER and it may be easy to forget to monitor it's battery life.

Plus, these controllers are extremely robust. People spend hours dealing with open-loop filters on joystick inputs and often come up with odd non-linear controllers which have no easy way to optimize. The linear feedback control system uses the motors own natural low-pass effects to smooth out its own input. The linear feedback control system needs very little tweaking to be operational, and will do its hardest to perform as close to optimally as possible even on a low battery or when facing an odd load.

However, there is a much stronger dependence on hardware. There is a tremendous increase in complexity. There simply are costs for all the things that the feedback gains you.


Anyway, I hope that code might help some people. I'm afraid my post might be too long to help pepole directly, but hopefully some will read it. The system works great on our robot; I hope it can help yours.

TedP, let me start by saying that was an excellent post that explained several things i wasn't clear about. I know that you said for most applications in FIRST, a simple linear PID loop does the trick, but i have a drive system application in which i need an accurate velocity needs to be reached pretty quickly (much quicker than a simple skid steer design requires) and also needs to be accurate and fast for a pretty wide range of velocities. Maybe the best way would be to use some more complex non linear feedback loop, but i thought that maybe a simpler solution would be to use both an open loop (a calibration curve) and a linear feedback loop. We are starting this project now, so time to tweak all the coefficients and the calibration curve is not a major consideration. Is there any reason against doing something like this, or were you just saying that, in general, a linear PID feedback loop should do the trick, and that open-loop systems take too much time?


All times are GMT -5. The time now is 14:04.

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