Hey guys, my team’s current robot code still uses JoystickButton, but I heard that it’s getting removed soon and we should use CommandXboxController instead. How can I do that? I was reading through the documentations and I am very confused. I am pretty much an absolute beginner atm. Can someone please help me? For example, how should I replace this code?
JoystickButton was just a wrapper around the Trigger system, and CommandXboxController has methods that return triggers associated with certain buttons. For example, the first line would be Trigger yButton = fight.y(); (assuming fight is a commandxboxcontroller). The second line would be done the same way but use the leftBumper method instead of y.
Thank you! What is a wrapper? I never fully understood what they are.
Essentially, it is a class that is a layer between you and some other class (like how a candy wrapper is a layer between you and a piece of candy), allowing for a different interface with it.
So by creating a JoystickButton, it essentially creates a Trigger as well?
If I remember right each JoystickButton contains a trigger yeah, so at a certain point why not just use the trigger? (Thus the deprecation)
ohh ok thanks!
The main benefit to CommandJoystick
et al is that you don’t have to instantiate individual Trigger
objects for each controller binding. Instead, you can just call a method on the single CommandJoystick
(or equivalent) that returns a trigger for the specified button. This is easier to write and easier to read.
Can I please see what that looks like?
To use an example from our 2023 robot code:
private void configureBindings() {
// cowcatcher commands ---------------------------------------------------------------------------------
driveController.a().onTrue(cowCatcherSub.toggle_Half_Command());
driveController.b().onTrue(cowCatcherSub.toggle_Full_Command());
// driveController.y().onTrue(driveSub.centerOnChargeStation());
// drive Controlls ----------------------------------------------------------------------------------
driveController.leftBumper().onTrue(driveSub.toggleBreak());
driveController.rightBumper().onTrue(driveSub.ShiftCmd());
// center robot on charge station ----------------------------------------------------------------------------
//driveController.rightStick().onTrue(null);
// arm Commands -----------------------------------------------------------------------------------------
operatorController.a().onTrue(armSub.retactArmPID());
operatorController.b().onTrue(armSub.extendArmMidPID());
operatorController.y().onTrue(armSub.extendArmHighPID());
// etc
}
The reason we are calling subsystem methods is that we are using subsystem command factory methods (or methods that return commands).
ohhhh cool!!! Thanks! So driveController is of type CommandJoystick? What is operatorController?
Both are CommandXboxController, but the principle is the same for any of the “Command[thing]” classes (CommandJoystick, CommandXboxController, CommandPS4Controller, etc).
Ohhhhhhh that makes so much sense! Thank you! I’m assuming that operatorController and driveController are different controllers irl then? Could the same controller have different variables?
They are separate physical controllers yes, but what do you mean by different variables? You can attach as many triggers as you want to a given button (though using the relevant method multiple times), but there is no real reason to do that in an FRC context (if you want two actions to run in parallel when you press a button, just use a parallel command group).
oh yea true haha
I just realized that fight for our code is this:
package com.lib.controllers;
import edu.wpi.first.wpilibj.GenericHID;
public class FightStick extends GenericHID {
public FightStick(int port) {
super(port);
}
public boolean getButton(Button button) {
return getRawButton(button.value);
}
public boolean getAButton() {
return getRawButton(Button.A.value);
}
public boolean getBButton() {
return getRawButton(Button.B.value);
}
public boolean getXButton() {
return getRawButton(Button.X.value);
}
public boolean getYButton() {
return getRawButton(Button.Y.value);
}
public boolean getLBButton() {
return getRawButton(Button.LB.value);
}
public boolean getRBButton() {
return getRawButton(Button.RB.value);
}
public boolean getL3Button() {
return getRawButton(Button.L3.value);
}
public boolean getR3Button() {
return getRawButton(Button.R3.value);
}
public enum Button {
X(3), // Controller Fightstick - 3 | Fightstick - 1
A(1), // Controller FightStick - 1 | Fightstick - 2
B(2), // Controller Fightstick - 2 | Fightstick - 3
Y(4),
LB(5),
RB(6),
LT(7),
RT(8),
L3(11),
R3(12);
public final int value;
Button(int value) {
this.value = value;
}
}
}
I’m not sure how to modify the code ;-;
private static final FightStick fight = new FightStick(1);