Any expert PID tuners w/resolution advice?

In 2005 Kevin wrote the scripted automous mode along with some PID system for his motors in the kickoff. Ever since then, our team has been trying to close a PID around our drive system full time with encoders. But every year we struggle. We struggle because their mentor doesn’t understand the resolution issues that we might be having. That would be me…I buy off the shelf servo systems that have been proven and work no problems, and I know how to tune a PID, but when it comes to designing my own motor control system with the correct resolution required to close a PID loop around a custom motor application I struggle in a sense. So any help would be appreciated.

We want a fly by wire control system with the joysticks giving only input to the drive system and let the motor control software a closed loop PID and respond.

So most of you know the situation, but let’s start out with the basics.

Let’s suppose we have a DC motor controlled by a PWM controller. And we have a quadrature encoder with an A and B phase. The encoder however only has a resolution of 128 pulses per one revolution of the encoder shaft in relation to feedback available. Which isn’t that great compared to the thousands of pulses encoder off the shelf that I buy currently.

Almost one encoder pulse is three (2.8) degrees on the motor if coupled 1 to 1 with the motor shaft. If you introduce a gearbox, your really making a wide-open feedback issue. “sloppy”. That is if you mount your encoder somewhere else in your gear box other than the motor shaft.

Question one: Where’s the BEST place to put your encoders for a closed loop PID drive system? At the end of the motor shaft I would say. But maybe I am thinking wrong. The GrayHill encoders can’t take the RPM of the direct motor shaft, seems to me would be the best and highest resolution feedback to the motor which leads me to believe look for another encoder… Also turning that fast would cause some SERIOUS over time interrupts. Based on last year, we got somewhere around 755 interrupts per second, at full RPM of the motor shaft we would be killing the PIC cpu with interrupts, so that’s no good either…

Because the resolution is so low, and let’s say we want to control this motor for position, would it be very difficult to tune the PID? Or no matter what the parameters are in any control system, a PID should be able to be tuned? In other words, is there a point where your feedback system isn’t what it’s cracked up to be when trying to tune your PID? Or does it amount to response time? If your feedback hardware has a low resolution, then you have to trade off response time or what I call a sluggish PID loop? It will tune or settle, but it takes it longer to get there and can’t be as responsive?

Limited by the resolution, the worst part is that the derivative gain will be useless. The derivative gain is necessary if we want to move from over damp to critically damped tuning. This is important if we are doing position control. Actually, our PID for our drive system would most likely be velocity control not position based.

Any thoughts for those of you that have designed PID systems? Are their any of you that have a successfully fly-by-wire closed loop PID system around your transmissions that you use FULL TIME during telly mode and auto mode?

I can tell you that a loose system can make a huge headache. We used a closed PID loop to position our turret last year, and at first it was inaccurate and sloppy, then once we ended up rebuilding the turret, it was much much tighter and code that previously couldn’t work very well almost instantly started working, it just needed a final retune to be set. Moral? Slop will pose a significant problem for a PID loop and we couldn’t find a very effective software solution.


Team 1126 has been using a velocity controlled drive system for the past 2 years. In 2005 it was implemented both in autonomous and teleoperated mode. Last year, we still used it in autonomous mode, but reverted back to a more direct joystick to pwm mode during the operator controlled mode (with some joystick filtering). This post has some details about our physical setup. In our case, we’ve used a 4 speed transmission so the encoder needed to be placed on the output shaft of the transmission, since the robot velocity is dependant on the transmission gear as well as the motor speed. The velocity controlled drive system allows the robot to move in a much more controlled and repeatable manner mostly independent of mechanical differences between the drive systems during autonomous. The reason we did not use this feature during the teleoperated period in 2006 is that a more direct control of the drives seemed to give the drivers a little more control. Observing the drivers during a typical match you would generally see large movements of the joystick (either full forward or full reverse) for various amounts of time. Either they wanted to go a long distance quickly, or they were “bumping” the joysticks almost full stroke for a very short period of time for “minor” corrections. Either way, it seemed like they would be better served without the PID loop in the middle.

Our systems have been strictly PI, no derivative, and have worked well. If you have any specific questions, please ask.


My only comment at the moment is that if 755 interrupts per second is swamping your PIC, then you need to rewrite and tighten up your interrupt service routine. Kevin Watson’s basic encoder code can handle up to a few thousand interrupts per second. At any rate, you can figure for yourself the minimum resolution you’re likely to need. If you’re updating the PID in the 26.2ms loop, that’s around 38 Hz. If you pick an encoder that gives you at most 800 cps at full speed, then your code sees full speed as 21 counts. So you’d have 21 different forward speeds to command, and relatively large jumps in speed between them. This is especially problematic given that your joysticks can command around 100 different forward speeds. Solutions to this problem vary. I’ll assume you’re not looking to move to a co-processor solution so you need to:
A. Tighten up the interrupt code by tossing anything in it you don’t need and possibly declaring functions inline/moving the code straight into the ISR. This gives you more max counts per second in your code.
B. Reduce your loop rate. Updating the PID every other slow loop doubles your resolution, thought you lose on the update rate. However, these robots aren’t high performance marginally stable systems, so a 20Hz loop isn’t necessarily going to kill you.

I’d mostly stick with the A option first and see where that gets you, then try B if things still aren’t working out very well. Also, I’ll whip out my digital controls book tonight and remind myself what the quantization of an input does to a control loop…

I used a Proportional control with our 05 robot for driving by encoders. It works very well in balancing the drive train so the robot drives strait. I basically converted the joystick data to +/- 127 and then make that the RPM target for encoders.

Proportional is very easy to do. Output = Gain(Target - Actual);
The Joystick sets the Target value
Actual is the RPM
Gain can be used to adjust the output to scale to +/-127
Then add back in +127 and your golden

When the joystick is in the dead band and the robot comes to a stop I have it switch to robot switch to positional mode and it tries to maintain position.

Directly on the motor is the best way for really nice feedback control. If the counts get too fast, you can:

(a) reduce robot drive speed (which is a bad idea generally)
(b) get a lower resolution encoder
© get an Encoder Divider card from They let you divide the tick rate by 2, 4, 8, or 16, as well as decoding the signal into direction and count lines. Note that some soldering is required (directions are given)
(d) build an equivalent circuit as in c on your own

The first thing you should do is to make sure your ISRs are as lightweight as possible, in any event.

I should also say that for velocity control, I’ve never had a problem coupling to the wheel shaft or intermediately into the gearbox. The play in the system isn’t usually a huge deal - and you can write clever ways to get around it (i.e. allow for a certain deadband of acceptable values).

For position control, it’s much more important that you have a tight system.

Also, my $0.02 is that PID velocity control for a teleoperated robot is sometimes going to be overkill. Unless you are using an omni/mecanum drive where subtle speed variations can make big differences, usually an open loop drive will do fine. I have occasionally thrown in a gyro to help the bot stay straight, but that’s about it.

The other solution is not to use pulse counts per loop as the indicator of speed but to use the timers to mesure the period between successive pulses. This will give you finer resolution without increasing the pulse frequency or multiple updates per loop.