๐ป Programming ยท Engineer ยท Intermediate
IMU Setup & Calibration
Inconsistent turns are almost always an IMU problem. This guide covers mounting, PROS API, EZ Template integration, drift, and a complete troubleshooting table for the four failure modes you'll actually encounter.
Before this guide: You should have a working drivetrain that uses pid_drive_set(). If your turns are off by more than a few degrees consistently, this is where to look.
The V5 Inertial Sensor (IMU) is a gyroscope + accelerometer. For drivetrains, you only care about the gyroscope โ it measures rotation rate and integrates it into a heading angle (degrees). EZ Template uses this heading to:
- Hold straight lines: The heading PID constantly corrects drive direction using the IMU. Without it, your robot drifts
- Execute precise turns:
pid_turn_set(90, 90) is targeting an IMU heading of 90ยฐ, not a timer
- Accumulate absolute position: Odometry tracks heading changes โ IMU accuracy compounds across the whole auton
Mounting matters more than calibration. A correctly mounted IMU needs no special handling. A poorly mounted one can't be compensated with software.
- Mount flat: The IMU reads rotation around its Z-axis. If it's tilted even 5ยฐ, every turn reading is wrong
- Mount at robot center (or close): Off-center mounting still works, but reduces accuracy on tight turns
- Away from motors: Motor vibration introduces noise. Keep at least 3 inches of physical separation
- Away from the Brain: The Brain's Bluetooth module can cause EMI interference with the IMU
- Rigid mount only: If the IMU can flex or vibrate independently, its readings will be noisy. Bolt it, don't zip-tie it
// Declare in globals.hpp
pros::Imu imu(7); // port number
// In initialize() โ ALWAYS call before using
imu.reset(); // starts calibration, takes ~2 seconds
while(imu.is_calibrating()) pros::delay(10); // wait for finish
// Read heading (0โ360, clockwise positive in EZ Template)
double heading = imu.get_rotation(); // accumulates past 360
double heading = imu.get_heading(); // wraps 0โ360
// Reset to zero mid-auton
imu.set_rotation(0.0);
โ EZ Template Integration
EZ Template handles the IMU automatically โ you just declare it in the constructor. The 4th argument is the IMU port:
ez::Drive chassis ({-1,-2,-3}, {4,5,6}, 7, 3.25, 36.0/48.0, 360);
// โ IMU port โ must match physical wiring
EZ Template's initialize() calls chassis.initialize() which resets the IMU automatically. You don't need manual imu.reset() calls in most setups.
Resetting heading mid-auton: Use chassis.drive_imu_reset(); to zero the heading at any point. Useful for long routes where drift may accumulate.
๐ Calibration Protocol
- Place robot on competition field tile (not smooth floor โ carpet surface matters)
- Do not touch robot after uploading code. Even a small bump during calibration corrupts the zero
- Wait for Brain display to confirm IMU is calibrated. EZ Template shows "Calibrating..." โ do not proceed until it clears
- Run a test turn:
pid_turn_set(90, 90); chassis.pid_wait(); โ should stop within ยฑ1ยฐ of 90ยฐ
- Run 5 turns in a row and check if error accumulates. Under 3ยฐ total drift across 5 turns = good calibration
๐ง Troubleshooting Table
| Symptom | Cause | Fix |
| IMU never finishes calibrating | Robot was moving during calibration, or IMU port is wrong | Check port number. Ensure robot is completely still for 2+ seconds after upload. Try a different port. |
| Turns overshoot consistently | PID kP too high, or exit conditions too loose | Reduce turn kP in default_constants(). Check pid_turn_exit_condition_set โ tighten the settle time. |
| Turns undershoot consistently | PID kP too low, or too much friction in drivetrain | Increase turn kP. Check wheel bearings and drive screws โ mechanical resistance stops turns early. |
| Heading drifts during straight drive | Heading PID constants off, or physical drivetrain imbalance | Tune pid_heading_constants_set. Check that all drive motors are the same cartridge. Ensure left/right motor counts match. |
All gyroscopes drift โ the V5 IMU is no exception. In a 15-second auton, expect 0.5โ2ยฐ of total drift if well-calibrated. This is acceptable. If drift exceeds 3ยฐ across the full auton:
- Check mounting rigidity. A flexing IMU mount is the #1 drift amplifier
- Add a mid-auton reset. After your first scoring action, call
chassis.drive_imu_reset() and define subsequent turns from that new zero
- Consider odometry. If your game requires very precise multi-point routing, an odom system with tracking wheels compensates for IMU drift automatically. See the odometry guide
The IMU applies MEMS gyroscope technology: a microscopic vibrating mass that experiences Coriolis force proportional to angular velocity. Integration amplifies small measurement errors — a 0.1 degree/s bias accumulates to 6 degrees error per minute without correction. Calibration measures and cancels this bias. Placement near motors introduces electromagnetic interference that corrupts the magnetometer, causing systematic heading error.
🎤 Interview line: “We place our IMU away from motor controllers and test calibration accuracy quantitatively. After every significant code change, we run a 48-inch straight-line test and measure heading error. Our current IMU placement achieves under 0.5 degrees of drift over 48 inches. We have that data in our notebook because we treat sensor calibration as an engineering experiment.”
Your IMU is mounted next to a motor controller and heading drift worsens after calibration. What is the most likely cause?
⬛ The IMU needs a longer delay after power-on before calibrating
⬛ Electromagnetic interference from the motor controller is corrupting the magnetometer, causing systematic heading bias
⬛ The IMU library has a calibration bug in this PROS version
📝Notebook entry tip: Build & Program — Orange slide — Document your IMU placement as a build entry: which port, where on the robot, and the reasoning (distance from motors, mounting plane, vibration isolation). Include calibration accuracy data: heading reported vs actual after a 48-inch straight drive, 5 trials. Moving the IMU between robot versions with documented before/after accuracy improvement is strong iterative build evidence.