For the complete documentation index, see llms.txt. This page is also available as Markdown.

Module Behaviors

Module-level control behaviors and why they exist

YAMS's SwerveModule/SwerveModuleConfig provide a handful of behaviors beyond "go to this angle at this speed." This page explains what each one does and why it matters. Where a behavior is configurable, it's noted below — several of these are currently hardcoded on by SwerveParser and are not yet exposed as JSON fields.

Cosine Compensation

Cosine compensation scales the speed of your wheel by the cosine of the angle delta between the module's current angle and its commanded angle. While a module is still rotating to its target angle, driving it at full commanded speed wastes power and skids the wheel — scaling speed down by how far off-angle the module still is keeps the wheel's actual velocity vector closer to what was commanded.

SwerveModuleConfig exposes this as .withCosineCompensation(boolean). Today, SwerveParser always builds modules with cosine compensation enabled (SwerveParser.createSwerveModule hardcodes .withCosineCompensation(true)) — there is no JSON field to disable it. If you need it off (e.g. to compare behavior in simulation), you would need to construct the SwerveModuleConfig yourself rather than going through SwerveParser.

Heading Correction / Heading-Snap Control

Heading correction keeps the robot facing a fixed heading while translating with no rotation input, or snaps to a heading chosen by a second controller axis. It used to be a JSON-configured PID (controllerproperties.json, driven by SwerveController.headingCalculate) that ran automatically inside SwerveDrive.drive(). That class and JSON file no longer exist.

Heading control now lives in your robot code via yams.mechanisms.swerve.utility.SwerveInputStream, and the PID gains for it are supplied directly in Java through SwerveDriveConfig.withRotationController(PIDController):

var cfg = new SwerveDriveConfig()
    .withRotationController(new PIDController(1.0, 0, 0))
    .withTranslationController(new PIDController(1.0, 0, 0));

SwerveInputStream headingStream = angularVelocityStream.clone()
    .withControllerHeadingAxis(driver::getRightX, driver::getRightY)
    .withHeadingControl(() -> driver.getRightStickButton());

This is a deliberate architectural change: heading control is now composed per-SwerveInputStream (you can have multiple drive modes with different heading behavior) rather than a single global toggle on SwerveDrive.

Module Auto-synchronization

Absolute encoders and the motor controller's internal relative encoder can drift apart over a match (belt slip, CAN dropouts, etc). Auto-synchronization periodically re-zeros the internal encoder against the absolute encoder when the module has been at rest and the two disagree by more than a threshold.

This used to be a SwerveDrive-level toggle: SwerveDrive.setModuleEncoderAutoSynchronize(boolean, double). It is now configured per motor controller, via SmartMotorControllerConfig.withFeedbackSynchronizationThreshold(Angle):

Note this is currently only supported on REV SPARK-family controllers in YAMS — CTRE TalonFX/TalonFXS wrappers throw if you set this option, since those controllers handle absolute/relative fusion differently.

Offset Offloading (External vs. Internal Feedback Sensor)

Offset offloading is where the absolute encoder position (or an attached absolute encoder's offset) is used directly as the motor controller's feedback sensor, instead of the control system (roboRIO today, SystemCore starting in 2027) reading the absolute encoder and re-seeding a separate relative encoder in software. This usually means a faster, more direct control loop, at the cost of a little resilience if that sensor connection drops mid-match.

Today, SwerveDriveConfig.useExternalFeedbackSensor() is hardcoded to always return true in the current YAMS release — external feedback (offset offloading) is always used when an absolute encoder is attached directly to the azimuth motor controller's dataport. There is no JSON field or builder setter to disable this yet.

Auto-centering Modules

The old YAGSL had an "auto-centering" behavior (SwerveDrive.setAutoCenteringModules, SwerveModule.setAntiJitter) that snapped idle modules back to 0° when no drive input was present. This behavior could not be found anywhere in the current YAMS source — it does not appear to have been ported to the new architecture. If your team relied on this, treat it as removed rather than renamed; open an issue if you need it back.

Angular Velocity Compensation

The old YAGSL compensated for a known skew effect: when translating and rotating at the same time, a swerve drive's actual path bows away from the commanded path unless you correct for it (a technique pioneered by Jack-in-the-bot, enabled via SwerveDrive.setAngularVelocityCompensation(boolean, boolean, double)).

This has been ported to YAMS under a new name: SwerveDriveConfig.withGyroAngularVelocityScaleFactor(double scaleFactor), with withSimGyroAngularVelocityScaleFactor(double) as a simulation-only override. Both take a [0, 1] scale factor applied to the gyro's angular velocity for skew correction, and require SwerveDriveConfig.withGyroVelocity(Supplier<AngularVelocity>) to be set. See Swerve Drive Drift: Causes and Tuning Order for where this fits in the tuning order, and note that Chassis Speed Discretization addresses a related but distinct skew problem.

Last updated

Was this helpful?