Subsystems

Subsystems - Understanding the Foundation

Subsystems are the foundation of command-based programming. They represent physical hardware components and provide methods to control them safely and effectively.

🎯 Key Concept: One subsystem per mechanism. Each subsystem manages its own hardware and state.

Subsystem Structure & Code Examples

📦 Basic Subsystem Example
ExampleSubsystem.javaJAVA
1package frc.robot.subsystems;
2
3import edu.wpi.first.wpilibj2.command.SubsystemBase;
4import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
5import com.ctre.phoenix6.hardware.TalonFX;
6import com.ctre.phoenix6.configs.TalonFXConfiguration;
7import com.ctre.phoenix6.controls.VoltageOut;
8
9public class ExampleSubsystem extends SubsystemBase {
10    // 🔧 MOTORS GO HERE - Hardware instantiation
11    private final TalonFX motor = new TalonFX(1); // Device ID 1
12    
13    // Control requests
14    private final VoltageOut voltageOut = new VoltageOut(0);
15
16    // 🔧 MOTOR CONFIGURATIONS GO IN CONSTRUCTOR
17    public ExampleSubsystem() {
18        TalonFXConfiguration config = new TalonFXConfiguration();
19        
20        // Configure motor settings
21        config.MotorOutput.NeutralMode = NeutralModeValue.Coast;
22        motor.getConfigurator().apply(config);
23    }
24    
25    // 🔄 PERIODIC() RUNS EVERY 20ms - for telemetry/monitoring. 
26    // This we can leave blank as we can use TunerX.
27    @Override
28    public void periodic() {
29        // Update dashboard with current values
30        SmartDashboard.putNumber("Motor Position", 
31            motor.getPosition().getValueAsDouble());
32        SmartDashboard.putNumber("Motor Velocity", 
33            motor.getVelocity().getValueAsDouble());
34        SmartDashboard.putNumber("Motor Current", 
35            motor.getSupplyCurrent().getValueAsDouble());
36    }
37    
38    // Control methods
39    public void setVoltage(double volts) {
40        motor.setControl(voltageOut.withOutput(volts));
41    }
42    
43    public void stop() {
44        motor.stopMotor();
45    }
46    
47    public double getPosition() {
48        return motor.getPosition().getValueAsDouble();
49    }
50}

🔧 Hardware Instantiation

Motors, sensors, and other hardware objects are declared as private fields at the top of the class.

TalonFX motor = new TalonFX(1);

⚙️ Configuration Location

Motor configurations, current limits, and mode settings go in the constructor to run once at startup.

motor.getConfigurator()
    .apply(config);

🔄 Periodic Method

Runs every 20ms (50Hz). Use for telemetry, monitoring, and updating dashboard values - not for control!

SmartDashboard.putNumber(
    "Value", sensor.get());

Workshop Implementation

🔄 Before → After: Implementation

📋 Before

  • • Basic WPILib project structure
  • • No hardware integration
  • • No subsystem implementation

✅ After

  • • Complete Arm subsystem class
  • • TalonFX motor (ID: 31) configured
  • • CANCoder sensor (ID: 22) integrated
  • • Basic voltage control methods

Loading file...

🔍 Code Walkthrough

Hardware Setup:

  • TalonFX Motor: Main drive motor with integrated controller
  • CANCoder: Absolute position feedback sensor
  • Remote Sensor: CANCoder connected as remote feedback

Key Methods:

  • setVoltage(): Direct voltage control for basic movement
  • stop(): Safe motor stop with neutral output
  • periodic(): Understand that periodic runs every robot loop

💡 Next Step: This subsystem is ready for command integration! Next, we'll add commands to control this Arm subsystem through user input.