View Full Version : Handling Exceptional Cases in a CommandGroup
shindigo
19-02-2015, 19:59
Hi all -
I'm looking for some advice on handling exceptional cases in a CommandGroup.
The most common situation we are considering is if one of the commands times out, we want to cancel the whole group, and/or maybe schedule a different group.
Is there any way to do this directly within a CommandGroup or do I have to have the subsystem(s) keep track of what timed out and feed that information on to subsequent commands?
tia -
mp
Hi all -
I'm looking for some advice on handling exceptional cases in a CommandGroup.
The most common situation we are considering is if one of the commands times out, we want to cancel the whole group, and/or maybe schedule a different group.
Is there any way to do this directly within a CommandGroup or do I have to have the subsystem(s) keep track of what timed out and feed that information on to subsequent commands?
tia -
mp
I haven't tried to do this, but since it's been a couple of days, I'll throw out some possibly wild pitches:
Perhaps if you throw an exception that CommandGroup is not ready for, it will stop execution of the group.
Another possibility (sounds a bit more likely) I found in the documentation was:
Any command in the main sequence .. that requires a subsystem in use by a parallel command will cause the parallel command to be canceled.
So, if you start a new command group that requires the same subsystems, it should (as I read the docs) effectively cancel and replace the original command group, which sounds like what you want.
notmattlythgoe
22-02-2015, 12:59
What about something like this?
private Command2 timeoutCommand = new Command2();
public SomethingCommandGroup() {
addSequential(new Command1());
addSequential(timeoutCommand, 5);
addSequential(new Command3());
}
protected boolean isFinished() {
return super.isFinished()
|| timeoutCommand.isTimedOut();
}
Since a CommandGroup is still a Command you can override isFinished() to finish if a certain command or several have timed out.
I am unsure if the timed out command will need reinitialized or not. My gut says no.
Or in your Robot you can have an enum that is kind of like a Robot State, then in your commands in the isFinished method you can say
@Override
protected boolean isFinished() {
// TODO Auto-generated method stub
return (Normal End Condition) || Robot.RobotState != RunningCommandGroupX;
}
its also fairly common to have a state based robot or state based anything really. Lots of video games and Robots are state based.
ps. If you need more help on setting this up just Pm me, Ill be glad to help!
notmattlythgoe
24-02-2015, 08:40
What about something like this?
private Command2 timeoutCommand = new Command2();
public SomethingCommandGroup() {
addSequential(new Command1());
addSequential(timeoutCommand, 5);
addSequential(new Command3());
}
protected boolean isFinished() {
return super.isFinished()
|| timeoutCommand.isTimedOut();
}
Since a CommandGroup is still a Command you can override isFinished() to finish if a certain command or several have timed out.
I am unsure if the timed out command will need reinitialized or not. My gut says no.
Unfortunately, after looking into this a bit further, the commands don't know they've timed out when they are added with a timeout to the CommandGroup. However, you could set a timeout value of the command itself and let it take car of the timeout. To do this you are going to need to increase the visibility of isTimedOut() and setTimeout() to public. Tod o this just add both of these methods to your command like this:
public boolean isTimedOut() {
return super.isTimedOut();
}
public void setTImeout(double timeout) {
super.setTimeout(timeout);
}
Then use it like this:
private Command2 timeoutCommand = new Command2();
public SomethingCommandGroup() {
addSequential(new Command1());
timeoutCommand.setTimeout(5);
addSequential(timeoutCommand);
addSequential(new Command3());
}
protected boolean isFinished() {
return super.isFinished()
|| timeoutCommand.isTimedOut();
}
shindigo
26-02-2015, 15:53
Hi all -
We tested out a successful solution last night: as GeeTwo suggested, a command that requires the same subsystem(s) as a scheduled command will interrupt the scheduled commands.
So in the original Command (within the CommandGroup) when we get a timeout, we schedule a new Command with (something like)
Scheduler.Instance.Add(New StopAllMotors());
This StopAllMotors command requires all subsystems that we want to stop, thus interrupting any running commands.
This works in practice for us - we can see running commands getting interrupted and canceled.
I suppose if we wanted to extend this to do something other than stop all motors, we could try something like:
Scheduler.Instance.Add(New InterruptAllCommands());
Scheduler.Instance.Add(New ExecutePlanB());
Where InterruptAllCommands is a command that just requires all the subsystems we want to reset and ExecutePlanB is our CommandGroup to execute an alternative autonomous plan.
Thanks again for all your great suggestions. Hope someone else profits from this...
mp
vBulletin® v3.6.4, Copyright ©2000-2017, Jelsoft Enterprises Ltd.