Quote:
Originally Posted by notmattlythgoe
Code:
...
public class DriveToLine extends CommandGroup {
public DriveToLine() {
addSequential(new DriveCommand(0.5));
addSequential(waitUntil(drivetrain.getDistance(), GREATER_THAN, 50));
addSequential(new DriveCommand(0));
}
}
...
|
Be sure that the command that precedes the conditional command is a one-shot command that executes once and returns immediately. Otherwise, it will never complete and your conditional command will never get a chance to run.
If you're using Java 8, you could simplify most of your code by using lambdas rather than hard-code the comparison operations. For example, your ConditionalWaitCommand can use the `java.util.function.Predicate` functional interface to define when it is completed:
Code:
public class ConditionalWaitCommand extends Command {
public static ConditionalWaitCommand waitUntil( Predicate isComplete ) {
}
private final Predicate isComplete;
private ConditionalWaitCommand(Predicate isComplete) {
this.isComplete = isComplete;
}
@Override
protected void initialize() { }
@Override
protected void execute() {
return isComplete().test();
}
protected boolean isFinished() { }
@Override
protected void end() { }
@Override
protected void interrupted() { }
}
This makes this class very simple but even more flexible than your version. Your DriveToLine command group becomes:
Code:
public class DriveToLine extends CommandGroup {
public DriveToLine() {
addSequential(new DriveCommand(0.5));
addSequential(waitUntil(drivetrain.getDistance() > 50));
addSequential(new DriveCommand(0));
}
}
But sometimes it is much easier just to create a generic and reusable command that is easily instantiated with custom lambdas using static methods. One example might be a very simple but generic Command subclass that takes an optional lambda to run once, a predicate to know when it is complete, and an optional function to run when complete. The static factory methods make this really easy to reuse without having to create a concrete subclass.
Here's what that might look like to create a command instance that drives at 50% power while the distance is greater than 50, and once that condition has occurred then stop:
Code:
Drivetrain driveTrain = ...
Command myCommand = ConditionalCommand.runUntil(driveTrain.drive(0.5),
drivetrain.getDistance() > 50.0,
driveTrain.stop());
where
Code:
public class ConditionalCommand extends Command {
public static ConditionalCommand waitUntil( Runnable initial, Predicate isComplete, Runnable uponComplete ) {
return new ConditionalCommand(initial, isComplete, uponComplete);
}
public static ConditionalCommand waitUntil( Predicate isComplete, Runnable uponComplete ) {
return new ConditionalCommand(initial, isComplete, uponComplete);
}
private final Runnable initial;
private final Predicate isComplete;
private final Runnable uponComplete;
private boolean completed;
private ConditionalCommand(Predicate isComplete) {
this.isComplete = isComplete;
}
@Override
protected void initialize() {
if ( initial != null ) initial.run();
}
@Override
protected void execute() {
if ( isComplete().test() ) {
if ( uponComplete != null ) uponComplete.run();
completed = true;
}
}
protected boolean isFinished() {
return completed;
}
@Override
protected void end() { }
@Override
protected void interrupted() { }
}
This is not the only pattern, either.