11package swervelib ;
22
33import edu .wpi .first .math .Matrix ;
4- import edu .wpi .first .math .VecBuilder ;
54import edu .wpi .first .math .controller .SimpleMotorFeedforward ;
65import edu .wpi .first .math .estimator .SwerveDrivePoseEstimator ;
76import edu .wpi .first .math .filter .SlewRateLimiter ;
@@ -72,9 +71,12 @@ public class SwerveDrive
7271 */
7372 private final Lock odometryLock = new ReentrantLock ();
7473 /**
75- * Deadband for speeds in heading correction .
74+ * Alert to recommend Tuner X if the configuration is compatible .
7675 */
77- private double HEADING_CORRECTION_DEADBAND = 0.01 ;
76+ private final Alert tunerXRecommendation = new Alert ("Swerve Drive" ,
77+ "Your Swerve Drive is compatible with Tuner X swerve generator, please consider using that instead of YAGSL. More information here!\n " +
78+ "https://pro.docs.ctr-electronics.com/en/latest/docs/tuner/tuner-swerve/index.html" ,
79+ AlertType .WARNING );
7880 /**
7981 * Field object.
8082 */
@@ -83,26 +85,6 @@ public class SwerveDrive
8385 * Swerve controller for controlling heading of the robot.
8486 */
8587 public SwerveController swerveController ;
86- /**
87- * Standard deviation of encoders and gyroscopes, usually should not change. (meters of position and degrees of
88- * rotation)
89- */
90- public Matrix <N3 , N1 > stateStdDevs = VecBuilder .fill (0.1 ,
91- 0.1 ,
92- 0.1 );
93- /**
94- * The standard deviation of the vision measurement, for best accuracy calculate the standard deviation at 2 or more
95- * points and fit a line to it and modify this using {@link SwerveDrive#addVisionMeasurement(Pose2d, double, Matrix)}
96- * with the calculated optimal standard deviation. (Units should be meters per pixel). By optimizing this you can get
97- * vision accurate to inches instead of feet.
98- */
99- public Matrix <N3 , N1 > visionMeasurementStdDevs = VecBuilder .fill (0.9 ,
100- 0.9 ,
101- 0.9 );
102- /**
103- * Invert odometry readings of drive motor positions, used as a patch for debugging currently.
104- */
105- public boolean invertOdometry = false ;
10688 /**
10789 * Correct chassis velocity in {@link SwerveDrive#drive(Translation2d, double, boolean, boolean)} using 254's
10890 * correction.
@@ -112,6 +94,10 @@ public class SwerveDrive
11294 * Whether to correct heading when driving translationally. Set to true to enable.
11395 */
11496 public boolean headingCorrection = false ;
97+ /**
98+ * Deadband for speeds in heading correction.
99+ */
100+ private double HEADING_CORRECTION_DEADBAND = 0.01 ;
115101 /**
116102 * Whether heading correction PID is currently active.
117103 */
@@ -144,13 +130,6 @@ public class SwerveDrive
144130 * Maximum speed of the robot in meters per second.
145131 */
146132 private double maxSpeedMPS ;
147- /**
148- * Alert to recommend Tuner X if the configuration is compatible.
149- */
150- private final Alert tunerXRecommendation = new Alert ("Swerve Drive" ,
151- "Your Swerve Drive is compatible with Tuner X swerve generator, please consider using that instead of YAGSL. More information here!\n " +
152- "https://pro.docs.ctr-electronics.com/en/latest/docs/tuner/tuner-swerve/index.html" ,
153- AlertType .WARNING );
154133
155134 /**
156135 * Creates a new swerve drivebase subsystem. Robot is controlled via the {@link SwerveDrive#drive} method, or via the
@@ -194,9 +173,8 @@ public SwerveDrive(
194173 kinematics ,
195174 getYaw (),
196175 getModulePositions (),
197- new Pose2d (new Translation2d (0 , 0 ), Rotation2d .fromDegrees (0 )),
198- stateStdDevs ,
199- visionMeasurementStdDevs ); // x,y,heading in radians; Vision measurement std dev, higher=less weight
176+ new Pose2d (new Translation2d (0 , 0 ),
177+ Rotation2d .fromDegrees (0 ))); // x,y,heading in radians; Vision measurement std dev, higher=less weight
200178
201179 zeroGyro ();
202180
@@ -308,6 +286,16 @@ public void setDriveMotorConversionFactor(double conversionFactor)
308286 }
309287 }
310288
289+ /**
290+ * Fetch the latest odometry heading, should be trusted over {@link SwerveDrive#getYaw()}.
291+ *
292+ * @return {@link Rotation2d} of the robot heading.
293+ */
294+ public Rotation2d getOdometryHeading ()
295+ {
296+ return swerveDrivePoseEstimator .getEstimatedPosition ().getRotation ();
297+ }
298+
311299 /**
312300 * Set the heading correction capabilities of YAGSL.
313301 *
@@ -337,7 +325,7 @@ public void setHeadingCorrection(boolean state, double deadband)
337325 */
338326 public void driveFieldOriented (ChassisSpeeds velocity )
339327 {
340- ChassisSpeeds fieldOrientedVelocity = ChassisSpeeds .fromFieldRelativeSpeeds (velocity , getYaw ());
328+ ChassisSpeeds fieldOrientedVelocity = ChassisSpeeds .fromFieldRelativeSpeeds (velocity , getOdometryHeading ());
341329 drive (fieldOrientedVelocity );
342330 }
343331
@@ -349,7 +337,7 @@ public void driveFieldOriented(ChassisSpeeds velocity)
349337 */
350338 public void driveFieldOriented (ChassisSpeeds velocity , Translation2d centerOfRotationMeters )
351339 {
352- ChassisSpeeds fieldOrientedVelocity = ChassisSpeeds .fromFieldRelativeSpeeds (velocity , getYaw ());
340+ ChassisSpeeds fieldOrientedVelocity = ChassisSpeeds .fromFieldRelativeSpeeds (velocity , getOdometryHeading ());
353341 drive (fieldOrientedVelocity , centerOfRotationMeters );
354342 }
355343
@@ -401,7 +389,7 @@ public void drive(
401389 ChassisSpeeds velocity =
402390 fieldRelative
403391 ? ChassisSpeeds .fromFieldRelativeSpeeds (
404- translation .getX (), translation .getY (), rotation , getYaw ())
392+ translation .getX (), translation .getY (), rotation , getOdometryHeading ())
405393 : new ChassisSpeeds (translation .getX (), translation .getY (), rotation );
406394
407395 drive (velocity , isOpenLoop , centerOfRotationMeters );
@@ -430,7 +418,7 @@ public void drive(
430418 ChassisSpeeds velocity =
431419 fieldRelative
432420 ? ChassisSpeeds .fromFieldRelativeSpeeds (
433- translation .getX (), translation .getY (), rotation , getYaw ())
421+ translation .getX (), translation .getY (), rotation , getOdometryHeading ())
434422 : new ChassisSpeeds (translation .getX (), translation .getY (), rotation );
435423
436424 drive (velocity , isOpenLoop , new Translation2d ());
@@ -466,11 +454,11 @@ public void drive(ChassisSpeeds velocity, boolean isOpenLoop, Translation2d cent
466454 {
467455 if (!correctionEnabled )
468456 {
469- lastHeadingRadians = getYaw ().getRadians ();
457+ lastHeadingRadians = getOdometryHeading ().getRadians ();
470458 correctionEnabled = true ;
471459 }
472460 velocity .omegaRadiansPerSecond =
473- swerveController .headingCalculate (lastHeadingRadians , getYaw ().getRadians ());
461+ swerveController .headingCalculate (lastHeadingRadians , getOdometryHeading ().getRadians ());
474462 } else
475463 {
476464 correctionEnabled = false ;
@@ -623,7 +611,7 @@ public ChassisSpeeds getFieldVelocity()
623611 // angle
624612 // given as the robot angle reverses the direction of rotation, and the conversion is reversed.
625613 return ChassisSpeeds .fromFieldRelativeSpeeds (
626- kinematics .toChassisSpeeds (getStates ()), getYaw ().unaryMinus ());
614+ kinematics .toChassisSpeeds (getStates ()), getOdometryHeading ().unaryMinus ());
627615 }
628616
629617 /**
@@ -680,8 +668,7 @@ public SwerveModuleState[] getStates()
680668 }
681669
682670 /**
683- * Gets the current module positions (azimuth and wheel position (meters)). Inverts the distance from each module if
684- * {@link #invertOdometry} is true.
671+ * Gets the current module positions (azimuth and wheel position (meters)).
685672 *
686673 * @return A list of SwerveModulePositions containg the current module positions
687674 */
@@ -692,10 +679,6 @@ public SwerveModulePosition[] getModulePositions()
692679 for (SwerveModule module : swerveModules )
693680 {
694681 positions [module .moduleNumber ] = module .getPosition ();
695- if (invertOdometry )
696- {
697- positions [module .moduleNumber ].distanceMeters *= -1 ;
698- }
699682 }
700683 return positions ;
701684 }
@@ -945,7 +928,7 @@ public void updateOdometry()
945928 SwerveDriveTelemetry .measuredChassisSpeeds [1 ] = measuredChassisSpeeds .vyMetersPerSecond ;
946929 SwerveDriveTelemetry .measuredChassisSpeeds [0 ] = measuredChassisSpeeds .vxMetersPerSecond ;
947930 SwerveDriveTelemetry .measuredChassisSpeeds [2 ] = Math .toDegrees (measuredChassisSpeeds .omegaRadiansPerSecond );
948- SwerveDriveTelemetry .robotRotation = getYaw ().getDegrees ();
931+ SwerveDriveTelemetry .robotRotation = getOdometryHeading ().getDegrees ();
949932 }
950933
951934 if (SwerveDriveTelemetry .verbosity .ordinal () >= TelemetryVerbosity .LOW .ordinal ())
@@ -961,7 +944,8 @@ public void updateOdometry()
961944 if (SwerveDriveTelemetry .verbosity == TelemetryVerbosity .HIGH )
962945 {
963946 module .updateTelemetry ();
964- SmartDashboard .putNumber ("Adjusted IMU Yaw" , getYaw ().getDegrees ());
947+ SmartDashboard .putNumber ("Raw IMU Yaw" , getYaw ().getDegrees ());
948+ SmartDashboard .putNumber ("Adjusted IMU Yaw" , getOdometryHeading ().getDegrees ());
965949 }
966950 if (SwerveDriveTelemetry .verbosity .ordinal () >= TelemetryVerbosity .HIGH .ordinal ())
967951 {
@@ -1019,28 +1003,6 @@ public void setGyroOffset(Rotation3d offset)
10191003 }
10201004 }
10211005
1022- /**
1023- * Add a vision measurement to the {@link SwerveDrivePoseEstimator} and update the {@link SwerveIMU} gyro reading with
1024- * the given timestamp of the vision measurement. <br /> <b>IT IS HIGHLY RECOMMENDED TO UPDATE YOUR GYROSCOPE OFFSET
1025- * AFTER USING THIS FUNCTION!</b> <br /> To update your gyroscope readings directly use
1026- * {@link SwerveDrive#setGyroOffset(Rotation3d)}.
1027- *
1028- * @param robotPose Robot {@link Pose2d} as measured by vision.
1029- * @param timestamp Timestamp the measurement was taken as time since startup, should be taken from
1030- * {@link Timer#getFPGATimestamp()} or similar sources.
1031- */
1032- public void addVisionMeasurement (Pose2d robotPose , double timestamp )
1033- {
1034- odometryLock .lock ();
1035- swerveDrivePoseEstimator .addVisionMeasurement (robotPose , timestamp );
1036- Pose2d newOdometry = new Pose2d (swerveDrivePoseEstimator .getEstimatedPosition ().getTranslation (),
1037- robotPose .getRotation ());
1038- odometryLock .unlock ();
1039-
1040- setGyroOffset (new Rotation3d (0 , 0 , robotPose .getRotation ().getRadians ()));
1041- resetOdometry (newOdometry );
1042- }
1043-
10441006 /**
10451007 * Add a vision measurement to the {@link SwerveDrivePoseEstimator} and update the {@link SwerveIMU} gyro reading with
10461008 * the given timestamp of the vision measurement.
@@ -1058,8 +1020,31 @@ public void addVisionMeasurement(Pose2d robotPose, double timestamp)
10581020 public void addVisionMeasurement (Pose2d robotPose , double timestamp ,
10591021 Matrix <N3 , N1 > visionMeasurementStdDevs )
10601022 {
1061- this .visionMeasurementStdDevs = visionMeasurementStdDevs ;
1062- addVisionMeasurement (robotPose , timestamp );
1023+ odometryLock .lock ();
1024+ swerveDrivePoseEstimator .addVisionMeasurement (robotPose , timestamp , visionMeasurementStdDevs );
1025+ odometryLock .unlock ();
1026+ }
1027+
1028+ /**
1029+ * Add a vision measurement to the {@link SwerveDrivePoseEstimator} and update the {@link SwerveIMU} gyro reading with
1030+ * the given timestamp of the vision measurement. <br /> <b>IT IS HIGHLY RECOMMENDED TO UPDATE YOUR GYROSCOPE OFFSET
1031+ * AFTER USING THIS FUNCTION!</b> <br /> To update your gyroscope readings directly use
1032+ * {@link SwerveDrive#setGyroOffset(Rotation3d)}.
1033+ *
1034+ * @param robotPose Robot {@link Pose2d} as measured by vision.
1035+ * @param timestamp Timestamp the measurement was taken as time since startup, should be taken from
1036+ * {@link Timer#getFPGATimestamp()} or similar sources.
1037+ */
1038+ public void addVisionMeasurement (Pose2d robotPose , double timestamp )
1039+ {
1040+ odometryLock .lock ();
1041+ swerveDrivePoseEstimator .addVisionMeasurement (robotPose , timestamp );
1042+ // Pose2d newOdometry = new Pose2d(swerveDrivePoseEstimator.getEstimatedPosition().getTranslation(),
1043+ // robotPose.getRotation());
1044+ odometryLock .unlock ();
1045+
1046+ // setGyroOffset(new Rotation3d(0, 0, robotPose.getRotation().getRadians()));
1047+ // resetOdometry(newOdometry);
10631048 }
10641049
10651050
0 commit comments