-
Notifications
You must be signed in to change notification settings - Fork 2
Lesson 3: Subsystems
Think of each subsystem as a self-contained box that manages a specific robot mechanism.
- Keeps code organized by robot functions (eg. drivetrain, intake)
- Improve readability
- Makes testing easier
- Smart motor controller with integrated encoder (can translate mechanical motion into code representing an angle, position, speed, etc)
- Supports advanced features
- Built in PID controls
- Motion profiling
- Current limiting
- Tells the motor to spin foward/backward at x percent power (Motor output power is in between -1.0 to 1.0):
.Set(ControlMode::PercentOutput, value) - Returns motor's encoder position:
.GetSelectedSensorPosition() - Tunes motor's built-in PID controllers:
.Config_kP(...),.Config_kI(...),.Config_kD(...),.Config_kF(...) .SetNeutralMode(Brake/Coast)
A control mode in CTRE TalonFX motor controllers that:
- Moves a mechanism to a target positionControls velocity and acceleration
- Has built-in control so it is not needed to manually write PID loops
For each subsystem (eg. Wrist), you may see:

Each plays a different role to make code clean, testable, and adaptable.
- Makes it easier to switch between real robot and simulation
- Supports hardware abstraction
- Enables unit testing without needing the robot
- Encourages clean seperation of logic
aka the main logic of the subsystem
- Receives sensor data from
WristIO - Tells
WristIOwhat motor outputs to apply - Holds PID loops, state machines, etc.
Think of it as the "brain of the wrist"
aka the Java interface file
- Defines the contract between the logic and the hardware
- Includes methods like
updateInputs(),setVoltage(), etc. that must be provdied by the real/sim classes.
public interface WristIO {
public void updateInputs(WristIOInputs inputs);
public void setVoltage(double volts);
}
- It ensures that implementations like
WristIOTalonFXorWristIOSimwill work when usingWrist.java
No matter the type of implementation, follow this interface"
- A data-holding class in
WristIO.javathat represents the current state of the hardware - Used to pass data like senor readings and status info from the IO implementation (eg,
WristIOTalonFX) to the main subsystem logic (Wrist.java)
- Inside
WristIOTalonFXorWristIOSim, for example:
@Override
public void updateInputs(WristIOInputs inputs) {
inputs.position = Radians.of(sim.getAngleRads());
inputs.velocity = RadiansPerSecond.of(sim.getVelocityRadPerSec());
inputs.appliedVoltage = appliedVoltage;
inputs.supplyCurrent = Amps.of(Math.abs(sim.getCurrentDrawAmps()));
// Add more
}
Raw sensor date is being used to populate the fields in the
inputsobject
- In
Wrist.java, declared and updated like this:
public class Wrist extends SubsystemBase {
private final WristIO io;
private final WristIOInputs inputs = new WristIOInputs();
}
@Override
public void periodic() {
io.updateInputs(inputs);
// Use the input data for logic after
}
- Aka a set of rules that defines how the code must be written so that the computer understands it
public static class WristIOInputs {
public Angle position = Radians.zero();
public AngularVelocity velocity = RadiansPerSecond.zero();
public Voltage appliedVoltage = Volts.zero();
public Current supplyCurrent = Amps.zero();
public Current statorCurrent = Amps.zero();
public Temperature temperature = Celsius.zero();
public boolean connected = false;
}
aka real hardware implementation
- Implements
WristIOusing a TalonFX motor - Talks to real motor controllers
- Updates sensor readings and sends voltage outputs
Plug in this file for real-world operation
aka simulation implementation
- Mocks sensor values and simulates movemennt
- Lets you run and test
Wrist.javawithout a robot - Implements
WristIOusing WPILib's sim features
Swap this in when testing in the simulation
Wrist.java
↕ (uses)
WristIO (interface)
↕ (implemented by)
WristIOTalonFX.java ← for real robot
WristIOSim.java ← for sim/testing
Choose which implementation to use based on which real/sim build mode you want to run
- Inside
RobotContainer, create your subsystem like this:
// For real robot
Wrist wrist = new Wrist(new WristIOTalonFX());
// For sim
Wrist wrist = new Wrist(new WristIOSim());
- If the subsystem uses motors/sensors
- Systems that want to be simulated
- Subsystems that's hardware might change later
