blob: 0b7b9cb3a2bc048659e63755cc499d8d438880be [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);
James Kuszmaulcf324122023-01-14 14:07:17 -080043 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(units::second_t period) : IterativeRobotBase(period) {
Austin Schuh812d0d12021-11-04 20:16:48 -070074 m_startTime = Timer::GetFPGATimestamp();
James Kuszmaulcf324122023-01-14 14:07:17 -080075 AddPeriodic([=, this] { LoopFunc(); }, period);
Austin Schuh1e69f942020-11-14 15:06:14 -080076
Brian Silverman8fce7482020-01-05 13:18:21 -080077 int32_t status = 0;
78 m_notifier = HAL_InitializeNotifier(&status);
James Kuszmaulcf324122023-01-14 14:07:17 -080079 FRC_CheckErrorStatus(status, "InitializeNotifier");
Brian Silverman8fce7482020-01-05 13:18:21 -080080 HAL_SetNotifierName(m_notifier, "TimedRobot", &status);
81
82 HAL_Report(HALUsageReporting::kResourceType_Framework,
83 HALUsageReporting::kFramework_Timed);
84}
85
86TimedRobot::~TimedRobot() {
87 int32_t status = 0;
88
89 HAL_StopNotifier(m_notifier, &status);
James Kuszmaulcf324122023-01-14 14:07:17 -080090 FRC_ReportError(status, "StopNotifier");
Brian Silverman8fce7482020-01-05 13:18:21 -080091
92 HAL_CleanNotifier(m_notifier, &status);
93}
94
Austin Schuh1e69f942020-11-14 15:06:14 -080095void TimedRobot::AddPeriodic(std::function<void()> callback,
96 units::second_t period, units::second_t offset) {
97 m_callbacks.emplace(callback, m_startTime, period, offset);
Brian Silverman8fce7482020-01-05 13:18:21 -080098}