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.
// Imagine this was the drivetrain file in the reference code for the XRP robot. publicclassDrivetrain{ // This is the singular object you are sharing. publicstaticDrivetrain instance; // GetInstance() method.publicstaticDrivetrainGetInstance(){ // if the instance is null, that means it has not been created yet.if(instance ==null){ instance =newDrivetrain ();} // 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() methodprivateDrivetrain(){}}// this class will use the GetInstance() method to access a pointer to the subsystem.// we will only show the header of the class.publicclassRobotContainer{privatefinalDrivetrain m_drivetrain =Drivetrain.getInstance();privatefinalXRPOnBoardIO m_onboardIO =newXRPOnBoardIO();privatefinalArm m_arm =newArm(); // Assumes a gamepad plugged into channel 0privatefinalJoystick m_controller =newJoystick(0); // Create SmartDashboard chooser for autonomous routinesprivatefinalSendableChooser<Command> m_chooser =newSendableChooser<>();/** The container for the robot. Contains subsystems, OI devices, and commands. */publicRobotContainer(){ // Configure the button bindingsconfigureButtonBindings();}}
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.