Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
fe6c579
Added start for solo controller
Jetblackdragon Sep 19, 2025
e261298
All controls for solo controller
Jetblackdragon Sep 20, 2025
77b4bae
Merge branch 'main' of https://github.com/robototes/Reefscape2025 int…
Jetblackdragon Sep 20, 2025
d66fb27
spot
Jetblackdragon Sep 20, 2025
8a941ba
drive pratice changes
RobototesProgrammers Sep 21, 2025
c5f6f8e
V2 Set up for solo controls
Jetblackdragon Sep 24, 2025
e96486b
Override on driving when sticks are press down
Jetblackdragon Sep 24, 2025
d534668
dpot
Jetblackdragon Sep 24, 2025
fc7533b
LEDs for solo mode
TrisDooley Sep 24, 2025
460a687
Drive practice changes
RobototesProgrammers Sep 25, 2025
67b5733
Drive pracitce changes
RobototesProgrammers Sep 25, 2025
94dc7fc
Rebump up current limits
Jetblackdragon Sep 25, 2025
7d21c83
NO_GAME_PIECE mode actually works
Jetblackdragon Sep 25, 2025
e4a648d
Drive c
RobototesProgrammers Sep 28, 2025
b2d7d37
Code Clean up
Jetblackdragon Sep 28, 2025
a374024
New command that in theory changes the algae intake command based on …
Jetblackdragon Sep 29, 2025
13299e7
added booleanInIntake
Jetblackdragon Oct 1, 2025
3277113
Supercycling working
Jetblackdragon Oct 1, 2025
7f8c421
Change so auto evelator movements get canceled when you have a game p…
TrisDooley Oct 2, 2025
9ce9866
oops i did withtimeout instead of until
Jetblackdragon Oct 2, 2025
311ce02
spot
Jetblackdragon Oct 2, 2025
49cb5bc
spotspot
Jetblackdragon Oct 2, 2025
4503b62
quick fix
Jetblackdragon Oct 2, 2025
7c4aa9c
spot 😭
Jetblackdragon Oct 2, 2025
8260fb2
ground intake sets intake mode to coral
Jetblackdragon Oct 2, 2025
c382db6
command name correction
Jetblackdragon Oct 2, 2025
b91070c
AutoAlgaeHeights Working
RobototesProgrammers Oct 3, 2025
d80af1a
hold voltage out until retract
RobototesProgrammers Oct 3, 2025
0d78e78
Code cleanup
Jetblackdragon Oct 3, 2025
be66692
Merge branch 'cyclesuper' of https://github.com/robototes/Reefscape20…
Jetblackdragon Oct 3, 2025
0b3c6f6
merge conflict
Jetblackdragon Oct 3, 2025
b64b691
spotttt
Jetblackdragon Oct 3, 2025
7c30820
Merge branch 'cyclesuper' of https://github.com/robototes/Reefscape20…
Jetblackdragon Oct 5, 2025
d015c10
Prescore fix
Jetblackdragon Oct 5, 2025
5fb07b7
Merge branch 'main' of https://github.com/robototes/Reefscape2025 int…
Jetblackdragon Oct 5, 2025
4a686be
spot
Jetblackdragon Oct 5, 2025
9e23717
More code clean up
Jetblackdragon Oct 5, 2025
5293b44
s
Jetblackdragon Oct 5, 2025
c9f4263
holdGroundIntakeOut Fix
Jetblackdragon Oct 6, 2025
c9910b4
Fix for prescore bug
Jetblackdragon Oct 6, 2025
03d1a52
Fixed barge score not finishing
Jetblackdragon Oct 7, 2025
1cb71aa
pre score fix attempt #???
Jetblackdragon Oct 7, 2025
4bdd1ea
controller connceted bug
Jetblackdragon Oct 7, 2025
3564465
super cycle fix probably
Jetblackdragon Oct 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 97 additions & 55 deletions src/main/java/frc/robot/Controls.java
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,10 @@ private void configureDrivebaseBindings() {
// Stop running this method
return;
}

