TeleOp
Creating a TeleOp in NextFTC is just as easy as autonomous! This page will walk you through creating a TeleOp. This page assumes you have already read the Autonomous guide.
This TeleOp program will teach you how to bind commands to gamepad buttons and control your drivetrain using NextFTC.
Step 1: Create your OpMode
Just like for autonomous, your OpMode will extend NextFTCOpMode
. With that in mind, here is the basic structure for a TeleOp:
@TeleOp(name = "NextFTC TeleOp Program Kotlin")
class TeleOpProgram : NextFTCOpMode() {
}
Just like for autonomous, we need to add the required subsystems as a SubsystemComponent
. We will also add a BulkReadComponent
. Additionally, we will add a BindingsComponent
, which allows us to use gamepads from NextBindings.
class TeleOpProgram : NextFTCOpMode() {
init {
addComponents(
SubsystemComponent(Lift, Claw),
BulkReadComponent(),
BindingsComponent()
)
}
}
That's all! Now we will allow the joysticks to control our robot's driving.
Step 2: Create your drive command
NextFTC has built-in commands for common drivetrains.
IMPORTANT
Currently, NextFTC only has support for mecanum, x-drive, and differential ( tank) drivetrains. If you write a command for another, please share it with us!
Go to the drivetrain commands page to get the code for your drivetrain. In this guide we will be using the MecanumDriverControlled
command. If you are using a different drivetrain command, follow the instructions there to get it set up and then come back to this guide.
After adding the MecanumDriverControlled
command, here is our code:
// change the names and directions to suit your robot
private val frontLeftMotor = MotorEx("front_left").reversed()
private val frontRightMotor = MotorEx("front_right")
private val backLeftMotor = MotorEx("back_left").reversed()
private val backRightMotor = MotorEx("back_right")
override fun onStartButtonPressed() {
val driverControlled = MecanumDriverControlled(
frontLeftMotor,
frontRightMotor,
backLeftMotor,
backRightMotor,
Gamepads.gamepad1.leftStickY,
Gamepads.gamepad1.leftStickX,
Gamepads.gamepad1.rightStickX
)
driverControlled()
}
Step 3: Create your gamepad bindings
In the last guide you learned how to schedule a command when the OpMode starts. Now you will learn how to schedule a command whenever the driver presses a button. We will use NextBindings to accomplish this.
In this guide, we will have the following buttons, all on gamepad 2:
- Pressing d-pad up moves the lift up.
- Releasing d-pad up opens the claw.
- Pressing the right trigger closes the claw and then moves the lift up.
- Pressing the left bumper opens the claw and at the same time moves the lift down.
NOTE
It is unlikely that these commands will be useful for any real robot, but it will give you an idea of how you can achieve practically any gamepad bindings possible with NextBindings.
TIP
It is best to have the most commonly used functions activated by bumpers and triggers. This is because to press any other button, your thumb must move, while no finger has to move to press the bumpers and triggers.
We will bind our commands in onStartButtonPressed()
. If we wanted them accessible in init, we would do it in onInit()
.
CAUTION
Although it is possible to bind the commands in init, keep in mind that your robot is not allowed to move during the transition from autonomous to TeleOp. There is almost never a time you would want to use the gamepads during init in TeleOp.
First, we will make d-pad up move the lift up when pressed:
Gamepads.gamepad2.dpadUp whenBecomesTrue Lift.toHigh
Next, we will make it so releasing d-pad up opens the claw:
Gamepads.gamepad2.dpadUp whenBecomesTrue Lift.toHigh whenBecomesFalse Claw.open
NOTE
If d-pad up is released before the lift has fully finished moving up, then the claw will open while the lift is moving up.
Now, we must make the right trigger close the claw and then move the lift up. To do this, we can use a SequentialGroup
! We would like to schedule the command when the right trigger is greater than 0.2.
(Gamepads.gamepad2.rightTrigger greaterThan 0.2)
.whenBecomesTrue(
Claw.close.then(Lift.toHigh)
)
Lastly, we must make the left bumper open the claw and at the same time move the lift down. We can use a ParallelGroup
for this!
Gamepads.gamepad2.leftBumper whenBecomesTrue Claw.open.and(Lift.toLow)
Final Result
That's all! You now have created a TeleOp program with driving and operating the lift and claw. You also now know how to create any TeleOp you wish, even if it has complicated sequences.
For reference, here is the final result:
@TeleOp(name = "NextFTC TeleOp Program Kotlin")
class TeleOpProgram : NextFTCOpMode() {
init {
addComponents(
SubsystemComponent(Lift, Claw),
BulkReadComponent(),
BindingsComponent()
)
}
// change the names and directions to suit your robot
private val frontLeftMotor = MotorEx("front_left").reversed()
private val frontRightMotor = MotorEx("front_right")
private val backLeftMotor = MotorEx("back_left").reversed()
private val backRightMotor = MotorEx("back_right")
override fun onStartButtonPressed() {
val driverControlled = MecanumDriverControlled(
frontLeftMotor,
frontRightMotor,
backLeftMotor,
backRightMotor,
{ gamepad1.left_stick_y },
{ gamepad1.left_stick_x },
{ gamepad1.right_stick_x }
)
driverControlled()
whenButton { gamepad2.dpad_up } isPressed Lift.toHigh isReleased Claw.open
range { gamepad2.right_trigger } whenGreaterThan 0.2 isPressed SequentialGroup(
Claw.close,
Lift.toHigh
)
whenButton { gamepad2.left_bumper } isPressed ParallelGroup(
Claw.open,
Lift.toLow
)
}
}