Command based addparallel addsequential when complete

We have two actions that we wish to execute at the same time.



addparallel(new rotateRobot());
addsequential(new raiseLift());
addsequential(..............

In most cases the robot will be rotated before the lift completes but we expect lift could complete before the rotate and both commands end and the program moves on.
Is this expected behavior with command Based? Are the string of addparallel() commands a slave to the isfinished() method located in the next addsequential() command?

Reading the docs I found this with the addparalle:

Instead of waiting for the child to finish, a {@link CommandGroup} will have it run at the
   * same time as the subsequent {@link Command Commands}. The child will run until either it
   * finishes, a new child with conflicting requirements is started, or the main sequence runs a
   * {@link Command} with conflicting requirements. In the latter two cases, the child will be
   * canceled even if it says it can't be interrupted. </p>

The next step is addsequential(new driveRobot());. So since rotateRobot() requires(robot.drivetrain) and driveRobot() requires(Robot.drivetrain) this is taking control of the subsystem after liftraise() completes.

I guest the question remains. Is there a way to run parallel commands that all must finish before the next step?

When I run into issues like this, I would go about making a flag variable and a waiting command. That command would be placed after raiseLift() and would A) require the drivetrain to prevent movement and B) wait until that flag is set by the first drivetrain movement to confirm it is done.

A command group is considered finished when all the commands in it finish, including any parallel commands. So if you want to wait for both of those to finish, add them to a group and do an addsequential of that new group there.

Brad

Here’s how to do that neatly with an anonymous class:

addSequential(new CommandGroup() {
    {
        addParallel(new rotateRobot());
        addSequential(new raiseLift());
    }
});
addSequential(..............

The extra set of braces inside the anonymous class creates an “initialization block”, which is code that is run when the object is constructed.

I would look at the WaitForChildren command. Running this (via AddSequential) following the last command you want to be run in parallel will cause the main thread to stall until the parallel commands finish.

I like this if i don’t have to create a one off command for every parallel group of commands

That’s a really good solution that I forgot to mention. That lets you sync all the commands in a group without needing more nested command groups.

Thanks all great suggesting and both have valid implications. Seems there are lots of fun tools barried in the library.

Backing up just one page from the above link roborio/beta/docs/java/edu/wpi/first/wpilibj/command/Command.html I often wondered if i could add multiple requires () and call methods from each I that command. With these three options our code could clean up all the special case commands we have listed in programs.

The requires() methods are there to make sure there aren’t 2 commands running at the same time that use the same subsystems (think motors). So you should add a requires() for any subsystem used by your command.

Suppose you had an arm with one command that makes it go up to set point and another that makes it go down to a set point. Both commands require the the arm subsystem and each command is connected to a joystick button. If you were to run the arm up command to start moving the arm up, the while it’s still moving, realize that you really wanted it to go down. Pressing the joystick button for arm down would stop the arm up command and start the arm down command. This is because they each require the arm subsystem. If you left out the requires, then the both commands would start running a the same time and each command would start the arm moving towards it’s goal at the same time, and the results wouldn’t be good.

Incidentally, if you have command groups, you don’t need to have the requires because the group automatically requires ALL the subsystems of the commands in the group.

Brad

Thanks, I always understood the reasoning for requires() it makes good sense to asure only one command controls a motor at any time, but it’s good to review for everyone that happens across the thread.

Also knowing that a command group will inherently require all subsystems that the commands in it require was well established or at least I understood it.

It’s good to know that with a regular command I can add multiple requires() if i wish to control motors from two subsystems with out making command groups.