Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
24 changes: 5 additions & 19 deletions src/main/java/frc/robot/RobotContainer.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,13 @@

package frc.robot;

import static edu.wpi.first.units.Units.Volts;
import static frc.robot.subsystems.vision.VisionConstants.*;

import com.ctre.phoenix6.CANBus;
import edu.wpi.first.wpilibj.GenericHID;
import edu.wpi.first.wpilibj.XboxController;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.Commands;
import edu.wpi.first.wpilibj2.command.InstantCommand;
import edu.wpi.first.wpilibj2.command.button.CommandXboxController;
import frc.robot.commands.DriveCommands;
import frc.robot.generated.TunerConstants;
Expand All @@ -24,20 +22,21 @@
import frc.robot.operator.OperatorIntent;
import frc.robot.state.MatchState;
import frc.robot.subsystems.drive.Drive;
import frc.robot.util.GoalBehavior;
import frc.robot.util.SubsystemBehavior;
import frc.robot.subsystems.drive.GyroIO;
import frc.robot.subsystems.drive.GyroIOPigeon2;
import frc.robot.subsystems.drive.ModuleIO;
import frc.robot.subsystems.drive.ModuleIOSim;
import frc.robot.subsystems.drive.ModuleIOTalonFX;
import frc.robot.subsystems.launcher.LauncherBehavior;
import frc.robot.subsystems.launcher.LauncherIOSim;
import frc.robot.subsystems.launcher.LauncherIOTalonFX;
import frc.robot.subsystems.launcher.LauncherSubsystem;
import frc.robot.subsystems.vision.AprilTagVision;
import frc.robot.subsystems.vision.VisionIO;
import frc.robot.subsystems.vision.VisionIOLimelight;
import frc.robot.subsystems.vision.VisionIOPhotonVisionSim;
import frc.robot.util.GoalBehavior;
import frc.robot.util.SubsystemBehavior;

/**
* This class is where the bulk of the robot should be declared. Since Command-based is a
Expand Down Expand Up @@ -155,14 +154,15 @@ public RobotContainer() {

// Create goal behaviors (wires operator intent → robot goals)
new RobotGoalsBehavior(robotGoals);
new LauncherBehavior(launcher);

// TODO (students): Create subsystem behaviors here, e.g.:
// new LauncherBehavior(launcher);
// new DriveBehavior(drive);

// Configure all behaviors
GoalBehavior.configureAll(operatorIntent);
SubsystemBehavior.configureAll(robotGoals, matchState);
SubsystemBehavior.configureAll(robotGoals, matchState, launcher);

// Configure the button bindings
configureButtonBindings();
Expand Down Expand Up @@ -193,20 +193,6 @@ private void configureButtonBindings() {
// () -> -controller.getLeftX(),
// () -> Rotation2d.kZero));

controller
.b()
.onTrue(
new InstantCommand(
() -> {
launcher.setLaunchSpeed(Volts.of(2));
launcher.setIndexerSpeed(Volts.of(2));
}))
.onFalse(
new InstantCommand(
() -> {
launcher.stop();
}));

// Switch to X pattern when X button is pressed
controller.x().onTrue(Commands.runOnce(drive::stopWithX, drive));

Expand Down
7 changes: 4 additions & 3 deletions src/main/java/frc/robot/goals/RobotGoal.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package frc.robot.goals;

/**
* Enum representing what the robot is currently trying to accomplish.
* These are high-level goals, not hardware states.
* Enum representing what the robot is currently trying to accomplish. These are high-level goals,
* not hardware states.
*
* <p>TODO (students): Add your robot's goals here (e.g., LAUNCHING, INTAKING)
*/
public enum RobotGoal {
IDLE
IDLE,
LAUNCHING
}
8 changes: 5 additions & 3 deletions src/main/java/frc/robot/goals/RobotGoalEvents.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
import edu.wpi.first.wpilibj2.command.button.Trigger;

