Unit 12 Mastery Quiz: IMU & Rotation
I. Conceptual Questions
1. Coordinate Transformation: Why is it necessary to pass a RevHubOrientationOnRobot object into imu.initialize() rather than simply calling the method with no parameters?
Show answer
The IMU chip inside the Control Hub reports acceleration and rotation along its own internal axes, which are fixed to the circuit board. When the Hub is mounted at any orientation other than flat with the logo up, those internal axes do not align with the field's axes. Without the orientation declaration, the SDK cannot perform the coordinate transformation needed to make Yaw correspond to turning on the field. The result is that heading values are mathematically incorrect for any non-standard mounting. Providing the orientation tells the SDK exactly how to rotate the raw sensor data so that the output always reflects the robot's motion on the field, regardless of how the Hub is physically installed.
2. The Wraparound Problem: When implementing field-centric driving, why must you apply AngleUnit.normalizeRadians() to the result of subtracting the robot's heading from the joystick angle, rather than using the raw subtraction result directly?
Show answer
Heading values are defined on a circular number line, not a linear one. Subtracting two angles that are on opposite sides of the -π/π boundary produces a result that falls outside the -π to π range. For example, subtracting -2.9 radians from 2.9 radians gives 5.8 radians. When that value is then fed into Math.sin() and Math.cos() to reconstruct Cartesian motor commands, it produces the correct mathematical result -- but it represents the long way around the circle rather than the short path the driver intended. normalizeRadians() wraps any value back into -π to π, ensuring the motor commands always correspond to the shortest rotation between the joystick direction and the robot's heading.
3. Relative vs. Absolute Measurement: Why is an IMU-corrected turn considered a closed-loop system, and why does this make it more reliable than a timed turn?
Show answer
A closed-loop system uses sensor feedback to continuously compare the actual output to the desired output and adjusts accordingly. The IMU turn reads the robot's real heading each loop cycle, calculates the remaining error, and scales motor power to match. If a wheel slips or the battery drops mid-turn, the heading error increases, and the control loop automatically responds by applying more corrective power. A timed turn is open-loop: it applies a fixed output for a fixed duration with no awareness of whether the intended rotation actually occurred. Any disturbance -- battery voltage, floor friction, contact -- directly corrupts the result with no possibility of self-correction.
4. Proportional Gain Tuning: A student sets kP = 0.1 in their turn-to-angle loop and observes that the robot oscillates back and forth around the target heading rather than settling. Explain what is happening and what adjustment should be made.
Show answer
A proportional gain that is too large causes the motor power to overshoot the target. When the robot reaches the target, it is still moving at a significant speed because the power was high for most of the turn. It crosses the target, the error reverses sign, power reverses direction, and the robot swings back past the target again. This repeating oscillation is a classic sign of an over-tuned proportional controller. The fix is to reduce kP to a smaller value so the motor power scales down more aggressively as the target is approached, giving the robot time to decelerate and settle within the tolerance band.
5. Pitch, Roll, and the Gravity Vector: From a hardware physics perspective, explain why the IMU can detect that the robot is tilting (pitch and roll) even when the robot is completely stationary on the field.
Show answer
The IMU contains an accelerometer that measures acceleration along each of its axes. When the robot is stationary, the only acceleration acting on it is gravity, which always pulls straight down at approximately 9.8 m/s^2. When the robot is perfectly level, this gravitational acceleration falls entirely along the IMU's vertical axis. When the robot tilts, gravity projects onto the IMU's horizontal axes in proportion to the tilt angle. The accelerometer reads these horizontal projections, and the firmware uses trigonometry to compute the pitch and roll angles from them. The robot does not need to be moving for this to work because gravity is always present as a reference vector.
II. Debug the Code
The following code is intended to display the robot's current heading in degrees. Identify and fix the 2 errors.
package org.firstinspires.ftc.teamcode;
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
import com.qualcomm.robotcore.hardware.IMU;
import com.qualcomm.hardware.rev.RevHubOrientationOnRobot;
import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit;
@TeleOp(name="IMU_Debug")
public class ImuDebug extends LinearOpMode {
private IMU imu;
@Override
public void runOpMode() {
imu = hardwareMap.get(IMU.class, "imu");
RevHubOrientationOnRobot orientation = new RevHubOrientationOnRobot(
RevHubOrientationOnRobot.LogoFacingDirection.UP,
RevHubOrientationOnRobot.UsbFacingDirection.FORWARD
);
imu.initialize(orientation);
waitForStart();
while (opModeIsActive()) {
double heading = imu.getRobotYawPitchRollAngles()
.getPitch(AngleUnit.DEGREES);
telemetry.addData("Heading (deg)", "%.2f", heading);
telemetry.update();
}
}
}
Show answers
Error 1 -- Syntax/API Error:
imu.initialize() does not accept a RevHubOrientationOnRobot object directly. It requires an IMU.Parameters object that wraps the orientation. Passing the raw orientation object will either fail to compile or produce an incorrect initialization at runtime.
imu.initialize(new IMU.Parameters(orientation)); // must wrap in IMU.Parameters
Error 2 -- Logic Error:
The code calls .getPitch(AngleUnit.DEGREES) but the intent is to display the heading, which is Yaw. Pitch measures the forward/backward tilt of the robot, not its rotational heading on the field. Displaying pitch as the heading will show a value that is nearly zero when the robot is level and only changes when the robot tips forward or backward, regardless of how far it has turned.
double heading = imu.getRobotYawPitchRollAngles()
.getYaw(AngleUnit.DEGREES); // getYaw, not getPitch
Ready to move on?
Sign in with Google to save your progress with Telemark, or continue without saving.