Skip to content

Commit 51bbc7e

Browse files
authored
Merge pull request #8 from strykeforce/algae
Initial Algae
2 parents cfccccf + 6696633 commit 51bbc7e

File tree

8 files changed

+225
-93
lines changed

8 files changed

+225
-93
lines changed

src/main/java/frc/robot/RobotContainer.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import edu.wpi.first.wpilibj2.command.Commands;
1414
import edu.wpi.first.wpilibj2.command.button.JoystickButton;
1515
import edu.wpi.first.wpilibj2.command.button.Trigger;
16+
import frc.robot.commands.algae.OpenLoopAlgaeCommand;
1617
import frc.robot.commands.coral.EnableEjectBeamCommand;
1718
import frc.robot.commands.coral.OpenLoopCoralCommand;
1819
import frc.robot.commands.drive.DriveTeleopCommand;
@@ -21,6 +22,8 @@
2122
import frc.robot.constants.ElevatorConstants;
2223
import frc.robot.constants.RobotConstants;
2324
import frc.robot.controllers.FlyskyJoystick;
25+
import frc.robot.subsystems.algae.AlgaeIOFX;
26+
import frc.robot.subsystems.algae.AlgaeSubsystem;
2427
import frc.robot.subsystems.coral.CoralIO;
2528
import frc.robot.subsystems.coral.CoralIOFX;
2629
import frc.robot.subsystems.coral.CoralSubsystem;
@@ -33,22 +36,29 @@
3336
import org.strykeforce.telemetry.TelemetryService;
3437

