Java 4: Command-Based Programming

From Deep Blue Robotics Wiki
Revision as of 21:50, 22 September 2016 by Ben shimota (Talk | contribs)

Jump to: navigation, search

Although Iterative Robot is very easy to use, it does not allow for very complicated functionality. As a result, for the actual robot project we use a template called Command-Based Robot. This template is based on dividing the robot into different subsystems, which are each capable of individually carrying out different commands. This section will cover the command-based model of robot programming.

Robot Builder


Robot Builder is a powerful tool that allows you to build the basic framework of a command based robot much more quickly than writing it yourself.


Opening Robot Builder - To get to Robot Builder, follow this file path: "C:\Users\Student\wpilib\tools" and run the executable. Begin by going to: File>new. Name the robot, enter your team number and hit "Create Robot" button.


Creating Subsystems - To add a subsystem, right click the subsystems folder. You should be prompted to create a new subsystem. For this tutorial, we will be creating a drive train. By clicking on the new subsystem folder, you should have the option to rename the subsystem, as well as set a default command.


Creating Actuators - Now, we need to actually add the actuators to the robot project. For the drive train, we can add speed controllers to the drive train quite easily. Just drag the "Robot Drive (2 Speed Controllers)" or "Robot Drive (4 Speed Controllers)" into the DriveTrain subsystem folder. Then, drag the actual speed controllers for the Actuators tab into the robot drive and name them.


Creating Commands - You can also create a command in the same way that you create other robot components. All that you need to do is drag the command that you want from the command section on the left into the "Commands" folder. All you need to do is name the command for now. You will write the code for the command later.


Creating Joysticks - Now that you have some commands, you need to assign them to actual controls. First, drag a Joystick into the Operator Interface folder. Then, drag a few joystick buttons into the joystick. If you select one of these buttons, you can specify its name, its location on the joystick, the command that it should trigger, and under what conditions it should trigger that command.


Exporting to Java - Once you have created all of your subsystems and commands, exporting the robot project is fairly simple. To do so, all you need to do is select the export tab at the top and select the "Java" option, and the Robot Builder will automatically generate a new Java project. To choose the location where the project should be created, select the folder with the name of your robot and change the file path next to the "Java Project" preference. You can also specify the autonomous command for your robot here, or change the robot's name. If you make additional changes to the Robot Builder project after generating the Java project, then you can just export the Robot Builder project again.


  • Important note: The code that Robot Builder creates will be in between two blocks of comments. DO NOT put your code in between the comments, as it will be overwritten if you ever need to re-export the Robot Builder project. If you delete the auto-generated comments, then Robot Builder will be unable to make changes to that section of the code.

Robot Map


The RobotMap class defines all of the actuators, sensors, etc. that the robot will use. This allows you to easily change the ports of various components, because they are all declared in one place. It is auto-generated when you export the Robot Builder project. The robot map is also where actuators and sensors are added to LiveWindow and any settings (like encoder ratios) can be set. Robot Builder will auto-generate references to the objects declared in the robot map into their assigned subsystems. Subsystems


In general, any part of a robot that will need to operate independently of other parts of the robot needs to be its own subsystem. For example, if you can raise and lower the elevator on SlideWinder, while simultaneously opening and closing the arms, then the elevator and the arms need to be in separate subsystems.


In the robot code, each subsystem is its own class inside the subsystems package. Robot Builder will add all of the actuators and sensors to the subsystem class automatically.


Default Commands - All subsystems have the option to set a default command using the setDefaultCommand method in the constructor. The subsystem will run the default command whenever no other subsystem commands are running.


Subsystem Methods - Generally, all the methods that commands will need to call should be written in their respective subsystem. For example, we drive the robot using the drive command, but the Drive command uses the drive method in the Drivetrain subsystem. Commands


