blob: 47eb29914da90f295a1e73fe54b9045f3c5ed1db [file] [log] [blame]
Austin Schuh812d0d12021-11-04 20:16:48 -07001// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
Brian Silverman8fce7482020-01-05 13:18:21 -08004
5#include "frc/IterativeRobotBase.h"
6
Austin Schuh812d0d12021-11-04 20:16:48 -07007#include <fmt/format.h>
Brian Silverman8fce7482020-01-05 13:18:21 -08008#include <hal/DriverStation.h>
Austin Schuh812d0d12021-11-04 20:16:48 -07009#include <networktables/NetworkTableInstance.h>
Brian Silverman8fce7482020-01-05 13:18:21 -080010
Austin Schuh812d0d12021-11-04 20:16:48 -070011#include "frc/DSControlWord.h"
12#include "frc/Errors.h"
Brian Silverman8fce7482020-01-05 13:18:21 -080013#include "frc/livewindow/LiveWindow.h"
14#include "frc/shuffleboard/Shuffleboard.h"
15#include "frc/smartdashboard/SmartDashboard.h"
16
17using namespace frc;
18
19IterativeRobotBase::IterativeRobotBase(double period)
20 : IterativeRobotBase(units::second_t(period)) {}
21
22IterativeRobotBase::IterativeRobotBase(units::second_t period)
23 : m_period(period),
24 m_watchdog(period, [this] { PrintLoopOverrunMessage(); }) {}
25
Austin Schuh812d0d12021-11-04 20:16:48 -070026void IterativeRobotBase::RobotInit() {}
Brian Silverman8fce7482020-01-05 13:18:21 -080027
Austin Schuh812d0d12021-11-04 20:16:48 -070028void IterativeRobotBase::SimulationInit() {}
Austin Schuh1e69f942020-11-14 15:06:14 -080029
Austin Schuh812d0d12021-11-04 20:16:48 -070030void IterativeRobotBase::DisabledInit() {}
Brian Silverman8fce7482020-01-05 13:18:21 -080031
Austin Schuh812d0d12021-11-04 20:16:48 -070032void IterativeRobotBase::AutonomousInit() {}
Brian Silverman8fce7482020-01-05 13:18:21 -080033
Austin Schuh812d0d12021-11-04 20:16:48 -070034void IterativeRobotBase::TeleopInit() {}
Brian Silverman8fce7482020-01-05 13:18:21 -080035
Austin Schuh812d0d12021-11-04 20:16:48 -070036void IterativeRobotBase::TestInit() {}
Brian Silverman8fce7482020-01-05 13:18:21 -080037
38void IterativeRobotBase::RobotPeriodic() {
39 static bool firstRun = true;
40 if (firstRun) {
Austin Schuh812d0d12021-11-04 20:16:48 -070041 fmt::print("Default {}() method... Override me!\n", __FUNCTION__);
Brian Silverman8fce7482020-01-05 13:18:21 -080042 firstRun = false;
43 }
44}
45
Austin Schuh1e69f942020-11-14 15:06:14 -080046void IterativeRobotBase::SimulationPeriodic() {
47 static bool firstRun = true;
48 if (firstRun) {
Austin Schuh812d0d12021-11-04 20:16:48 -070049 fmt::print("Default {}() method... Override me!\n", __FUNCTION__);
Austin Schuh1e69f942020-11-14 15:06:14 -080050 firstRun = false;
51 }
52}
53
Brian Silverman8fce7482020-01-05 13:18:21 -080054void IterativeRobotBase::DisabledPeriodic() {
55 static bool firstRun = true;
56 if (firstRun) {
Austin Schuh812d0d12021-11-04 20:16:48 -070057 fmt::print("Default {}() method... Override me!\n", __FUNCTION__);
Brian Silverman8fce7482020-01-05 13:18:21 -080058 firstRun = false;
59 }
60}
61
62void IterativeRobotBase::AutonomousPeriodic() {
63 static bool firstRun = true;
64 if (firstRun) {
Austin Schuh812d0d12021-11-04 20:16:48 -070065 fmt::print("Default {}() method... Override me!\n", __FUNCTION__);
Brian Silverman8fce7482020-01-05 13:18:21 -080066 firstRun = false;
67 }
68}
69
70void IterativeRobotBase::TeleopPeriodic() {
71 static bool firstRun = true;
72 if (firstRun) {
Austin Schuh812d0d12021-11-04 20:16:48 -070073 fmt::print("Default {}() method... Override me!\n", __FUNCTION__);
Brian Silverman8fce7482020-01-05 13:18:21 -080074 firstRun = false;
75 }
76}
77
78void IterativeRobotBase::TestPeriodic() {
79 static bool firstRun = true;
80 if (firstRun) {
Austin Schuh812d0d12021-11-04 20:16:48 -070081 fmt::print("Default {}() method... Override me!\n", __FUNCTION__);
Brian Silverman8fce7482020-01-05 13:18:21 -080082 firstRun = false;
83 }
84}
85
Austin Schuh812d0d12021-11-04 20:16:48 -070086void IterativeRobotBase::DisabledExit() {}
87
88void IterativeRobotBase::AutonomousExit() {}
89
90void IterativeRobotBase::TeleopExit() {}
91
92void IterativeRobotBase::TestExit() {}
93
94void IterativeRobotBase::SetNetworkTablesFlushEnabled(bool enabled) {
95 m_ntFlushEnabled = enabled;
96}
97
98units::second_t IterativeRobotBase::GetPeriod() const {
99 return m_period;
100}
101
Brian Silverman8fce7482020-01-05 13:18:21 -0800102void IterativeRobotBase::LoopFunc() {
103 m_watchdog.Reset();
104
Austin Schuh812d0d12021-11-04 20:16:48 -0700105 // Get current mode
106 DSControlWord word;
107 Mode mode = Mode::kNone;
108 if (word.IsDisabled()) {
109 mode = Mode::kDisabled;
110 } else if (word.IsAutonomous()) {
111 mode = Mode::kAutonomous;
112 } else if (word.IsTeleop()) {
113 mode = Mode::kTeleop;
114 } else if (word.IsTest()) {
115 mode = Mode::kTest;
116 }
117
118 // If mode changed, call mode exit and entry functions
119 if (m_lastMode != mode) {
120 // Call last mode's exit function
121 if (m_lastMode == Mode::kDisabled) {
122 DisabledExit();
123 } else if (m_lastMode == Mode::kAutonomous) {
124 AutonomousExit();
125 } else if (m_lastMode == Mode::kTeleop) {
126 TeleopExit();
127 } else if (m_lastMode == Mode::kTest) {
128 LiveWindow::SetEnabled(false);
Brian Silverman8fce7482020-01-05 13:18:21 -0800129 Shuffleboard::DisableActuatorWidgets();
Austin Schuh812d0d12021-11-04 20:16:48 -0700130 TestExit();
131 }
132
133 // Call current mode's entry function
134 if (mode == Mode::kDisabled) {
Brian Silverman8fce7482020-01-05 13:18:21 -0800135 DisabledInit();
136 m_watchdog.AddEpoch("DisabledInit()");
Austin Schuh812d0d12021-11-04 20:16:48 -0700137 } else if (mode == Mode::kAutonomous) {
Brian Silverman8fce7482020-01-05 13:18:21 -0800138 AutonomousInit();
139 m_watchdog.AddEpoch("AutonomousInit()");
Austin Schuh812d0d12021-11-04 20:16:48 -0700140 } else if (mode == Mode::kTeleop) {
Brian Silverman8fce7482020-01-05 13:18:21 -0800141 TeleopInit();
142 m_watchdog.AddEpoch("TeleopInit()");
Austin Schuh812d0d12021-11-04 20:16:48 -0700143 } else if (mode == Mode::kTest) {
144 LiveWindow::SetEnabled(true);
Brian Silverman8fce7482020-01-05 13:18:21 -0800145 Shuffleboard::EnableActuatorWidgets();
146 TestInit();
147 m_watchdog.AddEpoch("TestInit()");
Brian Silverman8fce7482020-01-05 13:18:21 -0800148 }
149
Austin Schuh812d0d12021-11-04 20:16:48 -0700150 m_lastMode = mode;
151 }
152
153 // Call the appropriate function depending upon the current robot mode
154 if (mode == Mode::kDisabled) {
155 HAL_ObserveUserProgramDisabled();
156 DisabledPeriodic();
157 m_watchdog.AddEpoch("DisabledPeriodic()");
158 } else if (mode == Mode::kAutonomous) {
159 HAL_ObserveUserProgramAutonomous();
160 AutonomousPeriodic();
161 m_watchdog.AddEpoch("AutonomousPeriodic()");
162 } else if (mode == Mode::kTeleop) {
163 HAL_ObserveUserProgramTeleop();
164 TeleopPeriodic();
165 m_watchdog.AddEpoch("TeleopPeriodic()");
166 } else if (mode == Mode::kTest) {
Brian Silverman8fce7482020-01-05 13:18:21 -0800167 HAL_ObserveUserProgramTest();
168 TestPeriodic();
169 m_watchdog.AddEpoch("TestPeriodic()");
170 }
171
172 RobotPeriodic();
173 m_watchdog.AddEpoch("RobotPeriodic()");
174
175 SmartDashboard::UpdateValues();
176 m_watchdog.AddEpoch("SmartDashboard::UpdateValues()");
Austin Schuh812d0d12021-11-04 20:16:48 -0700177 LiveWindow::UpdateValues();
Brian Silverman8fce7482020-01-05 13:18:21 -0800178 m_watchdog.AddEpoch("LiveWindow::UpdateValues()");
179 Shuffleboard::Update();
180 m_watchdog.AddEpoch("Shuffleboard::Update()");
Austin Schuh1e69f942020-11-14 15:06:14 -0800181
182 if constexpr (IsSimulation()) {
Austin Schuh812d0d12021-11-04 20:16:48 -0700183 HAL_SimPeriodicBefore();
Austin Schuh1e69f942020-11-14 15:06:14 -0800184 SimulationPeriodic();
Austin Schuh812d0d12021-11-04 20:16:48 -0700185 HAL_SimPeriodicAfter();
Austin Schuh1e69f942020-11-14 15:06:14 -0800186 m_watchdog.AddEpoch("SimulationPeriodic()");
187 }
188
Brian Silverman8fce7482020-01-05 13:18:21 -0800189 m_watchdog.Disable();
190
Austin Schuh812d0d12021-11-04 20:16:48 -0700191 // Flush NetworkTables
192 if (m_ntFlushEnabled) {
193 nt::NetworkTableInstance::GetDefault().Flush();
194 }
195
Brian Silverman8fce7482020-01-05 13:18:21 -0800196 // Warn on loop time overruns
197 if (m_watchdog.IsExpired()) {
198 m_watchdog.PrintEpochs();
199 }
200}
201
202void IterativeRobotBase::PrintLoopOverrunMessage() {
Austin Schuh812d0d12021-11-04 20:16:48 -0700203 FRC_ReportError(err::Error, "Loop time of {:.6f}s overrun", m_period.value());
Brian Silverman8fce7482020-01-05 13:18:21 -0800204}