CTRE Phoenix 6 C++ 26.0.0-beta-1
Loading...
Searching...
No Matches
HootAutoReplay.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) Cross The Road Electronics.  All rights reserved.
3 * License information can be found in CTRE_LICENSE.txt
4 * For support and suggestions contact support@ctr-electronics.com or file
5 * an issue tracker at https://github.com/CrossTheRoadElec/Phoenix-Releases
6 */
7#pragma once
8
13#include <functional>
14
15namespace ctre {
16namespace phoenix6 {
17
18/**
19 * \brief Class for handling automatic logging and replay of custom signal inputs.
20 * Each subsystem typically creates a new instance of this class.
21 *
22 * Note that all StatusSignals are automatically logged and replayed, so they
23 * do not need to be registered with this class. Additionally, the SignalLogger
24 * must be separately started at the start of the robot program.
25 *
26 * \details "Inputs" are signals measured directly from devices that should be
27 * replayed unmodified. By comparison, a processed signal, such as a signal
28 * indicating that a mechanism has reached the target, is considered an "output".
29 * This class should only be used with inputs.
30 *
31 * Inputs are registered with a getter that returns a value to log and a setter
32 * that updates the value in your robot program. For example, a `Vision` class
33 * with a `Pose2d cameraPose` input would register the input using:
34 *
35 * ```
36 * HootAutoReplay autoReplay = HootAutoReplay{}
37 * .WithStruct<frc::Pose2d>(
38 * "Vision/CameraPose",
39 * [this]() -> frc::Pose2d const& { return cameraPose; },
40 * [this](SignalMeasurement<frc::Pose2d> val) {
41 * cameraPose = val.value;
42 * }
43 * );
44 * ```
45 *
46 * After registering all relevant inputs, call #Update() periodically
47 * to perform the following:
48 *
49 * - In normal/simulated robot operation, registered inputs will be
50 * fetched from your robot code using the provided getter, and then
51 * logged using the SignalLogger.
52 *
53 * - During Hoot Replay, registered inputs will be fetched from
54 * HootReplay and then updated in your robot code using the
55 * provided setter.
56 *
57 * Note that for non-primitive types, the getter function must return a
58 * reference to or std::span over the original data. As a result, they cannot
59 * return temporary values. If a getter lambda must return a temporary value,
60 * capture a unique_ptr or shared_ptr in the lambda, then modify and return the
61 * value of the unique_ptr/shared_ptr.
62 */
64 std::vector<std::function<void()>> updates;
65
66public:
67 /**
68 * \brief Updates the state of the robot program by doing one of the following:
69 *
70 * - In normal/simulated robot operation, registered signals will be
71 * fetched from your robot code using the provided getter, and then
72 * logged using the SignalLogger.
73 *
74 * - During Hoot Replay, registered signals will be fetched from
75 * HootReplay and then updated in your robot code using the
76 * provided setter.
77 *
78 * This should be called periodically, typically in the subsystem.
79 */
80 void Update() const
81 {
82 for (auto const &update : updates) {
83 update();
84 }
85 }
86
87#if (__has_include("frc/RobotController.h") && __has_include("frc/Timer.h")) || defined(_CTRE_DOCS_)
88 /**
89 * \brief Registers Timer::GetTimestamp() logging and playback with this
90 * instance. This should only be applied to one instance in the robot
91 * program.
92 *
93 * The #Update() of this HootAutoReplay instance must be run at the
94 * start of RobotPeriodic() before the CommandScheduler is run.
95 *
96 * \returns this object
97 */
99#endif
100
101#if (__has_include("frc/DriverStation.h") && __has_include("frc/simulation/DriverStationSim.h")) || defined(_CTRE_DOCS_)
102 /**
103 * \brief Registers joystick logging and playback with this instance.
104 * This should only be applied to one instance in the robot program.
105 *
106 * To get joysticks to playback during Hoot Replay, "Turn off DS" must be
107 * checked in the simulation GUI (under "DS" at the top of the window).
108 * Additionally, the #Update() of this HootAutoReplay instance must be run
109 * at the start of RobotPeriodic() before the CommandScheduler is run.
110 *
111 * \returns this object
112 */
114#endif
115
116 /**
117 * \brief Registers the schema-serialized bytes as a Hoot-Replayed input.
118 *
119 * \param name Name of the signal in the log
120 * \param schemaName Name of the schema
121 * \param type Type of the schema, such as struct or protobuf
122 * \param schema Schema bytes to write
123 * \param getter Function that returns the current value of the input
124 * \param setter Function that sets the input to a new value
125 * \returns this object
126 */
128 std::string name, std::string schemaName,
129 HootSchemaType type, std::span<uint8_t const> schema,
130 std::function<std::span<uint8_t const>()> getter,
131 std::function<void(SignalMeasurement<std::vector<uint8_t>>)> setter
132 );
133
134 /**
135 * \brief Registers the schema-serialized bytes as a Hoot-Replayed input.
136 *
137 * \param name Name of the signal in the log
138 * \param schemaName Name of the schema
139 * \param type Type of the schema, such as struct or protobuf
140 * \param schema Schema string to write
141 * \param getter Function that returns the current value of the input
142 * \param setter Function that sets the input to a new value
143 * \returns this object
144 */
146 std::string name, std::string schemaName,
147 HootSchemaType type, std::string_view schema,
148 std::function<std::span<uint8_t const>()> getter,
149 std::function<void(SignalMeasurement<std::vector<uint8_t>>)> setter
150 );
151
152#if __has_include("wpi/struct/Struct.h") || defined(_CTRE_DOCS_)
153 /**
154 * \brief Registers the WPILib Struct as a Hoot-Replayed input.
155 *
156 * \param name Name of the signal in the log
157 * \param info Optional struct type info
158 * \param getter Function that returns the current value of the input
159 * \param setter Function that sets the input to a new value
160 * \returns this object
161 */
162 template <typename T, typename... I>
163 requires wpi::StructSerializable<T, I...>
165 std::string name, I &&... info,
166 std::function<T const &()> getter,
167 std::function<void(SignalMeasurement<T>)> setter
168 ) {
169 if (utils::IsReplay()) {
170 updates.emplace_back([name=std::move(name), ... info = std::forward<I>(info), setter=std::move(setter)] {
171 auto val = HootReplay::GetStruct<T>(name, info...);
172 if (val.status.IsOK() && val.value) {
174 std::move(val.name),
175 std::move(*val.value),
176 val.timestamp,
177 std::move(val.units),
178 val.status
179 };
180 setter(std::move(v));
181 }
182 });
183 } else {
184 updates.emplace_back([name=std::move(name), ... info = std::forward<I>(info), getter=std::move(getter)] {
185 SignalLogger::WriteStruct(name, info..., getter());
186 });
187 }
188 return *this;
189 }
190
191 /**
192 * \brief Registers the array of WPILib Structs as a Hoot-Replayed input.
193 *
194 * \param name Name of the signal in the log
195 * \param info Optional struct type info
196 * \param getter Function that returns the current value of the input
197 * \param setter Function that sets the input to a new value
198 * \returns this object
199 */
200 template <typename T, typename... I>
201 requires wpi::StructSerializable<T, I...>
203 std::string name, I &&... info,
204 std::function<std::span<T const>()> getter,
205 std::function<void(SignalMeasurement<std::vector<T>>)> setter
206 ) {
207 if (utils::IsReplay()) {
208 updates.emplace_back([name=std::move(name), ... info = std::forward<I>(info), setter=std::move(setter)] {
209 auto val = HootReplay::GetStructArray<T>(name, info...);
210 if (val.status.IsOK() && val.value) {
212 std::move(val.name),
213 std::move(*val.value),
214 val.timestamp,
215 std::move(val.units),
216 val.status
217 };
218 setter(std::move(v));
219 }
220 });
221 } else {
222 updates.emplace_back([name=std::move(name), ... info = std::forward<I>(info), getter=std::move(getter)] {
223 SignalLogger::WriteStructArray(name, info..., getter());
224 });
225 }
226 return *this;
227 }
228#endif
229
230#if __has_include("wpi/protobuf/Protobuf.h") || defined(_CTRE_DOCS_)
231 /**
232 * \brief Registers the protobuf as a Hoot-Replayed input.
233 *
234 * \param name Name of the signal in the log
235 * \param getter Function that returns the current value of the input
236 * \param setter Function that sets the input to a new value
237 * \returns this object
238 */
239 template <wpi::ProtobufSerializable T>
241 std::string name,
242 std::function<T const &()> getter,
243 std::function<void(SignalMeasurement<T>)> setter
244 ) {
245 if (utils::IsReplay()) {
246 updates.emplace_back([name=std::move(name), setter=std::move(setter)] {
247 auto val = HootReplay::GetProtobuf<T>(name);
248 if (val.status.IsOK() && val.value) {
250 std::move(val.name),
251 std::move(*val.value),
252 val.timestamp,
253 std::move(val.units),
254 val.status
255 };
256 setter(std::move(v));
257 }
258 });
259 } else {
260 updates.emplace_back([name=std::move(name), getter=std::move(getter)] {
261 SignalLogger::WriteProtobuf(name, getter());
262 });
263 }
264 return *this;
265 }
266#endif
267
268 /**
269 * \brief Registers the raw data bytes as a Hoot-Replayed input.
270 *
271 * \param name Name of the signal in the log
272 * \param getter Function that returns the current value of the input
273 * \param setter Function that sets the input to a new value
274 * \returns this object
275 */
277 std::string name,
278 std::function<std::span<uint8_t const>()> getter,
279 std::function<void(SignalMeasurement<std::vector<uint8_t>>)> setter
280 );
281
282 /**
283 * \brief Registers the boolean as a Hoot-Replayed input.
284 *
285 * \param name Name of the signal in the log
286 * \param getter Function that returns the current value of the input
287 * \param setter Function that sets the input to a new value
288 * \returns this object
289 */
291 std::string name,
292 std::function<bool()> getter,
293 std::function<void(SignalMeasurement<bool>)> setter
294 );
295
296 /**
297 * \brief Registers the integer as a Hoot-Replayed input.
298 *
299 * \param name Name of the signal in the log
300 * \param getter Function that returns the current value of the input
301 * \param setter Function that sets the input to a new value
302 * \returns this object
303 */
305 std::string name,
306 std::function<int64_t()> getter,
307 std::function<void(SignalMeasurement<int64_t>)> setter
308 );
309
310 /**
311 * \brief Registers the float as a Hoot-Replayed input.
312 *
313 * \param name Name of the signal in the log
314 * \param getter Function that returns the current value of the input
315 * \param setter Function that sets the input to a new value
316 * \returns this object
317 */
319 std::string name,
320 std::function<float()> getter,
321 std::function<void(SignalMeasurement<float>)> setter
322 );
323
324 /**
325 * \brief Registers the double as a Hoot-Replayed input.
326 *
327 * \param name Name of the signal in the log
328 * \param getter Function that returns the current value of the input
329 * \param setter Function that sets the input to a new value
330 * \returns this object
331 */
333 std::string name,
334 std::function<double()> getter,
335 std::function<void(SignalMeasurement<double>)> setter
336 );
337
338 /**
339 * \brief Registers the string as a Hoot-Replayed input.
340 *
341 * \param name Name of the signal in the log
342 * \param getter Function that returns the current value of the input
343 * \param setter Function that sets the input to a new value
344 * \returns this object
345 */
347 std::string name,
348 std::function<std::string_view()> getter,
349 std::function<void(SignalMeasurement<std::string>)> setter
350 );
351
352 /**
353 * \brief Registers the unit value as a Hoot-Replayed input.
354 *
355 * \param name Name of the signal in the log
356 * \param getter Function that returns the current value of the input
357 * \param setter Function that sets the input to a new value
358 * \returns this object
359 */
360 template <typename U>
361 requires units::traits::is_unit_t_v<U>
363 std::string name,
364 std::function<U()> getter,
365 std::function<void(SignalMeasurement<U>)> setter
366 ) {
367 if (utils::IsReplay()) {
368 updates.emplace_back([name=std::move(name), setter=std::move(setter)] {
369 auto val = HootReplay::GetValue<U>(name);
370 if (val.status.IsOK()) {
371 setter(std::move(val));
372 }
373 });
374 } else {
375 updates.emplace_back([name=std::move(name), getter=std::move(getter)] {
376 SignalLogger::WriteValue(name, getter());
377 });
378 }
379 return *this;
380 }
381
382 /**
383 * \brief Registers the array of booleans as a Hoot-Replayed input.
384 *
385 * \param name Name of the signal in the log
386 * \param getter Function that returns the current value of the input
387 * \param setter Function that sets the input to a new value
388 * \returns this object
389 */
391 std::string name,
392 std::function<std::span<bool const>()> getter,
393 std::function<void(SignalMeasurement<std::vector<uint8_t>>)> setter
394 );
395
396 /**
397 * \brief Registers the array of booleans as a Hoot-Replayed input.
398 *
399 * \param name Name of the signal in the log
400 * \param getter Function that returns the current value of the input
401 * \param setter Function that sets the input to a new value
402 * \returns this object
403 */
405 std::string name,
406 std::function<std::span<uint8_t const>()> getter,
407 std::function<void(SignalMeasurement<std::vector<uint8_t>>)> setter
408 );
409
410 /**
411 * \brief Registers the array of integers as a Hoot-Replayed input.
412 *
413 * \param name Name of the signal in the log
414 * \param getter Function that returns the current value of the input
415 * \param setter Function that sets the input to a new value
416 * \returns this object
417 */
419 std::string name,
420 std::function<std::span<int64_t const>()> getter,
421 std::function<void(SignalMeasurement<std::vector<int64_t>>)> setter
422 );
423
424 /**
425 * \brief Registers the array of floats as a Hoot-Replayed input.
426 *
427 * \param name Name of the signal in the log
428 * \param getter Function that returns the current value of the input
429 * \param setter Function that sets the input to a new value
430 * \returns this object
431 */
433 std::string name,
434 std::function<std::span<float const>()> getter,
435 std::function<void(SignalMeasurement<std::vector<float>>)> setter
436 );
437
438 /**
439 * \brief Registers the array of doubles as a Hoot-Replayed input.
440 *
441 * \param name Name of the signal in the log
442 * \param getter Function that returns the current value of the input
443 * \param setter Function that sets the input to a new value
444 * \returns this object
445 */
447 std::string name,
448 std::function<std::span<double const>()> getter,
449 std::function<void(SignalMeasurement<std::vector<double>>)> setter
450 );
451
452 /**
453 * \brief Registers the array of strings as a Hoot-Replayed input.
454 *
455 * \param name Name of the signal in the log
456 * \param getter Function that returns the current value of the input
457 * \param setter Function that sets the input to a new value
458 * \returns this object
459 */
461 std::string name,
462 std::function<std::span<std::string_view const>()> getter,
463 std::function<void(SignalMeasurement<std::vector<std::string>>)> setter
464 );
465
466 /**
467 * \brief Registers the array of strings as a Hoot-Replayed input.
468 *
469 * \param name Name of the signal in the log
470 * \param getter Function that returns the current value of the input
471 * \param setter Function that sets the input to a new value
472 * \returns this object
473 */
475 std::string name,
476 std::function<std::span<std::string const>()> getter,
477 std::function<void(SignalMeasurement<std::vector<std::string>>)> setter
478 );
479};
480
481}
482}
Class for handling automatic logging and replay of custom signal inputs.
Definition HootAutoReplay.hpp:63
HootAutoReplay & WithFloatArray(std::string name, std::function< std::span< float const >()> getter, std::function< void(SignalMeasurement< std::vector< float > >)> setter)
Registers the array of floats as a Hoot-Replayed input.
HootAutoReplay & WithStructArray(std::string name, I &&... info, std::function< std::span< T const >()> getter, std::function< void(SignalMeasurement< std::vector< T > >)> setter)
Registers the array of WPILib Structs as a Hoot-Replayed input.
Definition HootAutoReplay.hpp:202
HootAutoReplay & WithBooleanArray(std::string name, std::function< std::span< uint8_t const >()> getter, std::function< void(SignalMeasurement< std::vector< uint8_t > >)> setter)
Registers the array of booleans as a Hoot-Replayed input.
HootAutoReplay & WithRaw(std::string name, std::function< std::span< uint8_t const >()> getter, std::function< void(SignalMeasurement< std::vector< uint8_t > >)> setter)
Registers the raw data bytes as a Hoot-Replayed input.
HootAutoReplay & WithSchemaValue(std::string name, std::string schemaName, HootSchemaType type, std::string_view schema, std::function< std::span< uint8_t const >()> getter, std::function< void(SignalMeasurement< std::vector< uint8_t > >)> setter)
Registers the schema-serialized bytes as a Hoot-Replayed input.
HootAutoReplay & WithTimestampReplay()
Registers Timer::GetTimestamp() logging and playback with this instance.
HootAutoReplay & WithDoubleArray(std::string name, std::function< std::span< double const >()> getter, std::function< void(SignalMeasurement< std::vector< double > >)> setter)
Registers the array of doubles as a Hoot-Replayed input.
HootAutoReplay & WithStringArray(std::string name, std::function< std::span< std::string const >()> getter, std::function< void(SignalMeasurement< std::vector< std::string > >)> setter)
Registers the array of strings as a Hoot-Replayed input.
HootAutoReplay & WithIntegerArray(std::string name, std::function< std::span< int64_t const >()> getter, std::function< void(SignalMeasurement< std::vector< int64_t > >)> setter)
Registers the array of integers as a Hoot-Replayed input.
HootAutoReplay & WithStringArray(std::string name, std::function< std::span< std::string_view const >()> getter, std::function< void(SignalMeasurement< std::vector< std::string > >)> setter)
Registers the array of strings as a Hoot-Replayed input.
HootAutoReplay & WithValue(std::string name, std::function< U()> getter, std::function< void(SignalMeasurement< U >)> setter)
Registers the unit value as a Hoot-Replayed input.
Definition HootAutoReplay.hpp:362
HootAutoReplay & WithBooleanArray(std::string name, std::function< std::span< bool const >()> getter, std::function< void(SignalMeasurement< std::vector< uint8_t > >)> setter)
Registers the array of booleans as a Hoot-Replayed input.
HootAutoReplay & WithInteger(std::string name, std::function< int64_t()> getter, std::function< void(SignalMeasurement< int64_t >)> setter)
Registers the integer as a Hoot-Replayed input.
HootAutoReplay & WithJoystickReplay()
Registers joystick logging and playback with this instance.
HootAutoReplay & WithBoolean(std::string name, std::function< bool()> getter, std::function< void(SignalMeasurement< bool >)> setter)
Registers the boolean as a Hoot-Replayed input.
HootAutoReplay & WithStruct(std::string name, I &&... info, std::function< T const &()> getter, std::function< void(SignalMeasurement< T >)> setter)
Registers the WPILib Struct as a Hoot-Replayed input.
Definition HootAutoReplay.hpp:164
HootAutoReplay & WithDouble(std::string name, std::function< double()> getter, std::function< void(SignalMeasurement< double >)> setter)
Registers the double as a Hoot-Replayed input.
HootAutoReplay & WithString(std::string name, std::function< std::string_view()> getter, std::function< void(SignalMeasurement< std::string >)> setter)
Registers the string as a Hoot-Replayed input.
void Update() const
Updates the state of the robot program by doing one of the following:
Definition HootAutoReplay.hpp:80
HootAutoReplay & WithProtobuf(std::string name, std::function< T const &()> getter, std::function< void(SignalMeasurement< T >)> setter)
Registers the protobuf as a Hoot-Replayed input.
Definition HootAutoReplay.hpp:240
HootAutoReplay & WithSchemaValue(std::string name, std::string schemaName, HootSchemaType type, std::span< uint8_t const > schema, std::function< std::span< uint8_t const >()> getter, std::function< void(SignalMeasurement< std::vector< uint8_t > >)> setter)
Registers the schema-serialized bytes as a Hoot-Replayed input.
HootAutoReplay & WithFloat(std::string name, std::function< float()> getter, std::function< void(SignalMeasurement< float >)> setter)
Registers the float as a Hoot-Replayed input.
static SignalMeasurement< std::optional< std::vector< T > > > GetStructArray(std::string_view name, I const &... info)
Gets a WPILib Struct array user signal.
Definition HootReplay.hpp:242
static SignalMeasurement< std::optional< T > > GetStruct(std::string_view name, I const &... info)
Gets a WPILib Struct user signal.
Definition HootReplay.hpp:209
static SignalMeasurement< U > GetValue(std::string_view name)
Gets a unit value user signal.
Definition HootReplay.hpp:360
static SignalMeasurement< std::optional< T > > GetProtobuf(std::string_view name)
Gets a Protobuf user signal.
Definition HootReplay.hpp:286
static ctre::phoenix::StatusCode WriteValue(std::string_view name, U value, units::time::second_t latencySeconds=0_s)
Writes the unit value to the log file.
Definition SignalLogger.hpp:398
static ctre::phoenix::StatusCode WriteStructArray(std::string_view name, std::span< T const > values, I const &... info, units::time::second_t latencySeconds=0_s)
Writes the array of WPILib Structs to the log file.
Definition SignalLogger.hpp:233
static ctre::phoenix::StatusCode WriteStruct(std::string_view name, T const &value, I const &... info, units::time::second_t latencySeconds=0_s)
Writes the WPILib Struct to the log file.
Definition SignalLogger.hpp:194
static ctre::phoenix::StatusCode WriteProtobuf(std::string_view name, T const &value, units::time::second_t latencySeconds=0_s)
Writes the protobuf to the log file.
Definition SignalLogger.hpp:278
CTREXPORT bool IsReplay()
Get whether the program is running in replay mode.
HootSchemaType
Supported schema types for a hoot user signal.
Definition HootSchemaType.hpp:15
Definition motor_constants.h:14
Information from a single measurement of a status signal.
Definition SignalMeasurement.hpp:20