> For the complete documentation index, see [llms.txt](https://yagsl.yassrobotics.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yagsl.yassrobotics.com/how-to-guides/the-8-steps.md).

# The 8 steps

## Something is wrong but it's driving-ish?

When changing inversion states doesn't work and nothing else you know of fixes the issue, debugging can be painful and arduous. Here are the eight steps that are unfortunately necessary to work through it.

Affectionately known as *"Translational Axis change based off of the robot heading"* (the X and Y axis change in field-oriented control based on your robot turning), these steps will resolve it somewhere along the way.

## Prepare your robot code

To run these tests quickly and effectively, use the following (or a variation of it) as your drive code. You may need to port it to your joystick or negate axis data, but this will help you debug faster.

{% code title="RobotContainer.java" %}

```java
SwerveDriveSubsystem drivebase;
CommandXboxController driverXbox;

// Applies deadbands and inverts controls because joysticks
// are back-right positive while robot controls are front-left positive.
// Left stick controls translation, right stick controls the desired
// heading directly (NOT angular rotation).
SwerveInputStream driveDirectAngle =
    new SwerveInputStream(drivebase.getSwerveDrive(),
                          () -> -driverXbox.getLeftY(),
                          () -> -driverXbox.getLeftX(),
                          () -> -driverXbox.getRightX(),
                          () -> -driverXbox.getRightY())
        .withAllianceRelativeControl();

drivebase.setDefaultCommand(drivebase.drive(driveDirectAngle));
```

{% endcode %}

This uses the four-argument `SwerveInputStream(drive, x, y, headingX, headingY)` constructor, which drives directly to a heading computed from the right stick instead of an angular velocity — the same "point the stick where you want the robot to face" behavior the old `SwerveController.getTargetSpeeds()` heading-hold path provided. If you're using the two-argument angular-velocity constructor instead, the steps below are identical; only the exact symptom description changes slightly.

## The eight steps

{% hint style="danger" %}
**The steps are dangerous!**

6 of them will cause your robot to spin out of control.

1 of them will be correct.

1 of them will appear to be correct but have the translational axis change based on the robot's heading.
{% endhint %}

{% hint style="warning" %}
You are not expected to complete all of these steps to get a functioning swerve drive — somewhere along the way your issue should disappear.
{% endhint %}

1. Start by setting `gyroInvert` in `swervedrive.json` to `false` **AND** `drive.inverted` to `false` in every module JSON.
2. THEN set `gyroInvert` to `true`.
3. THEN invert all of the drive motors in the module JSONs by setting `inverted.drive` to `true`.
4. THEN set `gyroInvert` back to `false`.
5. THEN [flip the modules](#user-content-fn-1)[^1].\\

   <figure><img src="/files/ssEuCY0WRJ82tOLchCIO" alt=""><figcaption><p>Depiction of flipping the modules correctly.</p></figcaption></figure>
6. THEN un-invert all of the drive motors (`inverted.drive` back to `false`).
7. THEN set `gyroInvert` to `true`.
8. THEN set your drive motors' `inverted.drive` back to `true`.

{% hint style="danger" %}
IF none of these work, you most likely have an incorrect hardware configuration, something is not working as expected, or something is wired incorrectly.
{% endhint %}

## Verifying behavior

Sometimes the eight steps don't look done when they really are. Here's an example where the robot is actually tuned correctly, but the desired front of the robot is really the back of the robot.

<details>

<summary>How to swap module configurations</summary>

For the examples, we label modules with numbers to reduce confusion; when changing module files around, we assign the numbers to the respective initial module configuration names. For the example above:

1. `frontleft.json`
2. `frontright.json`
3. `backleft.json`
4. `backright.json`

**Swapping `frontleft.json` with `backright.json`**

```json
{
  "drive": { "type": "sparkmax_neo", "id": 4, "canbus": "" },
  "angle": { "type": "sparkmax_neo", "id": 3, "canbus": "" },
  "absoluteEncoder": { "type": "cancoder_can", "id": 9, "channel": 0, "canbus": "" },
  "inverted": { "drive": false, "angle": false },
  "absoluteEncoderOffset": -114.609,
  "location": { "front": 12, "left": 12 }
}
```

```json
{
  "drive": { "type": "sparkmax_neo", "id": 5, "canbus": "" },
  "angle": { "type": "sparkmax_neo", "id": 6, "canbus": "" },
  "absoluteEncoder": { "type": "cancoder_can", "id": 11, "channel": 0, "canbus": "" },
  "inverted": { "drive": false, "angle": false },
  "absoluteEncoderOffset": -18.281,
  "location": { "front": -12, "left": -12 }
}
```

Swap the device IDs and offsets between the two files (keep each file's own `location`) and you've swapped the module configurations correctly.

#### The easy way

1. Change the `location` negations to the desired module side.
2. Rename the files without overwriting each other.

</details>

[^1]: Change the device configuration for the drive AND angle motor controllers AND the absolute encoders in the following way:

    (Front Left -> Back Right) (Front Right -> Back Left) (Back Left -> Front Right) (Back Right -> Front Left)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://yagsl.yassrobotics.com/how-to-guides/the-8-steps.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
