Inertial Measurement Unit (IMU)
An Inertial Measurement Unit (IMU) is a critical sensor in FRC robotics that measures a robot's orientation, angular velocity, and linear acceleration. IMUs enable autonomous navigation, field-oriented drive systems, and precise robot positioning.
What is an IMU?
An IMU typically combines several sensors:
- Gyroscope: Measures angular velocity (rotation rate) around three axes
- Accelerometer: Measures linear acceleration along three axes
- Magnetometer: Measures magnetic field strength (compass functionality)
Together, these sensors provide 9 degrees of freedom (9-DOF) of motion data, allowing you to determine your robot's orientation in 3D space. The most important measurements are typically from the gyroscope (heading/yaw) and accelerometer (pitch and roll).
CTRE Pigeon 2.0
Key Features:
- 9-axis fusion algorithm for precise heading calculation
- CAN bus communication for reduced wiring
- Temperature compensation for improved accuracy
- Built-in vibration rejection
- Easy integration with Phoenix framework
Wiring:
CAN High (Yellow) → CAN Bus High
CAN Low (Green) → CAN Bus Low
V+ (Red) → 12V
GND (Black) → Ground
CTRE Docs:
Kauai Labs (Studica Robotics) NavX-MXP
Key Features:
- 200Hz update rate for responsive control
- Multiple connection interfaces (SPI, I2C, USB, Serial)
- Built-in sensor fusion algorithms
- Collision detection capabilities
- Comprehensive software libraries
Wiring (SPI Connection - Recommended): Connect to the MXP port on the roboRIO:
MXP Pin 1 → 3.3V
MXP Pin 2 → DIO 0 (CS)
MXP Pin 4 → DIO 1 (MISO)
MXP Pin 6 → DIO 2 (MOSI)
MXP Pin 8 → DIO 3 (SCLK)
MXP Pin 14 → Ground
Studica Docs:
FRC Applications
1. Field-Oriented Drive
IMUs enable field-oriented (field-centric) drive systems where robot movement is relative to the field rather than the robot's orientation.
public void fieldOrientedDrive(double xSpeed, double ySpeed, double rotation) {
// Get current robot heading
double robotAngle = Math.toRadians(imu.getHeading());
// Transform driver inputs to field-relative coordinates
double fieldRelativeXSpeed = xSpeed * Math.cos(robotAngle) + ySpeed * Math.sin(robotAngle);
double fieldRelativeYSpeed = -xSpeed * Math.sin(robotAngle) + ySpeed * Math.cos(robotAngle);
// Drive the robot
drivetrain.drive(fieldRelativeXSpeed, fieldRelativeYSpeed, rotation);
}
2. Autonomous Navigation
IMUs provide critical heading information for autonomous routines:
public class TurnToAngleCommand extends CommandBase {
private final DriveSubsystem drivetrain;
private final double targetAngle;
private final PIDController turnController = new PIDController(0.02, 0, 0.004);
public TurnToAngleCommand(DriveSubsystem drivetrain, double targetAngle) {
this.drivetrain = drivetrain;
this.targetAngle = targetAngle;
addRequirements(drivetrain);
turnController.setTolerance(2.0); // 2 degree tolerance
turnController.enableContinuousInput(-180, 180);
}
@Override
public void execute() {
double currentAngle = drivetrain.getHeading();
double turnSpeed = turnController.calculate(currentAngle, targetAngle);
drivetrain.arcadeDrive(0, turnSpeed);
}
@Override
public boolean isFinished() {
return turnController.atSetpoint();
}
}
3. Balance Detection
Use IMU pitch readings to detect when your robot is on the charging station (2023):
public boolean isOnChargingStation() {
double pitch = Math.abs(imu.getPitch());
return pitch > 10.0; // Robot is tilted more than 10 degrees
}
public boolean isBalanced() {
double pitch = Math.abs(imu.getPitch());
return pitch < 2.5; // Robot is within 2.5 degrees of level
}
Troubleshooting
- IMU not detected: Check wiring and CAN/SPI connections
- Inconsistent readings: Ensure proper mounting and calibration
- Drift over time: Implement periodic resets and consider environmental factors
- Noisy data: Add software filtering or check for mechanical vibration