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.
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:
3. IMU
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 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);
}
| Term | What it does |
|---|---|
| P | Pushes harder when far from the target. |
| I | Adds push if you stay off target. |
| D | Slows you down as you get close. |
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.
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();
5. LemLib
Same plan: set up the robot, set up sensors, then tune.
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
);
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 PID
Tune one thing at a time:
void autonomous() {
chassis.setPose(0, 0, 0);
chassis.moveToPoint(0, 24, 3000);
chassis.waitUntilDone();
chassis.turnToHeading(90, 2000);
chassis.waitUntilDone();
}
LemLib Odom
Good odometry needs correct wheel sizes and offsets.
LemLib vs EZ-Template
Don't copy PID numbers between them.
| Idea | EZ-Template | LemLib |
|---|---|---|
| Drive | Drive PID | Lateral controller |
| Turn | Turn PID | Angular controller |
| Heading | Heading PID | Built in |
| Paths | Odom / Boomerang / PP | moveToPoint, moveToPose |
| Ramp up | Slew | Controller slew |
6. Test order
7. Fixes
| Problem | Check first |
|---|---|
| Goes too far or too short | Wheel diameter |
| Drives in an arc | Drivetrain alignment, motor setup, heading |
| Overshoots | More D, less P |
| Shakes back and forth | P is too high |
| Stops short | Gains, exit settings, friction |
| 90° turn is off | IMU, track width, turn PID |
| Position drifts after turns | Tracking offsets, heading |
| Different every run | Battery, wheel slip, loose sensors |