Go to Post Yes, it is fun. Its fun to watch the students expand their thinking and look outside the "normal" and watch their thoughts explode! Its also fun to watch the mentor's minds fry trying to out think the students.;) - Robert Cawthon [more]
Home
Go Back   Chief Delphi > Technical > Programming > Java
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
 
 
Thread Tools Rate Thread Display Modes
Prev Previous Post   Next Post Next
  #2   Spotlight this post!  
Unread 15-11-2015, 14:20
randallh randallh is offline
Registered User
FRC #4931
 
Join Date: Oct 2015
Location: Greater St. Louis area
Posts: 15
randallh is on a distinguished road
Re: Java Conditional Command

Quote:
Originally Posted by notmattlythgoe View Post
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.
Reply With Quote
 


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump


All times are GMT -5. The time now is 11:51.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi