Subsystems

The different mechanisms of the robot that help it move.

As we mentioned earlier, Subsystems are the different components on the robot. Each subsystem has its own code file that the robot uses to run it. For the XRP robot, an example of a subsystem are the two wheels helping move around. A subsystem involving moving the robot around on the field is called a Drivetrain, and you will build one yourself to move your robot around as you play Depot Derby!

Subsystem Design + GetInstance() Method

In a subsystem, you can put whatever you need into the class to run the subsystem, so there is lots of freedom when designing one. However- the only rule is that our subsystems are singletons- classes that only have one object created at a time.

We make our subsystems singletons so that all the data stored in a subsystem will be the same for everything that decides to use the subsystem. To do this, we create a static method that returns a reference to a central object. Here, we like to call it GetInstance() for all our subsystems for consistency.

Here is an example below similar to something you might find in your source code. If you want to see a slightly different action, click this.arrow-up-right

// Imagine this was the drivetrain file in the reference code for the XRP robot. 
public class Drivetrain {
    // This is the singular object you are sharing. 
    public static Drivetrain instance;
    
    // GetInstance() method.
    public static Drivetrain GetInstance() {
    
        // if the instance is null, that means it has not been created yet.
        if(instance == null) {
            instance = new Drivetrain ();
        }
        
        // This gives whatever class is using this method a pointer to the object through
        // pass-by-reference. 
        return instance;
    }
    
    // Constructor of the class. You should only use the constructor 
    // in the getInstance() method
    private Drivetrain () {
    
    }
}

// this class will use the GetInstance() method to access a pointer to the subsystem.
// we will only show the header of the class.
public class RobotContainer {
  private final Drivetrain m_drivetrain = Drivetrain.getInstance();
  private final XRPOnBoardIO m_onboardIO = new XRPOnBoardIO();
  private final Arm m_arm = new Arm();

  // Assumes a gamepad plugged into channel 0
  private final Joystick m_controller = new Joystick(0);

  // Create SmartDashboard chooser for autonomous routines
  private final SendableChooser<Command> m_chooser = new SendableChooser<>();

  /** The container for the robot. Contains subsystems, OI devices, and commands. */
  public RobotContainer() {
    // Configure the button bindings
    configureButtonBindings();
  }

}

Periodic() Methods

The Periodic() method is continuously called by Command Scheduler- a class that manages commands. This method runs roughly 50 times a second, so it can be used for constant adjustments, such as checking if a specific criteria is true.

SimulatorPeriodic() works the exact same way as Periodic(), except it runs at a different time. It only runs when you are simulating the robot's code. Right now there is no difference, but for other robots where you'd use different software to run the robot, it will be different.

Default Commands

Default Commands are commands that are run when nothing is using the subsystem. They're useful for handling background tasks, such as preventing gravity from dragging down an arm while it is idle.

To set a default command for the subsystem, simply call setDefaultCommand() on the subsystem object, and put the command you want inside it as shown below.

Last updated