@@ -27,6 +27,8 @@ public class SwerveDrive {
2727 private final SwerveDriveOdometry odometry ;
2828 private final Gyro gyro ;
2929 private final double maxSpeedMetersPerSecond ;
30+ private Rotation2d gyroOffset = new Rotation2d ();
31+ private boolean hasGyroOffset = false ;
3032
3133 /**
3234 * Construct a swerve drive object. Along with a gyro, this takes in four configured swerve
@@ -60,7 +62,7 @@ public SwerveDrive(Gyro gyro, SwerveModule... swerveModules) {
6062 maxSpeedMetersPerSecond = swerveModules [0 ].getMaxSpeedMetersPerSecond ();
6163
6264 kinematics = new SwerveDriveKinematics (translation2ds );
63- odometry = new SwerveDriveOdometry (kinematics , gyro .getRotation2d ());
65+ odometry = new SwerveDriveOdometry (kinematics , gyro .getRotation2d (). rotateBy ( gyroOffset ) );
6466 }
6567
6668 /**
@@ -101,7 +103,7 @@ public Pose2d getPoseMeters() {
101103 * @return the Rotation2d of the robot relative to gyro zero
102104 */
103105 public Rotation2d getHeading () {
104- return gyro .getRotation2d ();
106+ return hasGyroOffset ? gyro . getRotation2d (). rotateBy ( gyroOffset ) : gyro .getRotation2d ();
105107 }
106108
107109 /**
@@ -113,7 +115,8 @@ public Rotation2d getHeading() {
113115 *
114116 * @return the current heading in degrees of the robot relative to gyro zero
115117 */
116- public double getGyroAngle () {
118+ double getGyroAngle () {
119+ // FIXME: does not have gyro offset
117120 return gyro .getAngle ();
118121 }
119122
@@ -128,6 +131,29 @@ public double getGyroRate() {
128131 return gyro .getRate ();
129132 }
130133
134+ /**
135+ * Get the current gyro offset applied to the IMU gyro angle during field oriented driving.
136+ *
137+ * @return the gyro offset
138+ */
139+ public Rotation2d getGyroOffset () {
140+ return gyroOffset ;
141+ }
142+
143+ /**
144+ * Set the current gyro offset applied to the IMU gyro angle during field oriented driving,
145+ * defaults to zero.
146+ *
147+ * @param gyroOffset the desired offset
148+ */
149+ public void setGyroOffset (Rotation2d gyroOffset ) {
150+ if (this .gyroOffset .equals (gyroOffset )) {
151+ return ;
152+ }
153+ this .gyroOffset = gyroOffset ;
154+ hasGyroOffset = true ;
155+ }
156+
131157 /**
132158 * Get the configured swerve modules.
133159 *
@@ -144,7 +170,7 @@ public SwerveModule[] getSwerveModules() {
144170 * @param pose The robot's actual position on the field.
145171 */
146172 public void resetOdometry (Pose2d pose ) {
147- odometry .resetPosition (pose , gyro .getRotation2d ());
173+ odometry .resetPosition (pose , gyro .getRotation2d (). rotateBy ( gyroOffset ) );
148174 }
149175
150176 /** Resets the drive encoders to currently read a position of 0. */
@@ -165,7 +191,7 @@ public void resetGyro() {
165191 */
166192 public void periodic () {
167193 odometry .update (
168- gyro .getRotation2d (),
194+ hasGyroOffset ? gyro . getRotation2d (). rotateBy ( gyroOffset ) : gyro .getRotation2d (),
169195 swerveModules [0 ].getState (),
170196 swerveModules [1 ].getState (),
171197 swerveModules [2 ].getState (),
@@ -223,7 +249,10 @@ private SwerveModuleState[] getSwerveModuleStates(
223249 ChassisSpeeds chassisSpeeds =
224250 isFieldOriented
225251 ? ChassisSpeeds .fromFieldRelativeSpeeds (
226- vxMetersPerSecond , vyMetersPerSecond , omegaRadiansPerSecond , gyro .getRotation2d ())
252+ vxMetersPerSecond ,
253+ vyMetersPerSecond ,
254+ omegaRadiansPerSecond ,
255+ hasGyroOffset ? gyro .getRotation2d ().rotateBy (gyroOffset ) : gyro .getRotation2d ())
227256 : new ChassisSpeeds (vxMetersPerSecond , vyMetersPerSecond , omegaRadiansPerSecond );
228257
229258 var swerveModuleStates = kinematics .toSwerveModuleStates (chassisSpeeds );
0 commit comments