blob: 3669bce78ee3bf0cde7ed226bf21588000727bb0 [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
James Kuszmaulcf324122023-01-14 14:07:17 -08007#include <frc/DriverStation.h>
8
Austin Schuh812d0d12021-11-04 20:16:48 -07009#include <fmt/format.h>
Brian Silverman8fce7482020-01-05 13:18:21 -080010#include <hal/DriverStation.h>
Maxwell Henderson80bec322024-01-09 15:48:44 -080011#include <hal/FRCUsageReporting.h>
Austin Schuh812d0d12021-11-04 20:16:48 -070012#include <networktables/NetworkTableInstance.h>
Brian Silverman8fce7482020-01-05 13:18:21 -080013
Austin Schuh812d0d12021-11-04 20:16:48 -070014#include "frc/DSControlWord.h"
15#include "frc/Errors.h"
Brian Silverman8fce7482020-01-05 13:18:21 -080016#include "frc/livewindow/LiveWindow.h"
17#include "frc/shuffleboard/Shuffleboard.h"
18#include "frc/smartdashboard/SmartDashboard.h"
19
20using namespace frc;
21
Brian Silverman8fce7482020-01-05 13:18:21 -080022IterativeRobotBase::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
James Kuszmaulb13e13f2023-11-22 20:44:04 -080028void IterativeRobotBase::DriverStationConnected() {}
29
Austin Schuh812d0d12021-11-04 20:16:48 -070030void IterativeRobotBase::SimulationInit() {}
Austin Schuh1e69f942020-11-14 15:06:14 -080031
Austin Schuh812d0d12021-11-04 20:16:48 -070032void IterativeRobotBase::DisabledInit() {}
Brian Silverman8fce7482020-01-05 13:18:21 -080033
Austin Schuh812d0d12021-11-04 20:16:48 -070034void IterativeRobotBase::AutonomousInit() {}
Brian Silverman8fce7482020-01-05 13:18:21 -080035
Austin Schuh812d0d12021-11-04 20:16:48 -070036void IterativeRobotBase::TeleopInit() {}
Brian Silverman8fce7482020-01-05 13:18:21 -080037
Austin Schuh812d0d12021-11-04 20:16:48 -070038void IterativeRobotBase::TestInit() {}
Brian Silverman8fce7482020-01-05 13:18:21 -080039
40void IterativeRobotBase::RobotPeriodic() {
41 static bool firstRun = true;
42 if (firstRun) {
Austin Schuh812d0d12021-11-04 20:16:48 -070043 fmt::print("Default {}() method... Override me!\n", __FUNCTION__);
Brian Silverman8fce7482020-01-05 13:18:21 -080044 firstRun = false;
45 }
46}
47
Austin Schuh1e69f942020-11-14 15:06:14 -080048void IterativeRobotBase::SimulationPeriodic() {
49 static bool firstRun = true;
50 if (firstRun) {
Austin Schuh812d0d12021-11-04 20:16:48 -070051 fmt::print("Default {}() method... Override me!\n", __FUNCTION__);
Austin Schuh1e69f942020-11-14 15:06:14 -080052 firstRun = false;
53 }
54}
55
Brian Silverman8fce7482020-01-05 13:18:21 -080056void IterativeRobotBase::DisabledPeriodic() {
57 static bool firstRun = true;
58 if (firstRun) {
Austin Schuh812d0d12021-11-04 20:16:48 -070059 fmt::print("Default {}() method... Override me!\n", __FUNCTION__);
Brian Silverman8fce7482020-01-05 13:18:21 -080060 firstRun = false;
61 }
62}
63
64void IterativeRobotBase::AutonomousPeriodic() {
65 static bool firstRun = true;
66 if (firstRun) {
Austin Schuh812d0d12021-11-04 20:16:48 -070067 fmt::print("Default {}() method... Override me!\n", __FUNCTION__);
Brian Silverman8fce7482020-01-05 13:18:21 -080068 firstRun = false;
69 }
70}
71
72void IterativeRobotBase::TeleopPeriodic() {
73 static bool firstRun = true;
74 if (firstRun) {
Austin Schuh812d0d12021-11-04 20:16:48 -070075 fmt::print("Default {}() method... Override me!\n", __FUNCTION__);
Brian Silverman8fce7482020-01-05 13:18:21 -080076 firstRun = false;
77 }
78}
79
80void IterativeRobotBase::TestPeriodic() {
81 static bool firstRun = true;
82 if (firstRun) {
Austin Schuh812d0d12021-11-04 20:16:48 -070083 fmt::print("Default {}() method... Override me!\n", __FUNCTION__);
Brian Silverman8fce7482020-01-05 13:18:21 -080084 firstRun = false;
85 }
86}
87
Austin Schuh812d0d12021-11-04 20:16:48 -070088void IterativeRobotBase::DisabledExit() {}
89
90void IterativeRobotBase::AutonomousExit() {}
91
92void IterativeRobotBase::TeleopExit() {}
93
94void IterativeRobotBase::TestExit() {}
95
96void IterativeRobotBase::SetNetworkTablesFlushEnabled(bool enabled) {
97 m_ntFlushEnabled = enabled;
98}
99
James Kuszmaulcf324122023-01-14 14:07:17 -0800100void IterativeRobotBase::EnableLiveWindowInTest(bool testLW) {
Maxwell Henderson80bec322024-01-09 15:48:44 -0800101 static bool hasReported;
James Kuszmaulb13e13f2023-11-22 20:44:04 -0800102 if (IsTestEnabled()) {
James Kuszmaulcf324122023-01-14 14:07:17 -0800103 throw FRC_MakeError(err::IncompatibleMode,
104 "Can't configure test mode while in test mode!");
105 }
Maxwell Henderson80bec322024-01-09 15:48:44 -0800106 if (!hasReported && testLW) {
107 HAL_Report(HALUsageReporting::kResourceType_SmartDashboard,
108 HALUsageReporting::kSmartDashboard_LiveWindow);
109 hasReported = true;
110 }
James Kuszmaulcf324122023-01-14 14:07:17 -0800111 m_lwEnabledInTest = testLW;
112}
113
114bool IterativeRobotBase::IsLiveWindowEnabledInTest() {
115 return m_lwEnabledInTest;
116}
117
Austin Schuh812d0d12021-11-04 20:16:48 -0700118units::second_t IterativeRobotBase::GetPeriod() const {
119 return m_period;
120}
121
Brian Silverman8fce7482020-01-05 13:18:21 -0800122void IterativeRobotBase::LoopFunc() {
James Kuszmaulcf324122023-01-14 14:07:17 -0800123 DriverStation::RefreshData();
Brian Silverman8fce7482020-01-05 13:18:21 -0800124 m_watchdog.Reset();
125
Austin Schuh812d0d12021-11-04 20:16:48 -0700126 // Get current mode
127 DSControlWord word;
128 Mode mode = Mode::kNone;
129 if (word.IsDisabled()) {
130 mode = Mode::kDisabled;
131 } else if (word.IsAutonomous()) {
132 mode = Mode::kAutonomous;
133 } else if (word.IsTeleop()) {
134 mode = Mode::kTeleop;
135 } else if (word.IsTest()) {
136 mode = Mode::kTest;
137 }
138
James Kuszmaulb13e13f2023-11-22 20:44:04 -0800139 if (!m_calledDsConnected && word.IsDSAttached()) {
140 m_calledDsConnected = true;
141 DriverStationConnected();
142 }
143
Austin Schuh812d0d12021-11-04 20:16:48 -0700144 // If mode changed, call mode exit and entry functions
145 if (m_lastMode != mode) {
146 // Call last mode's exit function
147 if (m_lastMode == Mode::kDisabled) {
148 DisabledExit();
149 } else if (m_lastMode == Mode::kAutonomous) {
150 AutonomousExit();
151 } else if (m_lastMode == Mode::kTeleop) {
152 TeleopExit();
153 } else if (m_lastMode == Mode::kTest) {
James Kuszmaulcf324122023-01-14 14:07:17 -0800154 if (m_lwEnabledInTest) {
155 LiveWindow::SetEnabled(false);
156 Shuffleboard::DisableActuatorWidgets();
157 }
Austin Schuh812d0d12021-11-04 20:16:48 -0700158 TestExit();
159 }
160
161 // Call current mode's entry function
162 if (mode == Mode::kDisabled) {
Brian Silverman8fce7482020-01-05 13:18:21 -0800163 DisabledInit();
164 m_watchdog.AddEpoch("DisabledInit()");
Austin Schuh812d0d12021-11-04 20:16:48 -0700165 } else if (mode == Mode::kAutonomous) {
Brian Silverman8fce7482020-01-05 13:18:21 -0800166 AutonomousInit();
167 m_watchdog.AddEpoch("AutonomousInit()");
Austin Schuh812d0d12021-11-04 20:16:48 -0700168 } else if (mode == Mode::kTeleop) {
Brian Silverman8fce7482020-01-05 13:18:21 -0800169 TeleopInit();
170 m_watchdog.AddEpoch("TeleopInit()");
Austin Schuh812d0d12021-11-04 20:16:48 -0700171 } else if (mode == Mode::kTest) {
James Kuszmaulcf324122023-01-14 14:07:17 -0800172 if (m_lwEnabledInTest) {
173 LiveWindow::SetEnabled(true);
174 Shuffleboard::EnableActuatorWidgets();
175 }
Brian Silverman8fce7482020-01-05 13:18:21 -0800176 TestInit();
177 m_watchdog.AddEpoch("TestInit()");
Brian Silverman8fce7482020-01-05 13:18:21 -0800178 }
179
Austin Schuh812d0d12021-11-04 20:16:48 -0700180 m_lastMode = mode;
181 }
182
183 // Call the appropriate function depending upon the current robot mode
184 if (mode == Mode::kDisabled) {
185 HAL_ObserveUserProgramDisabled();
186 DisabledPeriodic();
187 m_watchdog.AddEpoch("DisabledPeriodic()");
188 } else if (mode == Mode::kAutonomous) {
189 HAL_ObserveUserProgramAutonomous();
190 AutonomousPeriodic();
191 m_watchdog.AddEpoch("AutonomousPeriodic()");
192 } else if (mode == Mode::kTeleop) {
193 HAL_ObserveUserProgramTeleop();
194 TeleopPeriodic();
195 m_watchdog.AddEpoch("TeleopPeriodic()");
196 } else if (mode == Mode::kTest) {
Brian Silverman8fce7482020-01-05 13:18:21 -0800197 HAL_ObserveUserProgramTest();
198 TestPeriodic();
199 m_watchdog.AddEpoch("TestPeriodic()");
200 }
201
202 RobotPeriodic();
203 m_watchdog.AddEpoch("RobotPeriodic()");
204
205 SmartDashboard::UpdateValues();
206 m_watchdog.AddEpoch("SmartDashboard::UpdateValues()");
Austin Schuh812d0d12021-11-04 20:16:48 -0700207 LiveWindow::UpdateValues();
Brian Silverman8fce7482020-01-05 13:18:21 -0800208 m_watchdog.AddEpoch("LiveWindow::UpdateValues()");
209 Shuffleboard::Update();
210 m_watchdog.AddEpoch("Shuffleboard::Update()");
Austin Schuh1e69f942020-11-14 15:06:14 -0800211
212 if constexpr (IsSimulation()) {
Austin Schuh812d0d12021-11-04 20:16:48 -0700213 HAL_SimPeriodicBefore();
Austin Schuh1e69f942020-11-14 15:06:14 -0800214 SimulationPeriodic();
Austin Schuh812d0d12021-11-04 20:16:48 -0700215 HAL_SimPeriodicAfter();
Austin Schuh1e69f942020-11-14 15:06:14 -0800216 m_watchdog.AddEpoch("SimulationPeriodic()");
217 }
218
Brian Silverman8fce7482020-01-05 13:18:21 -0800219 m_watchdog.Disable();
220
Austin Schuh812d0d12021-11-04 20:16:48 -0700221 // Flush NetworkTables
222 if (m_ntFlushEnabled) {
James Kuszmaulcf324122023-01-14 14:07:17 -0800223 nt::NetworkTableInstance::GetDefault().FlushLocal();
Austin Schuh812d0d12021-11-04 20:16:48 -0700224 }
225
Brian Silverman8fce7482020-01-05 13:18:21 -0800226 // Warn on loop time overruns
227 if (m_watchdog.IsExpired()) {
228 m_watchdog.PrintEpochs();
229 }
230}
231
232void IterativeRobotBase::PrintLoopOverrunMessage() {
Austin Schuh812d0d12021-11-04 20:16:48 -0700233 FRC_ReportError(err::Error, "Loop time of {:.6f}s overrun", m_period.value());
Brian Silverman8fce7482020-01-05 13:18:21 -0800234}