Skip to main content

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. Turning to a heading is a drivetrain state: the state's updateLogic arm runs a PID on the yaw, and isAimed() lets the transition table (and the behavior tree, through the robot's AIM state) know when it is done:

// In the drivetrain subsystem's constructor
turn_controller_ = new PIDController(0.02, 0, 0.004);
turn_controller_.setTolerance(2.0); // 2 degree tolerance
turn_controller_.enableContinuousInput(-180, 180);

// updateLogic: the AIM arm commands the mechanisms, nothing else
case AIM -> {
double turn = turn_controller_.calculate(getHeading(), target_angle_);
drive_.arcadeDrive(0, turn);
}

// A condition the transition table and the robot's AIM state read
public boolean isAimed() {
return turn_controller_.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​

  1. IMU not detected: Check wiring and CAN/SPI connections
  2. Inconsistent readings: Ensure proper mounting and calibration
  3. Drift over time: Implement periodic resets and consider environmental factors
  4. Noisy data: Add software filtering or check for mechanical vibration