/**
* Interface exposing robot goal triggers for behaviors to react to.
* Behaviors should only depend on this interface, not on RobotGoals directly.
* Interface exposing robot goal triggers for behaviors to react to. Behaviors should only depend on
* this interface, not on RobotGoals directly.
*
* <p>TODO (students): Add triggers for each goal in RobotGoal enum
*/
public interface RobotGoalEvents {
Trigger isIdle();
Trigger isIdleTrigger();

Trigger isLaunchingTrigger();
}
39 changes: 22 additions & 17 deletions src/main/java/frc/robot/goals/RobotGoals.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,36 @@
/**
* Central robot state: what we're doing (goal).
*
* Can be set by:
* - Teleop via RobotGoalsBehavior reacting to OperatorIntent
* - Autonomous via direct command calls
* <p>Can be set by: - Teleop via RobotGoalsBehavior reacting to OperatorIntent - Autonomous via
* direct command calls
*
* <p>TODO (students): Add goal triggers for each value in RobotGoal enum
*/
public class RobotGoals extends VirtualSubsystem implements RobotGoalEvents {

private final EnumState<RobotGoal> currentGoal = new EnumState<>("RobotGoals/Goal", RobotGoal.IDLE);
private final EnumState<RobotGoal> currentGoal =
new EnumState<>("RobotGoals/Goal", RobotGoal.IDLE);

public RobotGoals() {}
public RobotGoals() {}

public Command setGoal(RobotGoal goal) {
return Commands.runOnce(() -> currentGoal.set(goal));
}
public Command setGoalCommand(RobotGoal goal) {
return Commands.runOnce(() -> currentGoal.set(goal));
}

@Override
public Trigger isIdle() {
return currentGoal.is(RobotGoal.IDLE);
}
@Override
public Trigger isIdleTrigger() {
return currentGoal.is(RobotGoal.IDLE);
}

public RobotGoal getCurrentGoal() {
return currentGoal.get();
}
public RobotGoal getCurrentGoal() {
return currentGoal.get();
}

@Override
public void periodic() {}
@Override
public void periodic() {}

@Override
public Trigger isLaunchingTrigger() {
return currentGoal.is(RobotGoal.LAUNCHING);
}
}
30 changes: 16 additions & 14 deletions src/main/java/frc/robot/goals/RobotGoalsBehavior.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,26 @@
/**
* Wires operator button presses to robot goal state.
*
* This is the teleop-specific logic. Autonomous bypasses this
* and calls RobotGoals.setGoal() directly.
* <p>This is the teleop-specific logic. Autonomous bypasses this and calls RobotGoals.setGoal()
* directly.
*
* <p>TODO (students): Map your button intents to goals here
* Example:
* intent.wantsToScore().onTrue(goals.setGoal(RobotGoal.LAUNCHING))
* .onFalse(goals.setGoal(RobotGoal.IDLE));
* <p>TODO (students): Map your button intents to goals here Example:
* intent.wantsToScore().onTrue(goals.setGoal(RobotGoal.LAUNCHING))
* .onFalse(goals.setGoal(RobotGoal.IDLE));
*/
public class RobotGoalsBehavior extends GoalBehavior {

private RobotGoals goals;
private RobotGoals goals;

public RobotGoalsBehavior(RobotGoals goals) {
this.goals = goals;
}
public RobotGoalsBehavior(RobotGoals goals) {
this.goals = goals;
}

@Override
public void configure(OperatorIntentEvents intent) {
// TODO (students): Wire intent triggers to goal state changes
}
@Override
public void configure(OperatorIntentEvents intent) {
intent
.wantsToScoreTrigger()
.whileTrue(goals.setGoalCommand(RobotGoal.LAUNCHING))
.whileFalse(goals.setGoalCommand(RobotGoal.IDLE));
}
}
35 changes: 20 additions & 15 deletions src/main/java/frc/robot/operator/OperatorIntent.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,33 @@
/**
* Interprets driver controller inputs into intent triggers.
*
* This class has NO state - it just wraps controller buttons
* and provides semantic meaning (wantsToScore vs rightTrigger).
* <p>This class has NO state - it just wraps controller buttons and provides semantic meaning
* (wantsToScore vs rightTrigger).
*
* State lives in RobotGoals. This class just says what the
* operator is physically doing right now.
* <p>State lives in RobotGoals. This class just says what the operator is physically doing right
* now.
*
* <p>TODO (students): Map your controller buttons to semantic intents here
*/
public class OperatorIntent implements OperatorIntentEvents {

private final CommandXboxController driver;
private final CommandXboxController driver;

public OperatorIntent(int driverPort) {
this.driver = new CommandXboxController(driverPort);
}
public OperatorIntent(int driverPort) {
this.driver = new CommandXboxController(driverPort);
}

@Override
public Trigger wantsToScore() {
return driver.rightTrigger(0.5);
}
@Override
public Trigger wantsToScoreTrigger() {
return driver.rightTrigger(0.5);
}

public CommandXboxController getDriver() {
return driver;
}
public CommandXboxController getDriver() {
return driver;
}

@Override
public Trigger wantsToOutake() {
return driver.b();
}
}
8 changes: 5 additions & 3 deletions src/main/java/frc/robot/operator/OperatorIntentEvents.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
import edu.wpi.first.wpilibj2.command.button.Trigger;

