Create RobotMap to decouple Subsystems from their hardware.

With the hardware objects decoupled from the subsystems, we can then pass mock hardware into these subsystems to run simulations/tests on.
This commit is contained in:
Keenan D. Buckley
2020-03-28 21:27:15 -06:00
parent 2e0330cab5
commit 850f503889
4 changed files with 131 additions and 75 deletions
+16 -14
View File
@@ -27,9 +27,14 @@ import frc4388.utility.controller.XboxController;
* commands, and button mappings) should be declared here.
*/
public class RobotContainer {
/* RobotMap */
private final RobotMap m_robotMap = new RobotMap();
/* Subsystems */
private final Drive m_robotDrive = new Drive();
private final LED m_robotLED = new LED();
private final Drive m_robotDrive = new Drive(m_robotMap.leftFrontMotor, m_robotMap.rightFrontMotor,
m_robotMap.leftBackMotor, m_robotMap.rightBackMotor, m_robotMap.gyroDrive);
private final LED m_robotLED = new LED(m_robotMap.LEDController);
/* Controllers */
private final XboxController m_driverXbox = new XboxController(OIConstants.XBOX_DRIVER_ID);
@@ -43,18 +48,18 @@ public class RobotContainer {
/* Default Commands */
// drives the robot with a two-axis input from the driver controller
m_robotDrive.setDefaultCommand(new RunCommand(() -> m_robotDrive.driveWithInput(
getDriverController().getLeftYAxis(),
m_robotDrive.setDefaultCommand(
new RunCommand(() -> m_robotDrive.driveWithInput(getDriverController().getLeftYAxis(),
getDriverController().getRightXAxis()), m_robotDrive));
// continually sends updates to the Blinkin LED controller to keep the lights on
m_robotLED.setDefaultCommand(new RunCommand(() -> m_robotLED.updateLED(), m_robotLED));
}
/**
* Use this method to define your button->command mappings. Buttons can be created by
* instantiating a {@link GenericHID} or one of its subclasses ({@link
* edu.wpi.first.wpilibj.Joystick} or {@link XboxController}), and then passing it to a
* {@link edu.wpi.first.wpilibj2.command.button.JoystickButton}.
* Use this method to define your button->command mappings. Buttons can be
* created by instantiating a {@link GenericHID} or one of its subclasses
* ({@link edu.wpi.first.wpilibj.Joystick} or {@link XboxController}), and then
* passing it to a {@link edu.wpi.first.wpilibj2.command.button.JoystickButton}.
*/
private void configureButtonBindings() {
/* Driver Buttons */
@@ -89,24 +94,21 @@ public class RobotContainer {
/**
* Add your docs here.
*/
public IHandController getOperatorController()
{
public IHandController getOperatorController() {
return m_operatorXbox;
}
/**
* Add your docs here.
*/
public Joystick getOperatorJoystick()
{
public Joystick getOperatorJoystick() {
return m_operatorXbox.getJoyStick();
}
/**
* Add your docs here.
*/
public Joystick getDriverJoystick()
{
public Joystick getDriverJoystick() {
return m_driverXbox.getJoyStick();
}
}
+71
View File
@@ -0,0 +1,71 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2018-2019 FIRST. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
package frc4388.robot;
import com.ctre.phoenix.motorcontrol.InvertType;
import com.ctre.phoenix.motorcontrol.NeutralMode;
import com.ctre.phoenix.motorcontrol.can.WPI_TalonSRX;
import com.ctre.phoenix.sensors.PigeonIMU;
import edu.wpi.first.wpilibj.Spark;
import edu.wpi.first.wpilibj.drive.DifferentialDrive;
import frc4388.robot.Constants.DriveConstants;
import frc4388.robot.Constants.LEDConstants;
import frc4388.utility.RobotGyro;
/**
* Defines and holds all I/O objects on the Roborio. This is useful for unit
* testing and modularization.
*/
public class RobotMap {
public RobotMap() {
configureLEDSubsystem();
configureDriveSubsystem();
}
/* LED Subsystem */
public final Spark LEDController = new Spark(LEDConstants.LED_SPARK_ID);
void configureLEDSubsystem() {
}
/* Drive Subsystem */
public final WPI_TalonSRX leftFrontMotor = new WPI_TalonSRX(DriveConstants.DRIVE_LEFT_FRONT_CAN_ID);
public final WPI_TalonSRX rightFrontMotor = new WPI_TalonSRX(DriveConstants.DRIVE_RIGHT_FRONT_CAN_ID);
public final WPI_TalonSRX leftBackMotor = new WPI_TalonSRX(DriveConstants.DRIVE_LEFT_BACK_CAN_ID);
public final WPI_TalonSRX rightBackMotor = new WPI_TalonSRX(DriveConstants.DRIVE_RIGHT_BACK_CAN_ID);
public final DifferentialDrive driveTrain = new DifferentialDrive(leftFrontMotor, rightFrontMotor);
public final RobotGyro gyroDrive = new RobotGyro(new PigeonIMU(DriveConstants.DRIVE_PIGEON_ID));
void configureDriveSubsystem() {
/* factory default values */
leftFrontMotor.configFactoryDefault();
rightFrontMotor.configFactoryDefault();
leftBackMotor.configFactoryDefault();
rightBackMotor.configFactoryDefault();
/* set back motors as followers */
leftBackMotor.follow(leftFrontMotor);
rightBackMotor.follow(rightFrontMotor);
/* set neutral mode */
leftFrontMotor.setNeutralMode(NeutralMode.Brake);
rightFrontMotor.setNeutralMode(NeutralMode.Brake);
leftFrontMotor.setNeutralMode(NeutralMode.Brake);
rightFrontMotor.setNeutralMode(NeutralMode.Brake);
/* flip input so forward becomes back, etc */
leftFrontMotor.setInverted(false);
rightFrontMotor.setInverted(false);
leftBackMotor.setInverted(InvertType.FollowMaster);
rightBackMotor.setInverted(InvertType.FollowMaster);
}
}
@@ -7,10 +7,7 @@
package frc4388.robot.subsystems;
import com.ctre.phoenix.motorcontrol.InvertType;
import com.ctre.phoenix.motorcontrol.NeutralMode;
import com.ctre.phoenix.motorcontrol.can.WPI_TalonSRX;
import com.ctre.phoenix.sensors.PigeonIMU;
import edu.wpi.first.wpilibj.drive.DifferentialDrive;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
@@ -27,38 +24,25 @@ public class Drive extends SubsystemBase {
// Put methods for controlling this subsystem
// here. Call these from Commands.
private WPI_TalonSRX m_leftFrontMotor = new WPI_TalonSRX(DriveConstants.DRIVE_LEFT_FRONT_CAN_ID);
private WPI_TalonSRX m_rightFrontMotor = new WPI_TalonSRX(DriveConstants.DRIVE_RIGHT_FRONT_CAN_ID);
private WPI_TalonSRX m_leftBackMotor = new WPI_TalonSRX(DriveConstants.DRIVE_LEFT_BACK_CAN_ID);
private WPI_TalonSRX m_rightBackMotor = new WPI_TalonSRX(DriveConstants.DRIVE_RIGHT_BACK_CAN_ID);
private DifferentialDrive m_driveTrain = new DifferentialDrive(m_leftFrontMotor, m_rightFrontMotor);
private RobotGyro m_gyro = new RobotGyro(new PigeonIMU(DriveConstants.DRIVE_PIGEON_ID));
private WPI_TalonSRX m_leftFrontMotor;
private WPI_TalonSRX m_rightFrontMotor;
private WPI_TalonSRX m_leftBackMotor;
private WPI_TalonSRX m_rightBackMotor;
private DifferentialDrive m_driveTrain;
private RobotGyro m_gyro;
/**
* Add your docs here.
*/
public Drive(){
/* factory default values */
m_leftFrontMotor.configFactoryDefault();
m_rightFrontMotor.configFactoryDefault();
m_leftBackMotor.configFactoryDefault();
m_rightBackMotor.configFactoryDefault();
public Drive(WPI_TalonSRX leftFrontMotor, WPI_TalonSRX rightFrontMotor, WPI_TalonSRX leftBackMotor,
WPI_TalonSRX rightBackMotor, RobotGyro gyro) {
/* set back motors as followers */
m_leftBackMotor.follow(m_leftFrontMotor);
m_rightBackMotor.follow(m_rightFrontMotor);
/* set neutral mode */
m_leftFrontMotor.setNeutralMode(NeutralMode.Brake);
m_rightFrontMotor.setNeutralMode(NeutralMode.Brake);
m_leftFrontMotor.setNeutralMode(NeutralMode.Brake);
m_rightFrontMotor.setNeutralMode(NeutralMode.Brake);
/* flip input so forward becomes back, etc */
m_leftFrontMotor.setInverted(false);
m_rightFrontMotor.setInverted(false);
m_leftBackMotor.setInverted(InvertType.FollowMaster);
m_rightBackMotor.setInverted(InvertType.FollowMaster);
m_leftFrontMotor = leftFrontMotor;
m_rightFrontMotor = rightFrontMotor;
m_leftBackMotor = leftBackMotor;
m_rightBackMotor = rightBackMotor;
m_driveTrain = new DifferentialDrive(m_leftFrontMotor, m_rightFrontMotor);
m_gyro = gyro;
}
@Override
@@ -77,16 +61,15 @@ public class Drive extends SubsystemBase {
m_driveTrain.arcadeDrive(move, steer);
}
public RobotGyro getRobotGyro(){
return m_gyro;
}
/**
* Add your docs here.
*/
private void updateSmartDashboard() {
// Examples of the functionality of RobotGyro
SmartDashboard.putBoolean("Is Gyro a Pigeon?", getRobotGyro().m_isGyroAPigeon);
SmartDashboard.putNumber("Turn Rate", getRobotGyro().getRate());
SmartDashboard.putNumber("Gyro Pitch", getRobotGyro().getPitch());
SmartDashboard.putData(getRobotGyro());
SmartDashboard.putBoolean("Is Gyro a Pigeon?", m_gyro.m_isGyroAPigeon);
SmartDashboard.putNumber("Turn Rate", m_gyro.getRate());
SmartDashboard.putNumber("Gyro Pitch", m_gyro.getPitch());
SmartDashboard.putData(m_gyro);
}
}
+13 -13
View File
@@ -20,36 +20,36 @@ import frc4388.utility.LEDPatterns;
*/
public class LED extends SubsystemBase {
private float currentLED;
private Spark LEDController;
private float m_currentLED;
private Spark m_LEDController;
/**
* Add your docs here.
*/
public LED(){
LEDController = new Spark(LEDConstants.LED_SPARK_ID);
public LED(Spark LEDController){
m_LEDController = LEDController;
setPattern(LEDConstants.DEFAULT_PATTERN);
LEDController.set(currentLED);
m_LEDController.set(m_currentLED);
System.err.println("In the Beginning, there was Joe.\nAnd he said, 'Let there be LEDs.'\nAnd it was good.");
}
@Override
public void periodic(){
SmartDashboard.putNumber("LED", m_currentLED);
}
/**
* Add your docs here.
*/
public void updateLED(){
LEDController.set(currentLED);
m_LEDController.set(m_currentLED);
}
/**
* Add your docs here.
*/
public void setPattern(LEDPatterns pattern){
currentLED = pattern.getValue();
LEDController.set(currentLED);
}
@Override
public void periodic(){
SmartDashboard.putNumber("LED", currentLED);
m_currentLED = pattern.getValue();
m_LEDController.set(m_currentLED);
}
}