// if the solo controller is connected, use it for driving
// gets set when robot code starts running for the first time so usally is false and isnt
// currently in use
boolean soloCC = soloController.isConnected();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will result in soloCC only being set when the robot code starts running, so changing to or from soloCC will require a restart of the robot code. Consider instead making this a boolean class member variable and then updating it ever second or so based on whether the solo controller is connected (via adding a new update method in this class that Robot.robotPeriodic() calls, and have the update method do the soloCC update every second or so).

Copy link
Contributor

@RobototesProgrammers RobototesProgrammers Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it worked fine at drive practice we can check again at the meeting on monday
-Aarya (I forgot what account im on)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you think it actually matter is we just call soloController.isConnected() instead of soloCC for the drive request (changing it back to what is was before)?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at what isConnected does, it's similar to what driverController.getLeftX() does by looking at DriverStation.getStickAxis() vs DriverStation.isJoystickConnected

I wouldn't go back to the original change which did .withVelocityX(soloController.isConnected() ? getSoloDriveX() : getDriveX()), since it ends up reading from the HID four times (three times to check if the controller is connected & once to get that axis value), but instead have a class variable that's updated every loop to cache the result of soloController.isConnected() and then switch off of that: .withVelocityX(soloCC ? getSoloDriveX() : getDriveX()). To ensure the commands are run with the most up-to-date value, I'd sequence the new Command class periodic update in Robot.robotPeriodic to happen before the call to CommandScheduler.getInstance().run();

// Note that X is defined as forward according to WPILib convention,
// and Y is defined as to the left according to WPILib convention.

Expand Down Expand Up @@ -379,9 +382,6 @@ private void configureSuperStructureBindings() {
.asProxy()
: Commands.none())
.withName("Automatic Intake"));
}

if (sensors.armSensor != null) {
sensors
.armSensor
.inClaw()
Expand All @@ -394,12 +394,7 @@ private void configureSuperStructureBindings() {
case ALGAE -> soloScoringMode = SoloScoringMode.ALGAE_IN_CLAW;
}
})
.withName("Set solo scoring mode"));

sensors
.armSensor
.inClaw()
.and(RobotModeTriggers.teleop())
.withName("Set solo scoring mode"))
.onFalse(
Commands.runOnce(
() -> {
Expand Down Expand Up @@ -718,7 +713,7 @@ private void configureSpinnyClawBindings() {
} else {
return switch (scoringMode) {
case CORAL -> Commands.none().withName("No manual spit - Coral mode");
case ALGAE -> s.spinnyClawSubsytem.algaeExtakePower();
case ALGAE -> s.spinnyClawSubsytem.algaeExtakeProcessorPower();
};
}
}));
Expand Down Expand Up @@ -884,7 +879,7 @@ public void vibrateCoDriveController(double vibration) {
}
}

