This may be exactly what Matt was suggesting, but I think it is a bit more useful than his idea of doing something in initialize of the actual command.
You could write a separate command called CreateCommand. Have this present itself on SmartDashboard along with the arguments. In your case Distance.
then something like:
public class CreateCommand extends Command {
public CreateCommand() {
}
public void initialize() {
double dist=SmartDashboard.getNumber("MoveDistance");
Move moveCmd=new Move(dist);
moveCmd.start();
}
public execute() {
}
public boolean isFinished() {
return true;
}
..
}
So above you type in a distance and hit start, which in turn instantiates the Move command and starts it. It’s singleShot and will return true to isFinsished() always.
Expanding on that idea you could take it a step futher with
public class CreateCommand extends Command {
public CreateCommand() {
}
public void initialize() {
double d1=SmartDashboard.getNumber("double1");
double d2=SmartDashboard.getNumber("double2");
double d3=SmartDashboard.getNumber("double3");
double d4=SmartDashboard.getNumber("double4");
boolean b1=SmartDashboard.getBoolean("boolean1");
boolean b2=SmartDashboard.getBoolean("boolean1");
boolean b3=SmartDashboard.getBoolean("boolean1");
boolean b4=SmartDashboard.getBoolean("boolean1");
String cmdType=SmartDashboard.getString("Command To Create");
if(cmdType=="Move") {
Move myCmd=new Move(d1);
myCmd.start();
}
if(cmdType=="MoveForTime") {
//Assume we have move for time that takes speed, time and
//a boolean for if it should brake at end or not before completing.
MoveForTime myCmd=new MoveForTime(d1,d2,b1);
myCmd.start()
} else {
//some kind of error
System.out.println("Don't have a command for " + cmdType);
}
}
public execute() {
}
public boolean isFinished() {
return true;
}
..
}
Now you can add as many else clauses allowing you to deal with any command that needs to be built with up to 4 doubles and 4 booleans or any subset thereof. But you need a cheat sheet to know what d1 means for Move and what it means for MoveForTime, etc.
Extending this idea even further, two years ago our team created the ability to associate a keyword with each command and add in a parse entry that would receive all the passed args. This allowed us to do things like
D(0.5,4);DP(0.9,120);X;P_L;D(-0.5,2)
which would be parsed into a command group effectively doing
addSequential(new DriveForTime(0.5,4));
addSequential(new DriveToPosition(0.9,120));
addSequential(new ShootSequence());
addParallel(new ReloadSequenc());
addSequential(new DriveForTime(-0.5,2);
During disabledPeriodic we would monitor the string value from SmartDashboard and rebuild the autonomous command any time it changed.
So tuning an autonomous sequence never required a recompile-- just change the string while disabled and then start autonomous again.
We’d head into a tournament with quite a few canned sequences for various situations, or we could quickly write a brand new one if we had to do something unexpected. Once the robot was on out on the field we could paste the sequence we needed into the smart dashboard and look for feedback in the drive station log that it was accepted and we were good to go for autonomous.
Our lead programmer who wrote all this code is gone this year, and the code package he published relies on CommandBase base class. But this year we have generics (which I know nothing about but I understand they are like C++ templates) so I think that might greatly simplify the code needed to accomplish this. That along with a full java with a full complement of parsing functionality we may get there yet this year.
You’re starting down a path that leads to much happiness IMO.