> 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/reference/swerve-drift-causes.md).

# Swerve Drive Drift: Causes and Tuning Order

Swerve drive drift has been a persistent problem for many years, and there have been many discussions as to why it happens. This is a lookup of common causes, followed by the fixed tuning order that removes what's left. For step-by-step tuning instructions, see [How to Tune PIDF Gains](/how-to-guides/tune-pidf-gains.md).

It's important to keep in mind that SEVERAL of these issues could be present on your robot at once.

## Hardware causes

### Wiring

Incorrect, worn, or loose wiring produces different symptoms depending on which connector is affected.

**Encoder**

* [ ] Telemetry readings are erratic and nonsensical.
* [ ] Motor could spin out of control.
* [ ] Errors appear in the Driver Station console.

**Motor controller**

* [ ] Telemetry may be slow to update.
* [ ] Motors may suddenly stop or spin out of control.
* [ ] Motors may not respond to commands.
* [ ] Errors appear in the Driver Station console.

**Gyroscope**

* [ ] Telemetry may be slow to update.
* [ ] Field-relative robot control may be unusable.
* [ ] Autonomous drifts uncontrollably.
* [ ] Errors appear in the Driver Station console.
* [ ] The gyro is moving/shaking violently, or shifted during movement.

### Physical components

**Magnetic (absolute) encoder**

* [ ] Magnet is not secured to the swerve module and slips while in motion — absolute encoder offsets would need constant readjustment until the magnet is secured (loctite/glue it in).
* [ ] Magnetic encoder itself is not secured to the module.

**Motor**

* [ ] Motor doesn't have a firm connection to the module shaft — it will "twitch" while running if a current limit is set.
* [ ] Motor is dying — it may pull more current to hit the same speeds.

**Swerve module**

* [ ] Wheels are misaligned.
* [ ] Modules behave inconsistently with the same PID gains — grease may need to be applied to the gears.

**Robot**

* [ ] Robot center of gravity is not ideal.

## Software causes

* [ ] Constant `Command Scheduler loop overruns` because of other parts of your code.
* [ ] Maximum physical velocity isn't set correctly — see `SwerveDriveConfig.withMaximumChassisSpeed()`/`withMaximumModuleSpeed()`.
* [ ] If using open-loop control, modules run at different speeds.
* [ ] Controller input filtering.
* [ ] Discretization not compensating for system delay — see `SwerveDriveConfig.withDiscretizationTime()`.
* [ ] Vision measurement standard deviations aren't tuned — see `SwerveDrive.addVisionMeasurement()`/`setVisionMeasurementStdDevs()`.
* [ ] Gyro offset drifted — see `SwerveDrive.zeroGyro()` / `SwerveDriveConfig.withGyroOffset()`.

{% hint style="info" %}
Several runtime tuning knobs from older YAGSL versions (`setCosineCompensator`, `setHeadingCorrection`, `setAntiJitter`, `chassisVelocityCorrection`, `setMaximumSpeeds`, `replaceSwerveModuleFeedforward`, `setOdometryPeriod`, `updateCacheValidityPeriods`) no longer exist as runtime methods on `SwerveDrive`. Cosine compensation is now always enabled internally by the parser, and the rest are configured once, up front, via `SwerveDriveConfig`/`SwerveModuleConfig` (or `pidfproperties.json`'s `s`/`v`/`a` feedforward terms) rather than toggled at runtime. See the [API reference](/reference/api-reference.md) and [schema changes reference](/reference/schema-changes.md) for what replaced each.
{% endhint %}

### PathPlanner

* [ ] PathPlanner `AutoBuilder` PIDs aren't tuned well.
* [ ] Maximum module velocity is too high or too low.
* [ ] Test path is curved instead of straight.
* [ ] PathPlanner auto doesn't define a preset starting pose.
* [ ] PathPlanner path doesn't reset odometry on start.

## Configuration causes

* [ ] Module locations aren't defined correctly — remember these are measured from the center of the robot to the center of the module. See [how to verify module locations](/how-to-guides/verify-module-locations.md).
* [ ] Swerve module JSON doesn't have the correct device definitions for the absolute encoder, angle motor, or drive motor.
* [ ] A module's `gearing` override in its module JSON disagrees with the default in `physicalproperties.json`.
  * A per-module `gearing` override is completely **OPTIONAL** and shouldn't be defined unless you have a specific reason (e.g. one swapped module with a different ratio) — otherwise rely on `physicalproperties.json` to avoid drift between modules.
* [ ] The gear ratio/wheel diameter is not correct.
  * If your swerve drive consistently travels further than expected with PathPlanner, this is a likely cause.
  * If your angle motors never align the module correctly, this can also cause it.
* [ ] Drive and steering/azimuth/angle motor PIDs aren't tuned well enough — see [how to tune PIDF gains](/how-to-guides/tune-pidf-gains.md).
* [ ] The current limit (`statorCurrentLimit`) is too low.
* [ ] [Translational axis changes with robot orientation](/how-to-guides/the-8-steps.md).

## Tuning order

Once hardware and configuration issues are ruled out, tune in this order — each step builds on the last, so redoing an earlier one (or replacing hardware like your gyro) means redoing everything after it:

1. **Drive and angle PID** — see [how to tune PIDF gains](/how-to-guides/tune-pidf-gains.md). Do this first; nothing else is worth tuning until the modules track their setpoints well.
2. **Vision standard deviation**, if you're using vision to help odometry — tune `SwerveDrive.setVisionMeasurementStdDevs()` mostly by guess-and-check, scaling with distance. Some teams get better stability by filtering out vision poses beyond a certain distance.
3. **Discretization**, to compensate for system delay — `SwerveDriveConfig.withDiscretizationTime()`. See [chassis control](/explanation/chassis-control.md) for what this does and why it matters.
4. **Gyro angular velocity scale factor**, to compensate for gyro system delay — `SwerveDriveConfig.withGyroAngularVelocityScaleFactor()` (less necessary with a Pigeon 2 on a CANivore, which has very low latency).

{% hint style="warning" %}
If you mess with a lower step, all the higher steps will be out of sync — and if you replace a part like your gyro, you may need to redo all of it anyway.
{% endhint %}

The math-heavy explanation of tuning out drift is available here:

{% embed url="<https://github.com/calcmogul/controls-engineering-in-frc>" %}


---

# 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/reference/swerve-drift-causes.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.
