Command Groups

Overview

Command groups combine multiple commands to create complex behaviors. Use them for autonomous routines or coordinated mechanism movements.

Group Types

Two main patterns:

  • Sequential: Commands run one after another, waiting for each to finish.
  • Parallel: Commands run simultaneously, all finishing when the last one completes.
  • Mixed: Combine both patterns for complex routines.

Sequential Commands

Commands execute in order. Each command waits for the previous one to finish before starting. Use new SequentialCommandGroup() to create sequential groups.

Sequential Example

import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.InstantCommand;
import edu.wpi.first.wpilibj2.command.SequentialCommandGroup;

// Run commands one after another
Command autoRoutine = new SequentialCommandGroup(
    new DriveForward(drivetrain).withTimeout(2.0),
    new RunIntake(intake).withTimeout(1.0),
    new InstantCommand(() -> intake.stop(), intake)
);

Parallel Commands

Commands run at the same time. The group finishes when all commands finish. Use new ParallelCommandGroup() to create parallel groups.

Parallel Example

import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.ParallelCommandGroup;

// Run commands simultaneously
Command simultaneous = new ParallelCommandGroup(
    new RaiseElevator(elevator).withTimeout(3.0),
    new ExtendArm(arm).withTimeout(2.0)
);

Mixed Groups

Combine sequential and parallel commands to create complex routines. Groups can contain other groups.

Autonomous Routine Example

package frc.robot;

import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.InstantCommand;
import edu.wpi.first.wpilibj2.command.SequentialCommandGroup;
import edu.wpi.first.wpilibj2.command.ParallelCommandGroup;
import frc.robot.commands.DriveForward;
import frc.robot.commands.RunIntake;
import frc.robot.subsystems.Drivetrain;
import frc.robot.subsystems.Intake;

public class RobotContainer {
    private Drivetrain drivetrain = new Drivetrain();
    private Intake intake = new Intake();
    
    public Command getAutoCommand() {
        return new SequentialCommandGroup(
            new ParallelCommandGroup(
                new DriveForward(drivetrain).withTimeout(2.0),
                new RunIntake(intake).withTimeout(2.0)
            ),
            new InstantCommand(() -> intake.stop(), intake)
        );
    }
}

Timeout & Conditions

Use .withTimeout(seconds) to limit command duration. Use .until(condition) to finish when a condition is met. Chain these methods for precise control.

Resources

Open full interactive app