3538
public class RobotContainer {
36-
private Swerve swerve;
37-
private DriveSubsystem driveSubsystem;
3839

3940
private ElevatorIO elevatorIO;
4041
private ElevatorSubsystem elevatorSubsystem;
4142

4243
private final CoralIO coralIO;
4344
private final CoralSubsystem coralSubsystem;
4445

46+
private AlgaeIOFX algaeIO;
47+
private AlgaeSubsystem algaeSubsystem;
48+
49+
private Swerve swerve;
50+
private DriveSubsystem driveSubsystem;
51+
4552
private final XboxController xboxController = new XboxController(1);
4653
private final Joystick driveJoystick = new Joystick(0);
4754

4855
private final FlyskyJoystick flysky = new FlyskyJoystick(driveJoystick);
4956
private final TelemetryService telemetryService = new TelemetryService(TelemetryController::new);
5057

5158
public RobotContainer() {
59+
algaeIO = new AlgaeIOFX();
60+
algaeSubsystem = new AlgaeSubsystem(algaeIO);
61+
5262
swerve = new Swerve();
5363
driveSubsystem = new DriveSubsystem(swerve);
5464

@@ -66,6 +76,8 @@ public RobotContainer() {
6676
private void configureTelemetry() {
6777
telemetryService.register(driveSubsystem);
6878
telemetryService.register(coralSubsystem);
79+
telemetryService.register(algaeSubsystem);
80+
telemetryService.register(elevatorSubsystem);
6981
telemetryService.start();
7082
}
7183

@@ -103,6 +115,12 @@ private void configureOperatorBindings() {
103115
// Zero Elevator
104116
new JoystickButton(xboxController, XboxController.Button.kX.value)
105117
.onTrue(new ZeroElevatorCommand(elevatorSubsystem));
118+
119+
// Algae Buttons
120+
new JoystickButton(xboxController, XboxController.Button.kLeftBumper.value)
121+
.onTrue(new OpenLoopAlgaeCommand(algaeSubsystem, 0.5));
122+
new JoystickButton(xboxController, XboxController.Button.kRightBumper.value)
123+
.onTrue(new OpenLoopAlgaeCommand(algaeSubsystem, -0.5));
106124
}
107125

108126
public Command getAutonomousCommand() {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package frc.robot.commands.algae;
2+
3+
import edu.wpi.first.wpilibj2.command.InstantCommand;
4+
import frc.robot.subsystems.algae.AlgaeSubsystem;
5+
6+
public class OpenLoopAlgaeCommand extends InstantCommand {
7+
private AlgaeSubsystem algaeSubsystem;
8+
private double pct;
9+
10+
public OpenLoopAlgaeCommand(AlgaeSubsystem algaeSubsystem, double pct) {
11+
this.algaeSubsystem = algaeSubsystem;
12+
this.pct = pct;
13+
}
14+
15+
@Override
16+
public void initialize() {
17+
algaeSubsystem.setPct(pct);
18+
}
19+
}

src/main/java/frc/robot/constants/AlgaeConstants.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package frc.robot.constants;
22

3-
import static edu.wpi.first.units.Units.Degrees;
4-
import static edu.wpi.first.units.Units.Rotations;
3+
import static edu.wpi.first.units.Units.RotationsPerSecond;
54

65
import com.ctre.phoenix6.configs.CurrentLimitsConfigs;
76
import com.ctre.phoenix6.configs.HardwareLimitSwitchConfigs;
@@ -16,16 +15,19 @@
1615
import com.ctre.phoenix6.signals.NeutralModeValue;
1716
import com.ctre.phoenix6.signals.ReverseLimitSourceValue;
1817
import com.ctre.phoenix6.signals.ReverseLimitTypeValue;
19-
import edu.wpi.first.units.measure.*;
18+
import edu.wpi.first.units.measure.AngularVelocity;
2019

2120
public class AlgaeConstants {
21+
public static int kFxId = 30;
2222

23-
public static int kFxId = 4; // CHANGE TO MOTOR NUMBER
23+
public static final AngularVelocity kCloseEnough = RotationsPerSecond.of(0.1);
24+
public static final AngularVelocity kMaxFwd = RotationsPerSecond.of(100);
25+
public static final AngularVelocity kMaxRev = RotationsPerSecond.of(-100);
2426

25-
public static final Angle kCloseEnough = Degrees.of(5);
26-
public static final Angle kMaxFwd = Rotations.of(100);
27-
public static final Angle kMaxRev = Rotations.of(-100);
28-
public static final Angle kZeroTicks = Rotations.of(1530);
27+
public static final AngularVelocity kHoldSpeed = RotationsPerSecond.of(-0.1);
28+
public static final AngularVelocity kBargeScoreSpeed = RotationsPerSecond.of(1);
29+
public static final AngularVelocity kProcessorScoreSpeed = RotationsPerSecond.of(1);
30+
public static final AngularVelocity kIntakingSpeed = RotationsPerSecond.of(-1);
2931

3032
// Example Talon FX Config
3133
public static TalonFXConfiguration getFXConfig() {
@@ -57,9 +59,9 @@ public static TalonFXConfiguration getFXConfig() {
5759
SoftwareLimitSwitchConfigs swLimit =
5860
new SoftwareLimitSwitchConfigs()
5961
.withForwardSoftLimitEnable(true)
60-
.withForwardSoftLimitThreshold(kMaxFwd)
62+
.withForwardSoftLimitThreshold(kMaxFwd.in(RotationsPerSecond))
6163
.withReverseSoftLimitEnable(true)
62-
.withReverseSoftLimitThreshold(kMaxRev);
64+
.withReverseSoftLimitThreshold(kMaxRev.in(RotationsPerSecond));
6365
fxConfig.SoftwareLimitSwitch = swLimit;
6466

6567
Slot0Configs slot0 =

src/main/java/frc/robot/constants/VisionConstants.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public final class VisionConstants {
9393
VecBuilder.fill(Units.degreesToRadians(0.01));
9494

9595
// Increase these numbers to trust global measurements from vision less. This matrix is in the
96-
// form [x, y, theta], with units in meters and radians.
96+
// form [x, y, theta], with units in meters and radians.
9797
// Vision Odometry Standard devs
9898
public static Matrix<N3, N1> kVisionMeasurementStdDevs =
9999
VecBuilder.fill(0.05, 0.05, Units.degreesToRadians(360));

src/main/java/frc/robot/subsystems/algae/algaeIO.java renamed to src/main/java/frc/robot/subsystems/algae/AlgaeIO.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
package frc.robot.subsystems.algae;
22

3-
import com.ctre.phoenix6.signals.ReverseLimitValue;
4-
import edu.wpi.first.units.measure.Angle;
53
import edu.wpi.first.units.measure.AngularVelocity;
64
import org.littletonrobotics.junction.AutoLog;
75
import org.strykeforce.telemetry.TelemetryService;
86

9-
public interface algaeIO {
7+
public interface AlgaeIO {
108
@AutoLog
11-
public static class IOInputs {
9+
public static class AlgaeIOInputs {
1210
public AngularVelocity velocity;
13-
public Angle location;
14-
public ReverseLimitValue reverseLimitSwitch;
11+
public boolean isFwdLimitSwitchClosed;
12+
public boolean isRevLimitSwitchClosed;
1513
}
1614

17-
public default void updateInputs(IOInputs inputs) {}
15+
public default void updateInputs(AlgaeIOInputs inputs) {}
1816

19-
public default void setPosition(double position) {}
17+
public default void setSpeed(AngularVelocity speed) {}
18+
19+
public default void setPct(double pct) {}
2020

2121
public default void zero() {}
2222

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package frc.robot.subsystems.algae;
2+
3+
import com.ctre.phoenix6.BaseStatusSignal;
4+
import com.ctre.phoenix6.StatusSignal;
5+
import com.ctre.phoenix6.controls.DutyCycleOut;
6+
import com.ctre.phoenix6.controls.VelocityVoltage;
7+
import com.ctre.phoenix6.hardware.TalonFX;
8+
import com.ctre.phoenix6.signals.ForwardLimitValue;
9+
import com.ctre.phoenix6.signals.ReverseLimitValue;
10+
import edu.wpi.first.units.measure.AngularVelocity;
11+
import frc.robot.constants.AlgaeConstants;
12+
import org.slf4j.Logger;
13+
import org.slf4j.LoggerFactory;
14+
import org.strykeforce.telemetry.TelemetryService;
15+
16+
public class AlgaeIOFX implements AlgaeIO {
17+
private Logger logger;
18+
private TalonFX talonFX;
19+
private AlgaeIOInputs inputs;
20+
21+
// FX Access objects
22+
private StatusSignal<AngularVelocity> curVelocity;
23+
private StatusSignal<ForwardLimitValue> fwdLimitSwitch;
24+
private StatusSignal<ReverseLimitValue> revLimitSwitch;
25+
private VelocityVoltage speedRequest = new VelocityVoltage(0).withEnableFOC(false).withSlot(0);
26+
private DutyCycleOut dutyCycleRequest = new DutyCycleOut(0).withEnableFOC(false);
27+
28+
public AlgaeIOFX() {
29+
logger = LoggerFactory.getLogger(this.getClass());
30+
talonFX = new TalonFX(AlgaeConstants.kFxId);
31+
fwdLimitSwitch = talonFX.getForwardLimit();
32+
revLimitSwitch = talonFX.getReverseLimit();
33+
curVelocity = talonFX.getVelocity();
34+
}
35+
36+
@Override
37+
public void updateInputs(AlgaeIOInputs inputs) {
38+
BaseStatusSignal.refreshAll(curVelocity, fwdLimitSwitch, revLimitSwitch);
39+
inputs.velocity = curVelocity.refresh().getValue();
40+
inputs.isFwdLimitSwitchClosed = fwdLimitSwitch.getValue().value == 1; // FIXME check right value
41+
inputs.isRevLimitSwitchClosed = revLimitSwitch.getValue().value == 0; // FIXME check right value
42+
}
43+
44+
@Override
45+
public void setSpeed(AngularVelocity speed) {
46+
talonFX.setControl(speedRequest.withVelocity(speed));
47+
}
48+
49+
@Override
50+
public void setPct(double pct) {
51+
talonFX.setControl(dutyCycleRequest.withOutput(pct));
52+
}
53+
54+
public AngularVelocity AngularVelocity() {
55+
return talonFX.getVelocity().getValue();
56+
}
57+
58+
@Override
59+
public void registerWith(TelemetryService telemetryService) {
60+
telemetryService.register(talonFX, true);
61+
}
62+
}
Lines changed: 103 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,119 @@
11
package frc.robot.subsystems.algae;
22

3-
public class AlgaeSubsystem {
3+
import static edu.wpi.first.units.Units.RotationsPerSecond;
44

5-
public static final String kStowSpeed = null;
5+
import edu.wpi.first.units.measure.AngularVelocity;
6+
import frc.robot.constants.AlgaeConstants;
7+
import frc.robot.standards.ClosedLoopSpeedSubsystem;
8+
import frc.robot.subsystems.algae.AlgaeIO.AlgaeIOInputs;
9+
import java.util.Set;
10+
import org.littletonrobotics.junction.Logger;
11+
import org.slf4j.LoggerFactory;
12+
import org.strykeforce.telemetry.TelemetryService;
13+
import org.strykeforce.telemetry.measurable.MeasurableSubsystem;
14+
import org.strykeforce.telemetry.measurable.Measure;
615

7-
public boolean hasAlgae() {
8-
// TODO Auto-generated method stub
9-
throw new UnsupportedOperationException("Unimplemented method 'hasAlgae'");
16+
public class AlgaeSubsystem extends MeasurableSubsystem implements ClosedLoopSpeedSubsystem {
17+
private org.slf4j.Logger logger = LoggerFactory.getLogger(AlgaeSubsystem.class);
18+
19+
private final AlgaeIO io;
20+
private final AlgaeIOInputs inputs = new AlgaeIOInputs();
21+
private AngularVelocity desiredSpeed;
22+
23+
private AlgaeStates curState = AlgaeStates.IDLE;
24+
25+
public AlgaeSubsystem(AlgaeIO io) {
26+
this.io = io;
27+
}
28+
29+
public AlgaeStates getState() {
30+
return curState;
31+
}
32+
33+
public void setState(AlgaeStates newState) {
34+
logger.info("{} -> {}", curState, newState);
35+
curState = newState;
1036
}
1137

1238
public void intake() {
13-
// TODO Auto-generated method stub
14-
throw new UnsupportedOperationException("Unimplemented method 'intake'");
39+
setSpeed(AlgaeConstants.kIntakingSpeed);
1540
}
1641

1742
public void scoreProcessor() {
18-
// TODO Auto-generated method stub
19-
throw new UnsupportedOperationException("Unimplemented method 'scoreProcessor'");
43+
setSpeed(AlgaeConstants.kProcessorScoreSpeed);
2044
}
2145

2246
public void scoreBarge() {
47+
setSpeed(AlgaeConstants.kBargeScoreSpeed);
48+
}
49+
50+
public void hold() {
51+
setSpeed(AlgaeConstants.kHoldSpeed);
52+
}
53+
54+
@Override
55+
public void setSpeed(AngularVelocity speed) {
56+
io.setSpeed(speed);
57+
desiredSpeed = speed;
58+
}
59+
60+
public void setPct(double pct) {
61+
io.setPct(pct);
62+
}
63+
64+
@Override
65+
public AngularVelocity getSpeed() {
66+
return inputs.velocity;
67+
}
68+
69+
@Override
70+
public boolean atSpeed() {
71+
return inputs.velocity.minus(desiredSpeed).abs(RotationsPerSecond)
72+
< AlgaeConstants.kCloseEnough.in(RotationsPerSecond);
73+
}
74+
75+
@Override
76+
public void periodic() {
77+
io.updateInputs(inputs);
78+
Logger.recordOutput("Algae/state", curState);
79+
Logger.recordOutput("Algae/setpoint", desiredSpeed.in(RotationsPerSecond));
80+
81+
switch (curState) {
82+
case HAS_ALGAE -> {
83+
if (!inputs.isFwdLimitSwitchClosed) {
84+
setState(AlgaeStates.EMPTY);
85+
setSpeed(RotationsPerSecond.of(0));
86+
}
87+
}
88+
case EMPTY -> {
89+
if (inputs.isRevLimitSwitchClosed) { // FIXME: correct?
90+
hold();
91+
setState(AlgaeStates.HAS_ALGAE);
92+
}
93+
}
94+
case IDLE -> {}
95+
}
96+
}
97+
98+
@Override
99+
public void registerWith(TelemetryService telemetryService) {
100+
super.registerWith(telemetryService);
101+
io.registerWith(telemetryService);
102+
}
103+
104+
@Override
105+
public Set<Measure> getMeasures() {
106+
return Set.of(new Measure("State", () -> curState.ordinal()));
107+
}
108+
109+
public enum AlgaeStates {
110+
HAS_ALGAE,
111+
EMPTY,
112+
IDLE
113+
}
114+
115+
public boolean hasAlgae() {
23116
// TODO Auto-generated method stub
24-
throw new UnsupportedOperationException("Unimplemented method 'scoreBarge'");
117+
throw new UnsupportedOperationException("Unimplemented method 'hasAlgae'");
25118
}
26119
}

0 commit comments

Comments
 (0)