Skip to content

Commit 106ca12

Browse files
committed
CANMappings + Drivetrain Logging and SOTM
1 parent ecaa2e0 commit 106ca12

2 files changed

Lines changed: 110 additions & 7 deletions

File tree

src/main/java/frc/robot/commands/DrivetrainCommand.java

Lines changed: 110 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,16 @@
55
import com.ctre.phoenix6.swerve.SwerveModule;
66
import com.ctre.phoenix6.swerve.SwerveRequest;
77
import edu.wpi.first.epilogue.Logged;
8+
import edu.wpi.first.math.controller.ProfiledPIDController;
89
import edu.wpi.first.math.geometry.Rotation2d;
10+
import edu.wpi.first.math.geometry.Translation2d;
11+
import edu.wpi.first.math.kinematics.ChassisSpeeds;
912
import edu.wpi.first.math.kinematics.SwerveModuleState;
13+
import edu.wpi.first.math.trajectory.TrapezoidProfile;
1014
import edu.wpi.first.wpilibj2.command.Command;
1115
import frc.robot.config.TunerConstants;
1216
import frc.robot.helpers.ApplyModuleStates;
17+
import frc.robot.helpers.ShotCalculator;
1318
import frc.robot.subsystems.CommandSwerveDrivetrain;
1419
import java.util.function.DoubleSupplier;
1520

