PID Tuning Help

We have a 4 CIM drive train, two per side. Each side has a center drive wheel and omne wheels at the front and back. We have a two-speed west coast drive that we’ll be running in low gear for autonomous.

Can anyone suggest some nominal P, I, D (and F?) values as a starting point? We tried a bunch of different values last night before bagging, but didn’t really get anywhere. We got the robot to move, but we couldn’t get a sustained oscillation. If P was too big, the drive train would react quickly on an overshoot. The result was that it sounded like the drive train was vibrating. We were worried we might damage the drive train by reversing direction so harshly so quickly. If we lowered P, then it reacted too slowly.

We’re using CanTalons in kposition. Each side has one Talon with an encoder fed directly to it. The second Talon on each side is just a follower. So each side is running an independent PID loop.

Would we be better off using kspeed? If I use kspeed, how can I determine when I’ve driven the right distance? Can I still read the encoder ticks from the Talon or will it only give me ticks/second? I suppose I can integrate the encoder ticks per second to get distance, but I’m not sure this will be accurate enough.

Any suggestions?

*What gear ratio, what wheel diameter, what model encoders are you using, where are they mounted, and what units are you using for your position command.

I’ll leave others to suggest good coefficients, as I’m sure others will have worked with a setup similar to yours. I will offer that speed is what you want for interactive control, and position may be what you want for autonomous. As you suggested, you can integrate speed to get position, and that should work OK, and may actually be superior if you do it correctly.

The advantage of using speed and integrating, is that you can control the ramp speeds of the drive, leading to less wheel slippage. If you just use position and just set the final position that you want, you may lose traction, if the maximum ramp rate is not set low enough. If you clamp the ramp, it may take much longer than you want to reach the end position.

A few years ago, there was a post somewhere here that discussed a motion profile filter, similar to ones used in Fanuc CNC controls. An example was given in the form af an Excel spreadsheet. Essentially, the filter would calculate position, velocity, and acceleration for going from one value to another, given a maximum velocity and acceleration and deceleration constants. I believe it was posted by one of the Capioli brothers, although memory fails me as to which one.

Anyway, the filter precalculates position, and required velocities, so you actually don’t have to integrate the speed. Our team implemented this filter in LabView, and then heavily modified it to deal with real world cases that use negative values and non-zero starting positions. It works well.

Edit: Found the thread!

You might get acceptable response by setting a P gain large enough to get things moving, but also setting an output rate limit to keep the acceleration from being too high. Or you might try seeing what happens if you just use the I term.

You can always read the raw encoder value.

There are many many PID tuning methods… for a drive train autonomous and you don’t want any overshoot and lower the amount of oscillation try this…

  1. leave I and D at 0. bump P up until it starts to oscillate.
  2. lower P to half of that value.
  3. slowly bump I up until the desired time to target is good for you even if it begins to become unstable.
  4. backoff I by a quarter of that value - ensure system is stable and not oscillating.
  5. if necessary, D can be adjusted up slightly to eliminate any further overshoot. Too much D and the system will become unstable again.

Will your setpoint be changing or do you only have one setpoint ? Tuning with load disturbance (especially constant load disturbance) is different.

Be careful - you can’t really compare apples to apples. For example, our P value would be terrible for you if your source units were not the same as ours.

We’ve just finished a bunch of PID tuning, and we think we learned a few things. We’re still neophites, so I’d listen for other advice as well.

First, with the drive train, we don’t think you want genuine oscillation. With a heavy robot and friction, what you want to shoot for instead, we think, is having the robot go past the set point, and come back, maybe once, maybe twice.

Second, your initial P value should make sense, at least to within a factor of 10. The P term is incredibly simple, so if it doesn’t make sense, it’s likely to be wrong by orders of magnitude, and nothing you do will make sense.

Our method is to pick a distance where we think the motor should be driving at full speed and then do a simple calculation of expected motor output divided by PID input.

So for example, our PID Source is coded to provide inches. Our robot is heavy, so we didn’t want to use full power; so we were clamping our PID output to a max 0.4 (although we raised this clamp later). So then if we think that we should use full power when there is 24 inches to go, then a good starting P would be 0.4/24 or about 0.016. That calculation is usually conservative; we ended up with a P of 0.06. But it got us within a factor of 10, which helped. (And it’s easy to think about: if there is 24 inches to go, 48 *0.016 == 0.4, so the motor should be set to 0.4 at that distance).

That does imply you have to fully and completely understand your PID input units and your PID output units.

Then, finally, one thing that actually answers your question: we came to a very nice PID of 0.06, 0, 0.30 that worked really well for us driving our heavy robot with a stock drive train with omnis on the front. We did raise the clamp to 0.6 first. If we had more time, it might have been fun to see if we could have gotten something using 0.8 or 1.0, but we ran out of time.

Again, because of units, don’t take away any of our numbers. You could perhaps take away a P = (your max output) / 10, D = 5xP.



^^quoted for truth

Our method is to pick a distance where we think the motor should be driving at full speed and then do a simple calculation of expected motor output divided by PID input.

Thus these questions:

If you want any more specific advice, you’re going to have to answer Ether’s questions.There are too many other variables for us to assume to provide good assistance without more information.

