2020-12-26 14:12:05 -08:00
|
|
|
// Copyright (c) FIRST and other WPILib contributors.
|
|
|
|
|
// Open Source Software; you can modify and/or share it under the terms of
|
|
|
|
|
// the WPILib BSD license file in the root directory of this project.
|
2017-07-08 10:50:56 -04:00
|
|
|
|
|
|
|
|
package edu.wpi.first.wpilibj;
|
|
|
|
|
|
2018-09-20 21:59:46 -07:00
|
|
|
import edu.wpi.first.hal.HAL;
|
2020-12-12 23:16:50 -08:00
|
|
|
import edu.wpi.first.networktables.NetworkTableInstance;
|
2017-07-08 10:50:56 -04:00
|
|
|
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
|
2018-09-28 04:18:18 -04:00
|
|
|
import edu.wpi.first.wpilibj.shuffleboard.Shuffleboard;
|
2017-12-26 17:18:02 -06:00
|
|
|
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
|
2017-07-08 10:50:56 -04:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* IterativeRobotBase implements a specific type of robot program framework, extending the RobotBase
|
|
|
|
|
* class.
|
|
|
|
|
*
|
|
|
|
|
* <p>The IterativeRobotBase class does not implement startCompetition(), so it should not be used
|
|
|
|
|
* by teams directly.
|
|
|
|
|
*
|
|
|
|
|
* <p>This class provides the following functions which are called by the main loop,
|
|
|
|
|
* startCompetition(), at the appropriate times:
|
|
|
|
|
*
|
|
|
|
|
* <p>robotInit() -- provide for initialization at robot power-on
|
|
|
|
|
*
|
2020-12-29 22:45:16 -08:00
|
|
|
* <p>init() functions -- each of the following functions is called once when the appropriate mode
|
|
|
|
|
* is entered: - disabledInit() -- called each and every time disabled is entered from another mode
|
|
|
|
|
* - autonomousInit() -- called each and every time autonomous is entered from another mode -
|
|
|
|
|
* teleopInit() -- called each and every time teleop is entered from another mode - testInit() --
|
|
|
|
|
* called each and every time test is entered from another mode
|
2017-07-08 10:50:56 -04:00
|
|
|
*
|
2020-12-29 22:45:16 -08:00
|
|
|
* <p>periodic() functions -- each of these functions is called on an interval: - robotPeriodic() -
|
|
|
|
|
* disabledPeriodic() - autonomousPeriodic() - teleopPeriodic() - testPeriodic()
|
2017-07-08 10:50:56 -04:00
|
|
|
*/
|
|
|
|
|
public abstract class IterativeRobotBase extends RobotBase {
|
2018-06-24 02:29:21 -05:00
|
|
|
protected double m_period;
|
|
|
|
|
|
2017-07-08 10:50:56 -04:00
|
|
|
private enum Mode {
|
|
|
|
|
kNone,
|
|
|
|
|
kDisabled,
|
|
|
|
|
kAutonomous,
|
|
|
|
|
kTeleop,
|
|
|
|
|
kTest
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Mode m_lastMode = Mode.kNone;
|
2018-06-24 02:29:21 -05:00
|
|
|
private final Watchdog m_watchdog;
|
2020-12-12 23:16:50 -08:00
|
|
|
private boolean m_ntFlushEnabled;
|
2018-06-24 02:29:21 -05:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Constructor for IterativeRobotBase.
|
|
|
|
|
*
|
|
|
|
|
* @param period Period in seconds.
|
|
|
|
|
*/
|
|
|
|
|
protected IterativeRobotBase(double period) {
|
|
|
|
|
m_period = period;
|
|
|
|
|
m_watchdog = new Watchdog(period, this::printLoopOverrunMessage);
|
|
|
|
|
}
|
2017-07-08 10:50:56 -04:00
|
|
|
|
2020-12-29 22:45:16 -08:00
|
|
|
/** Provide an alternate "main loop" via startCompetition(). */
|
2018-06-03 10:00:53 -07:00
|
|
|
@Override
|
2017-07-08 10:50:56 -04:00
|
|
|
public abstract void startCompetition();
|
|
|
|
|
|
|
|
|
|
/* ----------- Overridable initialization code ----------------- */
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Robot-wide initialization code should go here.
|
|
|
|
|
*
|
|
|
|
|
* <p>Users should override this method for default Robot-wide initialization which will be called
|
|
|
|
|
* when the robot is first powered on. It will be called exactly one time.
|
|
|
|
|
*
|
|
|
|
|
* <p>Warning: the Driver Station "Robot Code" light and FMS "Robot Ready" indicators will be off
|
|
|
|
|
* until RobotInit() exits. Code in RobotInit() that waits for enable will cause the robot to
|
|
|
|
|
* never indicate that the code is ready, causing the robot to be bypassed in a match.
|
|
|
|
|
*/
|
|
|
|
|
public void robotInit() {
|
2019-01-25 00:45:05 -06:00
|
|
|
System.out.println("Default robotInit() method... Override me!");
|
2017-07-08 10:50:56 -04:00
|
|
|
}
|
|
|
|
|
|
2020-02-19 02:05:16 -05:00
|
|
|
/**
|
|
|
|
|
* Robot-wide simulation initialization code should go here.
|
|
|
|
|
*
|
2020-12-29 22:45:16 -08:00
|
|
|
* <p>Users should override this method for default Robot-wide simulation related initialization
|
|
|
|
|
* which will be called when the robot is first started. It will be called exactly one time after
|
|
|
|
|
* RobotInit is called only when the robot is in simulation.
|
2020-02-19 02:05:16 -05:00
|
|
|
*/
|
|
|
|
|
public void simulationInit() {
|
|
|
|
|
System.out.println("Default simulationInit() method... Override me!");
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-08 10:50:56 -04:00
|
|
|
/**
|
|
|
|
|
* Initialization code for disabled mode should go here.
|
|
|
|
|
*
|
|
|
|
|
* <p>Users should override this method for initialization code which will be called each time the
|
|
|
|
|
* robot enters disabled mode.
|
|
|
|
|
*/
|
|
|
|
|
public void disabledInit() {
|
2019-01-25 00:45:05 -06:00
|
|
|
System.out.println("Default disabledInit() method... Override me!");
|
2017-07-08 10:50:56 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Initialization code for autonomous mode should go here.
|
|
|
|
|
*
|
|
|
|
|
* <p>Users should override this method for initialization code which will be called each time the
|
|
|
|
|
* robot enters autonomous mode.
|
|
|
|
|
*/
|
|
|
|
|
public void autonomousInit() {
|
2019-01-25 00:45:05 -06:00
|
|
|
System.out.println("Default autonomousInit() method... Override me!");
|
2017-07-08 10:50:56 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Initialization code for teleop mode should go here.
|
|
|
|
|
*
|
|
|
|
|
* <p>Users should override this method for initialization code which will be called each time the
|
|
|
|
|
* robot enters teleop mode.
|
|
|
|
|
*/
|
|
|
|
|
public void teleopInit() {
|
2019-01-25 00:45:05 -06:00
|
|
|
System.out.println("Default teleopInit() method... Override me!");
|
2017-07-08 10:50:56 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Initialization code for test mode should go here.
|
|
|
|
|
*
|
|
|
|
|
* <p>Users should override this method for initialization code which will be called each time the
|
|
|
|
|
* robot enters test mode.
|
|
|
|
|
*/
|
|
|
|
|
@SuppressWarnings("PMD.JUnit4TestShouldUseTestAnnotation")
|
|
|
|
|
public void testInit() {
|
2019-01-25 00:45:05 -06:00
|
|
|
System.out.println("Default testInit() method... Override me!");
|
2017-07-08 10:50:56 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ----------- Overridable periodic code ----------------- */
|
|
|
|
|
|
|
|
|
|
private boolean m_rpFirstRun = true;
|
|
|
|
|
|
2020-12-29 22:45:16 -08:00
|
|
|
/** Periodic code for all robot modes should go here. */
|
2017-07-08 10:50:56 -04:00
|
|
|
public void robotPeriodic() {
|
|
|
|
|
if (m_rpFirstRun) {
|
2019-01-25 00:45:05 -06:00
|
|
|
System.out.println("Default robotPeriodic() method... Override me!");
|
2017-07-08 10:50:56 -04:00
|
|
|
m_rpFirstRun = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-19 02:05:16 -05:00
|
|
|
private boolean m_spFirstRun = true;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Periodic simulation code should go here.
|
|
|
|
|
*
|
|
|
|
|
* <p>This function is called in a simulated robot after user code executes.
|
|
|
|
|
*/
|
|
|
|
|
public void simulationPeriodic() {
|
|
|
|
|
if (m_spFirstRun) {
|
|
|
|
|
System.out.println("Default simulationPeriodic() method... Override me!");
|
|
|
|
|
m_spFirstRun = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-08 10:50:56 -04:00
|
|
|
private boolean m_dpFirstRun = true;
|
|
|
|
|
|
2020-12-29 22:45:16 -08:00
|
|
|
/** Periodic code for disabled mode should go here. */
|
2017-07-08 10:50:56 -04:00
|
|
|
public void disabledPeriodic() {
|
|
|
|
|
if (m_dpFirstRun) {
|
2019-01-25 00:45:05 -06:00
|
|
|
System.out.println("Default disabledPeriodic() method... Override me!");
|
2017-07-08 10:50:56 -04:00
|
|
|
m_dpFirstRun = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean m_apFirstRun = true;
|
|
|
|
|
|
2020-12-29 22:45:16 -08:00
|
|
|
/** Periodic code for autonomous mode should go here. */
|
2017-07-08 10:50:56 -04:00
|
|
|
public void autonomousPeriodic() {
|
|
|
|
|
if (m_apFirstRun) {
|
2019-01-25 00:45:05 -06:00
|
|
|
System.out.println("Default autonomousPeriodic() method... Override me!");
|
2017-07-08 10:50:56 -04:00
|
|
|
m_apFirstRun = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean m_tpFirstRun = true;
|
|
|
|
|
|
2020-12-29 22:45:16 -08:00
|
|
|
/** Periodic code for teleop mode should go here. */
|
2017-07-08 10:50:56 -04:00
|
|
|
public void teleopPeriodic() {
|
|
|
|
|
if (m_tpFirstRun) {
|
2019-01-25 00:45:05 -06:00
|
|
|
System.out.println("Default teleopPeriodic() method... Override me!");
|
2017-07-08 10:50:56 -04:00
|
|
|
m_tpFirstRun = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean m_tmpFirstRun = true;
|
|
|
|
|
|
2020-12-29 22:45:16 -08:00
|
|
|
/** Periodic code for test mode should go here. */
|
2017-07-08 10:50:56 -04:00
|
|
|
@SuppressWarnings("PMD.JUnit4TestShouldUseTestAnnotation")
|
|
|
|
|
public void testPeriodic() {
|
|
|
|
|
if (m_tmpFirstRun) {
|
2019-01-25 00:45:05 -06:00
|
|
|
System.out.println("Default testPeriodic() method... Override me!");
|
2017-07-08 10:50:56 -04:00
|
|
|
m_tmpFirstRun = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-12 23:16:50 -08:00
|
|
|
/**
|
2020-12-29 22:45:16 -08:00
|
|
|
* Enables or disables flushing NetworkTables every loop iteration. By default, this is disabled.
|
2020-12-12 23:16:50 -08:00
|
|
|
*
|
|
|
|
|
* @param enabled True to enable, false to disable
|
|
|
|
|
*/
|
|
|
|
|
public void setNetworkTablesFlushEnabled(boolean enabled) {
|
|
|
|
|
m_ntFlushEnabled = enabled;
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-19 02:05:16 -05:00
|
|
|
@SuppressWarnings("PMD.CyclomaticComplexity")
|
2017-07-08 10:50:56 -04:00
|
|
|
protected void loopFunc() {
|
2018-06-24 02:29:21 -05:00
|
|
|
m_watchdog.reset();
|
|
|
|
|
|
2017-07-08 10:50:56 -04:00
|
|
|
// Call the appropriate function depending upon the current robot mode
|
|
|
|
|
if (isDisabled()) {
|
2018-06-24 02:29:21 -05:00
|
|
|
// Call DisabledInit() if we are now just entering disabled mode from either a different mode
|
|
|
|
|
// or from power-on.
|
2017-07-08 10:50:56 -04:00
|
|
|
if (m_lastMode != Mode.kDisabled) {
|
|
|
|
|
LiveWindow.setEnabled(false);
|
2018-09-28 04:18:18 -04:00
|
|
|
Shuffleboard.disableActuatorWidgets();
|
2017-07-08 10:50:56 -04:00
|
|
|
disabledInit();
|
2018-06-24 02:29:21 -05:00
|
|
|
m_watchdog.addEpoch("disabledInit()");
|
2017-07-08 10:50:56 -04:00
|
|
|
m_lastMode = Mode.kDisabled;
|
|
|
|
|
}
|
2018-06-24 02:29:21 -05:00
|
|
|
|
2017-07-08 10:50:56 -04:00
|
|
|
HAL.observeUserProgramDisabled();
|
|
|
|
|
disabledPeriodic();
|
2018-10-04 00:59:47 -07:00
|
|
|
m_watchdog.addEpoch("disablePeriodic()");
|
2017-07-08 10:50:56 -04:00
|
|
|
} else if (isAutonomous()) {
|
2018-06-24 02:29:21 -05:00
|
|
|
// Call AutonomousInit() if we are now just entering autonomous mode from either a different
|
|
|
|
|
// mode or from power-on.
|
2017-07-08 10:50:56 -04:00
|
|
|
if (m_lastMode != Mode.kAutonomous) {
|
|
|
|
|
LiveWindow.setEnabled(false);
|
2018-09-28 04:18:18 -04:00
|
|
|
Shuffleboard.disableActuatorWidgets();
|
2017-07-08 10:50:56 -04:00
|
|
|
autonomousInit();
|
2018-06-24 02:29:21 -05:00
|
|
|
m_watchdog.addEpoch("autonomousInit()");
|
2017-07-08 10:50:56 -04:00
|
|
|
m_lastMode = Mode.kAutonomous;
|
|
|
|
|
}
|
2018-06-24 02:29:21 -05:00
|
|
|
|
2017-07-08 10:50:56 -04:00
|
|
|
HAL.observeUserProgramAutonomous();
|
|
|
|
|
autonomousPeriodic();
|
2018-06-24 02:29:21 -05:00
|
|
|
m_watchdog.addEpoch("autonomousPeriodic()");
|
2017-07-08 10:50:56 -04:00
|
|
|
} else if (isOperatorControl()) {
|
2018-06-24 02:29:21 -05:00
|
|
|
// Call TeleopInit() if we are now just entering teleop mode from either a different mode or
|
|
|
|
|
// from power-on.
|
2017-07-08 10:50:56 -04:00
|
|
|
if (m_lastMode != Mode.kTeleop) {
|
|
|
|
|
LiveWindow.setEnabled(false);
|
2018-09-28 04:18:18 -04:00
|
|
|
Shuffleboard.disableActuatorWidgets();
|
2017-07-08 10:50:56 -04:00
|
|
|
teleopInit();
|
2018-06-24 02:29:21 -05:00
|
|
|
m_watchdog.addEpoch("teleopInit()");
|
2017-07-08 10:50:56 -04:00
|
|
|
m_lastMode = Mode.kTeleop;
|
|
|
|
|
}
|
2018-06-24 02:29:21 -05:00
|
|
|
|
2017-07-08 10:50:56 -04:00
|
|
|
HAL.observeUserProgramTeleop();
|
|
|
|
|
teleopPeriodic();
|
2018-06-24 02:29:21 -05:00
|
|
|
m_watchdog.addEpoch("teleopPeriodic()");
|
2017-07-08 10:50:56 -04:00
|
|
|
} else {
|
2018-06-24 02:29:21 -05:00
|
|
|
// Call TestInit() if we are now just entering test mode from either a different mode or from
|
|
|
|
|
// power-on.
|
2017-07-08 10:50:56 -04:00
|
|
|
if (m_lastMode != Mode.kTest) {
|
|
|
|
|
LiveWindow.setEnabled(true);
|
2018-09-28 04:18:18 -04:00
|
|
|
Shuffleboard.enableActuatorWidgets();
|
2017-07-08 10:50:56 -04:00
|
|
|
testInit();
|
2018-06-24 02:29:21 -05:00
|
|
|
m_watchdog.addEpoch("testInit()");
|
2017-07-08 10:50:56 -04:00
|
|
|
m_lastMode = Mode.kTest;
|
|
|
|
|
}
|
2018-06-24 02:29:21 -05:00
|
|
|
|
2017-07-08 10:50:56 -04:00
|
|
|
HAL.observeUserProgramTest();
|
|
|
|
|
testPeriodic();
|
2018-06-24 02:29:21 -05:00
|
|
|
m_watchdog.addEpoch("testPeriodic()");
|
2017-07-08 10:50:56 -04:00
|
|
|
}
|
2018-06-24 02:29:21 -05:00
|
|
|
|
2017-07-08 10:50:56 -04:00
|
|
|
robotPeriodic();
|
2018-06-24 02:29:21 -05:00
|
|
|
m_watchdog.addEpoch("robotPeriodic()");
|
|
|
|
|
|
2019-04-27 22:23:21 -07:00
|
|
|
SmartDashboard.updateValues();
|
|
|
|
|
m_watchdog.addEpoch("SmartDashboard.updateValues()");
|
2017-12-04 23:28:33 -08:00
|
|
|
LiveWindow.updateValues();
|
2019-04-27 22:23:21 -07:00
|
|
|
m_watchdog.addEpoch("LiveWindow.updateValues()");
|
2018-09-28 04:18:18 -04:00
|
|
|
Shuffleboard.update();
|
2019-04-27 22:23:21 -07:00
|
|
|
m_watchdog.addEpoch("Shuffleboard.update()");
|
2020-02-19 02:05:16 -05:00
|
|
|
|
|
|
|
|
if (isSimulation()) {
|
2020-11-30 23:55:36 -08:00
|
|
|
HAL.simPeriodicBefore();
|
2020-02-19 02:05:16 -05:00
|
|
|
simulationPeriodic();
|
2020-11-30 23:55:36 -08:00
|
|
|
HAL.simPeriodicAfter();
|
2020-02-19 02:05:16 -05:00
|
|
|
m_watchdog.addEpoch("simulationPeriodic()");
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-27 22:23:21 -07:00
|
|
|
m_watchdog.disable();
|
2018-06-24 02:29:21 -05:00
|
|
|
|
2020-12-12 23:16:50 -08:00
|
|
|
// Flush NetworkTables
|
|
|
|
|
if (m_ntFlushEnabled) {
|
|
|
|
|
NetworkTableInstance.getDefault().flush();
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-24 02:29:21 -05:00
|
|
|
// Warn on loop time overruns
|
|
|
|
|
if (m_watchdog.isExpired()) {
|
|
|
|
|
m_watchdog.printEpochs();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void printLoopOverrunMessage() {
|
|
|
|
|
DriverStation.reportWarning("Loop time of " + m_period + "s overrun\n", false);
|
2017-07-08 10:50:56 -04:00
|
|
|
}
|
|
|
|
|
}
|