@@ -18,14 +23,16 @@ public class DrivetrainCommand extends Command {
1823
public static enum Position {
1924
TELEOP,
2025
STILL_SHOT,
21-
SOTM
26+
SOTM,
27+
AUTO_ALIGN_HUB
2228
}
2329

2430
private CommandSwerveDrivetrain subsystem;
2531
private DrivetrainCommand.Position pose;
2632
private DoubleSupplier leftY;
2733
private DoubleSupplier leftX;
2834
private DoubleSupplier rightX;
35+
public static String drivetrainState = "Stopped";
2936

3037
private final double MaxSpeed =
3138
TunerConstants.kSpeedAt12Volts.in(MetersPerSecond); // kSpeedAt12Volts desired top speed
@@ -48,6 +55,9 @@ public static enum Position {
4855
};
4956
private final ApplyModuleStates applyRequest = new ApplyModuleStates();
5057
private final SwerveRequest.SwerveDriveBrake brakeRequest = new SwerveRequest.SwerveDriveBrake();
58+
private final ProfiledPIDController autoAlignPidController;
59+
private Rotation2d m_targetAngle = Rotation2d.kZero;
60+
private static final double FUEL_EXIT_VELOCITY = 10.0; // This needs to be tuned
5161

5262
public DrivetrainCommand(
5363
CommandSwerveDrivetrain subsystem,
@@ -60,10 +70,38 @@ public DrivetrainCommand(
6070
this.leftX = leftX;
6171
this.leftY = leftY;
6272
this.rightX = rightX;
73+
double alignP = 85;
74+
double alignI = 0;
75+
double alignD = 0;
76+
this.autoAlignPidController =
77+
new ProfiledPIDController(
78+
alignP,
79+
alignI,
80+
alignD,
81+
new TrapezoidProfile.Constraints(MaxAngularRate, MaxAngularRate / 0.2));
82+
this.autoAlignPidController.enableContinuousInput(
83+
-Math.PI, Math.PI); // Swerve angles are continuous (-180 to 180 deg)
84+
// Don't compute hub-facing target in the constructor (DriverStation alliance may be
85+
// unavailable during initialization). Initialize to current heading; execute() will
86+
// recompute the actual hub-facing target each loop.
87+
this.m_targetAngle = subsystem.getState().Pose.getRotation();
6388

6489
addRequirements(subsystem);
6590
}
6691

92+
public double getAutoAlignRotationalOutput() {
93+
Rotation2d currentAngle = subsystem.getState().Pose.getRotation();
94+
double current = currentAngle.getRadians();
95+
double target = m_targetAngle.getRadians();
96+
double output = autoAlignPidController.calculate(current, target);
97+
if (output > MaxAngularRate) {
98+
output = MaxAngularRate;
99+
} else if (output < -MaxAngularRate) {
100+
output = -MaxAngularRate;
101+
}
102+
return output;
103+
}
104+
67105
@Override
68106
public void execute() {
69107
switch (pose) {
@@ -78,20 +116,71 @@ public void execute() {
78116
.withRotationalRate(
79117
-rightX.getAsDouble()
80118
* MaxAngularRate)); // Drive counterclockwise with negative X
119+
drivetrainState = "Teleop Drive";
81120
break;
82121

83122
// (Needs check) Mode for when shots are from a still position
84123
case STILL_SHOT:
85124
// make X with wheels, set wheels to brake mode
86125
applyRequest.ModuleStates = states;
87126
subsystem.setControl(applyRequest);
88-
System.out.println("Drivetrain: Still Shot Configuration");
127+
drivetrainState = "Still Shot";
89128
break;
90129

91130
// (Incomplete) Mode for moving shots
92131
case SOTM:
93-
// shoot on the move, reference Mechanical Advantage build log
94-
System.out.println("Drivetrain: SOTM Drive");
132+
drivetrainState = "Shoot on the Move Drive";
133+
double vx = -leftY.getAsDouble() * MaxSpeed;
134+
double vy = -leftX.getAsDouble() * MaxSpeed;
135+
Translation2d robotPosition = subsystem.getState().Pose.getTranslation();
136+
ChassisSpeeds speeds = subsystem.getState().Speeds;
137+
Translation2d robotVelocity =
138+
new Translation2d(speeds.vxMetersPerSecond, speeds.vyMetersPerSecond);
139+
Translation2d goal = ShotCalculator.calculateHubPosition();
140+
double distance = robotPosition.getDistance(goal);
141+
double flightTime = distance / FUEL_EXIT_VELOCITY;
142+
Translation2d toGoal = goal.minus(robotPosition);
143+
Translation2d toGoalDir =
144+
toGoal.getNorm() > 1e-6 ? toGoal.div(toGoal.getNorm()) : new Translation2d();
145+
Translation2d lateralVelocity =
146+
robotVelocity.minus(toGoalDir.times(robotVelocity.dot(toGoalDir)));
147+
Translation2d virtualGoal = goal.minus(lateralVelocity.times(flightTime));
148+
Rotation2d targetAngle = virtualGoal.minus(robotPosition).getAngle();
149+
double currentHeading = subsystem.getState().Pose.getRotation().getRadians();
150+
double targetHeading = targetAngle.getRadians();
151+
double error = targetHeading - currentHeading;
152+
error = Math.atan2(Math.sin(error), Math.cos(error));
153+
double kP = 50; // tune
154+
double omega = error * kP;
155+
omega = Math.max(-MaxAngularRate, Math.min(MaxAngularRate, omega));
156+
subsystem.setControl(drive.withVelocityX(vx).withVelocityY(vy).withRotationalRate(omega));
157+
158+
break;
159+
160+
case AUTO_ALIGN_HUB:
161+
// Recompute the desired heading toward the hub each loop
162+
m_targetAngle =
163+
ShotCalculator.getRotationTowardsHub(
164+
ShotCalculator.calculateHubPosition(), subsystem.getState().Pose.getTranslation());
165+
double currentRad = subsystem.getState().Pose.getRotation().getRadians();
166+
double targetRad = m_targetAngle.getRadians();
167+
// Normalize error1 to [-pi, pi]
168+
double error1 =
169+
Math.atan2(Math.sin(targetRad - currentRad), Math.cos(targetRad - currentRad));
170+
double absError = Math.abs(error1);
171+
double angleTolerance = Math.toRadians(0.5); // stop within 1 degree
172+
173+
double rotOutput = getAutoAlignRotationalOutput();
174+
175+
if (absError < angleTolerance) {
176+
// Aligned: stop rotating (and hold position)
177+
subsystem.setControl(drive.withVelocityX(0.0).withVelocityY(0.0).withRotationalRate(0.0));
178+
} else {
179+
// Not aligned: apply rotational output
180+
subsystem.setControl(
181+
drive.withVelocityX(0.0).withVelocityY(0.0).withRotationalRate(rotOutput));
182+
}
183+
drivetrainState = "Auto Align";
95184
break;
96185

97186
default:
@@ -104,6 +193,22 @@ public void end(boolean interrupted) {}
104193

105194
@Override
106195
public boolean isFinished() {
107-
return false;
196+
if (pose != Position.AUTO_ALIGN_HUB) {
197+
return false;
198+
}
199+
200+
Translation2d hubPos = ShotCalculator.calculateHubPosition();
201+
202+
Translation2d currentTrans = subsystem.getState().Pose.getTranslation();
203+
if (currentTrans == null) {
204+
return false;
205+
}
206+
207+
Rotation2d target = ShotCalculator.getRotationTowardsHub(hubPos, currentTrans);
208+
double current = subsystem.getState().Pose.getRotation().getRadians();
209+
double targetRad = target.getRadians();
210+
double err = Math.atan2(Math.sin(targetRad - current), Math.cos(targetRad - current));
211+
double angleTolerance = Math.toRadians(1.0); // 1 degree
212+
return Math.abs(err) < angleTolerance;
108213
}
109214
}

src/main/java/frc/robot/config/CANMappings.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ public class CANMappings {
88

99
public static final int INTAKE_MOTOR_ID = 3;
1010

11-
public static final int CLIMB_MOTOR_ID = 22; // unset
12-
1311
public static final int FLYWHEEL_RIGHT_MOTOR_ID = 19;
1412
public static final int FLYWHEEL_LEFT_MOTOR_ID = 2;
1513

0 commit comments

Comments
 (0)