|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
| Thread Tools | Rate Thread | Display Modes |
|
#1
|
|||
|
|||
|
Using Coniditionals to Build Custom Command Groups
What is the proper way to build a custom command group based on a runtime change?
Example: Program will look at smartdashboard and get the number of blobs seen. Based on the number it will either drive straight and shot or turn, drive straight and shoot. I tied the following code in the command group constructor. Code:
if (blobs < 2.0) {
addSequential(new DriveToLeftAndPrepareShot());
addSequential(new ShortDelay());
addSequential(new TossBall3QPower());
addSequential(new TossBallResetPosition());
}
else
{
addSequential(new DriveToRightAndPrepareShot());
addSequential(new ShortDelay());
addSequential(new TossBall3QPower());
addSequential(new TossBallResetPosition());
}
I want it to run After autonomous is started. |
|
#2
|
||||||
|
||||||
|
Re: Using Coniditionals to Build Custom Command Groups
Why not have two command groups built, and then decide which to run at the beginning of Autonomous? This is what we've done in the past.
Alternately, you would build the Command Group in your autonomousInit, rather then in the constructor of the Command Group. |
|
#3
|
|||
|
|||
|
Re: Using Coniditionals to Build Custom Command Groups
The addsequential method does not work in a command for me?
It says that it is not defined. I think that only works in a command group? |
|
#4
|
||||||
|
||||||
|
Re: Using Coniditionals to Build Custom Command Groups
That's correct.
|
|
#5
|
||||
|
||||
|
Re: Using Coniditionals to Build Custom Command Groups
One thing we did, was stored the hot value in the Robot variable to reference later.
Here is an example of how we did that: DriveForwardAndWatch: -drives forward for n seconds -watches while doing it -if it determines the goal is hot, writes to the Robot hot variable. WaitForShot: -checks to see whether or not the first command saw hot through the Robot hot variable -if it saw hot, finish -if it didn't wait for n seconds Shoot: - Not exactly what you were looking for, but may be good enough. I for one wish there was a better way to do conditional commands, to support more complex state machines (i.e. firing different commands on success, failure, and timeout). However, I've never really been able to get this to work with the wpilib command structure. |
|
#6
|
||||
|
||||
|
Re: Using Coniditionals to Build Custom Command Groups
Quote:
If you move this statement down into autoInit() you should get what you're asking for, no? Code:
public void autonomousInit() {
// instantiate and schedule the command used for the autonomous period
autonomousCommand = new YourAutoCommand();
autonomousCommand.start();
...
|
|
#7
|
||||
|
||||
|
Re: Using Coniditionals to Build Custom Command Groups
My team created a class just for this purpose here. To use it:
Code:
addSequential(new Conditional(<Command for true>,<Command for false>) {
protected boolean condition() {
return <condition>;
}
});
|
|
#8
|
|||
|
|||
|
Re: Using Coniditionals to Build Custom Command Groups
Quote:
|
|
#9
|
|||
|
|||
|
Re: Using Coniditionals to Build Custom Command Groups
Quote:
|
|
#10
|
||||
|
||||
|
Re: Using Coniditionals to Build Custom Command Groups
We haven't had a chance to thoroughly test it, but initial tests seem successful. The key aspect of this implementation is that it does not just start the Command, but also waits for the Command to finish. There may be an issue with the internal Command killing the CommandGroup it is called from because they each require() the same Subsystem. I will see what I can do to mitigate that.
|
|
#11
|
|||
|
|||
|
Re: Using Coniditionals to Build Custom Command Groups
Quote:
Anyway, I'll be interested to see what solution you come up with! |
|
#12
|
||||
|
||||
|
Re: Using Coniditionals to Build Custom Command Groups
We will not be testing this until later today, but I wanted to share my expected solution to Conditional cancelling itself. It requires an extra class, edu.wpi.first.wpilibj.command.PublicCommand, which just exposes a number of Command's methods that are protected or package-private normally:
Code:
package edu.wpi.first.wpilibj.command;
import java.util.Enumeration;
/** A Command that exposes more internals to the world. */
public class PublicCommand extends Command {
private final Command _c;
public PublicCommand(Command c) {
_c = c;
for(Enumeration e = c.getRequirements();e.hasMoreElements();) {
requires((Subsystem) e.nextElement());
}
}
public Enumeration getRequirements() {
return _c.getRequirements();
}
public void initialize() {
if(_c != null) {
_c.initialize();
}
}
public void _initialize() {
if(_c != null) {
_c._initialize();
}
}
public void execute() {
if(_c != null) {
_c.execute();
}
}
public void _execute() {
if(_c != null) {
_c._execute();
}
}
public boolean isFinished() {
return _c == null || _c.isFinished();
}
public void end() {
if(_c != null) {
_c.end();
}
}
public void _end() {
if(_c != null) {
_c._end();
}
}
public void interrupted() {
if(_c != null) {
_c.interrupted();
}
}
public void _interrupted() {
if(_c != null) {
_c._interrupted();
}
}
}
Code:
package storm2014.commands.control;
import edu.wpi.first.wpilibj.command.Command;
import edu.wpi.first.wpilibj.command.PublicCommand;
import edu.wpi.first.wpilibj.command.Subsystem;
import java.util.Enumeration;
public abstract class Conditional extends Command {
private final PublicCommand _ifTrue,_ifFalse;
private PublicCommand _running = null;
public Conditional(final Command ifTrue,final Command ifFalse) {
// Wrap the Commands to expose protected methods
if(ifTrue != null) {
_ifTrue = new PublicCommand(ifTrue);
for(Enumeration e = _ifTrue.getRequirements();e.hasMoreElements();) {
requires((Subsystem) e.nextElement());
}
} else {
_ifTrue = null;
}
if(ifFalse != null) {
_ifFalse = new PublicCommand(ifFalse);
for(Enumeration e = _ifFalse.getRequirements();e.hasMoreElements();) {
requires((Subsystem) e.nextElement());
}
} else {
_ifFalse = null;
}
}
protected abstract boolean condition();
protected void initialize() {
if(condition()) {
_running = _ifTrue;
} else {
_running = _ifFalse;
}
if(_running != null) {
_running._initialize();
_running.initialize();
}
}
protected void execute() {
if(_running != null) {
_running._execute();
_running.execute();
}
}
protected boolean isFinished() {
return _running == null || _running.isFinished();
}
protected void end() {
if(_running != null) {
_running._end();
_running.end();
}
}
protected void interrupted() {
if(_running != null) {
_running._interrupted();
_running.interrupted();
}
}
}
Last edited by Ginto8 : 15-02-2014 at 05:00. |
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|