Skip to content
This repository was archived by the owner on May 19, 2024. It is now read-only.

Commit 887555e

Browse files
committed
refactor(arm): WIP.
1 parent b644913 commit 887555e

File tree

8 files changed

+101
-114
lines changed

8 files changed

+101
-114
lines changed

Diff for: src/main/java/frc/robot/RobotContainer.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ private void configureBindings() {
8888
operatorController.leftBumper().onTrue(superstructure.eject());
8989
operatorController.leftTrigger().onTrue(superstructure.intake());
9090

91-
operatorController.rightBumper().onTrue(superstructure.podium());
91+
operatorController.rightBumper().onTrue(superstructure.skim());
9292
operatorController.rightTrigger().onTrue(superstructure.subwoofer());
9393

9494
operatorController.a().onTrue(superstructure.amp());

Diff for: src/main/java/frc/robot/arm/Arm.java

+43-17
Original file line numberDiff line numberDiff line change
@@ -10,34 +10,39 @@
1010
import frc.lib.controller.PositionControllerIO.PositionControllerIOValues;
1111
import frc.robot.arm.ArmConstants.ShoulderConstants;
1212

13-
/** Subsystem class for the arm subsystem. */
13+
/** Arm subsystem. */
1414
public class Arm extends Subsystem {
1515

1616
/** Instance variable for the arm subsystem singleton. */
1717
private static Arm instance = null;
1818

19-
/** Shoulder. */
19+
/** Shoulder position controller. */
2020
private final PositionControllerIO shoulder;
2121

22-
/** Shoulder values. */
22+
/** Shoulder position controller values. */
2323
private final PositionControllerIOValues shoulderValues;
2424

25-
private double lastTimeSeconds;
25+
/** Arm's goal. Set by superstructure to use as end goal for setpoints. */
26+
private ArmState goal;
2627

27-
/** Arm goal. */
28-
private ArmState setpoint, goal;
28+
/** Arm's setpoint. Updated periodically to reach the goal within constraints. */
29+
private ArmState setpoint;
2930

30-
/** Creates a new instance of the arm subsystem. */
31+
/** Time of the start of the previous periodic call. Used for calculating the time elapsed since the previous setpoint was generated. */
32+
private double previousTimeSeconds;
33+
34+
/** Creates a new arm subsystem and configures arm hardware. */
3135
private Arm() {
3236
shoulder = ArmFactory.createShoulder();
33-
shoulderValues = new PositionControllerIOValues();
3437
shoulder.configure(ShoulderConstants.CONTROLLER_CONSTANTS);
3538

36-
lastTimeSeconds = Timer.getFPGATimestamp();
39+
shoulderValues = new PositionControllerIOValues();
40+
41+
previousTimeSeconds = Timer.getFPGATimestamp();
3742

38-
setPosition(ArmState.INITIAL);
39-
setpoint = ArmState.INITIAL;
40-
goal = ArmState.INITIAL;
43+
setPosition(ArmState.STOW_POSITION);
44+
setpoint = ArmState.STOW_POSITION;
45+
goal = ArmState.STOW_POSITION;
4146
}
4247

4348
/**
@@ -59,17 +64,18 @@ public void periodic() {
5964

6065
double timeSeconds = Timer.getFPGATimestamp();
6166

62-
double dt = timeSeconds - lastTimeSeconds;
63-
64-
lastTimeSeconds = timeSeconds;
67+
// Calculate the time elapsed in seconds since the previous setpoint was generated
68+
double timeElapsedSeconds = timeSeconds - previousTimeSeconds;
6569

6670
setpoint =
6771
new ArmState(
6872
ShoulderConstants.MOTION_PROFILE.calculate(
69-
dt, setpoint.shoulderRotations(), goal.shoulderRotations()));
73+
timeElapsedSeconds, setpoint.shoulderRotations(), goal.shoulderRotations()));
7074

7175
shoulder.setSetpoint(
7276
setpoint.shoulderRotations().position, setpoint.shoulderRotations().velocity);
77+
78+
previousTimeSeconds = timeSeconds;
7379
}
7480

7581
@Override
@@ -82,21 +88,41 @@ public void addToShuffleboard(ShuffleboardTab tab) {
8288
() -> Units.rotationsToDegrees(setpoint.shoulderRotations().position));
8389
}
8490

91+
/**
92+
* Returns the arm's state.
93+
*
94+
* @return the arm's state.
95+
*/
8596
public ArmState getState() {
8697
return new ArmState(
8798
new TrapezoidProfile.State(
8899
shoulderValues.positionRotations, shoulderValues.velocityRotationsPerSecond));
89100
}
90101

102+
/**
103+
* Sets the arm's goal state.
104+
*
105+
* @param goal the arm's goal state.
106+
*/
91107
public void setGoal(ArmState goal) {
92108
this.goal = goal;
93109
}
94110

111+
/**
112+
* Returns true if at the arm's set goal.
113+
*
114+
* @return true if at the arm's set goal.
115+
*/
95116
public boolean atGoal() {
96117
return getState().at(goal);
97118
}
98119

99-
public void setPosition(ArmState armState) {
120+
/**
121+
* Sets the position of the shoulder motor encoders.
122+
*
123+
* @param armState the position.
124+
*/
125+
private void setPosition(ArmState armState) {
100126
shoulder.setPosition(armState.shoulderRotations().position);
101127
}
102128
}

Diff for: src/main/java/frc/robot/arm/ArmConstants.java

+22-18
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,35 @@ public static class ShoulderConstants {
2525
public static final PIDFConstants PIDF = new PIDFConstants();
2626

2727
static {
28-
PIDF.kS = 0.14;
29-
PIDF.kG = 0.5125;
30-
PIDF.kV = 4.0;
31-
PIDF.kP = 4.0;
28+
PIDF.kS = 0.14; // volts
29+
PIDF.kG = 0.5125; // volts
30+
PIDF.kV = 4.0; // volts per rotation per second
31+
PIDF.kP = 4.0; // volts per rotation
3232
}
3333

3434
/** Shoulder's controller constants. */
3535
public static final PositionControllerIOConstants CONTROLLER_CONSTANTS =
3636
new PositionControllerIOConstants();
3737

3838
static {
39+
// The leading shoulder motor has the correct reference frame
3940
CONTROLLER_CONSTANTS.ccwPositiveMotor = true;
41+
42+
// The shoulder's absolute encoder has the wrong reference frame
4043
CONTROLLER_CONSTANTS.ccwPositiveAbsoluteEncoder = false;
44+
45+
// Use brake mode to hold the arm in place
46+
// Since the arm rests on a hard stop this isn't strictly necessary,
47+
// but it prevents the arm from being knocked around if disabled
4148
CONTROLLER_CONSTANTS.neutralBrake = true;
49+
50+
// Ask CAD if they can calculate this reduction or count the gears
4251
CONTROLLER_CONSTANTS.sensorToMechanismRatio = 39.771428571;
52+
53+
// 1. Rest the arm in the stow position
54+
// 2. Use a digital level to determine the actual angle of the stow position
55+
// 3. Observe the value reported by the absolute encoder while the arm is in the stow position
56+
// 4. Calculate the absolute encoder offset by subtracting the absolute encoder value from the actual angle
4357
CONTROLLER_CONSTANTS.absoluteEncoderOffsetRotations = Units.degreesToRotations(-173.135);
4458
}
4559

@@ -57,20 +71,10 @@ public static class ShoulderConstants {
5771
/** Motion profile of the shoulder. */
5872
public static final TrapezoidProfile MOTION_PROFILE = new TrapezoidProfile(CONSTRAINTS);
5973

60-
public static final Rotation2d STOW = Rotation2d.fromDegrees(-26);
61-
62-
public static final Rotation2d LOB = Rotation2d.fromDegrees(-26);
63-
64-
public static final Rotation2d SUBWOOFER = Rotation2d.fromDegrees(-26);
65-
66-
public static final Rotation2d PODIUM = Rotation2d.fromDegrees(-10);
67-
68-
public static final Rotation2d EJECT = Rotation2d.fromDegrees(30);
69-
70-
public static final Rotation2d SKIM = Rotation2d.fromDegrees(30);
71-
72-
public static final Rotation2d AMP = Rotation2d.fromDegrees(60);
74+
/** Shoulder angle when the arm is stowed. */
75+
public static final Rotation2d STOW_ANGLE = Rotation2d.fromDegrees(-26);
7376

74-
public static final Rotation2d BLOOP = Rotation2d.fromDegrees(-26);
77+
/** Shoulder angle when the shooter is parallel to the ground. Used for flat shots. */
78+
public static final Rotation2d FLAT_ANGLE = Rotation2d.fromDegrees(30);
7579
}
7680
}

Diff for: src/main/java/frc/robot/arm/ArmState.java

+7-15
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,17 @@
77
import frc.robot.arm.ArmConstants.ShoulderConstants;
88
import java.util.Objects;
99

10+
/** Represents an arm's state */
1011
public record ArmState(State shoulderRotations) {
1112

12-
public static final ArmState INITIAL = new ArmState(ShoulderConstants.STOW);
13+
/** State for stow position. */
14+
public static final ArmState STOW_POSITION = new ArmState(ShoulderConstants.STOW_ANGLE);
1315

14-
public static final ArmState STOW = new ArmState(ShoulderConstants.STOW);
16+
/** State for flat position. */
17+
public static final ArmState FLAT_POSITION = new ArmState(ShoulderConstants.FLAT_ANGLE);
1518

16-
public static final ArmState SUBWOOFER = new ArmState(ShoulderConstants.SUBWOOFER);
17-
18-
public static final ArmState PODIUM = new ArmState(ShoulderConstants.PODIUM);
19-
20-
public static final ArmState EJECT = new ArmState(ShoulderConstants.EJECT);
21-
22-
public static final ArmState SKIM = new ArmState(ShoulderConstants.SKIM);
23-
24-
public static final ArmState LOB = new ArmState(ShoulderConstants.LOB);
25-
26-
public static final ArmState AMP = new ArmState(ShoulderConstants.AMP);
27-
28-
public static final ArmState BLOOP = new ArmState(ShoulderConstants.BLOOP);
19+
/** State for amp position. */
20+
public static final ArmState AMP_POSITION = new ArmState(Rotation2d.fromDegrees(60));
2921

3022
public ArmState {
3123
Objects.requireNonNull(shoulderRotations);

Diff for: src/main/java/frc/robot/auto/Auto.java

+20-29
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
import com.pathplanner.lib.util.HolonomicPathFollowerConfig;
66
import com.pathplanner.lib.util.PIDConstants;
77
import com.pathplanner.lib.util.ReplanningConfig;
8-
import edu.wpi.first.math.geometry.Pose2d;
9-
import edu.wpi.first.math.kinematics.ChassisSpeeds;
108
import edu.wpi.first.wpilibj.shuffleboard.ShuffleboardTab;
119
import edu.wpi.first.wpilibj.smartdashboard.SendableChooser;
1210
import edu.wpi.first.wpilibj2.command.Command;
@@ -17,8 +15,6 @@
1715
import frc.robot.superstructure.Superstructure;
1816
import frc.robot.swerve.Swerve;
1917
import frc.robot.swerve.SwerveConstants;
20-
import java.util.function.Consumer;
21-
import java.util.function.Supplier;
2218

2319
/** Subsystem class for the auto subsystem. */
2420
public class Auto extends Subsystem {
@@ -44,40 +40,38 @@ private Auto() {
4440
superstructure = Superstructure.getInstance();
4541
swerve = Swerve.getInstance();
4642

47-
Supplier<Pose2d> robotPositionSupplier = () -> odometry.getPosition();
48-
49-
Consumer<Pose2d> robotPositionConsumer = position -> odometry.setPosition(position);
50-
51-
Supplier<ChassisSpeeds> swerveChassisSpeedsSupplier = () -> swerve.getChassisSpeeds();
52-
53-
Consumer<ChassisSpeeds> swerveChassisSpeedsConsumer =
54-
chassisSpeeds -> swerve.setChassisSpeeds(chassisSpeeds);
55-
56-
HolonomicPathFollowerConfig holonomicPathFollowerConfig =
43+
AutoBuilder.configureHolonomic(
44+
odometry::getPosition,
45+
odometry::setPosition,
46+
swerve::getChassisSpeeds,
47+
swerve::setChassisSpeeds,
48+
// TODO Move some of these constants to AutoConstants
5749
new HolonomicPathFollowerConfig(
5850
new PIDConstants(1.0),
5951
new PIDConstants(1.0),
6052
SwerveConstants.MAXIMUM_ATTAINABLE_SPEED,
6153
SwerveConstants.NORTH_EAST_MODULE_CONFIG.position().getNorm(),
62-
new ReplanningConfig());
63-
64-
AutoBuilder.configureHolonomic(
65-
robotPositionSupplier,
66-
robotPositionConsumer,
67-
swerveChassisSpeedsSupplier,
68-
swerveChassisSpeedsConsumer,
69-
holonomicPathFollowerConfig,
54+
new ReplanningConfig()),
7055
AllianceFlipHelper::shouldFlip,
7156
swerve);
7257

58+
registerNamedCommands();
59+
60+
autoChooser = AutoBuilder.buildAutoChooser();
61+
}
62+
63+
/**
64+
* Registers PathPlanner named commands.
65+
*/
66+
private void registerNamedCommands() {
7367
NamedCommands.registerCommand("stow", superstructure.stow());
7468
NamedCommands.registerCommand(
75-
"shoot", superstructure.subwoofer().withTimeout(1.5)); // 1 second could work
76-
NamedCommands.registerCommand(
77-
"shootNoPull", superstructure.subwooferNoPull().withTimeout(1.5)); // 1 second could work
69+
"shoot", superstructure.subwoofer().withTimeout(1.5));
7870
NamedCommands.registerCommand("intake", superstructure.intakeInstant());
7971

80-
autoChooser = AutoBuilder.buildAutoChooser();
72+
// TODO Deprecate after competition
73+
NamedCommands.registerCommand(
74+
"shootNoPull", superstructure.subwooferNoPull().withTimeout(1.5));
8175
}
8276

8377
/**
@@ -93,9 +87,6 @@ public static Auto getInstance() {
9387
return instance;
9488
}
9589

96-
@Override
97-
public void periodic() {}
98-
9990
@Override
10091
public void addToShuffleboard(ShuffleboardTab tab) {
10192
Telemetry.makeFullscreen(tab.add("Auto Chooser", autoChooser));

Diff for: src/main/java/frc/robot/shooter/ShooterState.java

-6
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,6 @@ public record ShooterState(
2020
public static final ShooterState SUBWOOFER =
2121
new ShooterState(FlywheelConstants.SPEAKER_SPEED, SerializerConstants.FAST_FEED_SPEED);
2222

23-
public static final ShooterState PODIUM =
24-
new ShooterState(FlywheelConstants.PODIUM_SPEED, SerializerConstants.FAST_FEED_SPEED);
25-
26-
public static final ShooterState LOB =
27-
new ShooterState(FlywheelConstants.LOB_SPEED, SerializerConstants.FAST_FEED_SPEED);
28-
2923
public static final ShooterState SKIM =
3024
new ShooterState(FlywheelConstants.SKIM_SPEED, SerializerConstants.FAST_FEED_SPEED);
3125

Diff for: src/main/java/frc/robot/superstructure/Superstructure.java

-14
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ private Superstructure() {
3737
intake = Intake.getInstance();
3838
shooter = Shooter.getInstance();
3939

40-
setPosition(SuperstructureState.STOW);
41-
4240
goal = SuperstructureState.STOW;
4341
}
4442

@@ -103,10 +101,6 @@ private void addStateToShuffleboard(
103101
() -> state.get().shooterState().serializerVelocityRotationsPerSecond());
104102
}
105103

106-
public void setPosition(SuperstructureState state) {
107-
arm.setPosition(state.armState());
108-
}
109-
110104
public void setGoal(SuperstructureState goal) {
111105
this.goal = goal;
112106

@@ -183,14 +177,6 @@ public Command subwoofer() {
183177
return shoot(SuperstructureState.SUBWOOFER).withName("SUBWOOFER");
184178
}
185179

186-
public Command podium() {
187-
return shoot(SuperstructureState.PODIUM).withName("PODIUM");
188-
}
189-
190-
public Command lob() {
191-
return shoot(SuperstructureState.LOB).withName("LOB");
192-
}
193-
194180
public Command skim() {
195181
return shoot(SuperstructureState.SKIM).withName("SKIM");
196182
}

0 commit comments

Comments
 (0)