|
1 | 1 | package frc.robot.rushinator; |
2 | 2 |
|
| 3 | +import com.ctre.phoenix6.hardware.CANcoder; |
| 4 | +import com.ctre.phoenix6.hardware.TalonFX; |
| 5 | + |
| 6 | +import edu.wpi.first.math.controller.ProfiledPIDController; |
| 7 | +import edu.wpi.first.math.controller.SimpleMotorFeedforward; |
| 8 | +import edu.wpi.first.math.geometry.Rotation2d; |
| 9 | +import edu.wpi.first.math.trajectory.TrapezoidProfile; |
3 | 10 | import edu.wpi.first.wpilibj2.command.SubsystemBase; |
4 | 11 |
|
5 | 12 | public class RushinatorWrist extends SubsystemBase { |
| 13 | + public static class Settings { |
| 14 | + static final int kTalonWristID = 98; //TODO |
| 15 | + static final int kCancoderWristID = 99; //TODO |
| 16 | + |
| 17 | + static final double kG = 0.19; // V |
| 18 | + static final double kS = 0.0; // V / rad |
| 19 | + static final double kV = 0; // V * sec / rad |
| 20 | + static final double kA = 0; // V * sec^2 / rad |
| 21 | + |
| 22 | + static final Rotation2d kMaxVelocity = Rotation2d.fromDegrees(100); |
| 23 | + static final Rotation2d kMaxAcceleration = Rotation2d.fromDegrees(100); |
| 24 | + static final double kP = 15.0; |
| 25 | + static final double kI = 0.0; |
| 26 | + static final double kD = 0; |
| 27 | + |
| 28 | + } |
| 29 | + |
| 30 | + public enum State { |
| 31 | + kGroundWrist(Rotation2d.fromDegrees(180)), |
| 32 | + kScoreWrist(Rotation2d.fromDegrees(90)); |
| 33 | + |
| 34 | + State(Rotation2d pos) { |
| 35 | + this.pos = pos; |
| 36 | + } |
| 37 | + public final Rotation2d pos; |
| 38 | + } |
| 39 | + |
| 40 | + |
| 41 | + private final CANcoder mWristCancoder; |
| 42 | + private final TalonFX mWristTalon; |
| 43 | + private final ProfiledPIDController mPPIDController; |
| 44 | + private final SimpleMotorFeedforward mFFController; |
6 | 45 |
|
| 46 | + public static State kLastState; |
| 47 | + |
| 48 | + public RushinatorWrist() { |
| 49 | + mWristTalon = new TalonFX(Settings.kTalonWristID); |
| 50 | + mWristCancoder = new CANcoder(Settings.kCancoderWristID); |
| 51 | + |
| 52 | + mPPIDController = new ProfiledPIDController(Settings.kP, Settings.kI, Settings.kD, new TrapezoidProfile.Constraints( |
| 53 | + Settings.kMaxVelocity.getRadians(), |
| 54 | + Settings.kMaxAcceleration.getRadians() |
| 55 | + )); |
| 56 | + mPPIDController.setTolerance(2); //degrees of tolerance |
| 57 | + |
| 58 | + mFFController = new SimpleMotorFeedforward(Settings.kS, Settings.kV, Settings.kA); |
| 59 | + } |
| 60 | + |
| 61 | + @Override |
| 62 | + public void periodic() { |
| 63 | + double currentAngle = mWristCancoder.getAbsolutePosition().getValueAsDouble(); |
| 64 | + double pidOutput = mPPIDController.calculate(currentAngle); |
| 65 | + TrapezoidProfile.State setpoint = mPPIDController.getSetpoint(); |
| 66 | + double ffOutput = mFFController.calculate(currentAngle, setpoint.velocity); |
| 67 | + double totalOutputVoltage = pidOutput + ffOutput; |
| 68 | + mWristTalon.setVoltage(totalOutputVoltage); |
| 69 | + } |
| 70 | + |
| 71 | + public void setTargetState(State targetState) { |
| 72 | + kLastState = targetState; |
| 73 | + setTargetPosition(targetState.pos); |
| 74 | + } |
| 75 | + |
| 76 | + public void setTargetPosition(Rotation2d targetPosition) { |
| 77 | + mPPIDController.setGoal(targetPosition.getRadians()); |
| 78 | + } |
| 79 | + |
| 80 | + public boolean atSetpoint() { |
| 81 | + return mPPIDController.atGoal(); |
| 82 | + } |
| 83 | + |
7 | 84 | } |
0 commit comments