OpMode Basics - SCHS-Robotics/Software-Wiki GitHub Wiki
The Standard OpMode
As of the 2016-2017 season, the easiest way to create a new OpMode is the following:
- In Android Studio, navigate to FtcRobotController > java > org.firstinspires.ftc.robotcontroller > external.samples
- Find the "TemplateOpMode_Iterative" or "TemplateOpMode_Linear" class and copy it (Which one to use is discussed below).
- Paste in your org.firstinspires.ftc.teamcode package and give it a new name.
- Read the comments. They explain the basics.
If you want to use the standard iterative OpMode, stop. Please. Why? Because it sucks. Let me explain:
loop()
is the method where you put your actual instructions. This method is called constantly - as soon as it finishes it starts again, until you hit stop. This comes with some caveats:- In addition to running your code, the robot controller must also manage other things such as listening for when the stop button is pressed and updating telemetry on the driver station. These things are only done in between loops.
- As a result you are forced to format your code in such a way that
loop()
is consistently looping. This means no while loops or sleeps that take a significant amount of time. - This is bad for autonomous. It is extremely convenient to use while loops in autonomous code (for example,
while(robotDoesNotSeeWhiteTape)
), and not doing so means it will be more difficult and take longer to write code. It could also be more difficult for others to decipher. - For TeleOp, this is ok, because you want to constantly be looping through checks for button presses. But what if you want to incorporate autonomous code in TeleOp?
Time to bow down to the Linear OpMode!
The Linear OpMode
As of the 2016-2017 season, the easiest way to create a new LinearOpMode is the following:
- In Android Studio, navigate to FtcRobotController > java > org.firstinspires.ftc.robotcontroller > external.samples
- Find the "TemplateOpMode_Linear" class (not the "Iterative" one) and copy it.
- Paste in your org.firstinspires.ftc.teamcode package and give it a new name.
- Read the comments. They explain the basics.
A Linear OpMode has many differences from a standard OpMode, but they are all advantageous for you. :)
Code Basics
- The
runOpMode()
method is where all your code goes. Code that comes beforewaitForStart()
is equivalent to theinit()
method in a regular OpMode. Anything that comes after is like theloop()
method, only you have to write your own loops, which brings us to... - While loops. Use them for any purpose. You don't even have to keep the one in the template. BUT, you have to always call
opModeIsActive()
. Sowhile(someCondition)
would becomewhile(someCondition && opModeIsActive())
. Not doing this will cause your program to get stuck when the stop button is pressed. - The
sleep()
method. Use it to wait for a specified time in milliseconds. It should automatically be interrupted when the program is stopped, so don't worry about it getting stuck.- If you use the
sleep()
method in another method, it will cause a compilation error. All you have to do in this case is addthrows InterruptedException
after your method declaration, just like you see withpublic void runOpMode() throws InterruptedException
.
- If you use the
Telemetry
- Telemetry works differently from simply printing out a value. You provide a label for a specific piece of information along with the information itself. Calling
telemetry.addData(caption, value)
sets the value for the specified caption, and overrides the previous value for the same caption. In order to display this information on the driver station, calltelemetry.update()
.- Except there is one catch.
telemetry.update()
will delete any data that was added before the previous call totelemetry.update()
. In fact, calling this method is exactly equivalent to reaching the end of theloop()
in a standard OpMode. If this sounds confusing, see examples below:
- Except there is one catch.
Bad:
telemetry.addData("Status", "Initialized");
telemetry.update();
// Driver station reads "Status: Initialized"
telemetry.addData("Alliance", "Red");
telemetry.update();
// Driver station reads "Alliance: Red"
telemetry.addData("Program", "Secret Weapon");
telemetry.update();
// Driver station reads "Program: Secret Weapon"
Good:
telemetry.addData("Status", "Initialized");
// Driver station shows nothing
telemetry.addData("Alliance", "Red");
// Driver station shows nothing
telemetry.addData("Program", "Secret Weapon");
// Driver station shows nothing
telemetry.update();
// Driver station reads "Status: Initialized, Alliance: Red, Program: Secret Weapon"