private double getJoystickInput(double input) {
private double getSoloJoystickInput(double input) {
if (soloController.leftStick().getAsBoolean() || soloController.rightStick().getAsBoolean()) {
return 0; // stop driving if either stick is pressed
}
Expand All @@ -898,65 +893,101 @@ private double getJoystickInput(double input) {
private double getSoloDriveX() {
// Joystick +Y is back
// Robot +X is forward
return getJoystickInput(-soloController.getLeftY()) * MaxSpeed;
return getSoloJoystickInput(-soloController.getLeftY()) * MaxSpeed;
}

// takes the Y value from the joystick, and applies a deadband and input scaling
private double getSoloDriveY() {
// Joystick +X is right
// Robot +Y is left
return getJoystickInput(-soloController.getLeftX()) * MaxSpeed;
return getSoloJoystickInput(-soloController.getLeftX()) * MaxSpeed;
}

// takes the rotation value from the joystick, and applies a deadband and input scaling
private double getSoloDriveRotate() {
// Joystick +X is right
// Robot +angle is CCW (left)
return getJoystickInput(-soloController.getRightX()) * MaxSpeed;
return getSoloJoystickInput(-soloController.getRightX()) * MaxSpeed;
}

private void configureSoloControllerBindings() {
// Barge + Auto align left + Select scoring mode Algae
soloController
.leftTrigger()
.onTrue(
Commands.runOnce(
() -> {
Command scoreCommand;
switch (soloScoringMode) {
case CORAL_IN_CLAW -> {
scoreCommand = getSoloCoralBranchHeightCommand();
}
case ALGAE_IN_CLAW -> {
Command bargeScoreCommand =
BargeAlign.bargeScore(
Commands.deferredProxy(
() -> {
Command scoreCommand;
switch (soloScoringMode) {
case CORAL_IN_CLAW -> {
scoreCommand =
getSoloCoralBranchHeightCommand()
.until(
() ->
soloController.a().getAsBoolean()
|| soloController.b().getAsBoolean()
|| soloController.x().getAsBoolean()
|| soloController.y().getAsBoolean());
}

case ALGAE_IN_CLAW -> {
Command bargeScoreCommand =
BargeAlign.bargeScore(
s.drivebaseSubsystem,
superStructure,
() -> getSoloDriveX(),
() -> getSoloDriveY(),
() -> getSoloDriveRotate(),
soloController.rightBumper())
.withName("Algae score then intake");
scoreCommand =
Commands.sequence(
bargeScoreCommand,
Commands.runOnce(
() -> soloScoringMode = soloScoringMode.NO_GAME_PIECE));
}
case NO_GAME_PIECE -> {
scoreCommand =
Commands.parallel(
Commands.runOnce(() -> intakeMode = ScoringMode.ALGAE)
.alongWith(scoringModeSelectRumble())
.withName("Algae Scoring Mode"),
AutoAlgaeHeights.autoAlgaeIntakeCommand(
s.drivebaseSubsystem, superStructure, this)
.until(() -> sensors.armSensor.booleanInClaw()));
}
default -> scoreCommand = Commands.none();
}
CommandScheduler.getInstance().schedule(scoreCommand);
}));
soloController.rightBumper());

if (sensors.intakeSensor.booleanInIntake()) {
Command holdGroundIntakeOut =
superStructure.holdGroundIntakeOut(soloController.povUp());

Command quickHandoff =
Commands.sequence(
superStructure
.quickGroundIntake(() -> true)
.withName("Quick Gound intake"),
Commands.runOnce(
() -> soloScoringMode = soloScoringMode.CORAL_IN_CLAW))
.withName("Quick Handoff After Algae Score");

scoreCommand =
holdGroundIntakeOut
.deadlineFor(bargeScoreCommand)
.andThen(quickHandoff)
.withName("Algae Score + Ground Handoff");
} else {
scoreCommand =
Commands.sequence(
bargeScoreCommand,
Commands.runOnce(
() -> soloScoringMode = soloScoringMode.NO_GAME_PIECE))
.withName("Barge Algae Score");
}
}

case NO_GAME_PIECE -> {
scoreCommand =
Commands.parallel(
Commands.runOnce(() -> intakeMode = ScoringMode.ALGAE)
.alongWith(scoringModeSelectRumble())
.withName("Algae Scoring Mode"),
AutoAlgaeHeights.autoAlgaeIntakeCommand(
s.drivebaseSubsystem, superStructure, this)
.until(() -> sensors.armSensor.booleanInClaw()));
}

default -> {
scoreCommand = Commands.none();
}
}

return scoreCommand;
})
.withName("Solo Left Trigger Action"));

soloController
.leftTrigger()
.and(() -> soloScoringMode == soloScoringMode.CORAL_IN_CLAW)
Expand All @@ -966,15 +997,14 @@ private void configureSoloControllerBindings() {
soloController
.rightTrigger()
.onTrue(
Commands.runOnce(
Commands.deferredProxy(
() -> {
Command scoreCommand =
switch (soloScoringMode) {
case CORAL_IN_CLAW -> getSoloCoralBranchHeightCommand();
case ALGAE_IN_CLAW -> Commands.sequence(
superStructure.algaeProcessorScore(
soloController.rightBumper()),
Commands.waitSeconds(0.7),
Commands.runOnce(
() -> soloScoringMode = soloScoringMode.NO_GAME_PIECE))
.withName("Processor score");
Expand All @@ -985,22 +1015,34 @@ private void configureSoloControllerBindings() {
superStructure.coralPreIntake(),
s.climbPivotSubsystem.toStow());
};
CommandScheduler.getInstance().schedule(scoreCommand);
return scoreCommand;
})
.withName("score"));
soloController
.rightTrigger()
.and(() -> soloScoringMode == soloScoringMode.CORAL_IN_CLAW)
.and(() -> branchHeight != BranchHeight.CORAL_LEVEL_ONE)
.whileTrue(AutoAlign.autoAlignRight(s.drivebaseSubsystem, this));
// Ground Intake
soloController
.leftBumper()
.onTrue(
Commands.parallel(
Commands.runOnce(() -> intakeMode = ScoringMode.CORAL),
superStructure.quickGroundIntake(soloController.povUp()))
.withName("Quick Gound intake"));
Commands.runOnce(
() -> {
Command intakeCommand;
switch (soloScoringMode) {
case CORAL_IN_CLAW, NO_GAME_PIECE -> intakeCommand =
superStructure
.quickGroundIntake(soloController.povUp())
.withName("Quick Ground Intake")
.alongWith(Commands.runOnce(() -> intakeMode = ScoringMode.CORAL));
case ALGAE_IN_CLAW -> intakeCommand =
superStructure
.holdGroundIntakeOut(soloController.povUp())
.withName("Hold Ground Intake Out");
default -> intakeCommand = Commands.none();
}
CommandScheduler.getInstance().schedule(intakeCommand);
}));
// Scoring levels coral and algae intake heights
soloController
.y()
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/frc/robot/sensors/IntakeSensor.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,9 @@ public Trigger inIntake() {
})
.debounce(0.1);
}

public boolean booleanInIntake() {
double distance = getSensorDistance().in(Meters);
return distance > INTAKE_LOWER_LIMIT && distance < INTAKE_UPPER_LIMIT;
}
}
3 changes: 1 addition & 2 deletions src/main/java/frc/robot/subsystems/SpinnyClaw.java
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,7 @@ public Command algaeIntakePower() {
return setPower(ALGAE_INTAKE_SPEED).withName("Algae intake power");
}

public Command
algaeExtakePower() { // can change to net extake maybe? also bound as general extake though
public Command algaeExtakeNetPower() {
return setPower(ALGAE_EXTAKE_SPEED).withName("Algae extake power");
}

Expand Down
17 changes: 16 additions & 1 deletion src/main/java/frc/robot/subsystems/SuperStructure.java
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,21 @@ public Command groundIntake(BooleanSupplier retract) {
}
}

public Command holdGroundIntakeOut(BooleanSupplier retract) {
if (groundSpinny == null || groundArm == null) {
return Commands.none().withName("hold ground intake disabled");
}

return Commands.sequence(
Commands.parallel(
groundArm
.moveToPosition(GroundArm.GROUND_POSITION)
.andThen(groundArm.setVoltage(GroundArm.GROUND_HOLD_VOLTAGE))
.withDeadline(Commands.waitUntil(retract)),
groundSpinny.setGroundIntakePower()))
.withName("Hold Ground Intake Out");
}

// This is the actual version in use. It moves the coral directly into the claw.
public Command quickGroundIntake(BooleanSupplier retract) { // thanks joseph
if (groundSpinny == null || groundArm == null || intakeSensor == null) {
Expand Down Expand Up @@ -421,7 +436,7 @@ public Command algaeNetScore(BooleanSupplier score) {
armPivot.moveToPosition(ArmPivot.ALGAE_NET_SCORE),
spinnyClaw.algaeIntakePower()),
Commands.waitUntil(score),
spinnyClaw.algaeHoldExtakePower().withTimeout(0.7),
spinnyClaw.algaeExtakeNetPower(),
Commands.waitSeconds(0.7),
armPivot.moveToPosition(
ArmPivot.CORAL_PRESET_UP), // added to prevent hitting the barge after scoring net
Expand Down