/**
* Interface exposing only the triggers that behaviors might need from OperatorIntent.
* Keeps the contract minimal - behaviors shouldn't know about raw button inputs.
* Interface exposing only the triggers that behaviors might need from OperatorIntent. Keeps the
* contract minimal - behaviors shouldn't know about raw button inputs.
*
* <p>TODO (students): Add intent triggers for your robot's actions
*/
public interface OperatorIntentEvents {
Trigger wantsToScore();
Trigger wantsToScoreTrigger();

Trigger wantsToOutake();
}
44 changes: 22 additions & 22 deletions src/main/java/frc/robot/state/MatchState.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,33 @@
import frc.robot.util.VirtualSubsystem;

/**
* Exposes match phase state as triggers for behaviors to react to.
* Wraps DriverStation calls into a reactive interface.
* Exposes match phase state as triggers for behaviors to react to. Wraps DriverStation calls into a
* reactive interface.
*/
public class MatchState extends VirtualSubsystem implements MatchStateEvents {

@Override
public Trigger isDisabled() {
return new Trigger(DriverStation::isDisabled);
}
@Override
public Trigger isDisabled() {
return new Trigger(DriverStation::isDisabled);
}

@Override
public Trigger isAutonomous() {
return new Trigger(DriverStation::isAutonomousEnabled);
}
@Override
public Trigger isAutonomous() {
return new Trigger(DriverStation::isAutonomousEnabled);
}

@Override
public Trigger isTeleop() {
return new Trigger(DriverStation::isTeleopEnabled);
}
@Override
public Trigger isTeleop() {
return new Trigger(DriverStation::isTeleopEnabled);
}

@Override
public Trigger isEnabled() {
return new Trigger(DriverStation::isEnabled);
}
@Override
public Trigger isEnabled() {
return new Trigger(DriverStation::isEnabled);
}

@Override
public void periodic() {
// No periodic updates needed - triggers poll DriverStation directly
}
@Override
public void periodic() {
// No periodic updates needed - triggers poll DriverStation directly
}
}
20 changes: 10 additions & 10 deletions src/main/java/frc/robot/state/MatchStateEvents.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@
import edu.wpi.first.wpilibj2.command.button.Trigger;

/**
* Interface exposing match phase state as triggers for behaviors to react to.
* Provides triggers for disabled, autonomous, teleop, and enabled states.
* Interface exposing match phase state as triggers for behaviors to react to. Provides triggers for
* disabled, autonomous, teleop, and enabled states.
*/
public interface MatchStateEvents {

/** Trigger when robot is disabled */
Trigger isDisabled();
/** Trigger when robot is disabled */
Trigger isDisabled();

/** Trigger when robot is in autonomous mode */
Trigger isAutonomous();
/** Trigger when robot is in autonomous mode */
Trigger isAutonomous();

/** Trigger when robot is in teleop mode */
Trigger isTeleop();
/** Trigger when robot is in teleop mode */
Trigger isTeleop();

/** Trigger when robot is enabled (auto OR teleop) */
Trigger isEnabled();
/** Trigger when robot is enabled (auto OR teleop) */
Trigger isEnabled();
}
21 changes: 21 additions & 0 deletions src/main/java/frc/robot/subsystems/launcher/LauncherBehavior.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package frc.robot.subsystems.launcher;

import frc.robot.goals.RobotGoalEvents;
import frc.robot.state.MatchStateEvents;
import frc.robot.util.SubsystemBehavior;

public class LauncherBehavior extends SubsystemBehavior {

private final LauncherSubsystem launcher;

public LauncherBehavior(LauncherSubsystem launcher) {
this.launcher = launcher;
}

@Override
public void configure(
RobotGoalEvents goals, MatchStateEvents matchState, LauncherEvents launcherState) {
goals.isLaunchingTrigger().whileTrue(this.launcher.launchCommand());
goals.isIdleTrigger().whileTrue(this.launcher.idleCommand());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package frc.robot.subsystems.launcher;

import edu.wpi.first.wpilibj2.command.button.Trigger;

public interface LauncherEvents {
public Trigger isIdleTrigger();

public Trigger isLaunchingTrigger();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package frc.robot.subsystems.launcher;

public enum LauncherState {
IDLE,
LAUNCHING
}
Loading