Commands are actions that the robot can perform. They will generally be created in Robot Builder. Commands have a constructor and five auto-generated methods that you can put code into. Constructor - In the constructor, call the requires method to specify what subsystems are used by the command. This prevents two commands from trying to control the same subsystem. Initialize - This method executes the code inside it once when the command is initially called. Execute - This method runs the code inside it as long as the command is running. IsFinished - This method is a boolean method that controls when the command ends. While isFinished returns false, the execute method will continue to run, but once isFinished returns true, the end method will execute. End - This method executes the code inside it once isFinished returns true. Afterwards, the command will terminate. Interrupted - This method will execute if another command starts that requires the same subsystem as the current one.

  • If you have some code that absolutely needs to run at the end of a command, put it in both the end and interrupted methods, or have the interrupted method call the end method

Command Groups


Command groups are a special type of command that runs other commands rather than having any code of their own. A command group will require any subsystems required by the commands it contains. There are two ways you can add commands to a command group: in sequence or in parallel.


Sequential Commands - To add a sequential command, call the addSequential method in the command group's constructor. The parameter for this method is an instance of the command you want to add. Sequential commands run one at time (i.e. sequentially) in the order they were added to the command group.


Parallel Commands - To add a parallel command, call the addParallel method in the command group's constructor. The parameter for this method is an instance of the command you want to add. Parallel commands can run at the same time as other commands (i.e. in parallel), so if you add a parallel command and then a sequential command, both will run at the same time. However, if you add the sequential command first, then the parallel command will not start until the sequential command terminates.


This example command group will run the DriveForward command and the SpinShooterWheels commands at the same time, then run the Shoot command after the DriveForward command finishes. Note that the SpinShooterWheels command won't end until the entire command group is terminated at the end of auto mode. public class Auto extends CommandGroup {

   public Auto() { 
       addParallel(new SpinShooterWheels()); 
       addSequential(new DriveForward()); 
       addSequential(new Shoot()); 
   } 

}


Operator Interface

The operator interface (OI) is a class that maps the joysticks and buttons to robot commands. Most of the code in this class is auto-generated by Robot Builder. The OI instantiates all of the joysticks and buttons, and assigns commands to those buttons. There are four different ways to add buttons to a command: WhenPressed - The whenPressed method starts the given command when the button is first pressed down. The command will not terminate until it is interrupted or terminates itself. WhenReleased - The whenReleased method starts the given command when the operator lets go of the button. The command will not terminate until it is interrupted or terminates itself. WhileHeld - The whileHeld method starts the given command when the button is first pressed down, and terminates the command when the button is released. ToggleWhenPressed - The toggleWhenPressed method starts the given command the first time the button is pressed down, and terminates the command when the button is pressed again. Robot


Robot is an IterativeRobot class that controls the rest of the robot project. It is traditionally renamed to the actual name of the robot that year. The Robot class has the same robotInit, teleopPeriodic, etc. commands as an IterativeRobot project. However, the only code that needs to go in the teleopPeriodic and autonomousPeriodic methods is a single line of code: Scheduler.getInstance().run(); This line of code tells the scheduler to update all currently active commands. You can also start commands in the teleopInit or autonomousInit methods, (e.g. new Auto().start();) but most commands will be started by default in the subsystems or by buttons on the joysticks. In the testPeriodic method, you should use a different line of code: LiveWindow.run(); This line of code just tells LiveWindow to update itself while the robot is in test mode. Advanced SmartDashboard


Starting commands, displaying subsystems, setting values, sendable choosers, preferences widget, SFX. Timer


The Timer class keeps track of real time. To use a Timer, just create a new instance of the Timer class and use a few simple methods: Start - The start method makes the Timer begin counting time. Stop - The stop method pauses the Timer. Reset - The reset method makes the Timer reset to zero. Get - The get method returns the amount of time in seconds since the Timer was last started or reset (ignoring time when the timer was stopped). GetMatchTime - The getMatchTime method returns the amount of time in seconds since the current match began Reset - The reset method makes the Timer reset to zero without stopping it. Delay - The delay method causes the current task to pause for a given amount of time in seconds. Commands also have a method called timeSinceInitialized that returns the time in seconds since the command was started.


Next Lesson:Inheritance