CTRE Phoenix 6 C++ 25.1.0
Loading...
Searching...
No Matches
HootReplay.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
10#include "units/time.h"
11#include <string>
12#include <vector>
13
14namespace ctre {
15namespace phoenix6 {
16
17/**
18 * \brief Static class for controlling Phoenix 6 hoot log replay.
19 *
20 * This replays all signals in the given hoot log in simulation. Hoot logs can
21 * be created by a robot program using SignalLogger. Only one hoot log,
22 * corresponding to one CAN bus, may be replayed at a time.
23 *
24 * During replay, all transmits from the robot program are ignored. This includes
25 * features such as control requests, configs, and setting signal update frequency.
26 * Additionally, Tuner X is not functional during log replay.
27 *
28 * To use Hoot Replay, call LoadFile(char const *) before any devices are constructed
29 * to load a hoot file and start replay. Alternatively, the CANBus(std::string_view, char const *)
30 * constructor can be used when constructing devices.
31 *
32 * After devices are constructed, Hoot Replay can be controlled using Play(), Pause(), Stop(),
33 * and Restart(). Additionally, Hoot Replay supports StepTiming(units::second_t) while paused.
34 * The current file can be closed using CloseFile(), after which a new file may be loaded.
35 */
37public:
38 /**
39 * \brief Loads the given file and starts signal log replay. Only one
40 * hoot log, corresponding to one CAN bus, may be replayed at a time.
41 *
42 * This must be called before constructing any devices or checking
43 * CAN bus status. The CANBus(std::string_view, char const *)
44 * constructor can be used when constructing devices to guarantee
45 * that this API is called first.
46 *
47 * When using relative paths, the file path is typically relative
48 * to the top-level folder of the robot project.
49 *
50 * This API is blocking on the file read.
51 *
52 * \param filepath Path and name of the hoot file to load
53 * \returns Status of opening and reading the file for replay
54 * \throws std::invalid_argument - The file is invalid, unlicensed, or
55 * targets a different version of Phoenix 6
56 */
57 static ctre::phoenix::StatusCode LoadFile(char const *filepath);
58 /**
59 * \brief Ends the hoot log replay. This stops the replay if it is running,
60 * closes the hoot log, and clears all signals read from the file.
61 */
62 static void CloseFile();
63 /**
64 * \brief Gets whether a valid hoot log file is currently loaded.
65 *
66 * \returns true if a valid hoot log file is loaded
67 */
68 static bool IsFileLoaded();
69
70 /**
71 * \brief Starts or resumes the hoot log replay.
72 *
73 * \returns Status of starting or resuming replay
74 */
76 /**
77 * \brief Pauses the hoot log replay. This maintains the current position
78 * in the log replay so it can be resumed later.
79 *
80 * \returns Status of pausing replay
81 */
83 /**
84 * \brief Stops the hoot log replay. This resets the current position in
85 * the log replay to the start.
86 *
87 * \returns Status of stopping replay
88 */
90 /**
91 * \brief Restarts the hoot log replay from the start of the log.
92 * This is equivalent to calling #Stop followed by #Play.
93 *
94 * \returns Status of restarting replay
95 */
97 {
98 auto retval = Stop();
99 if (retval.IsOK()) {
100 retval = Play();
101 }
102 return retval;
103 }
104
105 /**
106 * \brief Gets whether hoot log replay is actively playing.
107 *
108 * This API will return true in programs that do not support
109 * replay, making it safe to call without first checking if
110 * the program supports replay.
111 *
112 * \returns true if replay is playing back signals
113 */
114 static bool IsPlaying()
115 {
116 return WaitForPlaying(0_s);
117 }
118
119 /**
120 * \brief Waits until hoot log replay is actively playing.
121 *
122 * This API will immediately return true in programs that do
123 * not support replay, making it safe to call without first
124 * checking if the program supports replay
125 *
126 * Since this can block the calling thread, this should not
127 * be called with a non-zero timeout on the main thread.
128 *
129 * This can also be used with a timeout of 0 to perform
130 * a non-blocking check, which is equivalent to #IsPlaying.
131 *
132 * \param timeout Max time to wait for replay to start playing
133 * \returns true if replay is playing back signals
134 */
135 static bool WaitForPlaying(units::second_t timeout)
136 {
137 return WaitForPlayingImpl(timeout.value());
138 }
139
140 /**
141 * \brief Sets the speed of the hoot log replay. A speed of 1.0 corresponds
142 * to replaying the file in real time, and larger values increase the speed.
143 *
144 * - Minimum Value: 0.01
145 * - Maximum Value: 100.0
146 * - Default Value: 1.0
147 *
148 * \param speed Speed of the hoot log replay
149 */
150 static void SetSpeed(double speed);
151 /**
152 * \brief Advances the hoot log replay time by the given value. Replay must
153 * be paused or stopped before advancing its time.
154 *
155 * \param stepTimeSeconds The amount of time to advance
156 * \returns Status of advancing the replay time
157 */
158 static ctre::phoenix::StatusCode StepTiming(units::time::second_t stepTimeSeconds)
159 {
160 return StepTimingImpl(stepTimeSeconds.value());
161 }
162
163 /**
164 * \brief Stores information about a user signal from replay.
165 */
166 template <typename T>
167 struct SignalData {
168 /**
169 * \brief The name of the signal
170 */
171 std::string_view name;
172 /**
173 * \brief The units of the signal
174 */
175 std::string units;
176 /**
177 * \brief The timestamp of the signal
178 */
179 units::second_t timestamp;
180 /**
181 * \brief Status code response of getting the signal
182 */
184 /**
185 * \brief The value of the signal
186 */
188 };
189
190 /**
191 * \brief Gets a raw-bytes user signal.
192 *
193 * \param name Name of the signal
194 * \returns Structure with all information about the signal
195 */
196 static SignalData<std::vector<uint8_t>> GetRaw(std::string_view name)
197 {
198 return GetRawImpl(name).ToSignalData();
199 }
200 /**
201 * \brief Gets a boolean user signal.
202 *
203 * \param name Name of the signal
204 * \returns Structure with all information about the signal
205 */
206 static SignalData<bool> GetBoolean(std::string_view name)
207 {
208 return GetBooleanImpl(name).ToSignalData();
209 }
210 /**
211 * \brief Gets an integer user signal.
212 *
213 * \param name Name of the signal
214 * \returns Structure with all information about the signal
215 */
216 static SignalData<int64_t> GetInteger(std::string_view name)
217 {
218 return GetIntegerImpl(name).ToSignalData();
219 }
220 /**
221 * \brief Gets a float user signal.
222 *
223 * \param name Name of the signal
224 * \returns Structure with all information about the signal
225 */
226 static SignalData<float> GetFloat(std::string_view name)
227 {
228 return GetFloatImpl(name).ToSignalData();
229 }
230 /**
231 * \brief Gets a double user signal.
232 *
233 * \param name Name of the signal
234 * \returns Structure with all information about the signal
235 */
236 static SignalData<double> GetDouble(std::string_view name)
237 {
238 return GetDoubleImpl(name).ToSignalData();
239 }
240
241 /**
242 * \brief Gets a unit value user signal.
243 *
244 * \param name Name of the signal
245 * \returns Structure with all information about the signal
246 */
247 template <typename U, typename = std::enable_if_t<units::traits::is_unit_t_v<U>>>
248 static SignalData<U> GetValue(std::string_view name)
249 {
250 SignalData<double> doubleSig = GetDouble(name);
251 return {
252 doubleSig.name,
253 std::move(doubleSig.units),
254 doubleSig.timestamp,
255 doubleSig.status,
256 U{doubleSig.value}
257 };
258 }
259
260 /**
261 * \brief Gets a string user signal.
262 *
263 * \param name Name of the signal
264 * \returns Structure with all information about the signal
265 */
266 static SignalData<std::string> GetString(std::string_view name)
267 {
268 return GetStringImpl(name).ToSignalData();
269 }
270 /**
271 * \brief Get a boolean array user signal.
272 *
273 * \param name Name of the signal
274 * \returns Structure with all information about the signal
275 */
277 {
278 return GetBooleanArrayImpl(name).ToSignalData();
279 }
280 /**
281 * \brief Get an integer array user signal.
282 *
283 * \param name Name of the signal
284 * \returns Structure with all information about the signal
285 */
287 {
288 return GetIntegerArrayImpl(name).ToSignalData();
289 }
290 /**
291 * \brief Get a float array user signal.
292 *
293 * \param name Name of the signal
294 * \returns Structure with all information about the signal
295 */
296 static SignalData<std::vector<float>> GetFloatArray(std::string_view name)
297 {
298 return GetFloatArrayImpl(name).ToSignalData();
299 }
300 /**
301 * \brief Get a double array user signal.
302 *
303 * \param name Name of the signal
304 * \returns Structure with all information about the signal
305 */
306 static SignalData<std::vector<double>> GetDoubleArray(std::string_view name)
307 {
308 return GetDoubleArrayImpl(name).ToSignalData();
309 }
310
311private:
312 static bool WaitForPlayingImpl(double timeoutSeconds);
313 static ctre::phoenix::StatusCode StepTimingImpl(double stepTimeSeconds);
314
315 template <typename T>
316 struct UnitlessSignalData {
317 std::string_view name;
318 std::string units;
319 double timestampSec;
321 T value;
322
323 SignalData<T> ToSignalData() &&
324 {
325 return {
326 name,
327 std::move(units),
328 units::second_t{timestampSec},
329 status,
330 std::move(value)
331 };
332 }
333 };
334
335 static UnitlessSignalData<std::vector<uint8_t>> GetRawImpl(std::string_view name);
336 static UnitlessSignalData<bool> GetBooleanImpl(std::string_view name);
337 static UnitlessSignalData<int64_t> GetIntegerImpl(std::string_view name);
338 static UnitlessSignalData<float> GetFloatImpl(std::string_view name);
339 static UnitlessSignalData<double> GetDoubleImpl(std::string_view name);
340 static UnitlessSignalData<std::string> GetStringImpl(std::string_view name);
341 static UnitlessSignalData<std::vector<uint8_t>> GetBooleanArrayImpl(std::string_view name);
342 static UnitlessSignalData<std::vector<int64_t>> GetIntegerArrayImpl(std::string_view name);
343 static UnitlessSignalData<std::vector<float>> GetFloatArrayImpl(std::string_view name);
344 static UnitlessSignalData<std::vector<double>> GetDoubleArrayImpl(std::string_view name);
345};
346
347}
348}
Static class for controlling Phoenix 6 hoot log replay.
Definition HootReplay.hpp:36
static ctre::phoenix::StatusCode Play()
Starts or resumes the hoot log replay.
static SignalData< float > GetFloat(std::string_view name)
Gets a float user signal.
Definition HootReplay.hpp:226
static SignalData< std::string > GetString(std::string_view name)
Gets a string user signal.
Definition HootReplay.hpp:266
static ctre::phoenix::StatusCode Stop()
Stops the hoot log replay.
static SignalData< std::vector< uint8_t > > GetRaw(std::string_view name)
Gets a raw-bytes user signal.
Definition HootReplay.hpp:196
static bool IsFileLoaded()
Gets whether a valid hoot log file is currently loaded.
static void CloseFile()
Ends the hoot log replay.
static void SetSpeed(double speed)
Sets the speed of the hoot log replay.
static bool WaitForPlaying(units::second_t timeout)
Waits until hoot log replay is actively playing.
Definition HootReplay.hpp:135
static SignalData< std::vector< double > > GetDoubleArray(std::string_view name)
Get a double array user signal.
Definition HootReplay.hpp:306
static ctre::phoenix::StatusCode StepTiming(units::time::second_t stepTimeSeconds)
Advances the hoot log replay time by the given value.
Definition HootReplay.hpp:158
static bool IsPlaying()
Gets whether hoot log replay is actively playing.
Definition HootReplay.hpp:114
static SignalData< std::vector< uint8_t > > GetBooleanArray(std::string_view name)
Get a boolean array user signal.
Definition HootReplay.hpp:276
static SignalData< std::vector< float > > GetFloatArray(std::string_view name)
Get a float array user signal.
Definition HootReplay.hpp:296
static ctre::phoenix::StatusCode LoadFile(char const *filepath)
Loads the given file and starts signal log replay.
static SignalData< bool > GetBoolean(std::string_view name)
Gets a boolean user signal.
Definition HootReplay.hpp:206
static SignalData< int64_t > GetInteger(std::string_view name)
Gets an integer user signal.
Definition HootReplay.hpp:216
static SignalData< double > GetDouble(std::string_view name)
Gets a double user signal.
Definition HootReplay.hpp:236
static SignalData< std::vector< int64_t > > GetIntegerArray(std::string_view name)
Get an integer array user signal.
Definition HootReplay.hpp:286
static SignalData< U > GetValue(std::string_view name)
Gets a unit value user signal.
Definition HootReplay.hpp:248
static ctre::phoenix::StatusCode Restart()
Restarts the hoot log replay from the start of the log.
Definition HootReplay.hpp:96
static ctre::phoenix::StatusCode Pause()
Pauses the hoot log replay.
Status codes reported by APIs, including OK, warnings, and errors.
Definition StatusCodes.h:27
Definition MotionMagicExpoTorqueCurrentFOC.hpp:18
Stores information about a user signal from replay.
Definition HootReplay.hpp:167
ctre::phoenix::StatusCode status
Status code response of getting the signal.
Definition HootReplay.hpp:183
std::string_view name
The name of the signal.
Definition HootReplay.hpp:171
std::string units
The units of the signal.
Definition HootReplay.hpp:175
units::second_t timestamp
The timestamp of the signal.
Definition HootReplay.hpp:179
T value
The value of the signal.
Definition HootReplay.hpp:187