I’ve already confirmed it will compile so the question is really if it will behave correctly at run-time. Specifically do I need to do anything to de-register stick2_B as a trigger for Command1 or any other sort up cleanup first? I would just test it but I don’t have access to a robot until later this week for obvious reasons. Please don’t tell me it should work or you think it will work Only if you know from knowledge of the WPILib or experience. Thanks!
Actually now I am realizing that I want to be able to unmap a button action when switching between my two OI modes. Is there an API to do that or can I pass a null pointer to WhenPressed()?
In navigating through the source, it does not look like it is possible (at least not easily) to unregister a button handler.
Could you work around this by refactoring your command to take into account the SOME_CONDITION? For example if the difference is only in your execute() method, could you change your command implementation to:
My intent is to be able to have a different set of controls (xbox controller mapping) for the field and for the pit at the flip of a switch. The code below is not tested yet but the idea is to create new Button objects and set their WhenPressed()/WhileHeld() methods each time I want to switch the interface. I have a command that will check the switch as a DigitalInput and reconfigure the interface when needed.
CheckOIConfig.java
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package edu.wpi.first.wpilibj.templates.commands;
/**
*
* @author team63
*/
public class CheckOIConfig extends CommandBase {
public CheckOIConfig() {
}
// Called just before this Command runs the first time
protected void initialize() {
}
// Called repeatedly when this Command is scheduled to run
protected void execute() {
if(throwSwitch1.get() && oi.current_interface == oi.CONFIG_FIELD_INTERFACE)
{
oi.setPitInterface();
}
if(!throwSwitch1.get() && oi.current_interface == oi.CONFIG_PIT_INTERFACE)
{
oi.setFieldInterface();
}
}
// Make this return true when this Command no longer needs to run execute()
protected boolean isFinished() {
return true;
}
// Called once after isFinished returns true
protected void end() {
}
// Called when another command which requires one or more of the same
// subsystems is scheduled to run
protected void interrupted() {
}
}
OI.java:
package edu.wpi.first.wpilibj.templates;
import edu.wpi.first.wpilibj.Joystick;
import edu.wpi.first.wpilibj.buttons.Button;
import edu.wpi.first.wpilibj.buttons.JoystickButton;
import edu.wpi.first.wpilibj.templates.command.CommandGroup.GoToCatchPosition;
import edu.wpi.first.wpilibj.templates.command.CommandGroup.GoToGrabPosition;
import edu.wpi.first.wpilibj.templates.command.CommandGroup.GoToShootPosition;
import edu.wpi.first.wpilibj.templates.command.CommandGroup.ShootBall;
import edu.wpi.first.wpilibj.templates.command.CommandGroup.SpitBall;
import edu.wpi.first.wpilibj.templates.commands.ElbowExtend;
import edu.wpi.first.wpilibj.templates.commands.ElbowRetract;
import edu.wpi.first.wpilibj.templates.commands.FeedMotorManual;
import edu.wpi.first.wpilibj.templates.commands.ForkExtend;
import edu.wpi.first.wpilibj.templates.commands.ForkRetract;
import edu.wpi.first.wpilibj.templates.commands.HighDriveCommand;
import edu.wpi.first.wpilibj.templates.commands.HighGear;
import edu.wpi.first.wpilibj.templates.commands.LowGear;
import edu.wpi.first.wpilibj.templates.commands.ShooterDriveOverride;
import edu.wpi.first.wpilibj.templates.commands.ShooterDriveRelease;
import edu.wpi.first.wpilibj.templates.commands.WinchManual;
import edu.wpi.first.wpilibj.templates.commands.WinchPinExtend;
import edu.wpi.first.wpilibj.templates.commands.WinchPinRetract;
import edu.wpi.first.wpilibj.templates.commands.WristExtend;
import edu.wpi.first.wpilibj.templates.commands.WristRetract;
/**
* This class is the glue that binds the controls on the physical operator
* interface to the commands and command groups that allow control of the robot.
*/
public class OI {
public final int CONFIG_FIELD_INTERFACE = 1;
public final int CONFIG_PIT_INTERFACE = 2;
public int current_interface = CONFIG_FIELD_INTERFACE;
public Joystick stick1 = new Joystick(1);
public Joystick stick2 = new Joystick(2);
public Button stick1_BACK;
public Button stick1_START;
public Button stick1_LEFT_BUMPER;
public Button stick1_RIGHT_BUMPER;
public Button stick1_Y;
public Button stick1_X;
public Button stick1_B;
public Button stick1_A;
public Button stick2_BACK;
public Button stick2_START;
public Button stick2_LEFT_BUMPER;
public Button stick2_RIGHT_BUMPER;
public Button stick2_Y;
public Button stick2_X;
public Button stick2_B;
public Button stick2_A;
public OI()
{
this.setFieldInterface();
}
public final void setFieldInterface()
{
current_interface = CONFIG_FIELD_INTERFACE;
stick1_BACK = new JoystickButton(stick1, RobotMap.XBOX_BACK);
stick1_START = new JoystickButton(stick1, RobotMap.XBOX_START);
stick1_LEFT_BUMPER = new JoystickButton(stick1, RobotMap.XBOX_LEFT_BUMPER);
stick1_RIGHT_BUMPER = new JoystickButton(stick1, RobotMap.XBOX_RIGHT_BUMPER);
stick1_Y = new JoystickButton(stick1, RobotMap.XBOX_Y);
stick1_X = new JoystickButton(stick1, RobotMap.XBOX_X);
stick1_B = new JoystickButton(stick1, RobotMap.XBOX_B);
stick1_A = new JoystickButton(stick1, RobotMap.XBOX_A);
stick2_BACK = new JoystickButton(stick2, RobotMap.XBOX_BACK);
stick2_START = new JoystickButton(stick2, RobotMap.XBOX_START);
stick2_LEFT_BUMPER = new JoystickButton(stick2, RobotMap.XBOX_LEFT_BUMPER);
stick2_RIGHT_BUMPER = new JoystickButton(stick2, RobotMap.XBOX_RIGHT_BUMPER);
stick2_Y = new JoystickButton(stick2, RobotMap.XBOX_Y);
stick2_X = new JoystickButton(stick2, RobotMap.XBOX_X);
stick2_B = new JoystickButton(stick2, RobotMap.XBOX_B);
stick2_A = new JoystickButton(stick2, RobotMap.XBOX_A);
stick1_Y.whenPressed(new GoToGrabPosition());
stick1_X.whenPressed(new GoToShootPosition());
stick1_LEFT_BUMPER.whenPressed(new GoToCatchPosition());
stick1_RIGHT_BUMPER.whileHeld(new HighDriveCommand());
stick2_RIGHT_BUMPER.whileHeld(new ShooterDriveOverride());
stick2_RIGHT_BUMPER.whenReleased(new ShooterDriveRelease());
stick2_B.whenPressed(new ShootBall());
stick2_A.whenPressed(new SpitBall());
}
public final void setPitInterface()
{
current_interface = CONFIG_PIT_INTERFACE;
stick1_BACK = new JoystickButton(stick1, RobotMap.XBOX_BACK);
stick1_START = new JoystickButton(stick1, RobotMap.XBOX_START);
stick1_LEFT_BUMPER = new JoystickButton(stick1, RobotMap.XBOX_LEFT_BUMPER);
stick1_RIGHT_BUMPER = new JoystickButton(stick1, RobotMap.XBOX_RIGHT_BUMPER);
stick1_Y = new JoystickButton(stick1, RobotMap.XBOX_Y);
stick1_X = new JoystickButton(stick1, RobotMap.XBOX_X);
stick1_B = new JoystickButton(stick1, RobotMap.XBOX_B);
stick1_A = new JoystickButton(stick1, RobotMap.XBOX_A);
stick2_BACK = new JoystickButton(stick2, RobotMap.XBOX_BACK);
stick2_START = new JoystickButton(stick2, RobotMap.XBOX_START);
stick2_LEFT_BUMPER = new JoystickButton(stick2, RobotMap.XBOX_LEFT_BUMPER);
stick2_RIGHT_BUMPER = new JoystickButton(stick2, RobotMap.XBOX_RIGHT_BUMPER);
stick2_Y = new JoystickButton(stick2, RobotMap.XBOX_Y);
stick2_X = new JoystickButton(stick2, RobotMap.XBOX_X);
stick2_B = new JoystickButton(stick2, RobotMap.XBOX_B);
stick2_A = new JoystickButton(stick2, RobotMap.XBOX_A);
stick1_LEFT_BUMPER.whenPressed(new LowGear());
stick1_RIGHT_BUMPER.whenPressed(new HighGear());
stick1_X.whenPressed(new ForkRetract());
stick1_B.whenPressed(new ForkExtend());
stick1_Y.whenPressed(new ElbowExtend());
stick1_A.whenPressed(new ElbowRetract());
stick2_BACK.whenPressed(new WinchPinRetract());
stick2_START.whenPressed(new WinchPinExtend());
stick2_LEFT_BUMPER.whileHeld(new FeedMotorManual());
stick2_RIGHT_BUMPER.whileHeld(new WinchManual());
stick2_Y.whenPressed(new WristExtend());
stick2_A.whenPressed(new WristRetract());
}
}
The simplest way to do this for now would be to have it check the switch on start up and initialize the buttons one way or another. You wouldn’t be able to switch it on the fly with the robot on, but with a restart you could switch back and forth.
I was trying to avoid rebooting the robot to switch the controls. I was not 100% sure that I would be able to do it on the fly like this but wanted to give it a try. If the WPILib is polling (i.e. periodically dereferencing them to check some property) those Button objects then I can see how messing with them at runtime could cause it to crash. As you can probably tell I didn’t take the time to dig into the WPILib implementation on this and my plan was to just test it out and see if it worked…if not then go to what you suggested and check the switch on startup.
Can you be more specific as to what your reasoning is for why it won’t work?
Nothing jumps out at me as something that would keep this from working. Let me know if it does work when you give it a try, I’d be interested in the results and any unforeseen issues if there are any.
Sorry I re-read your previous reply and see now that you were just pointing out the simplest way to do it…not saying that what I had would not work. I’ll let you know if it works out!
Not a bad option…avoids the need to memorize which buttons do what on the xbox controller! What about the ones I am doing WhileHeld() with though? Is there some equivalent on the SmartDashboard?
Well I tried the dynamic re-mapping of button actions at run-time and it didn’t really work out. I could see that some of the button mappings were changing based on the switch position but it wasn’t behaving correctly and I had to quickly abandon the idea and go with the check the switch on start-up concept.
I may investigate this more later as i think it could be useful to be able to unmap/remap button actions.