Hardware Intro
Motors
Section titled “Motors”The difference between motors and motor controllers is motors are the physical actuators that move a robot’s mechanisms while motor controllers are the electronic interfaces and control the speed and direction of the motor.
Motor controllers are used throughout the robot in many mechanisms:
- Intakes: Spin wheels to collect game pieces
- Shooters: Spin flywheels to launch game pieces
- Indexers: Move game pieces through the robot
- Arms/Elevators: Raise and lower mechanisms (often with position control)
- Climbers: Extend or retract climbing mechanisms
public class Intake implements Mechanism { // Placeholder for TalonFX, SparkMax or SparkFlex private final ExampleMotor motor = new ExampleMotor(0, CANBus.systemcore(0));
public Command runIntake() { return run(coroutine -> { while (true) { motor.set(0.8); coroutine.yield(); } }) .named("Run Intake"); }
public Command stopIntake() { return run(coroutine -> { while (true) { motor.set(0.0); coroutine.yield(); } }) .named("Stop Intake"); }}CAN motor controllers are available through vendors such as CTR Electronics (Talon FX) and REV Robotics (SPARK MAX).

Encoders
Section titled “Encoders”Encoders are a sensor for measuring rotational motion. They are reliable and less-prone to noise and interference than analog devices (such as potentiometers) because they produce digital signals. They can return the position and velocity of a mechanism. Three common types of encoders in FRC are shafted encoders, on-shaft encoders, and magnetic encoders that vary in how they are mounted to mechanisms. Many motor controllers also have integrated encoders. Relative encoders track changes in position and reset to zero when the robot is turned off, while absolute encoders track exact, unique positions across a full rotation and retain this data even when powered off.
public class Turret implements Mechanism { // Placeholder for magnetic encoder private final ExampleEncoder encoder = new ExampleEncoder(1, CANBus.systemcore(0));
public Rotation2d getEncoderPosition() { double position = encoder.getAbsolutePosition().getValue().in(Rotations) * ENCODER_MECHANISM_RATIO; return Rotation2d.fromRotations(position); }}Beam Brake
Section titled “Beam Brake”A beam brake detects if anything is between two points. Beam brakes can be used to detect when game pieces pass a specific point on a robot.
public class Indexer implements Mechanism { private final DigitalInput beamBrake = new DigitalInput(3);
public boolean isBeanBakeTripped() { return !beanBake.get(); }}Limit Switch
Section titled “Limit Switch”A limit switch detects if something is past a certain threshold in distance. Limit switches are often used to restrict the range of motion of a joint or detect the presence of game pieces.
public class Climber implements Mechanism { private final DigitalInput limitSwitch = new DigitalInput(2);
public boolean isLimitSwitchPressed() { return !limitSwitch.get(); }}Inertial Measurement Units (IMUs)
Section titled “Inertial Measurement Units (IMUs)”An IMU is a sensor that combines an accelerometer and a gyroscope. IMUs are used to measure a robot’s orientation, rates of rotation, and acceleration. They can be used to control robot heading and calculate its odometry. The most popular IMUs in FRC are navX2, Pigeon 2.0, and the onboard SystemCore IMU.
One important thing to note is that gyros measure rate rather than position. Position is inferred by integrating the rate to calculate the total change in angle. Gyro angle measurements are always relative to some arbitrary zero angle determined by the angle of the gyro either when the robot was turned on or a zeroing method was called. They can have accumulated errors (called “drift”) that increase in magnitude the longer the gyro is used.
public class Drivetrain implements Mechanism { private final OnboardIMU imu = new OnboardIMU(MountOrientation.FLAT);
public Rotation2d getHeading() { return imu.getRotation2d(); }}