Drivetrain PID tuning

Today, I was encouraging my rookie programmers to utilize the NavX to experiment with PID Control in order to make our robot drive straight. Given that we’ve never done this in a season, one of the things that crossed my mind is how we should deal with the differences in CoFs between our lab’s carpet and that of a true to life field. What have other teams done to account for this? Have you guys just purchased carpet, and just calibrated it on that? What would you use to re-tune your loop at competition?

Thanks so much!

Sensitivity to carpet variation is somewhat dependent on your drivetrain geometry and dynamics. A 6 wheel drive, dropped-center robot with a roughly central CoM and hard wheels is going to turn pretty similarly on a wide variety of floor surfaces. Meanwhile, a 4 wheel drive robot with a long wheelbase and pneumatic wheels may scrub quite differently depending on carpet.

Ideally your PID algorithm can be tuned to compensate for various types of floor conditions (after all, well-worn vs. brand new field carpet can be quite different in its own right!). If you are able to control your robot on a couple different types of surfaces at home (including whatever you have that is most similar to the field surface), you ought to be good when you get to competition.

We’re able to get pretty good straight driving using only the P term with the navX, so that may be worth trying. As for carpet, a local store gave us a 5x12 foot square of the official carpet (different color though).

A P only loop makes sense in this application, because there is so much physical damping/resistance in the yaw of a robot; there is no need for a software dampening. The navX is likely much more dependable than the wheels for determining orientation, that I would not use drive train encoders in the navigation loop, but ONLY to to feed the wheel/motor PID loop.

As far as color, if you insist on the right color, you’d need a new piece (or two) of carpet each year.

Things to watch out for when doing this, based on personal experience:

  1. It is very hard for a loop to keep you driving straight at max speed, because if your motors are saturated you can only slow down one side to adjust, rather than both slow down one side and speed up the other. If you give yourself some headroom, it will work much better.

  2. Unless you are using cascading control (i.e. feeding the output of your heading loop to a wheel velocity loop), it is likely that you won’t be able to make the p gain high enough on the heading loop to make steady state error acceptably small without introducing instability. A quick and dirty fix for this is to simply add or subtract some minimum output to/from the calculated heading loop output whenever it is outside of some tolerance around 0.

1 Like

We have never needed to re-tune for a change in carpet. Our typical heading stabilization is a PI controller for angular rate via gyro to stabilize heading. We tune via the following:

1.We do a quick system id on the yaw axis
a. Apply a moderate amplitude yaw step
(usually 1/2 max input on whatever yaw command input you have)
b. Model the angular rate output with the equation
rate = inputk(1 - exp(-t/tau))

  1. design a controller using the following architecture;
    error = (yaw_cmd - yaw_rate)
    motor_cmd = PID(error, Kp, Ki, Kd)
    Kp = gain/K*tau
    Ki = gain/K
    Kd = 0
    gain = 5 to 10 (arbitrary, desired bandwith in rad/sec);

  2. Vary gain to get the command response you want. We start at 10, and if it’s too sluggish bump it up, if it oscillates or limit cycles (bounces back and forth due to backlash) we back it off.

Sorry for the terse explanation, but that’s pretty much it. We do all our own code, so the PI controller is just written into the yaw service function. Sorry I don’t have the code right now, but I can find it.


Can anyone explain to me why so many teams use gyros for driving straight instead of encoders?

Wheel slip is not a factor and the sensor’s value more directly represents robot angle*. That being said, there are downsides to both so it’s really just team preference.

*aka “math”

short answer: wheels slip.

Once the wheels have slipped against the carpet/floor/obstacle and you don’t know how much, you can’t reliably use the encoders (by themselves) to determine orientation. Gyros have more drift, but are not subject to this sudden loss of calibration.

I found it easy to implement with arcade drive. The heading loop replaces the rotate joystick.


Good point. I’m used to encoders because we use them for motion profiling, which you couldn’t really do with a gyro.

Sure you get a number that represents your angle, but if you’re trying to go a predetermined distance, encoders make corrections much easier.

How do you accomplish this? Do you just set your setpoint proportional to the position of the stick?

Robot.drivetrain.arcadeDrive(DriveForwardSpeed, (Robot.drivetrain.getGyroAngle().getAngle()));

You might want/need to multiply the gyro angle by a Kp or -Kp. We actually ended up with the following:

Robot.drivetrain.arcadeDrive(-DriveForwardSpeed, (-(Robot.drivetrain.getGyroAngle().getAngle()) * Kp+.1));

You can definitely do motion profiling with a gyro.

How are you allowing the driver to adjust the robot’s angle?

We did not use it to execute a turn or follow a path while driving. It was only used to make a stationary turn or maintain a heading for a “drive straight” mode similar to the example in your original post.

For tele-op drive straight, a button on the xBox controller sets the current heading as the desired heading value then replaces the driver’s rotation joystick value with the output of the heading proportional controller. Essentially the driver is only controlling thrust at that point and the loop maintains heading.

For our use, a proportional only loop worked but you could set up PID and experiment with the tuning.


In 2015 we used Mecanum wheels and one thing we really noticed was that the robot would rotate and drive forward well, but generated a lot more random slipping when moving sideways. We ended up using encoders for forward and lateral positioning and the gyro for heading. We could have used the encoders (one on each wheel) to determine heading, but the slip was giving us problems.

It was worse when the wheels got worn out. we were using the 6" Vexpro wheels, very cost effective but had a very noticeable life span for the rollers. Replacement wheels altered our autonomous timing required for the 3 tote auto.


This is very common for mecanum drives. The rollers don’t need to spin for forward movement or turns in place (depending on your drivebase geometry), but do need to spin for sideways translation. The less your rollers spin freely, the more your strafing performance suffers.

Of course I’m going to defer to you on this, but how reliable is displacement with a gyro? I’m skeptical.