Skip to content

Commit 68b5978

Browse files
committed
Move the initialization code in RobotContainer. This encapsulated the logic much better.
1 parent f3a3e9f commit 68b5978

2 files changed

Lines changed: 82 additions & 71 deletions

File tree

src/main/java/frc/robot/Robot.java

Lines changed: 7 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,8 @@
1616
import com.ctre.phoenix6.swerve.SwerveModuleConstants;
1717
import com.ctre.phoenix6.swerve.SwerveModuleConstants.DriveMotorArrangement;
1818
import com.ctre.phoenix6.swerve.SwerveModuleConstants.SteerMotorArrangement;
19-
import edu.wpi.first.wpilibj.DriverStation;
2019
import edu.wpi.first.wpilibj2.command.Command;
2120
import edu.wpi.first.wpilibj2.command.CommandScheduler;
22-
import frc.robot.controller.Controller;
23-
import frc.robot.controller.PS4Controller;
24-
import frc.robot.controller.XboxController;
2521
import frc.robot.generated.TunerConstants;
2622
import frc.robot.subsystems.SimulationVisualizer;
2723
import org.littletonrobotics.junction.LogFileUtil;
@@ -41,65 +37,6 @@ public class Robot extends LoggedRobot {
4137
private Command autonomousCommand;
4238
private RobotContainer robotContainer;
4339

44-
/** Initializes a 2813 {@link Controller} on the given port; auto detects the controller type.
45-
*
46-
* <p>This method initializes a generic 2813 Controller by auto detecting the type of controller plugged on {@code port}.
47-
*
48-
* <p>This method requires that the driver station is attached or returns an {@link IllegalStateException} exception.
49-
*
50-
* @param port Joystick port to connect controller to.
51-
* @throws IllegalStateException if DriverStation is not attached yet. This is a retryable error.
52-
* @throws InternalError if DriverStation is already attached but detects empty/invalid controller at specified port.
53-
*/
54-
private Controller createControllerWithTypeAutoDetect(int port) {
55-
String name = DriverStation.getJoystickName(port);
56-
57-
if (!DriverStation.isDSAttached()) {
58-
throw new IllegalStateException("DriverStation not yet attached.");
59-
}
60-
61-
Controller controller = null;
62-
if (name.contains("Xbox")) {
63-
name = "XBox";
64-
controller = new XboxController(port);
65-
} else if (name.contains("PS4") || name.contains("Wireless Controller")) {
66-
name = "PS4";
67-
controller = new PS4Controller(port);
68-
} else {
69-
throw new InternalError("Unsupported joystick type: [" + name + "]");
70-
}
71-
Logger.recordOutput("Controllers/" + port, name + " controller detected");
72-
return controller;
73-
}
74-
75-
/**
76-
* Configures robot bindings once.
77-
*
78-
* <p>This function configures robot button bindings the first time
79-
* createControllerWithTypeAutoDetect can auto-detect a valid controller
80-
* port 0. It just passes after that.
81-
*
82-
* <p>The function prints DriverStation error if the driver station is ready
83-
* but it cannot detect a valid joystick connected at port 0.
84-
*/
85-
void configureBindingsOnce() {
86-
if (robotContainer.getBindingsInitialized()) return;
87-
88-
try {
89-
Controller controller = createControllerWithTypeAutoDetect(0);
90-
robotContainer.configureButtonBindings(controller);
91-
} catch (IllegalStateException e) {
92-
// createControllerWithTypeAutoDetect throws this exception when
93-
// DriverStation is not ready yet. Ignore it and continue retrying
94-
// in the next periodic.
95-
} catch (InternalError e) {
96-
// createControllerWithTypeAutoDetect throws this error when there's
97-
// no joystick connected at all, or it cannot recognize it's type.
98-
boolean dontPrintStackTrace = false;
99-
DriverStation.reportError("Joistick[0] detection error: " + e, dontPrintStackTrace);
100-
}
101-
}
102-
10340
public Robot() {
10441
// Record metadata
10542
Logger.recordMetadata("ProjectName", BuildConstants.MAVEN_NAME);
@@ -164,7 +101,13 @@ public Robot() {
164101
/** This function is called periodically during all modes. */
165102
@Override
166103
public void robotPeriodic() {
167-
configureBindingsOnce();
104+
// This call will try to late-initialize controller bindings and once it succeeds
105+
// it becomes a no-op after that.
106+
// The reason we should keep retrying it in robotPeriodic is that this operation
107+
// succeeds only after DriverStation goes live and only after a controller is
108+
// connected to it. It will print warnings or errors in the DriverStation / logs
109+
// before that.
110+
robotContainer.configureBindingsOnce();
168111

169112
// Optionally switch the thread to high priority to improve loop
170113
// timing (see the template project documentation for details)

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

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,14 @@
1414
package frc.robot;
1515

1616
import com.pathplanner.lib.auto.AutoBuilder;
17+
import edu.wpi.first.wpilibj.DriverStation;
18+
import edu.wpi.first.wpilibj.RobotBase;
1719
import edu.wpi.first.wpilibj2.command.Command;
1820
import edu.wpi.first.wpilibj2.command.sysid.SysIdRoutine;
1921
import frc.robot.commands.DriveCommands;
2022
import frc.robot.controller.Controller;
23+
import frc.robot.controller.PS4Controller;
24+
import frc.robot.controller.XboxController;
2125
import frc.robot.generated.TunerConstants;
2226
import frc.robot.subsystems.arm.Arm;
2327
import frc.robot.subsystems.arm.ArmIO;
@@ -33,6 +37,7 @@
3337
import frc.robot.subsystems.elevator.ElevatorIO;
3438
import frc.robot.subsystems.elevator.ElevatorIOReal;
3539
import frc.robot.subsystems.elevator.ElevatorIOSim;
40+
import org.littletonrobotics.junction.Logger;
3641
import org.littletonrobotics.junction.networktables.LoggedDashboardChooser;
3742

3843
/**
@@ -53,6 +58,75 @@ public class RobotContainer {
5358
// Keeps track if the controller bindings have been initialized.
5459
private boolean bindingsInitialized = false;
5560

61+
/** Initializes a 2813 {@link Controller} on the given port; auto detects the controller type.
62+
*
63+
* <p>This method initializes a generic 2813 Controller by auto detecting the type of controller plugged on {@code port}.
64+
*
65+
* <p>This method requires that the driver station is attached or returns an {@link IllegalStateException} exception.
66+
*
67+
* @param port Joystick port to connect controller to.
68+
* @throws IllegalStateException if DriverStation is not attached yet. This is a retryable error.
69+
* @throws InternalError if DriverStation is already attached but detects empty/invalid controller at specified port.
70+
*/
71+
private static Controller createControllerWithTypeAutoDetect(int port) {
72+
if (!DriverStation.isDSAttached()) {
73+
throw new IllegalStateException("DriverStation not yet attached.");
74+
}
75+
76+
Controller controller = null;
77+
String name = DriverStation.getJoystickName(port);
78+
if (name.contains("Xbox")) {
79+
name = "XBox";
80+
controller = new XboxController(port);
81+
} else if (name.contains("PS4") || name.contains("Wireless Controller")) {
82+
name = "PS4";
83+
controller = new PS4Controller(port);
84+
} else if (name.contains("Keyboard") && RobotBase.isSimulation()) {
85+
// Support the emulated Keyboard X controllers in simulation mode.
86+
// Map them to XBox controllers.
87+
// It's up to the user to configure the right number of buttons for them
88+
// (see
89+
// https://docs.wpilib.org/en/stable/docs/software/wpilib-tools/robot-simulation/simulation-gui.html#using-the-keyboard-as-a-joystick).
90+
91+
// Keep `name` as is.
92+
controller = new XboxController(port);
93+
} else {
94+
throw new InternalError("Unsupported joystick type: [" + name + "]");
95+
}
96+
Logger.recordOutput("Controllers/" + port, name + " controller detected");
97+
return controller;
98+
}
99+
100+
/**
101+
* Configures robot bindings once.
102+
*
103+
* <p>This function configures robot button bindings the first time
104+
* createControllerWithTypeAutoDetect can auto-detect a valid controller
105+
* port 0. It just passes after that.
106+
*
107+
* <p>The function prints DriverStation error if the driver station is ready
108+
* but it cannot detect a valid joystick connected at port 0.
109+
*/
110+
public void configureBindingsOnce() {
111+
if (bindingsInitialized) return;
112+
113+
boolean dontPrintStackTrace = false;
114+
try {
115+
Controller controller = createControllerWithTypeAutoDetect(0);
116+
configureButtonBindings(controller);
117+
bindingsInitialized = true;
118+
} catch (IllegalStateException e) {
119+
// createControllerWithTypeAutoDetect throws this exception when
120+
// DriverStation is not ready yet. Ignore it and continue retrying
121+
// in the next periodic.
122+
DriverStation.reportWarning(e.getMessage(), dontPrintStackTrace);
123+
} catch (InternalError e) {
124+
// createControllerWithTypeAutoDetect throws this error when there's
125+
// no joystick connected at all, or it cannot recognize it's type.
126+
DriverStation.reportError("Joistick[0] detection error: " + e, dontPrintStackTrace);
127+
}
128+
}
129+
56130
/** The container for the robot. Contains subsystems, OI devices, and commands. */
57131
public RobotContainer() {
58132
// controller = getController(0);
@@ -113,15 +187,11 @@ public RobotContainer() {
113187
autoChooser.addOption("Drive SysId (Dynamic Reverse)", drive.sysIdDynamic(SysIdRoutine.Direction.kReverse));
114188
}
115189

116-
public boolean getBindingsInitialized() {
117-
return bindingsInitialized;
118-
}
119-
120190
/**
121191
* Use this method to define your button->command mappings. Buttons can be created by
122192
* instantiating a 2813's {@link Controller} subclasses.
123193
*/
124-
public void configureButtonBindings(Controller controller) {
194+
private void configureButtonBindings(Controller controller) {
125195
// Default command, normal field-relative drive.
126196
// Xbox controller that I got is busted or something, the getRightY() binds to a trigger for some reason.
127197
drive.setDefaultCommand(DriveCommands.joystickDrive(
@@ -160,8 +230,6 @@ public void configureButtonBindings(Controller controller) {
160230
controller.faceRight().onTrue(arm.setArmPositionCommand(Arm.ArmPositions.EAST));
161231
controller.faceDown().onTrue(arm.setArmPositionCommand(Arm.ArmPositions.SOUTH));
162232
controller.faceLeft().onTrue(arm.setArmPositionCommand(Arm.ArmPositions.WEST));
163-
164-
bindingsInitialized = true;
165233
}
166234

167235
/**

0 commit comments

Comments
 (0)