Merge pull request #17 from Team4388/dependency-injection

Setup Unit Testing
This commit is contained in:
Keenan D. Buckley
2020-04-11 16:36:39 +00:00
committed by GitHub
12 changed files with 542 additions and 98 deletions
+1
View File
@@ -53,6 +53,7 @@ dependencies {
nativeDesktopZip wpi.deps.vendor.jni(wpi.platforms.desktop) nativeDesktopZip wpi.deps.vendor.jni(wpi.platforms.desktop)
testImplementation 'junit:junit:4.12' testImplementation 'junit:junit:4.12'
testCompile "org.mockito:mockito-core:2.+"
// Enable simulation gui support. Must check the box in vscode to enable support // Enable simulation gui support. Must check the box in vscode to enable support
// upon debugging // upon debugging
+6 -5
View File
@@ -21,7 +21,8 @@ import frc4388.utility.RobotTime;
*/ */
public class Robot extends TimedRobot { public class Robot extends TimedRobot {
Command m_autonomousCommand; Command m_autonomousCommand;
private RobotTime m_robotTime = RobotTime.getInstance();
private RobotContainer m_robotContainer; private RobotContainer m_robotContainer;
/** /**
@@ -45,7 +46,7 @@ public class Robot extends TimedRobot {
*/ */
@Override @Override
public void robotPeriodic() { public void robotPeriodic() {
RobotTime.updateTimes(); m_robotTime.updateTimes();
// Runs the Scheduler. This is responsible for polling buttons, adding newly-scheduled // Runs the Scheduler. This is responsible for polling buttons, adding newly-scheduled
// commands, running already-scheduled commands, removing finished or interrupted commands, // commands, running already-scheduled commands, removing finished or interrupted commands,
// and running subsystem periodic() methods. This must be called from the robot's periodic // and running subsystem periodic() methods. This must be called from the robot's periodic
@@ -60,7 +61,7 @@ public class Robot extends TimedRobot {
*/ */
@Override @Override
public void disabledInit() { public void disabledInit() {
RobotTime.endMatchTime(); m_robotTime.endMatchTime();
} }
@Override @Override
@@ -85,7 +86,7 @@ public class Robot extends TimedRobot {
if (m_autonomousCommand != null) { if (m_autonomousCommand != null) {
m_autonomousCommand.schedule(); m_autonomousCommand.schedule();
} }
RobotTime.startMatchTime(); m_robotTime.startMatchTime();
} }
/** /**
@@ -104,7 +105,7 @@ public class Robot extends TimedRobot {
if (m_autonomousCommand != null) { if (m_autonomousCommand != null) {
m_autonomousCommand.cancel(); m_autonomousCommand.cancel();
} }
RobotTime.startMatchTime(); m_robotTime.startMatchTime();
} }
/** /**
+25 -23
View File
@@ -27,46 +27,51 @@ import frc4388.utility.controller.XboxController;
* commands, and button mappings) should be declared here. * commands, and button mappings) should be declared here.
*/ */
public class RobotContainer { public class RobotContainer {
/* RobotMap */
private final RobotMap m_robotMap = new RobotMap();
/* Subsystems */ /* Subsystems */
private final Drive m_robotDrive = new Drive(); private final Drive m_robotDrive = new Drive(m_robotMap.leftFrontMotor, m_robotMap.rightFrontMotor,
private final LED m_robotLED = new LED(); m_robotMap.leftBackMotor, m_robotMap.rightBackMotor, m_robotMap.driveTrain, m_robotMap.gyroDrive);
private final LED m_robotLED = new LED(m_robotMap.LEDController);
/* Controllers */ /* Controllers */
private final XboxController m_driverXbox = new XboxController(OIConstants.XBOX_DRIVER_ID); private final XboxController m_driverXbox = new XboxController(OIConstants.XBOX_DRIVER_ID);
private final XboxController m_operatorXbox = new XboxController(OIConstants.XBOX_OPERATOR_ID); private final XboxController m_operatorXbox = new XboxController(OIConstants.XBOX_OPERATOR_ID);
/** /**
* The container for the robot. Contains subsystems, OI devices, and commands. * The container for the robot. Contains subsystems, OI devices, and commands.
*/ */
public RobotContainer() { public RobotContainer() {
configureButtonBindings(); configureButtonBindings();
/* Default Commands */ /* Default Commands */
// drives the robot with a two-axis input from the driver controller // drives the robot with a two-axis input from the driver controller
m_robotDrive.setDefaultCommand(new RunCommand(() -> m_robotDrive.driveWithInput( m_robotDrive.setDefaultCommand(
getDriverController().getLeftYAxis(), new RunCommand(() -> m_robotDrive.driveWithInput(getDriverController().getLeftYAxis(),
getDriverController().getRightXAxis()), m_robotDrive)); getDriverController().getRightXAxis()), m_robotDrive));
// continually sends updates to the Blinkin LED controller to keep the lights on // continually sends updates to the Blinkin LED controller to keep the lights on
m_robotLED.setDefaultCommand(new RunCommand(() -> m_robotLED.updateLED(), m_robotLED)); m_robotLED.setDefaultCommand(new RunCommand(() -> m_robotLED.updateLED(), m_robotLED));
} }
/** /**
* Use this method to define your button->command mappings. Buttons can be created by * Use this method to define your button->command mappings. Buttons can be
* instantiating a {@link GenericHID} or one of its subclasses ({@link * created by instantiating a {@link GenericHID} or one of its subclasses
* edu.wpi.first.wpilibj.Joystick} or {@link XboxController}), and then passing it to a * ({@link edu.wpi.first.wpilibj.Joystick} or {@link XboxController}), and then
* {@link edu.wpi.first.wpilibj2.command.button.JoystickButton}. * passing it to a {@link edu.wpi.first.wpilibj2.command.button.JoystickButton}.
*/ */
private void configureButtonBindings() { private void configureButtonBindings() {
/* Driver Buttons */ /* Driver Buttons */
// test command to spin the robot while pressing A on the driver controller // test command to spin the robot while pressing A on the driver controller
new JoystickButton(getDriverJoystick(), XboxController.A_BUTTON) new JoystickButton(getDriverJoystick(), XboxController.A_BUTTON)
.whileHeld(() -> m_robotDrive.driveWithInput(0, 1)); .whileHeld(() -> m_robotDrive.driveWithInput(0, 1));
/* Operator Buttons */ /* Operator Buttons */
// activates "Lit Mode" // activates "Lit Mode"
new JoystickButton(getOperatorJoystick(), XboxController.A_BUTTON) new JoystickButton(getOperatorJoystick(), XboxController.A_BUTTON)
.whenPressed(() -> m_robotLED.setPattern(LEDPatterns.LAVA_RAINBOW)) .whenPressed(() -> m_robotLED.setPattern(LEDPatterns.LAVA_RAINBOW))
.whenReleased(() -> m_robotLED.setPattern(LEDConstants.DEFAULT_PATTERN)); .whenReleased(() -> m_robotLED.setPattern(LEDConstants.DEFAULT_PATTERN));
} }
/** /**
@@ -85,28 +90,25 @@ public class RobotContainer {
public IHandController getDriverController() { public IHandController getDriverController() {
return m_driverXbox; return m_driverXbox;
} }
/** /**
* Add your docs here. * Add your docs here.
*/ */
public IHandController getOperatorController() public IHandController getOperatorController() {
{
return m_operatorXbox; return m_operatorXbox;
} }
/** /**
* Add your docs here. * Add your docs here.
*/ */
public Joystick getOperatorJoystick() public Joystick getOperatorJoystick() {
{
return m_operatorXbox.getJoyStick(); return m_operatorXbox.getJoyStick();
} }
/** /**
* Add your docs here. * Add your docs here.
*/ */
public Joystick getDriverJoystick() public Joystick getDriverJoystick() {
{
return m_driverXbox.getJoyStick(); 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() {
configureLEDMotorControllers();
configureDriveMotorControllers();
}
/* LED Subsystem */
public final Spark LEDController = new Spark(LEDConstants.LED_SPARK_ID);
void configureLEDMotorControllers() {
}
/* 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 configureDriveMotorControllers() {
/* 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; 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.motorcontrol.can.WPI_TalonSRX;
import com.ctre.phoenix.sensors.PigeonIMU;
import edu.wpi.first.wpilibj.drive.DifferentialDrive; import edu.wpi.first.wpilibj.drive.DifferentialDrive;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
@@ -27,45 +24,34 @@ public class Drive extends SubsystemBase {
// Put methods for controlling this subsystem // Put methods for controlling this subsystem
// here. Call these from Commands. // here. Call these from Commands.
private WPI_TalonSRX m_leftFrontMotor = new WPI_TalonSRX(DriveConstants.DRIVE_LEFT_FRONT_CAN_ID); private RobotTime m_robotTime = RobotTime.getInstance();
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_leftFrontMotor;
private WPI_TalonSRX m_rightBackMotor = new WPI_TalonSRX(DriveConstants.DRIVE_RIGHT_BACK_CAN_ID); private WPI_TalonSRX m_rightFrontMotor;
private DifferentialDrive m_driveTrain = new DifferentialDrive(m_leftFrontMotor, m_rightFrontMotor); private WPI_TalonSRX m_leftBackMotor;
private RobotGyro m_gyro = new RobotGyro(new PigeonIMU(DriveConstants.DRIVE_PIGEON_ID)); private WPI_TalonSRX m_rightBackMotor;
private DifferentialDrive m_driveTrain;
private RobotGyro m_gyro;
/** /**
* Add your docs here. * Add your docs here.
*/ */
public Drive(){ public Drive(WPI_TalonSRX leftFrontMotor, WPI_TalonSRX rightFrontMotor, WPI_TalonSRX leftBackMotor,
/* factory default values */ WPI_TalonSRX rightBackMotor, DifferentialDrive driveTrain, RobotGyro gyro) {
m_leftFrontMotor.configFactoryDefault();
m_rightFrontMotor.configFactoryDefault();
m_leftBackMotor.configFactoryDefault();
m_rightBackMotor.configFactoryDefault();
/* set back motors as followers */ m_leftFrontMotor = leftFrontMotor;
m_leftBackMotor.follow(m_leftFrontMotor); m_rightFrontMotor = rightFrontMotor;
m_rightBackMotor.follow(m_rightFrontMotor); m_leftBackMotor = leftBackMotor;
m_rightBackMotor = rightBackMotor;
/* set neutral mode */ m_driveTrain = driveTrain;
m_leftFrontMotor.setNeutralMode(NeutralMode.Brake); m_gyro = gyro;
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);
} }
@Override @Override
public void periodic() { public void periodic() {
m_gyro.updatePigeonDeltas(); m_gyro.updatePigeonDeltas();
if (RobotTime.m_frameNumber % DriveConstants.SMARTDASHBOARD_UPDATE_FRAME == 0) { if (m_robotTime.m_frameNumber % DriveConstants.SMARTDASHBOARD_UPDATE_FRAME == 0) {
updateSmartDashboard(); updateSmartDashboard();
} }
} }
@@ -73,20 +59,27 @@ public class Drive extends SubsystemBase {
/** /**
* Add your docs here. * Add your docs here.
*/ */
public void driveWithInput(double move, double steer){ public void driveWithInput(double move, double steer) {
m_driveTrain.arcadeDrive(move, steer); m_driveTrain.arcadeDrive(move, steer);
} }
public RobotGyro getRobotGyro(){ /**
return m_gyro; * Add your docs here.
*/
public void tankDriveWithInput(double leftMove, double rightMove) {
m_leftFrontMotor.set(leftMove);
m_rightFrontMotor.set(rightMove);
} }
/**
* Add your docs here.
*/
private void updateSmartDashboard() { private void updateSmartDashboard() {
// Examples of the functionality of RobotGyro // Examples of the functionality of RobotGyro
SmartDashboard.putBoolean("Is Gyro a Pigeon?", getRobotGyro().m_isGyroAPigeon); SmartDashboard.putBoolean("Is Gyro a Pigeon?", m_gyro.m_isGyroAPigeon);
SmartDashboard.putNumber("Turn Rate", getRobotGyro().getRate()); SmartDashboard.putNumber("Turn Rate", m_gyro.getRate());
SmartDashboard.putNumber("Gyro Pitch", getRobotGyro().getPitch()); SmartDashboard.putNumber("Gyro Pitch", m_gyro.getPitch());
SmartDashboard.putData(getRobotGyro()); SmartDashboard.putData(m_gyro);
} }
} }
+19 -11
View File
@@ -20,36 +20,44 @@ import frc4388.utility.LEDPatterns;
*/ */
public class LED extends SubsystemBase { public class LED extends SubsystemBase {
private float currentLED; private LEDPatterns m_currentPattern;
private Spark LEDController; private Spark m_LEDController;
/** /**
* Add your docs here. * Add your docs here.
*/ */
public LED(){ public LED(Spark LEDController){
LEDController = new Spark(LEDConstants.LED_SPARK_ID); m_LEDController = LEDController;
setPattern(LEDConstants.DEFAULT_PATTERN); setPattern(LEDConstants.DEFAULT_PATTERN);
LEDController.set(currentLED); updateLED();
System.err.println("In the Beginning, there was Joe.\nAnd he said, 'Let there be LEDs.'\nAnd it was good."); 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_currentPattern.getValue());
}
/** /**
* Add your docs here. * Add your docs here.
*/ */
public void updateLED(){ public void updateLED(){
LEDController.set(currentLED); m_LEDController.set(m_currentPattern.getValue());
} }
/** /**
* Add your docs here. * Add your docs here.
*/ */
public void setPattern(LEDPatterns pattern){ public void setPattern(LEDPatterns pattern){
currentLED = pattern.getValue(); m_currentPattern = pattern;
LEDController.set(currentLED); m_LEDController.set(m_currentPattern.getValue());
} }
@Override /**
public void periodic(){ * Add your docs here.
SmartDashboard.putNumber("LED", currentLED); * @return
*/
public LEDPatterns getPattern() {
return m_currentPattern;
} }
} }
+14 -4
View File
@@ -18,8 +18,10 @@ import edu.wpi.first.wpiutil.math.MathUtil;
* Gyro class that allows for interchangeable use between a pigeon and a navX * Gyro class that allows for interchangeable use between a pigeon and a navX
*/ */
public class RobotGyro extends GyroBase { public class RobotGyro extends GyroBase {
private PigeonIMU m_pigeon; private RobotTime m_robotTime = RobotTime.getInstance();
private AHRS m_navX;
private PigeonIMU m_pigeon = null;
private AHRS m_navX = null;
public boolean m_isGyroAPigeon; //true if pigeon, false if navX public boolean m_isGyroAPigeon; //true if pigeon, false if navX
private double m_lastPigeonAngle; private double m_lastPigeonAngle;
@@ -115,7 +117,15 @@ public class RobotGyro extends GyroBase {
* @return heading from -180 to 180 degrees * @return heading from -180 to 180 degrees
*/ */
public double getHeading() { public double getHeading() {
return Math.IEEEremainder(getAngle(), 360); return getHeading(getAngle());
}
/**
* Gets an absolute heading of the robot
* @return heading from -180 to 180 degrees
*/
public double getHeading(double angle) {
return Math.IEEEremainder(angle, 360);
} }
/** /**
@@ -149,7 +159,7 @@ public class RobotGyro extends GyroBase {
@Override @Override
public double getRate() { public double getRate() {
if (m_isGyroAPigeon) { if (m_isGyroAPigeon) {
return m_deltaPigeonAngle / (RobotTime.m_deltaTime * 1000); return m_deltaPigeonAngle / m_robotTime.m_deltaTime * 1000;
} else { } else {
return m_navX.getRate(); return m_navX.getRate();
} }
+29 -17
View File
@@ -11,29 +11,42 @@ package frc4388.utility;
* <p>Keeps track of Robot times like time passed, delta time, etc * <p>Keeps track of Robot times like time passed, delta time, etc
* <p>All times are in milliseconds * <p>All times are in milliseconds
*/ */
public final class RobotTime { public class RobotTime {
private static long m_currTime = System.currentTimeMillis(); private long m_currTime = System.currentTimeMillis();
public static long m_deltaTime = 0; public long m_deltaTime = 0;
private static long m_startRobotTime = m_currTime; private long m_startRobotTime = m_currTime;
public static long m_robotTime = 0; public long m_robotTime = 0;
public static long m_lastRobotTime = 0; public long m_lastRobotTime = 0;
private static long m_startMatchTime = 0; private long m_startMatchTime = 0;
public static long m_matchTime = 0; public long m_matchTime = 0;
public static long m_lastMatchTime = 0; public long m_lastMatchTime = 0;
public static long m_frameNumber = 0; public long m_frameNumber = 0;
/** /**
* This class should not be instantiated. * Private constructor prevents other classes from instantiating
*/ */
private RobotTime(){} private RobotTime(){}
private static RobotTime instance = null;
/**
* Gets the instance of Robot Time. If there is no instance running one will be created.
* @return instance of Robot Time
*/
public static RobotTime getInstance() {
if (instance == null) {
instance = new RobotTime();
}
return instance;
}
/** /**
* Call this once per periodic loop. * Call this once per periodic loop.
*/ */
public static void updateTimes() { public void updateTimes() {
m_lastRobotTime = m_robotTime; m_lastRobotTime = m_robotTime;
m_lastMatchTime = m_matchTime; m_lastMatchTime = m_matchTime;
@@ -42,7 +55,7 @@ public final class RobotTime {
m_deltaTime = m_robotTime - m_lastRobotTime; m_deltaTime = m_robotTime - m_lastRobotTime;
m_frameNumber++; m_frameNumber++;
if (m_matchTime != 0) { if (m_startMatchTime != 0) {
m_matchTime = m_currTime - m_startMatchTime; m_matchTime = m_currTime - m_startMatchTime;
} }
} }
@@ -50,17 +63,16 @@ public final class RobotTime {
/** /**
* Call this in both the auto and periodic inits * Call this in both the auto and periodic inits
*/ */
public static void startMatchTime() { public void startMatchTime() {
if (m_matchTime == 0) { if (m_startMatchTime == 0) {
m_startMatchTime = m_currTime; m_startMatchTime = m_currTime;
m_matchTime = 1;
} }
} }
/** /**
* Call this in disabled init * Call this in disabled init
*/ */
public static void endMatchTime() { public void endMatchTime() {
m_startMatchTime = 0; m_startMatchTime = 0;
m_matchTime = 0; m_matchTime = 0;
} }
@@ -0,0 +1,54 @@
/*----------------------------------------------------------------------------*/
/* 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.mocks;
import com.ctre.phoenix.ErrorCode;
import com.ctre.phoenix.sensors.PigeonIMU;
/**
* Add your docs here.
*/
public class MockPigeonIMU extends PigeonIMU {
public int m_deviceNumber;
public double currentYaw;
public double currentPitch;
public double currentRoll;
public MockPigeonIMU(int deviceNumber) {
super(deviceNumber);
m_deviceNumber = deviceNumber;
}
@Override
public ErrorCode setYaw(double angleDeg) {
currentYaw = angleDeg;
return ErrorCode.OK;
}
/**
* @param currentPitch the Pitch to set
*/
public void setCurrentPitch(double currentPitch) {
this.currentPitch = currentPitch;
}
/**
* @param currentRoll the Roll to set
*/
public void setCurrentRoll(double currentRoll) {
this.currentRoll = currentRoll;
}
@Override
public ErrorCode getYawPitchRoll(double[] ypr_deg) {
ypr_deg[0] = currentYaw;
ypr_deg[1] = currentPitch;
ypr_deg[2] = currentRoll;
return ErrorCode.OK;
}
}
@@ -0,0 +1,41 @@
/*----------------------------------------------------------------------------*/
/* 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.subsystems;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import org.junit.*;
import edu.wpi.first.wpilibj.*;
import frc4388.robot.Constants.LEDConstants;
import frc4388.utility.LEDPatterns;
/**
* Add your docs here.
*/
public class LEDSubsystemTest {
Spark ledController = mock(Spark.class);
LED led = new LED(ledController);
@Test
public void testPatterns() {
// TEST 1
assertEquals(LEDConstants.DEFAULT_PATTERN.getValue(), led.getPattern().getValue(), 0.0001);
// TEST 2
led.setPattern(LEDPatterns.RAINBOW_RAINBOW);
assertEquals(LEDPatterns.RAINBOW_RAINBOW.getValue(), led.getPattern().getValue(), 0.0001);
// TEST 3
led.setPattern(LEDPatterns.BLUE_BREATH);
assertEquals(LEDPatterns.BLUE_BREATH.getValue(), led.getPattern().getValue(), 0.0001);
// TEST 4
led.setPattern(LEDPatterns.SOLID_BLACK);
assertEquals(LEDPatterns.SOLID_BLACK.getValue(), led.getPattern().getValue(), 0.0001);
}
}
@@ -0,0 +1,155 @@
/*----------------------------------------------------------------------------*/
/* 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.utility;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import org.junit.*;
import edu.wpi.first.wpilibj.*;
import com.ctre.phoenix.sensors.PigeonIMU;
import com.kauailabs.navx.frc.AHRS;
import frc4388.mocks.MockPigeonIMU;
import frc4388.robot.Constants.DriveConstants;
import frc4388.utility.RobotGyro;
/**
* Add your docs here.
*/
public class RobotGyroUtilityTest {
MockPigeonIMU pigeon = new MockPigeonIMU(DriveConstants.DRIVE_PIGEON_ID);
RobotGyro gyroPigeon = new RobotGyro(pigeon);
AHRS navX = mock(AHRS.class);
RobotGyro gyroNavX = new RobotGyro(navX);
RobotTime robotTime = RobotTime.getInstance();
// TODO UNTESTED: most functions for NavX
@Test
public void testConfig() {
// TEST 1
assertEquals(true, gyroPigeon.m_isGyroAPigeon);
assertEquals(pigeon, gyroPigeon.getPigeon());
assertEquals(null, gyroPigeon.getNavX());
// TEST 2
assertEquals(false, gyroNavX.m_isGyroAPigeon);
assertEquals(navX, gyroNavX.getNavX());
assertEquals(null, gyroNavX.getPigeon());
}
@Test
public void testHeading() {
// TESTS
assertEquals(-90, gyroPigeon.getHeading(270), 0.0001);
assertEquals(-45, gyroPigeon.getHeading(315), 0.0001);
assertEquals(-60, gyroPigeon.getHeading(-60), 0.0001);
assertEquals(30, gyroPigeon.getHeading(30), 0.0001);
assertEquals(0, gyroPigeon.getHeading(0), 0.0001);
assertEquals(180, gyroPigeon.getHeading(180), 0.0001);
assertEquals(-180, gyroPigeon.getHeading(-180), 0.0001);
assertEquals(97, gyroPigeon.getHeading(1537), 0.0001);
assertEquals(99, gyroPigeon.getHeading(-2781), 0.0001);
}
@Test
public void testYawPitchRoll() {
// TEST 1
assertEquals(0, gyroPigeon.getAngle(), 0.0001);
// TEST 2
pigeon.setYaw(40);
assertEquals(40, gyroPigeon.getAngle(), 0.0001);
// TEST 3
gyroPigeon.reset();
assertEquals(0, gyroPigeon.getAngle(), 0.0001);
// TEST 4
pigeon.setYaw(-1457);
pigeon.setCurrentPitch(100);
pigeon.setCurrentRoll(100);
assertEquals(-1457, gyroPigeon.getAngle(), 0.0001);
assertEquals(90, gyroPigeon.getPitch(), 0.0001);
assertEquals(90, gyroPigeon.getRoll(), 0.0001);
// TEST 5
pigeon.setCurrentPitch(45);
pigeon.setCurrentRoll(45);
assertEquals(45, gyroPigeon.getPitch(), 0.0001);
assertEquals(45, gyroPigeon.getRoll(), 0.0001);
// TEST 6
pigeon.setCurrentPitch(0);
pigeon.setCurrentRoll(0);
assertEquals(0, gyroPigeon.getPitch(), 0.0001);
assertEquals(0, gyroPigeon.getRoll(), 0.0001);
// TEST 7
pigeon.setCurrentPitch(-60);
pigeon.setCurrentRoll(-60);
assertEquals(-60, gyroPigeon.getPitch(), 0.0001);
assertEquals(-60, gyroPigeon.getRoll(), 0.0001);
// TEST 8
pigeon.setCurrentPitch(-90);
pigeon.setCurrentRoll(-90);
assertEquals(-90, gyroPigeon.getPitch(), 0.0001);
assertEquals(-90, gyroPigeon.getRoll(), 0.0001);
// TEST 9
pigeon.setCurrentPitch(-100);
pigeon.setCurrentRoll(-100);
assertEquals(-90, gyroPigeon.getPitch(), 0.0001);
assertEquals(-90, gyroPigeon.getRoll(), 0.0001);
}
@Test
public void testRates() {
// SETUP
pigeon.setYaw(0);
gyroPigeon.updatePigeonDeltas();
// TEST 1
robotTime.m_deltaTime = 5;
pigeon.setYaw(0);
gyroPigeon.updatePigeonDeltas();
assertEquals(0, gyroPigeon.getRate(), 1);
// TEST 2
robotTime.m_deltaTime = 5;
pigeon.setYaw(90);
gyroPigeon.updatePigeonDeltas();
assertEquals(18000, gyroPigeon.getRate(), 0.001);
// TEST 3
robotTime.m_deltaTime = 5;
pigeon.setYaw(90);
gyroPigeon.updatePigeonDeltas();
assertEquals(0, gyroPigeon.getRate(), 0.001);
// TEST 4
robotTime.m_deltaTime = 3;
pigeon.setYaw(-30);
gyroPigeon.updatePigeonDeltas();
assertEquals(-40000, gyroPigeon.getRate(), 0.001);
// TEST 5
robotTime.m_deltaTime = 6;
pigeon.setYaw(690);
gyroPigeon.updatePigeonDeltas();
assertEquals(120000, gyroPigeon.getRate(), 0.001);
}
private void wait(int millis) {
try {
Thread.sleep(millis);
} catch (Exception e) {}
}
}
@@ -0,0 +1,96 @@
/*----------------------------------------------------------------------------*/
/* 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.utility;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import org.junit.*;
import edu.wpi.first.wpilibj.*;
/**
* Add your docs here.
*/
public class RobotTimeUtilityTest {
RobotTime robotTime = RobotTime.getInstance();
@Test
public void testUpdateTimes() {
// SETUP
long lastTime;
robotTime.m_deltaTime = 0;
robotTime.m_robotTime = 0;
robotTime.m_lastRobotTime = 0;
robotTime.m_frameNumber = 0;
robotTime.endMatchTime();
robotTime.m_lastMatchTime = 0;
// TEST 1
assertEquals(0, robotTime.m_deltaTime);
assertEquals(0, robotTime.m_robotTime);
assertEquals(0, robotTime.m_lastRobotTime);
assertEquals(0, robotTime.m_frameNumber);
lastTime = robotTime.m_robotTime;
// TEST 2
wait(1);
robotTime.updateTimes();
assertEquals(true, robotTime.m_deltaTime > 0);
assertEquals(true, robotTime.m_robotTime > 0);
assertEquals(lastTime, robotTime.m_lastRobotTime);
assertEquals(1, robotTime.m_frameNumber);
lastTime = robotTime.m_robotTime;
// TEST 3
wait(1);
robotTime.updateTimes();
assertEquals(true, robotTime.m_deltaTime > 0);
assertEquals(true, robotTime.m_robotTime > 0);
assertEquals(lastTime, robotTime.m_lastRobotTime);
assertEquals(2, robotTime.m_frameNumber);
}
@Test
public void testMatchTime() {
// SETUP
long lastTime;
// TEST 1
assertEquals(0, robotTime.m_matchTime);
assertEquals(0, robotTime.m_lastMatchTime);
lastTime = robotTime.m_matchTime;
// TEST 2
robotTime.startMatchTime();
wait(1);
robotTime.updateTimes();
assertEquals(true, robotTime.m_matchTime > 0);
assertEquals(lastTime, robotTime.m_lastMatchTime);
lastTime = robotTime.m_matchTime;
// TEST 3
wait(1);
robotTime.updateTimes();
robotTime.endMatchTime();
assertEquals(0, robotTime.m_matchTime);
assertEquals(lastTime, robotTime.m_lastMatchTime);
lastTime = robotTime.m_matchTime;
// TEST 4
wait(1);
robotTime.updateTimes();
assertEquals(0, robotTime.m_matchTime);
assertEquals(lastTime, robotTime.m_lastMatchTime);
}
private void wait(int millis) {
try {
Thread.sleep(millis);
} catch (Exception e) {}
}
}