|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
| Thread Tools | Rate Thread | Display Modes |
|
#1
|
|||
|
|||
|
Command-Based robot button toggle question
We are having a problem regarding making a toggle method for the button class. In the OI file, we plan to code certain buttons such that the first time its pressed one command would execute, the next time a different command would, and it would alternate between (thus toggling between these two states).
One of the powerpoints we came across described going into the Button source code file and adding a new method, so we wrote a new one that accepts two commands as the parameters and have worked out the logic for the toggle. It doesn't seem to be working, so could someone explain the proper way to code it? Thank you very much. state is set to false in the beginning, and: void Button::WhenToggled(Command *command1, Command *command2){ if(state){ WhenActive(command2); state = false; } else { WhenActive(command1); state = true; } } |
|
#2
|
||||
|
||||
|
Re: Command-Based robot button toggle question
In order to toggle, you first have to detect the rising edge of your joystick button (because you want it to toggle only once when you press the button, not repeatedly while you're holding the button down). Then you toggle a boolean each time a rising edge is detected. Then use the value in that boolean to determine what action to take. For example: Code:
button1 = getButton(1); if (button1 && ! button1previous) toggle = ! toggle; button1previous = button1; Last edited by Ether : 23-02-2013 at 11:23. |
|
#3
|
||||
|
||||
|
Re: Command-Based robot button toggle question
Changing WPILib's code is a bit risky, I wouldn't do that. You could, however, write some classes of your own that demonstrate similar principles. What I would do is define a "ToggledPressedButtonScheduler" class:
http://pastebin.com/agFtqpAN http://pastebin.com/bZwmbD21 It's based on "PressedButtonScheduler", but starts a different command every time the button is clicked. Here's how you should use it: http://pastebin.com/SmBGNhFu Please note that the code was written in pastebin and was not tested (or compiled). |
|
#4
|
|||
|
|||
|
Re: Command-Based robot button toggle question
Are the two commands related in any way? (i.e., could you use one command for both actions?). If so, you may want to consider refactoring either your subsystem or command code so that you have this functionality.
OR, you could put them all inside a command group with a bool that holds state, and based on that run either of two commands. Just make sure your "state" variable inside of whatever subsystem is actually being toggled back to whatever is needs to be. Code:
//In the CommandGroup foo, you could either have a state that is toggled from within one of your subsystems,
//ala GetterSetter pattern and use this state to make a decision.
//OI code
JoystickButton *xyz = new JoystickButton(stick1, 11);
xyz->WhenPressed(new foo());
//CommandGroup 'foo' code
subsystemOne.ChangeStateOfFooBar();
if(subsystemOne.GetStateOfFooBar())
{
AddSequential(new bar());
}
else
{
AddSequential(new baz());
}
Last edited by Fifthparallel : 23-02-2013 at 14:11. |
|
#5
|
||||
|
||||
|
Re: Command-Based robot button toggle question
Quote:
|
|
#6
|
||||
|
||||
|
Re: Command-Based robot button toggle question
Quote:
Code:
button->WhenPressed(new DoStuff()); |
|
#7
|
||||
|
||||
|
Re: Command-Based robot button toggle question
Quote:
Code:
void WhenActive (Command *command) Code:
new DoStuff() Looking deeper into the code, you can see that instance ends up being stored in an instance of "PressedButtonScheduler", which takes it upon itself to check the state of the button and start the command instance if necessary (not create another instance). |
|
#8
|
|||
|
|||
|
Re: Command-Based robot button toggle question
So then would the OP be able to use a Command, but not a CommandGroup, and inside the Initialize() method get the state of whatever subsystem and run other commands from inside the Execute or Initialize methods?
Sorry, I did not look carefully and did not realize all of these happened in the constructor (I have been passing in values to command's constructors to have them do two different things during runtime, although all of that logic was in the subsystem's functions, not the command.) |
|
#9
|
||||
|
||||
|
Re: Command-Based robot button toggle question
While I would be interested in a ToggleButton type that provides this functionality we found the following much easier.
Example of how our shooter works. We use the following pattern for structuring our subsystems. Code:
void raiseShooter(); void lowerShooter(); bool isRaised(); RaiseShooterCommand: Code:
void Execute() {
shooter->raiseShooter();
}
Code:
void Execute() {
shooter->lowerShooter();
}
Code:
void Execute() {
if (shooter->isRaised())
shooter->lowerShooter();
else
shooter->raiseShooter();
}
|
|
#10
|
|||
|
|||
|
Re: Command-Based robot button toggle question
Thanks guys, we ended up going with the put-toggle-code-into-subsystems approach, and it works, so we're happy on that note.
|
|
#11
|
|||
|
|||
|
Re: Command-Based robot button toggle question
We originally did something very much like this final solution. Then we did something more like the command group idea:
Currently we have commands for Do, Undo and Toggle. On Toggle we ask the subsystem what the state is, then do a Start() on the appropriate Do or Undo command to go the other way. We did this because we want the command to indicate which operation is ongoing (Do or Undo) for such reasons as display on the SmartDashboard and logging. |
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|