blob: 93e66985acd678d1f45a21b97c3e3d0cab075009 [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/TimedRobot.h"
6
7#include <stdint.h>
8
Austin Schuh812d0d12021-11-04 20:16:48 -07009#include <cstdio>
Brian Silverman8fce7482020-01-05 13:18:21 -080010#include <utility>
11
12#include <hal/DriverStation.h>
13#include <hal/FRCUsageReporting.h>
14#include <hal/Notifier.h>
15
Austin Schuh812d0d12021-11-04 20:16:48 -070016#include "frc/Errors.h"
Brian Silverman8fce7482020-01-05 13:18:21 -080017#include "frc/Timer.h"
Brian Silverman8fce7482020-01-05 13:18:21 -080018
19using namespace frc;
20
21void TimedRobot::StartCompetition() {
22 RobotInit();
23
Austin Schuh1e69f942020-11-14 15:06:14 -080024 if constexpr (IsSimulation()) {
25 SimulationInit();
26 }
27
Brian Silverman8fce7482020-01-05 13:18:21 -080028 // Tell the DS that the robot is ready to be enabled
Austin Schuh812d0d12021-11-04 20:16:48 -070029 std::puts("\n********** Robot program startup complete **********");
Brian Silverman8fce7482020-01-05 13:18:21 -080030 HAL_ObserveUserProgramStarting();
31
Brian Silverman8fce7482020-01-05 13:18:21 -080032 // Loop forever, calling the appropriate mode-dependent function
33 while (true) {
Austin Schuh1e69f942020-11-14 15:06:14 -080034 // We don't have to check there's an element in the queue first because
35 // there's always at least one (the constructor adds one). It's reenqueued
36 // at the end of the loop.
37 auto callback = m_callbacks.pop();
38
Brian Silverman8fce7482020-01-05 13:18:21 -080039 int32_t status = 0;
Austin Schuh1e69f942020-11-14 15:06:14 -080040 HAL_UpdateNotifierAlarm(
41 m_notifier, static_cast<uint64_t>(callback.expirationTime * 1e6),
42 &status);
Austin Schuh812d0d12021-11-04 20:16:48 -070043 FRC_CheckErrorStatus(status, "{}", "UpdateNotifierAlarm");
Austin Schuh1e69f942020-11-14 15:06:14 -080044
Brian Silverman8fce7482020-01-05 13:18:21 -080045 uint64_t curTime = HAL_WaitForNotifierAlarm(m_notifier, &status);
Austin Schuh812d0d12021-11-04 20:16:48 -070046 if (curTime == 0 || status != 0) {
47 break;
48 }
Brian Silverman8fce7482020-01-05 13:18:21 -080049
Austin Schuh1e69f942020-11-14 15:06:14 -080050 callback.func();
Brian Silverman8fce7482020-01-05 13:18:21 -080051
Austin Schuh1e69f942020-11-14 15:06:14 -080052 callback.expirationTime += callback.period;
53 m_callbacks.push(std::move(callback));
Brian Silverman8fce7482020-01-05 13:18:21 -080054
Austin Schuh1e69f942020-11-14 15:06:14 -080055 // Process all other callbacks that are ready to run
56 while (static_cast<uint64_t>(m_callbacks.top().expirationTime * 1e6) <=
57 curTime) {
58 callback = m_callbacks.pop();
59
60 callback.func();
61
62 callback.expirationTime += callback.period;
63 m_callbacks.push(std::move(callback));
64 }
Brian Silverman8fce7482020-01-05 13:18:21 -080065 }
66}
67
68void TimedRobot::EndCompetition() {
69 int32_t status = 0;
70 HAL_StopNotifier(m_notifier, &status);
71}
72
Brian Silverman8fce7482020-01-05 13:18:21 -080073TimedRobot::TimedRobot(double period) : TimedRobot(units::second_t(period)) {}
74
75TimedRobot::TimedRobot(units::second_t period) : IterativeRobotBase(period) {
Austin Schuh812d0d12021-11-04 20:16:48 -070076 m_startTime = Timer::GetFPGATimestamp();
Austin Schuh1e69f942020-11-14 15:06:14 -080077 AddPeriodic([=] { LoopFunc(); }, period);
78
Brian Silverman8fce7482020-01-05 13:18:21 -080079 int32_t status = 0;
80 m_notifier = HAL_InitializeNotifier(&status);
Austin Schuh812d0d12021-11-04 20:16:48 -070081 FRC_CheckErrorStatus(status, "{}", "InitializeNotifier");
Brian Silverman8fce7482020-01-05 13:18:21 -080082 HAL_SetNotifierName(m_notifier, "TimedRobot", &status);
83
84 HAL_Report(HALUsageReporting::kResourceType_Framework,
85 HALUsageReporting::kFramework_Timed);
86}
87
88TimedRobot::~TimedRobot() {
89 int32_t status = 0;
90
91 HAL_StopNotifier(m_notifier, &status);
Austin Schuh812d0d12021-11-04 20:16:48 -070092 FRC_ReportError(status, "{}", "StopNotifier");
Brian Silverman8fce7482020-01-05 13:18:21 -080093
94 HAL_CleanNotifier(m_notifier, &status);
95}
96
Austin Schuh1e69f942020-11-14 15:06:14 -080097void TimedRobot::AddPeriodic(std::function<void()> callback,
98 units::second_t period, units::second_t offset) {
99 m_callbacks.emplace(callback, m_startTime, period, offset);
Brian Silverman8fce7482020-01-05 13:18:21 -0800100}