5
5
import com .pathplanner .lib .util .HolonomicPathFollowerConfig ;
6
6
import com .pathplanner .lib .util .PathPlannerLogging ;
7
7
import com .pathplanner .lib .util .ReplanningConfig ;
8
+ import edu .wpi .first .math .VecBuilder ;
9
+ import edu .wpi .first .math .estimator .SwerveDrivePoseEstimator ;
8
10
import edu .wpi .first .math .geometry .Pose2d ;
9
11
import edu .wpi .first .math .geometry .Rotation2d ;
10
12
import edu .wpi .first .math .geometry .Translation2d ;
11
- import edu .wpi .first .math .geometry .Twist2d ;
12
13
import edu .wpi .first .math .kinematics .ChassisSpeeds ;
13
14
import edu .wpi .first .math .kinematics .SwerveDriveKinematics ;
14
15
import edu .wpi .first .math .kinematics .SwerveModulePosition ;
18
19
import org .team1540 .robot2024 .util .LocalADStarAK ;
19
20
import org .littletonrobotics .junction .AutoLogOutput ;
20
21
import org .littletonrobotics .junction .Logger ;
22
+ import org .team1540 .robot2024 .util .vision .TimestampedVisionPose ;
21
23
22
24
import static org .team1540 .robot2024 .Constants .Drivetrain .*;
23
25
@@ -27,10 +29,11 @@ public class Drivetrain extends SubsystemBase {
27
29
private final Module [] modules = new Module [4 ]; // FL, FR, BL, BR
28
30
29
31
private final SwerveDriveKinematics kinematics = new SwerveDriveKinematics (getModuleTranslations ());
30
- private Pose2d pose = new Pose2d ();
31
- private Rotation2d lastGyroRotation = new Rotation2d ();
32
+ private Rotation2d rawGyroRotation = new Rotation2d ();
32
33
private boolean forceModuleAngleChange = false ;
33
34
35
+ private final SwerveDrivePoseEstimator poseEstimator ;
36
+
34
37
public Drivetrain (
35
38
GyroIO gyroIO ,
36
39
ModuleIO flModuleIO ,
@@ -43,6 +46,15 @@ public Drivetrain(
43
46
modules [2 ] = new Module (blModuleIO , 2 );
44
47
modules [3 ] = new Module (brModuleIO , 3 );
45
48
49
+ poseEstimator = new SwerveDrivePoseEstimator (
50
+ kinematics ,
51
+ rawGyroRotation ,
52
+ getModulePositions (),
53
+ new Pose2d (),
54
+ // TODO: tune std devs (scale vision by distance?)
55
+ VecBuilder .fill (0.1 , 0.1 , 0.1 ),
56
+ VecBuilder .fill (0.5 , 0.5 , 5.0 )); // Trust the gyro more than the AprilTags
57
+
46
58
// Configure AutoBuilder for PathPlanner
47
59
AutoBuilder .configureHolonomic (
48
60
this ::getPose ,
@@ -60,44 +72,35 @@ public Drivetrain(
60
72
(targetPose ) -> Logger .recordOutput ("Odometry/TrajectorySetpoint" , targetPose ));
61
73
}
62
74
75
+ @ Override
63
76
public void periodic () {
64
77
gyroIO .updateInputs (gyroInputs );
65
78
Logger .processInputs ("Drivetrain/Gyro" , gyroInputs );
66
79
for (Module module : modules ) {
67
80
module .periodic ();
68
81
}
69
82
70
- // Stop moving when disabled
71
- if (DriverStation .isDisabled ()) {
72
- for (Module module : modules ) {
73
- module .stop ();
74
- }
75
- }
76
- // Log empty setpoint states when disabled
77
83
if (DriverStation .isDisabled ()) {
84
+ // Stop moving when disabled
85
+ for (Module module : modules ) module .stop ();
86
+
87
+ // Log empty setpoint states when disabled
78
88
Logger .recordOutput ("SwerveStates/Setpoints" , new SwerveModuleState []{});
79
89
Logger .recordOutput ("SwerveStates/SetpointsOptimized" , new SwerveModuleState []{});
80
90
}
81
91
82
- // Update odometry
92
+ // Calculate module deltas
83
93
SwerveModulePosition [] wheelDeltas = new SwerveModulePosition [4 ];
84
94
for (int i = 0 ; i < 4 ; i ++) {
85
95
wheelDeltas [i ] = modules [i ].getPositionDelta ();
86
96
}
87
- // The twist represents the motion of the robot since the last
88
- // loop cycle in x, y, and theta based only on the modules,
89
- // without the gyro. The gyro is always disconnected in simulation.
90
- Twist2d twist = kinematics .toTwist2d (wheelDeltas );
91
- if (gyroInputs .connected ) {
92
- // If the gyro is connected, replace the theta component of the twist
93
- // with the change in angle since the last loop cycle.
94
- twist =
95
- new Twist2d (
96
- twist .dx , twist .dy , gyroInputs .yawPosition .minus (lastGyroRotation ).getRadians ());
97
- lastGyroRotation = gyroInputs .yawPosition ;
98
- }
99
- // Apply the twist (change since last loop cycle) to the current pose
100
- pose = pose .exp (twist );
97
+ // Use gyro rotation if gyro is connected, otherwise use module deltas to calculate rotation delta
98
+ rawGyroRotation =
99
+ gyroInputs .connected ?
100
+ gyroInputs .yawPosition
101
+ : rawGyroRotation .plus (Rotation2d .fromRadians (kinematics .toTwist2d (wheelDeltas ).dtheta ));
102
+ // Update odometry
103
+ poseEstimator .update (rawGyroRotation , getModulePositions ());
101
104
}
102
105
103
106
/**
@@ -164,6 +167,10 @@ public double getCharacterizationVelocity() {
164
167
return driveVelocityAverage / 4.0 ;
165
168
}
166
169
170
+ public ChassisSpeeds getChassisSpeeds () {
171
+ return kinematics .toChassisSpeeds (getModuleStates ());
172
+ }
173
+
167
174
/**
168
175
* Returns the module states (turn angles and drive velocities) for all the modules.
169
176
*/
@@ -181,21 +188,34 @@ private SwerveModuleState[] getModuleStates() {
181
188
*/
182
189
@ AutoLogOutput (key = "Odometry/Robot" )
183
190
public Pose2d getPose () {
184
- return pose ;
191
+ return poseEstimator . getEstimatedPosition () ;
185
192
}
186
193
187
194
/**
188
195
* Returns the current odometry rotation.
189
196
*/
190
197
public Rotation2d getRotation () {
191
- return pose .getRotation ();
198
+ return getPose () .getRotation ();
192
199
}
193
200
194
201
/**
195
202
* Resets the current odometry pose.
196
203
*/
197
204
public void setPose (Pose2d pose ) {
198
- this .pose = pose ;
205
+ poseEstimator .resetPosition (rawGyroRotation , getModulePositions (), pose );
206
+ }
207
+
208
+ public void addVisionMeasurement (TimestampedVisionPose visionPose ) {
209
+ poseEstimator .addVisionMeasurement (visionPose .poseMeters (), visionPose .timestampSecs ());
210
+ }
211
+
212
+ public SwerveModulePosition [] getModulePositions () {
213
+ return new SwerveModulePosition []{
214
+ modules [0 ].getPosition (),
215
+ modules [1 ].getPosition (),
216
+ modules [2 ].getPosition (),
217
+ modules [3 ].getPosition (),
218
+ };
199
219
}
200
220
201
221
/**
0 commit comments