WPILibC++ 2027.0.0-alpha-5
Loading...
Searching...
No Matches
PeriodicPriorityQueue.hpp
Go to the documentation of this file.
1// 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.
4
5#pragma once
6
7#include <chrono>
8#include <functional>
9#include <vector>
10
11#include "wpi/hal/Notifier.h"
12#include "wpi/units/time.hpp"
14
15namespace wpi::internal {
16
17/**
18 * A priority queue for scheduling periodic callbacks based on their next
19 * execution time.
20 *
21 * <p>This class manages a collection of periodic callbacks that execute at
22 * specified intervals. Callbacks are scheduled using FPGA timestamps and
23 * automatically rescheduled after execution to maintain their periodic
24 * behavior. The queue uses a priority heap to efficiently determine the next
25 * callback to execute.
26 *
27 * <p>This is an internal scheduling primitive used by robot frameworks like
28 * TimedRobot.
29 */
31 public:
32 /**
33 * A periodic callback with scheduling metadata.
34 *
35 * Each callback tracks its target function, period, and next expiration
36 * time. After execution, the expiration time is automatically advanced by
37 * full periods to maintain precise timing even when execution is delayed.
38 */
39 class Callback {
40 public:
41 /** The function to execute when the callback fires. */
42 std::function<void()> func;
43
44 /** The period at which to run the callback. */
45 std::chrono::microseconds period;
46
47 /** The next scheduled execution time in FPGA timestamp microseconds. */
48 std::chrono::microseconds expirationTime;
49
50 /**
51 * Construct a callback container.
52 *
53 * @param func The callback to run.
54 * @param startTime The common starting point for all callback scheduling.
55 * @param period The period at which to run the callback.
56 * @param offset The offset from the common starting time.
57 */
58 Callback(std::function<void()> func, std::chrono::microseconds startTime,
59 std::chrono::microseconds period,
60 std::chrono::microseconds offset);
61
62 /**
63 * Construct a callback container using units-based period and offset.
64 *
65 * @param func The callback to run.
66 * @param startTime The common starting point for all callback scheduling.
67 * @param period The period at which to run the callback.
68 * @param offset The offset from the common starting time.
69 */
70 Callback(std::function<void()> func, std::chrono::microseconds startTime,
71 wpi::units::second_t period, wpi::units::second_t offset);
72
73 /**
74 * Construct a callback container using units-based period.
75 *
76 * @param func The callback to run.
77 * @param startTime The common starting point for all callback scheduling.
78 * @param period The period at which to run the callback.
79 */
80 Callback(std::function<void()> func, std::chrono::microseconds startTime,
81 wpi::units::second_t period);
82
83 bool operator>(const Callback& rhs) const {
84 return expirationTime > rhs.expirationTime;
85 }
86
87 bool operator==(const Callback& rhs) const {
88 return expirationTime == rhs.expirationTime;
89 }
90 };
91
92 /**
93 * Adds a periodic callback to the queue.
94 *
95 * @param func The callback to run.
96 * @param startTime The common starting point for all callback scheduling.
97 * @param period The period at which to run the callback.
98 */
99 void Add(std::function<void()> func, std::chrono::microseconds startTime,
100 std::chrono::microseconds period);
101
102 /**
103 * Adds a periodic callback to the queue.
104 *
105 * @param func The callback to run.
106 * @param startTime The common starting point for all callback scheduling.
107 * @param period The period at which to run the callback.
108 * @param offset The offset from the common starting time.
109 */
110 void Add(std::function<void()> func, std::chrono::microseconds startTime,
111 std::chrono::microseconds period, std::chrono::microseconds offset);
112
113 /**
114 * Adds a periodic callback to the queue.
115 *
116 * @param func The callback to run.
117 * @param startTime The common starting point for all callback scheduling in
118 * FPGA timestamp microseconds.
119 * @param period The period at which to run the callback.
120 */
121 void Add(std::function<void()> func, std::chrono::microseconds startTime,
122 wpi::units::second_t period);
123
124 /**
125 * Adds a periodic callback to the queue.
126 *
127 * @param func The callback to run.
128 * @param startTime The common starting point for all callback scheduling in
129 * FPGA timestamp microseconds.
130 * @param period The period at which to run the callback.
131 * @param offset The offset from the common starting time.
132 */
133 void Add(std::function<void()> func, std::chrono::microseconds startTime,
134 wpi::units::second_t period, wpi::units::second_t offset);
135
136 /**
137 * Adds a pre-constructed callback to the queue.
138 *
139 * @param callback The callback to add.
140 */
141 void Add(Callback callback);
142
143 /**
144 * Removes a specific callback from the queue.
145 *
146 * @param callback The callback to remove.
147 * @return true if the callback was found and removed, false otherwise.
148 */
149 bool Remove(const Callback& callback);
150
151 /**
152 * Removes all callbacks from the queue.
153 */
154 void Clear();
155
156 /**
157 * Executes all callbacks that are due, then waits for the next callback's
158 * scheduled time.
159 *
160 * This method performs the following steps:
161 * -# Retrieves the callback with the earliest expiration time from the queue
162 * -# Sets a hardware notifier alarm to wait until that callback's expiration
163 * time
164 * -# Blocks until the notifier signals or is interrupted
165 * -# Executes the callback and reschedules it for its next period
166 * -# Processes any additional callbacks that have become due during execution
167 *
168 * When rescheduling callbacks, this method automatically compensates for
169 * execution delays by advancing the expiration time by the number of full
170 * periods that have elapsed, ensuring callbacks maintain their scheduled
171 * phase over time.
172 *
173 * @param notifier The HAL notifier handle to use for timing.
174 * @return false if the notifier was destroyed (loop should exit), true
175 * otherwise.
176 */
178
179 /**
180 * Returns the underlying priority queue.
181 */
184 return m_queue;
185 }
186
187 /**
188 * Return the system clock time in microseconds for the start of the current
189 * periodic loop. This is in the same time base as
190 * Timer.getMonotonicTimeStamp(), but is stable through a loop. It is updated
191 * at the beginning of every periodic callback (including the normal periodic
192 * loop).
193 *
194 * @return Robot running time in microseconds, as of the start of the current
195 * periodic function.
196 */
197 wpi::units::microsecond_t GetLoopStartTime() const { return m_loopStartTime; }
198
199 private:
201 m_queue;
202
203 wpi::units::microsecond_t m_loopStartTime{0};
204};
205
206} // namespace wpi::internal
A periodic callback with scheduling metadata.
Definition PeriodicPriorityQueue.hpp:39
bool operator==(const Callback &rhs) const
Definition PeriodicPriorityQueue.hpp:87
Callback(std::function< void()> func, std::chrono::microseconds startTime, wpi::units::second_t period, wpi::units::second_t offset)
Construct a callback container using units-based period and offset.
std::function< void()> func
The function to execute when the callback fires.
Definition PeriodicPriorityQueue.hpp:42
Callback(std::function< void()> func, std::chrono::microseconds startTime, std::chrono::microseconds period, std::chrono::microseconds offset)
Construct a callback container.
std::chrono::microseconds expirationTime
The next scheduled execution time in FPGA timestamp microseconds.
Definition PeriodicPriorityQueue.hpp:48
Callback(std::function< void()> func, std::chrono::microseconds startTime, wpi::units::second_t period)
Construct a callback container using units-based period.
bool operator>(const Callback &rhs) const
Definition PeriodicPriorityQueue.hpp:83
std::chrono::microseconds period
The period at which to run the callback.
Definition PeriodicPriorityQueue.hpp:45
A priority queue for scheduling periodic callbacks based on their next execution time.
Definition PeriodicPriorityQueue.hpp:30
void Add(std::function< void()> func, std::chrono::microseconds startTime, std::chrono::microseconds period)
Adds a periodic callback to the queue.
bool Remove(const Callback &callback)
Removes a specific callback from the queue.
bool RunCallbacks(HAL_NotifierHandle notifier)
Executes all callbacks that are due, then waits for the next callback's scheduled time.
void Add(std::function< void()> func, std::chrono::microseconds startTime, wpi::units::second_t period, wpi::units::second_t offset)
Adds a periodic callback to the queue.
void Add(Callback callback)
Adds a pre-constructed callback to the queue.
void Add(std::function< void()> func, std::chrono::microseconds startTime, std::chrono::microseconds period, std::chrono::microseconds offset)
Adds a periodic callback to the queue.
wpi::util::priority_queue< Callback, std::vector< Callback >, std::greater<> > & GetQueue()
Returns the underlying priority queue.
Definition PeriodicPriorityQueue.hpp:183
void Clear()
Removes all callbacks from the queue.
void Add(std::function< void()> func, std::chrono::microseconds startTime, wpi::units::second_t period)
Adds a periodic callback to the queue.
wpi::units::microsecond_t GetLoopStartTime() const
Return the system clock time in microseconds for the start of the current periodic loop.
Definition PeriodicPriorityQueue.hpp:197
This class is the same as std::priority_queue with two changes:
Definition priority_queue.hpp:26
HAL_Handle HAL_NotifierHandle
Definition Types.h:37
Definition DriverStationModeThread.hpp:13