88import com .pathplanner .lib .commands .PathPlannerAuto ;
99import com .pathplanner .lib .path .PathConstraints ;
1010import com .pathplanner .lib .path .PathPlannerPath ;
11- import com .pathplanner .lib .util .HolonomicPathFollowerConfig ;
12- import com .pathplanner .lib .util .ReplanningConfig ;
1311import edu .wpi .first .apriltag .AprilTagFieldLayout ;
1412import edu .wpi .first .apriltag .AprilTagFields ;
1513import edu .wpi .first .math .geometry .Pose2d ;
2119import edu .wpi .first .math .trajectory .Trajectory ;
2220import edu .wpi .first .math .util .Units ;
2321import edu .wpi .first .wpilibj .DriverStation ;
24- import edu .wpi .first .wpilibj .DriverStation .Alliance ;
2522import edu .wpi .first .wpilibj .Timer ;
23+ import edu .wpi .first .wpilibj .DriverStation .Alliance ;
2624import edu .wpi .first .wpilibj2 .command .Command ;
2725import edu .wpi .first .wpilibj2 .command .SubsystemBase ;
2826import edu .wpi .first .wpilibj2 .command .sysid .SysIdRoutine .Config ;
2927import frc .robot .Constants ;
3028import frc .robot .Constants .AutonConstants ;
3129
3230import java .util .function .DoubleSupplier ;
31+
32+ import org .photonvision .PhotonCamera ;
33+ import org .photonvision .targeting .PhotonPipelineResult ;
34+
3335// import org.photonvision.PhotonCamera;
3436// import org.photonvision.targeting.PhotonPipelineResult;
3537import swervelib .SwerveController ;
@@ -47,12 +49,19 @@ public class SwerveSubsystem extends SubsystemBase
4749 * Swerve drive object.
4850 */
4951 private final SwerveIO io ;
52+
53+ private SWERVEVision vision ;
5054
5155 /**
5256 * AprilTag field layout.
5357 */
5458 private final AprilTagFieldLayout aprilTagFieldLayout = AprilTagFields .k2024Crescendo .loadAprilTagLayoutField ();
5559
60+ /**
61+ * Enable vision odometry updates while driving.
62+ */
63+ private boolean visionEnabled = false ;
64+
5665 /**
5766 * Initialize {@link SwerveDrive} with the directory provided.
5867 *
@@ -79,6 +88,13 @@ public SwerveSubsystem(SwerveIO swerveIO)
7988
8089 io .swerveDrive .setHeadingCorrection (false ); // Heading correction should only be used while controlling the robot via angle.
8190 io .swerveDrive .setCosineCompensator (false );//!SwerveDriveTelemetry.isSimulation); // Disables cosine compensation for simulations since it causes discrepancies not seen in real life.
91+ if (visionEnabled )
92+ {
93+ setupPhotonVision ();
94+ // Stop the odometry thread if we are using vision that way we can synchronize updates better.
95+ io .swerveDrive .stopOdometryThread ();
96+ }
97+
8298 setupPathPlanner ();
8399 }
84100
@@ -103,6 +119,15 @@ public void setupPathPlanner()
103119 this // Reference to this subsystem to set requirements
104120 );
105121 }
122+ /**
123+ * Setup the photon vision class.
124+ */
125+ public void setupPhotonVision ()
126+ {
127+ vision = new SWERVEVision (io .swerveDrive ::getPose , io .swerveDrive .field );
128+ }
129+
130+
106131
107132 /**
108133 * Get the distance to the speaker.
@@ -157,20 +182,20 @@ public Command aimAtSpeaker(double tolerance)
157182 * @param camera {@link PhotonCamera} to communicate with.
158183 * @return A {@link Command} which will run the alignment.
159184 */
160- // public Command aimAtTarget(UsbCamera camera)
161- // {
185+ public Command aimAtTarget (PhotonCamera camera )
186+ {
162187
163- // // return run(() -> {
164- // // PhotonPipelineResult result = camera.getLatestResult();
165- // // if (result.hasTargets())
166- // // {
167- // // drive(getTargetSpeeds(0,
168- // // 0,
169- // // Rotation2d.fromDegrees(result.getBestTarget()
170- // // .getYaw()))); // Not sure if this will work, more math may be required.
171- // // }
172- // // });
173- // }
188+ return run (() -> {
189+ PhotonPipelineResult result = camera .getLatestResult ();
190+ if (result .hasTargets ())
191+ {
192+ drive (getTargetSpeeds (0 ,
193+ 0 ,
194+ Rotation2d .fromDegrees (result .getBestTarget ()
195+ .getYaw ()))); // Not sure if this will work, more math may be required.
196+ }
197+ });
198+ }
174199
175200 /**
176201 * Get the path follower with events.
@@ -347,6 +372,12 @@ public void drive(ChassisSpeeds velocity)
347372 @ Override
348373 public void periodic ()
349374 {
375+ // When vision is enabled we must manually update odometry in SwerveDrive
376+ if (visionEnabled )
377+ {
378+ io .swerveDrive .updateOdometry ();
379+ vision .updatePoseEstimation (io .swerveDrive );
380+ }
350381 }
351382
352383 @ Override
@@ -562,30 +593,12 @@ public Rotation2d getPitch()
562593 {
563594 return io .swerveDrive .getPitch ();
564595 }
565-
566- /**
567- * Add a fake vision reading for testing purposes.
568- */
569- public void addFakeVisionReading ()
570- {
571- io .swerveDrive .addVisionMeasurement (new Pose2d (3 , 3 , Rotation2d .fromDegrees (65 )), Timer .getFPGATimestamp ());
572- }
573-
574- /**
575- * Setup the photon vision class.
576- */
577- public void setupPhotonVision ()
578- {
579- io .vision = new SWERVEVision (io .swerveDrive ::getPose , io .swerveDrive .field );
580- io .vision .updatePoseEstimation (io .swerveDrive );
581- }
582-
583596 /**
584597 * Update the pose estimation with vision data.
585598 */
586599 public void updatePoseWithVision ()
587600 {
588- io . vision .updatePoseEstimation (io .swerveDrive );
601+ vision .updatePoseEstimation (io .swerveDrive );
589602 }
590603
591604 /**
@@ -595,7 +608,15 @@ public void updatePoseWithVision()
595608 */
596609 public Pose2d getVisionPose ()
597610 {
598- io . vision .updatePoseEstimation (io .swerveDrive );
611+ vision .updatePoseEstimation (io .swerveDrive );
599612 return io .swerveDrive .getPose ();
600613 }
614+
615+ /**
616+ * Add a fake vision reading for testing purposes.
617+ */
618+ public void addFakeVisionReading ()
619+ {
620+ io .swerveDrive .addVisionMeasurement (new Pose2d (3 , 3 , Rotation2d .fromDegrees (65 )), Timer .getFPGATimestamp ());
621+ }
601622}
0 commit comments