PIDController Parameter values for QuadEncoder

We are using the quadencoder from the kit with a victor motor control
for speed control and are having problem determining a set of values
for the P, I and D parameters.

We have tried increasing P until the wheels ran uniformly along with
other params, include PID Clock cycle and PID tolerance.

Any suggestions or help would be appreciated.

(Note, I don’t have all the details here as I’m composing this,
so if I left out something important, please let me know).


A simple heuristic for speed control:

Increase P until you get oscillation, then back it down a bit. If you aren’t satisfied with the quickness of the response, increase it again and start increasing D to try to damp the oscillations.

The I parameter should not be necessary.

Is there any typical range of values of the coefficients? 0 to 1, 0 to 100, 0 to 1000? Does the range differ for P, I, & D? Were not sure what value to start with other than just randomly pick one and be ready on the stop button. If it makes a difference, we’re looking at doing position control using a CAN Jaguar.


The appropriate range of constants depends entirely on what your feedback and process variables are, on the loop rate of the control function, and on the impulse response of the system. With typical FRC mechanisms, D often ends up being an order of magnitude smaller than P, but that’s by no means universal.

Start with P at zero and increase it. Have a way to toggle the set point between two values. It will be obvious when the P value starts to have an effect, and it will be just as obvious when it begins to make the system oscillate out of control.

If you intend to implement position control instead of speed control, you will almost certainly need the I parameter. Depending on the physical characteristics of what you’re controlling, D might not be necessary. Increase P until the system oscillates, then reduce it to about 80% of the too-high value. It probably won’t apply enough power to get to the desired set point anymore. Increase I until it does. Unless you want to do a whole bunch of mathematical analysis of the system, you’ll just have to tweak the values and watch the response until it’s doing what you want.

(If you’re using the LabVIEW PID function, keep in mind that it uses the “academic” form where I and D are actually time constants, not separate gains. Smaller values will have a larger effect on the output.)

You can usually eye-ball the initial P setting to get it in the ballpark.

Here’s how I do it:

  1. determine how much error (i.e. setpoint - processVar) should result in full motor command. Call this MaxError.

  2. set P to MaxCommand/MaxError.

For example, let’s say you’re building an arm that is to hold an angle using a PID controller. If something pulls on the arm, the controller should increase the motor command. A ballpark guess is that you would want to be at full power when the arm is deflected by 10 degrees (MaxError). The maximum PWM command is 1.0 (MaxCommand). Therefore, try using 0.1 as your initial P (MaxCommand/MaxError = 1 / 10).

Note that the above example assumes your setpoint and process variable are measure in degrees in your software.

We understand the theory of how to set the params.

We have varied them over a wide range and typically what happens is that the motors hit some max speed when we push the joystick fwd, but the speed starts to oscillate in speed in the same direction when we pull back on it.

The worst case is when they start oscillating in the fwd and back direction.


A few questions:

Are you using LabVIEW, C++ or Java? I’m assuming you’re using the pre-packaged PID, is that correct?

What are the P, I and D constants?

How much does your robot weigh as tested?

What motors are you using on the drive system?

What is the top speed of your robot as tested?

We are using Java with USDigital Quad Encoder E4P 360-250 -D-H-D-B
on a Innovation First Victor 884 motor controller

Using the PIDController class and QuadEncoder class and Victor clas
and are having problems getting the PID coefficients and period
to get reasonable action of the speed control.

We have the prototype up on blocks – ie the wheels just spin without resistance, so weight at this point isn’t relevant. We estimate the wheels spin at about 10 rev’s a second.

The last values we used are:
public static double P_DRIVE_CONST = 0.12;
public static double I_DRIVE_CONST = .07;
public static double D_DRIVE_CONST = 0;
but we have experimented with P over a very wide range.

Do we need to have the robot actually on the floor so the motors
react to inertia and resistance?


In a word, yes.

You could perhaps make some sort of dynamometer setup so you can keep the robot itself stationary. We’ve occasionally talked about doing that, building a fixture to put other wheels in contact with the robot wheels, backdriving a gearbox into a motor with an electrical load on it.