To provide some more background, this method…

Is a slightly modified Ziegler-Nichols method of tuning, and it’s one of the simplest and a good place to start, usually (although not always optimal).

In my own experience, I’ve found that closed loop drivetrain control ([edit]this works for both speed or position control[/edit]) is usually best as a just a P or PI controller. The gearboxes used often provide enough natural dampening to make a D term not needed. Depending on how fine control you need (and how fine control your hardware allows you), you may just be fine with a simple P controller (no external functions needed, just simple math).](

If you find that you’re constantly stopping short or overshooting your setpoint, consider adding in a small I term to counteract that.

That’s pretty much how we calibrated our 5 PID subsystems on our bot this year

For completeness: if it’s oscillating or not stable, then what.

Again, for more completeness, where should you start? We mostly gave up on trying for PI controllers, because we found that even apparently small values of I led to instability. (The 1114 guide to PID tuning suggests PD; a bunch of smart people I know swear by PI. I have no real experience other than sitting with students trying this for a few nights in a row).

We successfully tuned one with I, but only when our I was several orders of magnitude less than the P term.

Is there a rule of thumb? Start with an I that is X of P, and then increase slowly?

As a side note, if you’re tuning I, one of the challenges you may face is that the smart dashboard allows a tiny number of significant digits. (Afair, the lowest we could go was 0.001). We ended up making a scaled pid output just to get around that problem.

And, again, any rule of thumb? As we were tuning PD, we tended to start D at the P value, or perhaps below, and then gradually increased from there.

Sorry for the lack of details. We’re using 6" wheels. The encoders are Grayhill 63r256 encoders mounted directly on the gearbox with a 1:1 gearing to the drive shaft. We’re using encoder ticks as the distance unit.

I don’t know the exact gear ratio off hand. My team is currently out sledding to celebrate B&T. Our speed is about 7 ft/sec in low gear which is what we plan to use in Auto.

We tried the Ziegler-Nichols method, but our oscillation was so fast, that Tu was really small resulting in a huge Ki (>500).

In most of the common usages on “PID” just to seek a single constant target, P is really good enough… Unless if you have targets that shift, constantly changing targets, or random/sudden disturbances (noise in the measurements, problems in the output, spikes/impulses in the error…), really for most of our uses here … just P is good…

Take the frisbee shooter from 2 years back as an example… the error would shift on the shooter, due to loading and unloading of the frisbee… you would have had to tune D a bit if you needed to keep the spikes in the error under control…

We have tried this tuning method (EDIT: Lambda Tunning for speed control) and it works well for our drive-base
you just need to capture the information in a log, graph it and do the calculations.

*It would be helpful if folks posting about their favorite PID tuning method would state whether they are using said method to tune for a speed or a position setpoint

Here’s what I’ve done for PID that seems to work very well for us.

We’ve used it for:
Velocity PID on flywheel shooter
Position PID on window motor for bridge stinger
Position PID on window motor for turret
Position PID on climber
Position PID on elevator

To avoid breaking things, I start with p = .00001, so nothing happens. I increase p by one order of magnitude until the thing starts moving. At this point, we make sure that the mechanism is heading in the right direction. Finally, we increase P until the steady state error is 3 to 5 times larger than our largest acceptable error. This value usually ends up being near half the P value that causes uncontrollable acceleration. At this point, we slowly increase I (start with .00001, increase by orders of magnitude until something happens, then by increasingly smaller amounts) until the mechanism reaches the setpoint, even if it oscillates on reaching the setpoint. Then, we increase D very slowly (start at .00001, increase by order of magnitudes).

If D ends up too large and causes oscillations, use more low pass filter on your sensor data (or use a moving average with more samples).

It could be runaway, though that seems unlikely after passing through the previous steps in this process.

The likelihood was not in question. The “ensure” part was open-ended.

The great thing about PI controllers is that they will drive your error to zero, and are relatively robust. Imagine trying to stay 100 feet behind another car using a P or PD controller to press the accelerator pedal. You will never reach a steady state – when you have zero error and zero acceleration you won’t be pressing on the accelerator! On top of that, real world signals are noisy - differentiating them makes them even noisier, and filtering slows them down. This doesn’t make them unworkable – just not always desirable.

I stay on the mechanical side of FIRST robots, so I am somewhat clueless as to the implementation in the default code. What are the units on the integrated error? Is it errorframe or errorsecond? error*frame would be a much larger value, and explain why you need such a small value for Ki.

The answer is often integrator management. This means, when the integrator is not helpful, you turn it off. The great thing about integrators is that they will do everything in their power to satisfy the command. The bad thing about integrators is that they will do everything in their power to satisfy the command. A step command of the full length of the field is going to wind up the integrator. Your robot can’t satisfy the command of being 54 feet away in .1 second. One way to avoid this is to not command 54 feet in .1 second, instead ramp it in over several seconds. See this post by Ether. Another way to is to shut off the integrator for most of the travel – just start counting when you are close to the final value to make sure you achieve the commanded position. Or you limit the integrator’s authority to some fraction of the maximum command.

I read “and not oscillating” in OP above as a clarification; in some contexts (acoustics, radio, etc), oscillating is considered stable. This is not one of those contexts.