# 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.

{% hint style="info" %}
This command is available in both [SolversLib](https://docs.seattlesolvers.com/) and [NextFTC](https://nextftc.dev/) (separate packages).
{% endhint %}

***

## 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.

```java
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:

```java
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:

{% hint style="info" %}
This is by no means a functional autonomous program.
{% endhint %}

```java
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](https://github.com/Skeleton-Army/Marrow/tree/main/core/src/main/java/com/skeletonarmy/marrow/automation).

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