RetryCommand

Overview

RetryCommand is a powerful command for building robust and adaptable command sequences. It runs a command and, if a specified condition isn’t met upon completion, automatically retries it—either by re-running the same command or switching to a different one—up to a defined number of times.

This is especially useful for actions that may fail on the first attempt, such as vision-based alignment, object grabbing, or precise mechanism positioning.

This command is available in both SolversLib and NextFTC (separate packages).


Usage

Setup

To use RetryCommand, you need to provide the constructor with:

  • The command to run – the initial action you want to execute.

  • (Optional) A different command to run on retries – lets you customize the retry behavior per attempt (e.g., switching to a vision-assisted command if the initial attempt fails).

  • A retry condition – a function that checks whether the action was successful. If this condition returns true, the command will be retried.

  • The maximum number of retries – defines the maximum number of times the command can be retried.

new RetryCommand(
    new GrabCommand(claw),   // Command to run.
    () -> !claw.isGrabbed(), // If this condition is true
    5                        // retry up to 5 times.
)

Or with custom retry logic:

new RetryCommand(
    new GrabCommand(claw),                  // Command to run initially.
    new DetectAndGrabCommand(claw, vision), // Command to run on each retry.
    () -> !claw.isGrabbed(),                // If this condition is true
    5                                       // retry up to 5 times.
)

Example Usage

The following is an example autonomous program that showcases RetryCommand's functionality, using SolversLib's command system:

This is by no means a functional autonomous program.

public class MyAuto extends CommandOpMode {
    private ClawSubsystem clawSubsystem;
    private VisionSubsystem visionSubsystem;

    @Override
    public void initialize() {
        clawSubsystem = new ClawSubsystem(hardwareMap);
        visionSubsystem = new VisionSubsystem(hardwareMap);

        schedule(
            new SequentialCommandGroup(
                // First, try to grab. If unsuccessful, retry grabbing up to 3 times.
                new RetryCommand(
                    new GrabCommand(clawSubsystem),
                    () -> !clawSubsystem.isHoldingGameElement(),
                    3
                ),
                
                // ---- OR ----
                
                // First, try to grab. If unsuccessful, try to detect and grab using vision up to 3 times.
                new RetryCommand(
                    new GrabCommand(clawSubsystem),
                    new DetectAndGrabCommand(clawSubsystem, visionSubsystem), 
                    () -> !clawSubsystem.isHoldingGameElement(),
                    3
                )
            )
        );
    }
}

Source Code

You can check out the source code on the GitHub repository.

If you are using an unsupported command-based library and want to implement this command in your codebase, you may do so.

Last updated