|
15 | 15 | import dev.doglog.DogLog;
|
16 | 16 | import edu.wpi.first.epilogue.Logged;
|
17 | 17 | import edu.wpi.first.epilogue.Logged.Strategy;
|
| 18 | +import edu.wpi.first.math.geometry.Pose2d; |
| 19 | +import edu.wpi.first.math.geometry.Rotation2d; |
18 | 20 | import edu.wpi.first.math.kinematics.ChassisSpeeds;
|
| 21 | +import edu.wpi.first.math.kinematics.SwerveDriveKinematics; |
| 22 | +import edu.wpi.first.math.kinematics.SwerveModuleState; |
19 | 23 | import edu.wpi.first.wpilibj.Notifier;
|
20 | 24 | import edu.wpi.first.wpilibj.RobotBase;
|
21 | 25 | import edu.wpi.first.wpilibj.RobotController;
|
@@ -83,6 +87,7 @@ public CommandSwerveDrivetrain(
|
83 | 87 | totalDaqs = totalDaqs == 0 ? 1 : totalDaqs;
|
84 | 88 |
|
85 | 89 | DogLog.log("Swerve/Odometry Success %", state.SuccessfulDaqs / totalDaqs * 100);
|
| 90 | + DogLog.log("Swerve/Odometry Period", state.OdometryPeriod); |
86 | 91 | });
|
87 | 92 |
|
88 | 93 | if (RobotBase.isSimulation()) startSimThread();
|
@@ -129,6 +134,24 @@ public void drive(double velX, double velY, double velOmega) {
|
129 | 134 | _driverChassisSpeeds.vyMetersPerSecond = velY;
|
130 | 135 | _driverChassisSpeeds.omegaRadiansPerSecond = velOmega;
|
131 | 136 |
|
| 137 | + // go through a couple of steps to ensure that input speeds are actually achievable |
| 138 | + ChassisSpeeds tempSpeeds = _driverChassisSpeeds; |
| 139 | + SwerveModuleState[] tempStates; |
| 140 | + |
| 141 | + if (_isFieldOriented) |
| 142 | + tempSpeeds = ChassisSpeeds.fromFieldRelativeSpeeds(tempSpeeds, getHeading()); |
| 143 | + |
| 144 | + tempStates = getKinematics().toSwerveModuleStates(tempSpeeds); |
| 145 | + SwerveDriveKinematics.desaturateWheelSpeeds(tempStates, SwerveConstants.maxTranslationalSpeed); |
| 146 | + tempSpeeds = getKinematics().toChassisSpeeds(tempStates); |
| 147 | + |
| 148 | + if (_isFieldOriented) |
| 149 | + tempSpeeds = ChassisSpeeds.fromRobotRelativeSpeeds(tempSpeeds, getHeading()); |
| 150 | + |
| 151 | + velX = tempSpeeds.vxMetersPerSecond; |
| 152 | + velY = tempSpeeds.vyMetersPerSecond; |
| 153 | + velOmega = tempSpeeds.omegaRadiansPerSecond; |
| 154 | + |
132 | 155 | if (_isFieldOriented) {
|
133 | 156 | setControl(
|
134 | 157 | _fieldCentricRequest
|
@@ -170,6 +193,21 @@ public void drive(
|
170 | 193 | .withWheelForceFeedforwardsY(wheelForceFeedforwardsY));
|
171 | 194 | }
|
172 | 195 |
|
| 196 | + /** Wrapper for getting estimated pose. */ |
| 197 | + public Pose2d getPose() { |
| 198 | + return getState().Pose; |
| 199 | + } |
| 200 | + |
| 201 | + /** Wrapper for getting estimated heading. */ |
| 202 | + public Rotation2d getHeading() { |
| 203 | + return getPose().getRotation(); |
| 204 | + } |
| 205 | + |
| 206 | + /** Wrapper for getting current robot-relative chassis speeds. */ |
| 207 | + public ChassisSpeeds getChassisSpeeds() { |
| 208 | + return getState().Speeds; |
| 209 | + } |
| 210 | + |
173 | 211 | @Override
|
174 | 212 | public void periodic() {
|
175 | 213 | // This method will be called once per scheduler run
|
|
0 commit comments