Toggle Button For reverse

I have a command-based program with a DriveTrain subsystem that has this method:
void DriveTrain:: DriveDirectional(float x, float y){
robotDrive41->ArcadeDrive(y, x); //Call the ArcadeDrive Method using the Y
//Axis as the speed and the x axis as the Turn.

}

How would I implement a command to have a toggle button (i.e. the joystick button) to set the robot in reverse (press button once, in reverse, press button again, back to moving forward)?

The space after the D in : DriveDirectoinal is not a glitch. The : D was turning into :smiley: when I posted the comment.

Our team created something like this in Python last year. We call it a debounce button.

import wpilib

class Button:
    '''Useful utility class for debouncing buttons'''
    
    def __init__(self,joystick,buttonnum):
        self.joystick=joystick
        self.buttonnum=buttonnum
        self.latest = 0
        self.timer = wpilib.Timer()
        
    def get(self):
        '''Returns the value of the button. If the button is held down, then
        True will only be returned once every 600ms'''
        
        now = self.timer.getMsClock()
        if(self.joystick.getRawButton(self.buttonnum)):
            if (now-self.latest) > 600: 
                self.latest = now
                return True
        return False

Basically, create a separate class with a get method, and in the get method, if the current time - the last time it returned true is greater than 600ms, return true again or else return false. The problem with just having a method that multiplies the y value by -1 is if you hold the button down for longer than one cycle (20ms? ish) than it will reverse again, and the robot will go back and forth between reversed and not reversed. Having this timer helps a lot.

You need to toggle the direction only when the “rising edge” of the button is detected.

Here’s some C pseudo_code:

button_now = get_button(); // get the button state (pressed or not pressed)

if (button_now && ! button_previous) // detect rising edge only

{forward = ! forward;} // if rising edge, toggle the direction boolean

button_previous = button_now; // save the button state for comparison in the next iteration

… then use the “forward” boolean to determine whether to command forward or reverse.

As Ether said, you need to detect the “rising edge” of the button being held down. Here is a function I wrote for doing just this:


/*
This function allows a boolean to be toggled with a joystick button, inside of a while loop that is constantly updating.
	button:        Joystick button for toggling.
	buttonPressed: Boolean for tracking whether the button was pressed in the last cycle. This prevents toggleBool from rapidly switching states while the joystick button is held down.
	toggleBool:    Boolean to be toggled.
*/
void Robot::ToggleBool(bool button, bool &buttonPressed, bool &toggleBool){
	if(button && !buttonPressed){
		buttonPressed = true;
		toggleBool ? toggleBool = false : toggleBool = true;
	}else if(!button)
		buttonPressed = false;
}

…and here is how I implemented it:


ToggleBool(oJoystick->GetRawButton(JOYSTICK_BUTTON_REVERSE), reverseButtonPressed, reverse);