-
Notifications
You must be signed in to change notification settings - Fork 1
Ratio Coupling #48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Ratio Coupling #48
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -8,14 +8,14 @@ | |||||||||||||||||||||||||||||||
| import edu.wpi.first.math.kinematics.SwerveModuleState; | ||||||||||||||||||||||||||||||||
| import edu.wpi.first.units.Units; | ||||||||||||||||||||||||||||||||
| import edu.wpi.first.wpilibj.sysid.SysIdRoutineLog; | ||||||||||||||||||||||||||||||||
| import frc.trigon.robot.constants.RobotConstants; | ||||||||||||||||||||||||||||||||
| import frc.trigon.robot.poseestimation.robotposeestimator.RobotPoseEstimatorConstants; | ||||||||||||||||||||||||||||||||
| import frc.trigon.robot.subsystems.swerve.SwerveConstants; | ||||||||||||||||||||||||||||||||
| import frc.trigon.lib.hardware.phoenix6.cancoder.CANcoderEncoder; | ||||||||||||||||||||||||||||||||
| import frc.trigon.lib.hardware.phoenix6.cancoder.CANcoderSignal; | ||||||||||||||||||||||||||||||||
| import frc.trigon.lib.hardware.phoenix6.talonfx.TalonFXMotor; | ||||||||||||||||||||||||||||||||
| import frc.trigon.lib.hardware.phoenix6.talonfx.TalonFXSignal; | ||||||||||||||||||||||||||||||||
| import frc.trigon.lib.utilities.Conversions; | ||||||||||||||||||||||||||||||||
| import frc.trigon.robot.constants.RobotConstants; | ||||||||||||||||||||||||||||||||
| import frc.trigon.robot.poseestimation.robotposeestimator.RobotPoseEstimatorConstants; | ||||||||||||||||||||||||||||||||
| import frc.trigon.robot.subsystems.swerve.SwerveConstants; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| public class SwerveModule { | ||||||||||||||||||||||||||||||||
| private final TalonFXMotor | ||||||||||||||||||||||||||||||||
|
|
@@ -102,7 +102,9 @@ public void setTargetSteerAngle(Rotation2d angle) { | |||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| public SwerveModuleState getCurrentState() { | ||||||||||||||||||||||||||||||||
| return new SwerveModuleState(driveWheelRotationsToMeters(driveMotor.getSignal(TalonFXSignal.VELOCITY)), getCurrentSteerAngle()); | ||||||||||||||||||||||||||||||||
| final Rotation2d currentSteerAngle = getCurrentSteerAngle(); | ||||||||||||||||||||||||||||||||
| final double currentDriveVelocity = driveMotor.getSignal(TalonFXSignal.VELOCITY) - (currentSteerAngle.getRotations() * SwerveModuleConstants.COUPLED_RATIO); | ||||||||||||||||||||||||||||||||
| return new SwerveModuleState(driveWheelRotationsToMeters(currentDriveVelocity), currentSteerAngle); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| public SwerveModuleState getTargetState() { | ||||||||||||||||||||||||||||||||
|
|
@@ -115,7 +117,10 @@ public SwerveModuleState getTargetState() { | |||||||||||||||||||||||||||||||
| * @return the position of the drive wheel in meters | ||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||
| 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); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||
|
|
@@ -144,6 +149,7 @@ private boolean willOptimize(SwerveModuleState state) { | |||||||||||||||||||||||||||||||
| * @param targetVelocityMetersPerSecond the target drive velocity, in meters per second | ||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||
| private void setTargetDriveVelocity(double targetVelocityMetersPerSecond) { | ||||||||||||||||||||||||||||||||
| targetVelocityMetersPerSecond -= steerMotor.getSignal(TalonFXSignal.VELOCITY) * SwerveModuleConstants.COUPLED_RATIO; | ||||||||||||||||||||||||||||||||
| if (shouldDriveMotorUseClosedLoop) { | ||||||||||||||||||||||||||||||||
| setTargetClosedLoopDriveVelocity(targetVelocityMetersPerSecond); | ||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||
|
|
@@ -154,7 +160,6 @@ private void setTargetDriveVelocity(double targetVelocityMetersPerSecond) { | |||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| private void setTargetClosedLoopDriveVelocity(double targetVelocityMetersPerSecond) { | ||||||||||||||||||||||||||||||||
| final double targetDriveVelocityRotationsPerSecond = metersToDriveWheelRotations(targetVelocityMetersPerSecond); | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| driveMotor.setControl(driveVelocityRequest.withVelocity(targetDriveVelocityRotationsPerSecond)); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
Comment on lines
161
to
164
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Line 163 passes Additionally, the formula itself looks incorrect. Coupling compensation for velocity should involve the steer velocity, not the drive velocity. The typical pattern is: This adds a feed-forward term to counteract the parasitic drive caused by steering motion. Right now 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
Suggested change
|
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,8 +14,9 @@ | |
| import frc.trigon.robot.constants.AutonomousConstants; | ||
|
|
||
| public class SwerveModuleConstants { | ||
| static final double COUPLED_RATIO = 3; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial Add a brief comment explaining what The other gear ratios have clarifying comments (e.g., |
||
| private static final double | ||
| DRIVE_MOTOR_GEAR_RATIO = 7.03,//R1: 7.03, R2: 6.03, R3: 5.27 | ||
| DRIVE_MOTOR_GEAR_RATIO = 6.03,//R1: 7.03, R2: 6.03, R3: 5.27 | ||
| STEER_MOTOR_GEAR_RATIO = 287.0 / 11.0; | ||
| static final boolean ENABLE_FOC = true; | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: Programming-TRIGON/RobotCode2026
Length of output: 157
🏁 Script executed:
Repository: Programming-TRIGON/RobotCode2026
Length of output: 1939
🏁 Script executed:
Repository: Programming-TRIGON/RobotCode2026
Length of output: 690
🏁 Script executed:
Repository: Programming-TRIGON/RobotCode2026
Length of output: 714
🏁 Script executed:
Repository: Programming-TRIGON/RobotCode2026
Length of output: 161
🏁 Script executed:
Repository: Programming-TRIGON/RobotCode2026
Length of output: 896
🏁 Script executed:
Repository: Programming-TRIGON/RobotCode2026
Length of output: 1272
🏁 Script executed:
Repository: Programming-TRIGON/RobotCode2026
Length of output: 2406
🏁 Script executed:
Repository: Programming-TRIGON/RobotCode2026
Length of output: 2309
🏁 Script executed:
Repository: Programming-TRIGON/RobotCode2026
Length of output: 824
🏁 Script executed:
Repository: Programming-TRIGON/RobotCode2026
Length of output: 1022
Apply coupling correction in
getOdometryPositionfor consistency withgetDriveWheelPositionRadians.getDriveWheelPositionRadianscompensates for steering coupling, butgetOdometryPositioncallsdriveWheelRotationsToMeterson 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
getOdometryPositionusing the odometry steer angle snapshot (latestOdometrySteerPositions[odometryUpdateIndex]) to maintain temporal consistency: