Tutorials
Zero to Hero
Episode 3: Advanced Subsystems

🎯 What Makes a Subsystem "Advanced"?

Anyone can write motor.set(1.0). An Advanced Subsystem includes:

  1. Encapsulation: Private hardware, public actions.
  2. Safety: Current limits and soft limits.
  3. Telemetry: Telling the dashboard what's happening.
  4. Simulation Support: Working without a real robot.

πŸ”’ Chapter 1: The Fortress of Solitude (Encapsulation)

Your subsystem should be a fortress. NEVER let other classes touch your motors directly.

❌ The Bad Way

// BadSubsystem.java
public TalonFX myMotor = new TalonFX(1); // PUBLIC?! Oh the horror! 😱

Why is this bad? Because RobotContainer could do myMotor.set(100) and explode it, and the Subsystem wouldn't know.

βœ… The Good Way

// GoodSubsystem.java
public class IntakeSubsystem extends SubsystemBase {
    // 1. Private Hardware
    private final TalonFX m_motor = new TalonFX(1);
 
    public IntakeSubsystem() {
        // Config happening inside constructor
        TalonFXConfiguration config = new TalonFXConfiguration();
        config.CurrentLimits.SupplyCurrentLimit = 30; // 30 Amps max
        m_motor.getConfigurator().apply(config);
    }
 
    // 2. Public Actions (The "API")
    public void intake() {
        m_motor.set(0.5);
    }
 
    public void stop() {
        m_motor.set(0);
    }
 
    // 3. Public Queries
    public boolean isStalled() {
        return m_motor.getTorqueCurrent().getValue() > 40;
    }
}

πŸ“‘ Chapter 2: The Periodic Loop

Every Subsystem has a periodic() method. It runs every 20ms (50 times a second). This is the perfect place for Telemetry.

@Override
public void periodic() {
    // This runs constantly!
 
    // 1. Update Dashboard
    SmartDashboard.putNumber("Intake Temp", m_motor.getDeviceTemp().getValue());
    SmartDashboard.putNumber("Intake Current", m_motor.getSupplyCurrent().getValue());
 
    // 2. Continuous Safety Checks
    if (m_motor.getDeviceTemp().getValue() > 80) {
        System.out.println("πŸ”₯ INTAKE OVERHEATING! STOPPING!");
        m_motor.set(0);
    }
}
πŸ“Š

Pro Tip: Don't put heavy logic (like complex pathfinding math) in periodic(). It blocks the main thread. Keep it fast!


πŸ”Œ Chapter 3: Motor Safety & Configs

Robots are dangerous. Lithium batteries are scary. Motors are strong. You must configure current limits.

Why Current Limit?

If an arm gets stuck and you keep telling the motor to push, it will draw infinite current until something melts (usually the motor or the speed controller).

// CTRE Phoenix 6 Example
TalonFXConfiguration configs = new TalonFXConfiguration();
 
// "If current exceeds 40A, wait 0.1s, then limit to 30A"
configs.CurrentLimits.SupplyCurrentLimitEnable = true;
configs.CurrentLimits.SupplyCurrentLimit = 30; // Limit to 30A
configs.CurrentLimits.SupplyCurrentThreshold = 40; // Trigger at 40A
configs.CurrentLimits.SupplyTimeThreshold = 0.1; // Delay
 
m_motor.getConfigurator().apply(configs);

πŸ§ͺ Chapter 4: Simulation Basics

You don't always have a robot. You can make your subsystem work in Sim!

@Override
public void simulationPeriodic() {
    // This ONLY runs when you hit "Simulate Robot" in VS Code
 
    // Fake the physics
    double voltage = m_motor.getSimState().getMotorVoltage();
 
    // Use math to guess where the arm would be based on voltage
    // (We'll cover PhysicsSim in Episode 8!)
}

🏁 Summary

A good subsystem is:

  • Private: Hides its motors.
  • Safe: Has current limits.
  • Talkative: Posts data to SmartDashboard in periodic.

In Episode 4, we will give this muscle some senses. How does the arm know it's at the top? Encoders!


πŸ“ž Need Help? We've Got Your Back!

Keep coding, keep learning, and remember: every expert was once a beginner who refused to give up! πŸš€

P.S. - If your robot starts talking back, that's either very advanced AI or you need more sleep. Probably more sleep. πŸ€–πŸ’€


This documentation is part of the Zero to Hero programming series. For the complete learning experience, watch the accompanying video and practice with real robot code. Remember: the only way to get good at programming is to write lots of bad code first! πŸ˜„

πŸ’

Special Thanks: To all the students who asked "Why doesn't this work?" and inspired us to create better documentation. Your questions make us better teachers, and your curiosity drives innovation. You're the real MVPs! πŸ†

Remember: Every expert was once a beginner who refused to give up. Keep coding, keep learning, and most importantly - keep having fun! πŸš€