99import edu .wpi .first .math .geometry .Rotation2d ;
1010import edu .wpi .first .math .kinematics .SwerveModuleState ;
1111import edu .wpi .first .math .trajectory .TrapezoidProfile ;
12- import edu .wpi .first .math .trajectory .constraint .MaxVelocityConstraint ;
1312import edu .wpi .first .wpilibj2 .command .Command ;
14- import edu .wpi .first .wpilibj2 .command .Subsystem ;
1513import frc .robot .config .TunerConstants ;
1614import frc .robot .helpers .ApplyModuleStates ;
1715import frc .robot .helpers .ShotCalculator ;
@@ -24,7 +22,7 @@ public static enum Position {
2422 TELEOP ,
2523 STILL_SHOT ,
2624 SOTM ,
27- AUTO_ALIGN_HUB
25+ AUTO_ALIGN_HUB
2826 }
2927
3028 private CommandSwerveDrivetrain subsystem ;
@@ -72,19 +70,21 @@ public DrivetrainCommand(
7270 double alignI = 1 ;
7371 double alignD = 1 ;
7472 this .autoAlignPidController =
75- new ProfiledPIDController (
76- alignP ,
77- alignI ,
78- alignD ,
79- new TrapezoidProfile .Constraints (MaxAngularRate , MaxAngularRate / 0.2 ));
80- this .autoAlignPidController .enableContinuousInput (-Math .PI , Math .PI ); // Swerve angles are continuous (-180 to 180 deg)
73+ new ProfiledPIDController (
74+ alignP ,
75+ alignI ,
76+ alignD ,
77+ new TrapezoidProfile .Constraints (MaxAngularRate , MaxAngularRate / 0.2 ));
78+ this .autoAlignPidController .enableContinuousInput (
79+ -Math .PI , Math .PI ); // Swerve angles are continuous (-180 to 180 deg)
8180 // Don't compute hub-facing target in the constructor (DriverStation alliance may be
8281 // unavailable during initialization). Initialize to current heading; execute() will
8382 // recompute the actual hub-facing target each loop.
8483 this .m_targetAngle = subsystem .getState ().Pose .getRotation ();
8584
86- addRequirements (subsystem );
85+ addRequirements (subsystem );
8786 }
87+
8888 public double getAutoAlignRotationalOutput () {
8989 Rotation2d currentAngle = subsystem .getState ().Pose .getRotation ();
9090 double current = currentAngle .getRadians ();
@@ -97,6 +97,7 @@ public double getAutoAlignRotationalOutput() {
9797 }
9898 return output ;
9999 }
100+
100101 @ Override
101102 public void execute () {
102103 switch (pose ) {
@@ -127,33 +128,38 @@ public void execute() {
127128 System .out .println ("Drivetrain: SOTM Drive" );
128129 break ;
129130
130- case AUTO_ALIGN_HUB :
131- // Recompute the desired heading toward the hub each loop
132- m_targetAngle =
133- ShotCalculator .getRotationTowardsHub (
134- ShotCalculator .calculateHubPosition (), subsystem .getState ().Pose .getTranslation ());
135- System .out .println ("Auto Align Current Pose: " +subsystem .getState ().Pose .getX ()+" " +subsystem .getState ().Pose .getY ());
136-
137- double currentRad = subsystem .getState ().Pose .getRotation ().getRadians ();
138- double targetRad = m_targetAngle .getRadians ();
139- // Normalize error to [-pi, pi]
140- double error = Math .atan2 (Math .sin (targetRad - currentRad ), Math .cos (targetRad - currentRad ));
141- double absError = Math .abs (error );
142- double angleTolerance = Math .toRadians (1.0 ); // stop within 1 degree
143-
144- double rotOutput = getAutoAlignRotationalOutput ();
145-
146- if (absError < angleTolerance ) {
147- // Aligned: stop rotating (and hold position)
148- subsystem .setControl (drive .withVelocityX (0.0 ).withVelocityY (0.0 ).withRotationalRate (0.0 ));
149- } else {
150- // Not aligned: apply rotational output
151- System .out .println ("new rotational output: " +rotOutput );
152- subsystem .setControl (
153- drive .withVelocityX (0.0 ).withVelocityY (0.0 ).withRotationalRate (rotOutput ));
154- }
155-
156- break ;
131+ case AUTO_ALIGN_HUB :
132+ // Recompute the desired heading toward the hub each loop
133+ m_targetAngle =
134+ ShotCalculator .getRotationTowardsHub (
135+ ShotCalculator .calculateHubPosition (), subsystem .getState ().Pose .getTranslation ());
136+ System .out .println (
137+ "Auto Align Current Pose: "
138+ + subsystem .getState ().Pose .getX ()
139+ + " "
140+ + subsystem .getState ().Pose .getY ());
141+
142+ double currentRad = subsystem .getState ().Pose .getRotation ().getRadians ();
143+ double targetRad = m_targetAngle .getRadians ();
144+ // Normalize error to [-pi, pi]
145+ double error =
146+ Math .atan2 (Math .sin (targetRad - currentRad ), Math .cos (targetRad - currentRad ));
147+ double absError = Math .abs (error );
148+ double angleTolerance = Math .toRadians (1.0 ); // stop within 1 degree
149+
150+ double rotOutput = getAutoAlignRotationalOutput ();
151+
152+ if (absError < angleTolerance ) {
153+ // Aligned: stop rotating (and hold position)
154+ subsystem .setControl (drive .withVelocityX (0.0 ).withVelocityY (0.0 ).withRotationalRate (0.0 ));
155+ } else {
156+ // Not aligned: apply rotational output
157+ System .out .println ("new rotational output: " + rotOutput );
158+ subsystem .setControl (
159+ drive .withVelocityX (0.0 ).withVelocityY (0.0 ).withRotationalRate (rotOutput ));
160+ }
161+
162+ break ;
157163
158164 default :
159165 break ;
@@ -174,7 +180,8 @@ public boolean isFinished() {
174180 return false ;
175181 }
176182
177- edu .wpi .first .math .geometry .Translation2d currentTrans = subsystem .getState ().Pose .getTranslation ();
183+ edu .wpi .first .math .geometry .Translation2d currentTrans =
184+ subsystem .getState ().Pose .getTranslation ();
178185 if (currentTrans == null ) {
179186 return false ;
180187 }
0 commit comments