Unit 6: Intermediate FRC Coding
A Subsystem is a class that represents a single physical mechanism on your robot. It's the digital blueprint for your intake, arm, shooter, or drivetrain, encapsulating all its hardware and providing simple controls.
A well-designed subsystem has two primary goals that are central to the Command-Based model.
A subsystem "owns" all the code objects for the motors and sensors that make up that mechanism. All the `Spark`, `Encoder`, and `DigitalInput` objects for the arm live inside the `ArmSubsystem` class and should be `private`.
It offers a set of simple, `public` methods that commands can use to control the mechanism. An `ArmSubsystem` won't have complex logic; it will just have clear, direct actions like `setArmSpeed(double speed)`, `stopArm()`, and `getArmAngle()`.
Let's build a subsystem for a simple robot arm that has one motor to control its angle and one encoder to measure its angle. In your IDE, you would create a new class named `ArmSubsystem` in the `subsystems` package.
// Imports for the hardware classes we need
import edu.wpi.first.wpilibj.Encoder;
import edu.wpi.first.wpilibj.motorcontrol.Spark;
import edu.wpi.first.wpilibj2.command.SubsystemBase;
public class ArmSubsystem extends SubsystemBase {
// 1. Hardware Declaration: Fields are private and final.
private final Spark m_armMotor;
private final Encoder m_armEncoder;
// 2. Constructor: For one-time setup.
public ArmSubsystem() {
m_armMotor = new Spark(4); // Arm motor is on PWM Port 4
m_armEncoder = new Encoder(0, 1); // Arm encoder is on DIO ports 0 and 1
// Configure the encoder to return degrees
m_armEncoder.setDistancePerPulse(360.0 / 2048.0);
}
// 3. Public Methods: The "API" for this subsystem.
// These are the simple actions commands can tell the arm to do.
public void setArmSpeed(double speed) {
m_armMotor.set(speed);
}
public void stopArm() {
m_armMotor.set(0.0);
}
public double getArmAngle() {
return m_armEncoder.getDistance();
}
public void resetEncoder() {
m_armEncoder.reset();
}
// 4. periodic() Method: Runs every 20ms.
// Perfect for state machine logic or sending data to SmartDashboard.
@Override
public void periodic() {
// This method will be called once per scheduler run
}
}
Question: A programmer needs to read the state of a joystick to control the arm. Where should the code to read the joystick be placed?