Skip to content

Comments

Ratio Coupling#48

Open
ShmayaR wants to merge 2 commits intomainfrom
ratio-coupling
Open

Ratio Coupling#48
ShmayaR wants to merge 2 commits intomainfrom
ratio-coupling

Conversation

@ShmayaR
Copy link
Contributor

@ShmayaR ShmayaR commented Feb 14, 2026

No description provided.

@coderabbitai
Copy link

coderabbitai bot commented Feb 14, 2026

Warning

Rate limit exceeded

@ShmayaR has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 3 minutes and 51 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Walkthrough

Two swerve module files were modified. SwerveModuleConstants adds a new COUPLED_RATIO constant and updates DRIVE_MOTOR_GEAR_RATIO from 7.03 to 6.03. SwerveModule re-enables three imports and modifies getDriveWheelPositionRadians to apply steering angle coupling by subtracting steering rotation scaled by COUPLED_RATIO before converting to radians. In setTargetClosedLoopDriveVelocity, a local velocityToSet variable is calculated using COUPLED_RATIO but remains unused in the subsequent motor control call, which continues using the original targetDriveVelocityRotationsPerSecond value.

🚥 Pre-merge checks | ✅ 1 | ❌ 3
❌ Failed checks (2 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Merge Conflict Detection ⚠️ Warning ❌ Merge conflicts detected (24 files):

⚔️ src/main/deploy/pathplanner/navgrid.json (content)
⚔️ src/main/java/frc/trigon/lib (content)
⚔️ src/main/java/frc/trigon/robot/RobotContainer.java (content)
⚔️ src/main/java/frc/trigon/robot/commands/commandclasses/IntakeAssistCommand.java (content)
⚔️ src/main/java/frc/trigon/robot/commands/commandclasses/LEDAutoSetupCommand.java (content)
⚔️ src/main/java/frc/trigon/robot/commands/commandfactories/ClimbCommands.java (content)
⚔️ src/main/java/frc/trigon/robot/commands/commandfactories/FuelIntakeCommands.java (content)
⚔️ src/main/java/frc/trigon/robot/commands/commandfactories/ShootingCommands.java (content)
⚔️ src/main/java/frc/trigon/robot/constants/AutonomousConstants.java (content)
⚔️ src/main/java/frc/trigon/robot/constants/FieldConstants.java (content)
⚔️ src/main/java/frc/trigon/robot/misc/MatchTracker.java (content)
⚔️ src/main/java/frc/trigon/robot/misc/shootingphysics/ShootingCalculations.java (content)
⚔️ src/main/java/frc/trigon/robot/misc/simulatedfield/SimulatedGamePieceConstants.java (content)
⚔️ src/main/java/frc/trigon/robot/misc/simulatedfield/SimulationFieldHandler.java (content)
⚔️ src/main/java/frc/trigon/robot/subsystems/climber/Climber.java (content)
⚔️ src/main/java/frc/trigon/robot/subsystems/climber/ClimberConstants.java (content)
⚔️ src/main/java/frc/trigon/robot/subsystems/hood/HoodConstants.java (content)
⚔️ src/main/java/frc/trigon/robot/subsystems/shooter/ShooterConstants.java (content)
⚔️ src/main/java/frc/trigon/robot/subsystems/swerve/Swerve.java (content)
⚔️ src/main/java/frc/trigon/robot/subsystems/swerve/SwerveCommands.java (content)
⚔️ src/main/java/frc/trigon/robot/subsystems/swerve/swervemodule/SwerveModule.java (content)
⚔️ src/main/java/frc/trigon/robot/subsystems/swerve/swervemodule/SwerveModuleConstants.java (content)
⚔️ src/main/java/frc/trigon/robot/subsystems/turret/Turret.java (content)
⚔️ src/main/java/frc/trigon/robot/subsystems/turret/TurretConstants.java (content)

These conflicts must be resolved before merging into main.
Resolve conflicts locally and push changes to this branch.
Description check ❓ Inconclusive No description was provided by the author, making it impossible to assess relevance to the changeset. Add a description explaining what ratio coupling is, why DRIVE_MOTOR_GEAR_RATIO changed from 7.03 to 6.03, and how the coupling affects swerve module behavior.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Ratio Coupling' directly describes the main technical change: introducing COUPLED_RATIO constant and modifying drive gear ratio coupling logic.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Comment on lines 117 to 122
public double getDriveWheelPositionRadians() {
return edu.wpi.first.math.util.Units.rotationsToRadians(driveMotor.getSignal(TalonFXSignal.POSITION));
final double driveWheelPositionRotations = driveMotor.getSignal(TalonFXSignal.POSITION);
final double wheelAngleRotations = getCurrentSteerAngle().getRotations();
final double driveWheelPositionWithCouplingRatioRotations = driveWheelPositionRotations - (wheelAngleRotations * SwerveModuleConstants.COUPLED_RATIO);
return edu.wpi.first.math.util.Units.rotationsToRadians(driveWheelPositionWithCouplingRatioRotations);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, let's locate and examine the SwerveModule.java file
find . -name "SwerveModule.java" -type f

Repository: Programming-TRIGON/RobotCode2026

Length of output: 157


🏁 Script executed:

#!/bin/bash
# Read the relevant section of the file (around lines 117-136)
sed -n '110,145p' ./src/main/java/frc/trigon/robot/subsystems/swerve/swervemodule/SwerveModule.java

Repository: Programming-TRIGON/RobotCode2026

Length of output: 1939


🏁 Script executed:

#!/bin/bash
# Search for calls to getDriveWheelPositionRadians and getOdometryPosition
rg -n --type=java 'getDriveWheelPositionRadians|getOdometryPosition' --max-count=30

Repository: Programming-TRIGON/RobotCode2026

Length of output: 690


🏁 Script executed:

#!/bin/bash
# Search for where latestOdometryDrivePositions is populated
rg -n --type=java 'latestOdometryDrivePositions\s*=' -B2 -A2

Repository: Programming-TRIGON/RobotCode2026

Length of output: 714


🏁 Script executed:

#!/bin/bash
# Look at the full SwerveModule class to understand the context better
wc -l ./src/main/java/frc/trigon/robot/subsystems/swerve/swervemodule/SwerveModule.java

Repository: Programming-TRIGON/RobotCode2026

Length of output: 161


🏁 Script executed:

#!/bin/bash
# Look at the context around where latestOdometryDrivePositions and latestOdometrySteerPositions are populated
sed -n '75,95p' ./src/main/java/frc/trigon/robot/subsystems/swerve/swervemodule/SwerveModule.java

Repository: Programming-TRIGON/RobotCode2026

Length of output: 896


🏁 Script executed:

#!/bin/bash
# Check the whole update method and surrounding context
sed -n '70,100p' ./src/main/java/frc/trigon/robot/subsystems/swerve/swervemodule/SwerveModule.java

Repository: Programming-TRIGON/RobotCode2026

Length of output: 1272


🏁 Script executed:

#!/bin/bash
# Search for any comments or documentation about coupling correction in odometry
rg -n --type=java 'coupling|COUPLED_RATIO' -B2 -A2

Repository: Programming-TRIGON/RobotCode2026

Length of output: 2406


🏁 Script executed:

#!/bin/bash
# Check how driveWheelRotationsToMeters is implemented to understand the conversion
rg -n --type=java 'driveWheelRotationsToMeters' -A5

Repository: Programming-TRIGON/RobotCode2026

Length of output: 2309


🏁 Script executed:

#!/bin/bash
# Look at the broader context of where these methods are called to understand intent
sed -n '145,160p' ./src/main/java/frc/trigon/robot/subsystems/swerve/Swerve.java

Repository: Programming-TRIGON/RobotCode2026

Length of output: 824


🏁 Script executed:

#!/bin/bash
# Check around line 326 in Swerve.java to see how getOdometryPosition is used
sed -n '320,335p' ./src/main/java/frc/trigon/robot/subsystems/swerve/Swerve.java

Repository: Programming-TRIGON/RobotCode2026

Length of output: 1022


Apply coupling correction in getOdometryPosition for consistency with getDriveWheelPositionRadians.

getDriveWheelPositionRadians compensates for steering coupling, but getOdometryPosition calls driveWheelRotationsToMeters on the raw odometry drive position without any correction. This inconsistency means pose estimates from odometry will diverge from the coupling-corrected position used elsewhere.

Apply the same correction in getOdometryPosition using the odometry steer angle snapshot (latestOdometrySteerPositions[odometryUpdateIndex]) to maintain temporal consistency:

final double drivePositionWithCouplingCorrected = latestOdometryDrivePositions[odometryUpdateIndex] - 
    (Rotation2d.fromRotations(latestOdometrySteerPositions[odometryUpdateIndex]).getRotations() * SwerveModuleConstants.COUPLED_RATIO);
return new SwerveModulePosition(
    driveWheelRotationsToMeters(drivePositionWithCouplingCorrected),
    Rotation2d.fromRotations(latestOdometrySteerPositions[odometryUpdateIndex])
);

Comment on lines 158 to 164
private void setTargetClosedLoopDriveVelocity(double targetVelocityMetersPerSecond) {
final double targetDriveVelocityRotationsPerSecond = metersToDriveWheelRotations(targetVelocityMetersPerSecond);
final double driveRateBackOut = targetDriveVelocityRotationsPerSecond * SwerveModuleConstants.COUPLED_RATIO;
final double velocityToSet = driveRateBackOut;

driveMotor.setControl(driveVelocityRequest.withVelocity(targetDriveVelocityRotationsPerSecond));
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

velocityToSet is computed but never used—the motor still receives the uncorrected velocity.

Line 163 passes targetDriveVelocityRotationsPerSecond to the motor instead of velocityToSet. The coupling compensation has no effect.

Additionally, the formula itself looks incorrect. Coupling compensation for velocity should involve the steer velocity, not the drive velocity. The typical pattern is:

velocityToSet = targetDriveVelocityRotationsPerSecond + steerVelocityRotationsPerSecond * COUPLED_RATIO

This adds a feed-forward term to counteract the parasitic drive caused by steering motion. Right now driveRateBackOut = targetDriveVelocityRotationsPerSecond * COUPLED_RATIO scales the drive velocity by the coupling ratio, which doesn't model the physical coupling.

Proposed fix (verify the coupling direction sign for your module)
 private void setTargetClosedLoopDriveVelocity(double targetVelocityMetersPerSecond) {
     final double targetDriveVelocityRotationsPerSecond = metersToDriveWheelRotations(targetVelocityMetersPerSecond);
-    final double driveRateBackOut = targetDriveVelocityRotationsPerSecond * SwerveModuleConstants.COUPLED_RATIO;
-    final double velocityToSet = driveRateBackOut;
+    final double steerVelocityRotationsPerSecond = steerMotor.getSignal(TalonFXSignal.VELOCITY);
+    final double couplingCompensation = steerVelocityRotationsPerSecond * SwerveModuleConstants.COUPLED_RATIO;
+    final double velocityToSet = targetDriveVelocityRotationsPerSecond + couplingCompensation;

-    driveMotor.setControl(driveVelocityRequest.withVelocity(targetDriveVelocityRotationsPerSecond));
+    driveMotor.setControl(driveVelocityRequest.withVelocity(velocityToSet));
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private void setTargetClosedLoopDriveVelocity(double targetVelocityMetersPerSecond) {
final double targetDriveVelocityRotationsPerSecond = metersToDriveWheelRotations(targetVelocityMetersPerSecond);
final double driveRateBackOut = targetDriveVelocityRotationsPerSecond * SwerveModuleConstants.COUPLED_RATIO;
final double velocityToSet = driveRateBackOut;
driveMotor.setControl(driveVelocityRequest.withVelocity(targetDriveVelocityRotationsPerSecond));
}
private void setTargetClosedLoopDriveVelocity(double targetVelocityMetersPerSecond) {
final double targetDriveVelocityRotationsPerSecond = metersToDriveWheelRotations(targetVelocityMetersPerSecond);
final double steerVelocityRotationsPerSecond = steerMotor.getSignal(TalonFXSignal.VELOCITY);
final double couplingCompensation = steerVelocityRotationsPerSecond * SwerveModuleConstants.COUPLED_RATIO;
final double velocityToSet = targetDriveVelocityRotationsPerSecond + couplingCompensation;
driveMotor.setControl(driveVelocityRequest.withVelocity(velocityToSet));
}

import frc.trigon.robot.constants.AutonomousConstants;

public class SwerveModuleConstants {
static final double COUPLED_RATIO = 3;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Add a brief comment explaining what COUPLED_RATIO represents physically.

The other gear ratios have clarifying comments (e.g., R1: 7.03, R2: 6.03, R3: 5.27). A similar note here—e.g., the bevel gear teeth ratio or the mechanical source of this value—would help future readers understand why it's 3 and when it should change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant