blob: 90dc54b77aae06c56f474b6894a79d71615f15dc [file] [log] [blame]
Brian Silverman41cdd3e2019-01-19 19:48:58 -08001/*----------------------------------------------------------------------------*/
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -08002/* Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
Brian Silverman41cdd3e2019-01-19 19:48:58 -08003/* Open Source Software - may be modified and shared by FRC teams. The code */
4/* must be accompanied by the FIRST BSD license file in the root directory of */
5/* the project. */
6/*----------------------------------------------------------------------------*/
7
8#include "frc/IterativeRobotBase.h"
9
10#include <cstdio>
11
12#include <hal/HAL.h>
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080013#include <wpi/Format.h>
Brian Silverman41cdd3e2019-01-19 19:48:58 -080014#include <wpi/SmallString.h>
15#include <wpi/raw_ostream.h>
16
17#include "frc/DriverStation.h"
18#include "frc/Timer.h"
19#include "frc/commands/Scheduler.h"
20#include "frc/livewindow/LiveWindow.h"
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080021#include "frc/shuffleboard/Shuffleboard.h"
Brian Silverman41cdd3e2019-01-19 19:48:58 -080022#include "frc/smartdashboard/SmartDashboard.h"
23
24using namespace frc;
25
26IterativeRobotBase::IterativeRobotBase(double period)
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080027 : IterativeRobotBase(units::second_t(period)) {}
28
29IterativeRobotBase::IterativeRobotBase(units::second_t period)
Brian Silverman41cdd3e2019-01-19 19:48:58 -080030 : m_period(period),
31 m_watchdog(period, [this] { PrintLoopOverrunMessage(); }) {}
32
33void IterativeRobotBase::RobotInit() {
Brian Silverman60246092019-03-02 13:29:58 -080034 wpi::outs() << "Default " << __FUNCTION__ << "() method... Override me!\n";
Brian Silverman41cdd3e2019-01-19 19:48:58 -080035}
36
37void IterativeRobotBase::DisabledInit() {
Brian Silverman60246092019-03-02 13:29:58 -080038 wpi::outs() << "Default " << __FUNCTION__ << "() method... Override me!\n";
Brian Silverman41cdd3e2019-01-19 19:48:58 -080039}
40
41void IterativeRobotBase::AutonomousInit() {
Brian Silverman60246092019-03-02 13:29:58 -080042 wpi::outs() << "Default " << __FUNCTION__ << "() method... Override me!\n";
Brian Silverman41cdd3e2019-01-19 19:48:58 -080043}
44
45void IterativeRobotBase::TeleopInit() {
Brian Silverman60246092019-03-02 13:29:58 -080046 wpi::outs() << "Default " << __FUNCTION__ << "() method... Override me!\n";
Brian Silverman41cdd3e2019-01-19 19:48:58 -080047}
48
49void IterativeRobotBase::TestInit() {
Brian Silverman60246092019-03-02 13:29:58 -080050 wpi::outs() << "Default " << __FUNCTION__ << "() method... Override me!\n";
Brian Silverman41cdd3e2019-01-19 19:48:58 -080051}
52
53void IterativeRobotBase::RobotPeriodic() {
54 static bool firstRun = true;
55 if (firstRun) {
Brian Silverman60246092019-03-02 13:29:58 -080056 wpi::outs() << "Default " << __FUNCTION__ << "() method... Override me!\n";
Brian Silverman41cdd3e2019-01-19 19:48:58 -080057 firstRun = false;
58 }
59}
60
61void IterativeRobotBase::DisabledPeriodic() {
62 static bool firstRun = true;
63 if (firstRun) {
Brian Silverman60246092019-03-02 13:29:58 -080064 wpi::outs() << "Default " << __FUNCTION__ << "() method... Override me!\n";
Brian Silverman41cdd3e2019-01-19 19:48:58 -080065 firstRun = false;
66 }
67}
68
69void IterativeRobotBase::AutonomousPeriodic() {
70 static bool firstRun = true;
71 if (firstRun) {
Brian Silverman60246092019-03-02 13:29:58 -080072 wpi::outs() << "Default " << __FUNCTION__ << "() method... Override me!\n";
Brian Silverman41cdd3e2019-01-19 19:48:58 -080073 firstRun = false;
74 }
75}
76
77void IterativeRobotBase::TeleopPeriodic() {
78 static bool firstRun = true;
79 if (firstRun) {
Brian Silverman60246092019-03-02 13:29:58 -080080 wpi::outs() << "Default " << __FUNCTION__ << "() method... Override me!\n";
Brian Silverman41cdd3e2019-01-19 19:48:58 -080081 firstRun = false;
82 }
83}
84
85void IterativeRobotBase::TestPeriodic() {
86 static bool firstRun = true;
87 if (firstRun) {
Brian Silverman60246092019-03-02 13:29:58 -080088 wpi::outs() << "Default " << __FUNCTION__ << "() method... Override me!\n";
Brian Silverman41cdd3e2019-01-19 19:48:58 -080089 firstRun = false;
90 }
91}
92
93void IterativeRobotBase::LoopFunc() {
94 m_watchdog.Reset();
95
96 // Call the appropriate function depending upon the current robot mode
97 if (IsDisabled()) {
98 // Call DisabledInit() if we are now just entering disabled mode from
99 // either a different mode or from power-on.
100 if (m_lastMode != Mode::kDisabled) {
101 LiveWindow::GetInstance()->SetEnabled(false);
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -0800102 Shuffleboard::DisableActuatorWidgets();
Brian Silverman41cdd3e2019-01-19 19:48:58 -0800103 DisabledInit();
104 m_watchdog.AddEpoch("DisabledInit()");
105 m_lastMode = Mode::kDisabled;
106 }
107
108 HAL_ObserveUserProgramDisabled();
109 DisabledPeriodic();
110 m_watchdog.AddEpoch("DisabledPeriodic()");
111 } else if (IsAutonomous()) {
112 // Call AutonomousInit() if we are now just entering autonomous mode from
113 // either a different mode or from power-on.
114 if (m_lastMode != Mode::kAutonomous) {
115 LiveWindow::GetInstance()->SetEnabled(false);
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -0800116 Shuffleboard::DisableActuatorWidgets();
Brian Silverman41cdd3e2019-01-19 19:48:58 -0800117 AutonomousInit();
118 m_watchdog.AddEpoch("AutonomousInit()");
119 m_lastMode = Mode::kAutonomous;
120 }
121
122 HAL_ObserveUserProgramAutonomous();
123 AutonomousPeriodic();
124 m_watchdog.AddEpoch("AutonomousPeriodic()");
125 } else if (IsOperatorControl()) {
126 // Call TeleopInit() if we are now just entering teleop mode from
127 // either a different mode or from power-on.
128 if (m_lastMode != Mode::kTeleop) {
129 LiveWindow::GetInstance()->SetEnabled(false);
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -0800130 Shuffleboard::DisableActuatorWidgets();
Brian Silverman41cdd3e2019-01-19 19:48:58 -0800131 TeleopInit();
132 m_watchdog.AddEpoch("TeleopInit()");
133 m_lastMode = Mode::kTeleop;
134 Scheduler::GetInstance()->SetEnabled(true);
135 }
136
137 HAL_ObserveUserProgramTeleop();
138 TeleopPeriodic();
139 m_watchdog.AddEpoch("TeleopPeriodic()");
140 } else {
141 // Call TestInit() if we are now just entering test mode from
142 // either a different mode or from power-on.
143 if (m_lastMode != Mode::kTest) {
144 LiveWindow::GetInstance()->SetEnabled(true);
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -0800145 Shuffleboard::EnableActuatorWidgets();
Brian Silverman41cdd3e2019-01-19 19:48:58 -0800146 TestInit();
147 m_watchdog.AddEpoch("TestInit()");
148 m_lastMode = Mode::kTest;
149 }
150
151 HAL_ObserveUserProgramTest();
152 TestPeriodic();
153 m_watchdog.AddEpoch("TestPeriodic()");
154 }
155
156 RobotPeriodic();
157 m_watchdog.AddEpoch("RobotPeriodic()");
Brian Silverman41cdd3e2019-01-19 19:48:58 -0800158
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -0800159 SmartDashboard::UpdateValues();
160 m_watchdog.AddEpoch("SmartDashboard::UpdateValues()");
Brian Silverman41cdd3e2019-01-19 19:48:58 -0800161 LiveWindow::GetInstance()->UpdateValues();
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -0800162 m_watchdog.AddEpoch("LiveWindow::UpdateValues()");
163 Shuffleboard::Update();
164 m_watchdog.AddEpoch("Shuffleboard::Update()");
165 m_watchdog.Disable();
Brian Silverman41cdd3e2019-01-19 19:48:58 -0800166
167 // Warn on loop time overruns
168 if (m_watchdog.IsExpired()) {
169 m_watchdog.PrintEpochs();
170 }
171}
172
173void IterativeRobotBase::PrintLoopOverrunMessage() {
174 wpi::SmallString<128> str;
175 wpi::raw_svector_ostream buf(str);
176
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -0800177 buf << "Loop time of " << wpi::format("%.6f", m_period.to<double>())
178 << "s overrun\n";
Brian Silverman41cdd3e2019-01-19 19:48:58 -0800179
180 DriverStation::ReportWarning(str);
181}