Command Based Java for FRC By FIRST Team

Command Based Java for FRC By: FIRST Team 2636 Triple Helix

Agenda Advantages The Scheduler Basic FRC Project Classes(source code files) Subsystems Commands

The Scheduler Keeps a list of the currently running commands. Executes all commands one at a time every ~20 ms. Scheduler Initialize Command 1 Start First time? Execute Command 2 Command 3 Remove Finished? Finish

Advantages Java is the AP Computer Science language Teaches good Object Oriented design practices Easy to learn the basics The majority of FRC teams use java Java is a highly employable language

Basic FRC Project Classes Subsystem - Defines the parts of the robot Command - Controls the robot subsystems Robot - Controls the running of commands, stores subsystems and OI OI - Set up the operator interface devices Robot. Map - Mapping for device ports

Subsystem Any part that needs to act independently of other parts of the robot Drivetrain, shooter, arm, elevator, feeder, etc. Contains the sensors and motors specific to that robot component and only that robot component. Contains the behaviors that the subsystem will have.

Subsystem Class public class Example. Subsystem extends Subsystem { public void init. Default. Command() { set. Default. Command(new Example. Command()); } }

Subsystem Methods public void init. Default. Command() { set. Default. Command(new Example. Command()); } Sets the command that will run when no other commands are explicitly specified to run on the subsystem. A subsystem does not have to have a default command.

Drivetrain Subsystem public class Drivetrain extends Subsystem { private Talon left = new Talon(0); private Talon right = new Talon(1); private Robot. Drive drive = new Robot. Drive(left, right); public void drive(double y, double x) { drive. arcade. Drive(y, x); } }

Things to remember . . . If two parts of the robot are going to be controlled independently, split them into separate subsystems.

Robot Class public class Robot extends Iterative. Robot { public void robot. Init() { } public void autonomous. Periodic() { } public void teleop. Init() { } public void teleop. Periodic() { } }

Robot Methods public void robot. Init() { } This is executed when the robot is turned on This is a good place to set the autonomous command that you would like to run

Robot Methods public void autonomous. Init() { } This is called at the beginning of the autonomous period This is also a good place to set the autonomous command that you would like to run

Robot Methods public void autonomous. Periodic() { Scheduler. get. Instance(). run(); } This is repeated over and over again throughout the autonomous period. The Scheduler controls what commands are executing at any given time. DO NOT remove this line of code.

Robot Methods public void teleop. Init() { } public void teleop. Periodic() { Scheduler. get. Instance(). run(); } These are basically the same as the autonomous methods but during the teleoperated period instead. teleop. Init() is where you will cancel any currently running autonomous commands.

Declare a Drivetrain public class Robot Extends Iterative. Robot { public static Drivetrain drivetrain; public void robot. Init() { drivetrain = new Drivetrain(); } }

Commands control the subsystems. Commands will execute repeatedly until they either finish or something interrupts them. A command can control more than one subsystem at at time, but only one command can be running on each subsystem at a time. Default commands can be defined for subsystems that will run when no other commands are specified to run for that subsystem.

Command Class public class Example. Command extends Command { public Example. Command() { } protected void initialize() { } protected void execute() { } protected boolean is. Finished() { } protected void end() { } protected void interrupted() { } }

Command Methods public Example. Command() { requires(Robot. drivetrain); } Defines which subsystem(s) the command is going to use. Multiple subsystems can be required by a single command.

Command Methods protected void initialize() { } Anything that would need to happen before the command starts. Example: Getting the starting position from an encoder.

Command Methods protected void execute() { } The action that needs to be repeated over and over again. Treat this method as a single iteration of a loop. Example: Reading the values from a joystick and sending them to the drivetrain.

Command Methods protected boolean is. Finished() { return false; } This method is checked after the execute method runs and will stop the command if the method returns true. Default commands should return false. Commands that only run once should return true.

Command Methods protected void end() { } This method will run after the is. Finished() method returns a true value. This should contain anything that needs to happen after a command finishes. Example: Set the drivetrain motors to stop.

Command Methods protected void interrupted() { } This command will run if another command takes control of a subsystem that this command was using. Example: Setting a motor to stop.

Drive Command public class Drive. Command extends Command { public Drive. Command() { requires(Robot. drivetrain); } public void execute() { Robot. drivetrain. drive(0. 5, 0); } }

Things to remember. . . Make sure to use requires(subsystem), this will help avoid issues with multiple commands trying to control the same subsystem. Commands are NOT multi-threaded, if a commands takes a long time to finish one execution the robot will lock up. Default commands need to be set in the subsystem, don’t forget to go back and set them.

OI This is where you will declare any of your operator controls (joysticks, gamepads). This is also where you can map different buttons to activate different commands.

OI Class public class OI { public Joystick = new Joystick(0); public OI() { Joystick. Button button = new Joystick. Button(stick, 0); button. when. Pressed(new Example. Command()); } }

Mapping Buttons Create the button Joystick. Button button; Set which joystick and button it will use. button = new Joystick. Button(stick, 0); Set which command will fire when the button is used. button. when. Pressed(new Example. Command());

Button Execution Options button. when. Pressed(new Example. Command()); Will execute when the button is first pressed down button. when. Released(new Example. Command()); Will execute when the button is first released button. while. Held(new Example. Command()); Will repeatedly execute while the button is held down. The interrupted() method of the command will be called when the button is released.

Stop Command public class Stop. Command extends Command { public Drive. Command() { requires(Robot. drivetrain); } protected void execute() { Robot. drivetrain. drive(0, 0); } }

OI public class OI { public Joystick = new Joystick(0); public OI() { Joystick. Button drive. Button = new Joystick. Button(stick, 0); drive. Button. when. Pressed(new Drive. Command()); Joystick. Button stop. Button = new Joystick. Button(stick, 1); stop. Button. when. Pressed(new Stop. Command()); } }

Joystick Drive Command public class Joystick. Drive. Command extends Command { public Joystick. Drive. Command() { requires(Robot. drivetrain); } protected void execute() { Robot. drivetrain. drive(Robot. oi. get. Y(), Robot. oi. get. X()); } }

Set Joystick Drive as Default public class Drivetrain extends Subsystem { public void init. Default. Command() { set. Default. Command(new Joystick. Drive. Command()); } }

Robot Map Class public class Robot. Map { public static final int left. Motor = 0; public static final int right. Motor = 1; }

Robot. Map This is where you can set up all of your device port configurations. This allows you to have all of your configuration information in one place. This is also a good place to set up constant values to use in your code.

Autonomous Command public class Robot extends Iterative. Robot { public void autonomous. Init() { autonomous. Command = new Drive. Command(); autonomous. Command. start(); } }

In Review Write the subsystems. Add the subsystem to the Robot class. Write any commands for the subsystems. Add any default commands. Map any OI controls to the commands. Set the autonomous command.

Suggestions Use descriptive variable names. Use buttons and very basic commands to test functionality. Save often

Questions Contact me at lythgoe. matthew@gmail. com
- Slides: 40