← Planner

Robot Tuning Guide

Measure the robot. Set up the sensors. Tune the movement. Then build your auton.

1. Measure the robot

Your code must match the real robot. Wrong numbers can't be fixed with PID.

Drive wheel diameterMeasure the wheel on the field. Worn wheels can be smaller.
Tracking wheel diameterMeasure the wheel your odometry uses.
Tracking wheel offsetDistance from the wheel to the robot's center of turning.
Track widthDistance between the left and right wheels.
Robot widthNeeded to plan paths that fit.
Robot lengthFront to back.
Don't guess. A wrong wheel size makes the robot drive too far or too short every time.

Measure each one a few times. Write the numbers down before you type them in.

2. Odometry

Odometry tracks where the robot is. Check these four things:

1
Wheel diameter. It sets how far one spin goes.
2
Wheel position. Where the tracking wheel sits on the robot.
3
Sensor direction. Forward should count up.
4
Heading. Turn the robot and check the reading.
Tip: Fix odometry before you touch PID.

3. IMU

1
Mount it tight. It must not wiggle.
2
Calibrate with the robot still.
3
Test turns. Turn 90°, 180° and 360°. Compare to the reading.
If turns are always off, check the IMU first. Don't change turn PID yet.
EZ-TEMPLATE

4. EZ-Template

It has separate PID for driving, heading and turning. It also has a built-in PID tuner.

Drive

chassis.pid_drive_set(24_in, 110);
chassis.pid_wait();

That's a distance and a max speed (0–127).

EZ-TEMPLATE

EZ PID

void initialize() {
  // Drive
  chassis.pid_drive_constants_set(10, 0, 100);
  // Heading
  chassis.pid_heading_constants_set(3, 0, 20);
  // Turn
  chassis.pid_turn_constants_set(3, 0, 20);
}
TermWhat it does
PPushes harder when far from the target.
IAdds push if you stay off target.
DSlows you down as you get close.
Set P first. Add D to stop overshoot. Only add I if you really need it.
EZ-TEMPLATE

EZ Odom

void autonomous() {
  chassis.pid_targets_reset();
  chassis.drive_imu_reset();
  chassis.drive_sensor_reset();
  chassis.odom_xyt_set(0_in, 0_in, 0_deg);
  chassis.drive_brake_set(MOTOR_BRAKE_HOLD);

  chassis.pid_odom_set({{24_in, 24_in}, ez::fwd, 110});
  chassis.pid_wait();
}

Start is (0, 0) at 0°. Right is +X. Forward is +Y. Clockwise is +theta.

Check that the planner's axes match your code.
EZ-TEMPLATE

EZ Slew

Slew limits how fast speed ramps up. It gives smoother starts.

chassis.slew_drive_set(true);
chassis.slew_drive_constants_set(5_in, 50);
chassis.pid_drive_set(24_in, 110);
chassis.pid_wait();
Tune PID first. Don't use slew to hide bad PID.
LEMLIB

5. LemLib

Same plan: set up the robot, set up sensors, then tune.

1
Motors. Check ports, directions and gearing.
2
Tracking wheels. Enter diameter and offset.
3
IMU. Mount it and match the code.
4
Chassis. Put it all together.

Setup

Change the ports, sizes and offsets to match your robot.

// Drivetrain
lemlib::Drivetrain drivetrain(
    &leftMotors,
    &rightMotors,
    11.5,                          // track width
    lemlib::Omniwheel::NEW_275,    // wheel
    450,                           // wheel RPM
    2                              // horizontal drift
);

// IMU
pros::Imu imu(6);

// Tracking wheel
pros::Rotation verticalEncoder(5);
lemlib::TrackingWheel vertical(
    &verticalEncoder,
    lemlib::Omniwheel::NEW_275,
    -2.5                           // offset
);

// Odometry sensors
lemlib::OdomSensors sensors(
    &vertical,  // vertical 1
    nullptr,    // vertical 2
    nullptr,    // horizontal 1
    nullptr,    // horizontal 2
    &imu
);

PID

One controller for driving. One for turning.

// Forward / backward
lemlib::ControllerSettings lateral_controller(
    10,   // kP
    0,    // kI
    3,    // kD
    3,    // anti-windup
    1,    // small error range
    100,  // small error timeout
    3,    // large error range
    500,  // large error timeout
    20    // slew
);

// Turning
lemlib::ControllerSettings angular_controller(
    2,    // kP
    0,    // kI
    10,   // kD
    3,    // anti-windup
    1,    // small error range
    100,  // small error timeout
    3,    // large error range
    500,  // large error timeout
    0     // slew
);

lemlib::Chassis chassis(
    drivetrain,
    lateral_controller,
    angular_controller,
    sensors
);
These numbers are only a start. Tune them for your robot.

Calibrate

void initialize() {
    chassis.calibrate();
}

Move

void autonomous() {
    chassis.setPose(0, 0, 0);          // start X, Y, heading
    chassis.moveToPoint(0, 24, 3000);  // X, Y, timeout (ms)
    chassis.turnToHeading(90, 2000);   // heading, timeout (ms)
    chassis.moveToPoint(24, 24, 3000);
    chassis.waitUntilDone();
}

Read position

lemlib::Pose pose = chassis.getPose();
double x = pose.x;
double y = pose.y;
double heading = pose.theta;
LEMLIB

LemLib PID

Tune one thing at a time:

1
Straight driving.
2
Turning. Try 90° and 180°.
3
Staying straight.
4
Point to point.
Drives fine but turns badly? Leave drive PID alone. Check turn PID and the IMU.
void autonomous() {
    chassis.setPose(0, 0, 0);
    chassis.moveToPoint(0, 24, 3000);
    chassis.waitUntilDone();
    chassis.turnToHeading(90, 2000);
    chassis.waitUntilDone();
}
LEMLIB

LemLib Odom

Good odometry needs correct wheel sizes and offsets.

1
Put the robot on a known spot.
2
Reset the position in code.
3
Drive a distance you know.
4
Compare the code's position to the real one.
5
Repeat in another direction.
Error grows with distance? Check wheel diameter. Error appears in turns? Check offsets and heading.

LemLib vs EZ-Template

Don't copy PID numbers between them.

IdeaEZ-TemplateLemLib
DriveDrive PIDLateral controller
TurnTurn PIDAngular controller
HeadingHeading PIDBuilt in
PathsOdom / Boomerang / PPmoveToPoint, moveToPose
Ramp upSlewController slew

6. Test order

1
Check the robot. Wheels, axles, sensor mounts.
2
Measure it.
3
Check sensors. Right direction?
4
Check odometry.
5
Tune drive PID.
6
Tune turn PID.
7
Tune point to point.
8
Build the auton.

7. Fixes

ProblemCheck first
Goes too far or too shortWheel diameter
Drives in an arcDrivetrain alignment, motor setup, heading
OvershootsMore D, less P
Shakes back and forthP is too high
Stops shortGains, exit settings, friction
90° turn is offIMU, track width, turn PID
Position drifts after turnsTracking offsets, heading
Different every runBattery, wheel slip, loose sensors

8. Checklist

Remember: Measure, set up, calibrate, tune, test. Don't change numbers at random.