Robot Code Introduction
Structure
Our source code is written in Java. Each source code file is specialized.
Even though each source code file is a .java file, different .java
files can be classified into different subcategories. There are also
sourcefiles that stand alone and don't fit with others. For example,
it's typical to have files named RobotContainer.java, Robot.java,
Constants.java, and Main.java. We also have commands and subsystems.
Most frequently, we work with commands, subsystems, Constants, and
RobotContainer.java, so that's all I'll discuss here.
Subsystems
A subsystem allows you to control a certain system in the bot. For example, if the bot
shoots items, it might have a subsystem called Shooter. That subsystem could contain a
method void setShooterSpeed(double speed), then that method could be called elsewhere in order
to shoot. When programming a subsystem, your job is to make sure the methods in the subsystem
function as expected by any other peice of code that calls those methods. For this example,
you would have to ensure that the void setShooterSpeed(double speed) method properly modifies
the speed of the shooter wheels or whatever mechanism is used to shoot, based on the input to the
method.
Commands
A command is just a way to utilize subsystems in order to do things. Within a command there
are four primary methods which define how the command functions.
- The constructor takes in subsystems and other parameters, and adds subsystem requirements
and sets instance variables
- The method void initialize(), is called once when a command starts running
- The method void execute(), is called repeatedly in very quick succession
- The method void end(), is called once when a command stops
- The method boolean isFinished(), is called repeatedly until the method returns true, in which
case the void end() method is called, which ends the command
When programming a command, your job is to define each of these methods so that they make up a command that does what you want.
As a basic example, let's say you want to write a command that spins a wheel a certain number
of times, called SpinWheel. You have a subsystem Wheel with the methods void setWheelPower(double power) and
double timesRotated(). Typically an instance of a subsystem is named the same thing as the class,
but lowercase instead of uppercase. So an instance of Wheel would usually would be called wheel.
Below is a code excerpt showing how you might write this command.
public class SpinWheel extends Command {
// subsystem Wheel
private final Wheel wheel;
// number of times the wheel should rotate
private final double numRotations;
// gives the command the information it needs to function
// provides the command with the wheel using the wheel parameter
// tells the command how many times to turn the wheel with the numRotations parameter
// adds requirements to specify to WPILib which sybsystems are being used
public SpinWheel(Wheel wheel, double numRotations) {
this.numRotations = numRotations;
this.wheel = wheel;
addRequirements(wheel);
}
// starts spinning the wheel
public void initialize() {
wheel.setWheelPower(Constants.WHEEL_SPEED);
}
// nothing needs to occur here
public void execute() {}
// stops spinning the wheel
// the interrupted parameter is unimportant for our purposes
public void end(boolean interrupted) {
wheel.setWheelPower(0.0);
}
// returns true if wheel rotates enough times
boolean isFinished() {
return wheel.timesRotated() >= numRotations;
}
}
RobotContainer
The file RobotContainer.java is where all the commands and subsystems finally come together.
It's where each subsystem instance is constructed, buttons are assigned to commands, default
commands are assigned, the autonomous command is assigned, and more. As an example, let's use
the Wheel subsystem from earlier. First, we would have to construct an instance of Wheel.
It's common to name the instance of a subsystem as the lowercase version of the subsystem name,
so we might construct the subsystem instance like this: private static Wheel shooter = new Wheel().
We have a command called SpinWheel, which we can bind to the "A" button by inserting the following
code into the body of the configureBindings method: