Fixposition SDK 0.0.0-heads/main-0-g5e3c297
Collection of c++ libraries and apps for use with Fixposition products on Linux
Loading...
Searching...
No Matches
fpl.hpp
Go to the documentation of this file.
1/**
2 * \verbatim
3 * ___ ___
4 * \ \ / /
5 * \ \/ / Copyright (c) Fixposition AG (www.fixposition.com) and contributors
6 * / /\ \ License: see the LICENSE file
7 * /__/ \__\
8 * \endverbatim
9 *
10 * @file
11 * @brief Fixposition SDK: .fpl utilities
12 *
13 * @page FPSDK_COMMON_FPL .fpl utilities
14 *
15 * **API**: fpsdk_common/fpl.hpp and fpsdk::common::fpl
16 *
17 */
18#ifndef __FPSDK_COMMON_FPL_HPP__
19#define __FPSDK_COMMON_FPL_HPP__
20
21/* LIBC/STL */
22#include <cstdint>
23#include <iostream>
24#include <memory>
25#include <string>
26#include <vector>
27
28/* EXTERNAL */
29
30/* PACKAGE */
31#include "time.hpp"
32
33namespace fpsdk {
34namespace common {
35/**
36 * @brief .fpl utilities
37 */
38namespace fpl {
39/* ****************************************************************************************************************** */
40
41/**
42 * @brief FplMessage types
43 */
44enum class FplType : uint16_t
45{ // clang-format off
46 UNSPECIFIED = 0x0000, //!< Invalid
47 ROSMSGDEF = 0x0101, //!< Message definition for a topic (a.k.a. "connection header" in rosbag speak)
48 ROSMSGBIN = 0x0102, //!< Serialised ROS message with timestamp
49 LOGMETA = 0x0105, //!< Logfile meta data
50 STREAMMSG = 0x0106, //!< Stream message raw data with timestamp
51 LOGSTATUS = 0x0107, //!< Logging status
52 FILEDUMP = 0x0108, //!< Dump of an entire (small) file
53 BLOB = 0xbaad, //!< Arbitrary data, not FplMessage framing
54 INT_D = 0xffaa, //!< Fixposition internal use only
55 INT_F = 0xffbb, //!< Fixposition internal use only
56 INT_X = 0xffcc, //!< Fixposition internal use only
57}; // clang-format on
58
59/**
60 * @brief Stringify type
61 *
62 * @param[in] type The type
63 *
64 * @returns a unique string identifying the type
65 */
66const char* FplTypeStr(const FplType type);
67
68// ---------------------------------------------------------------------------------------------------------------------
69
70/**
71 * @brief One message in the log
72 */
73class FplMessage
74{
75 public:
76 FplMessage();
77
78 /**
79 * @brief Parse message from buffer
80 *
81 * @param[in] data Pointer to start of message data
82 * @param[in] size Size of message data
83 *
84 * @returns 0 if the data is not a valid message,
85 * -1 if the size is too small to decide, or
86 * the message size (>0) if a valid message was found and loaded
87 */
88 int Parse(const uint8_t* data, const uint32_t size);
89
90 /**
91 * @brief Get message
92 *
93 * @returns a reference to the message data
94 */
95 const std::vector<uint8_t>& Raw() const;
96 /**
97 * @brief Get message data
98 *
99 * @returns a pointer to the message data (size = Size())
100 */
101 const uint8_t* RawData() const;
102
103 /**
104 * @brief Get message size
105 *
106 * @returns the size of the message (data = Data())
107 */
108 uint32_t RawSize() const;
109
110 /**
111 * @brief Get payload (log) type
112 *
113 * @returns type of the payload
114 */
116
117 /**
118 * @brief Get payload data
119 *
120 * @returns a pointer to the payload data
121 */
122 const uint8_t* PayloadData() const;
123
124 /**
125 * @brief Get payload size
126 *
127 * @returns size of the payload data
128 */
129 uint32_t PayloadSize() const;
130
131 // Debugging stuff, only with FplParser. For debugging.
132 uint64_t file_pos_; //!< Offset in logfile of the log message
133 uint64_t file_size_; //!< Size in the logfile of the log message
134 uint64_t file_seq_; //!< Message sequence counter in logfile
135
136 static constexpr std::uint32_t MAX_SIZE = 2000000; //!< Maximum message size
137 static constexpr std::size_t MAX_NAME_LEN = 100; //!< Maximum length of (file, topic, ...) names
138
139 /**
140 * @brief Make message a BLOB
141 *
142 * @param[in] data The data
143 * @param[in] size The size of the data
144 */
145 void SetBlob(const uint8_t* data, const uint32_t size);
146
147 private:
148 static constexpr uint16_t MAGIC = 0x55aa; //!< Start of message marker
149 static constexpr uint32_t HEADER_SIZE = 8; //!< Message header size
150 FplType payload_type_; //!< Payload type
151 uint32_t payload_size_; //!< Payload size
152 std::vector<uint8_t> message_; //!< Entire message
153};
154
155// ---------------------------------------------------------------------------------------------------------------------
156
157/**
158 * @brief Logfile parser
159 */
160class FplParser
161{
162 public:
163 FplParser();
164
165 /**
166 * @brief Add data to parser
167 *
168 * @param[in] data Pointer to data, can be NULL, in which case \c size is ignored
169 * @param[in] size Size of data, can be <= 0, in which case \c data is ignored
170 *
171 * The suggested chunk size to add to the parser is FplMessage::MAX_SIZE
172 *
173 * @returns true if data was added to the parser, false if there was not enough space left (parser overflow)
174 */
175 bool Add(const uint8_t* data, const std::size_t size);
176
177 /**
178 * @brief Reset parser
179 *
180 * Resets the parser state and discards all collected data.
181 */
182 void Reset();
183
184 /**
185 * @brief Process data in parser, return message
186 *
187 * @param[out] log_msg The detected message
188 *
189 * @returns true if a message was detected, false otherwise (meaning: not enough data in parser). Note that also in
190 * the false case the \c log_msg may be modified.
191 */
192 bool Process(FplMessage& log_msg);
193
194 private:
195 std::vector<uint8_t> buf_; //!< Working buffer
196 std::size_t offs_; //!< Current offset into buf_
197 std::size_t size_; //!< Current size of useful data in buf_ (counted from offs_)
198 std::size_t file_pos_; //!< Offset into "file", i.e. total number of bytes processed so far
199 std::size_t file_seq_; //!< Count of messages from "file"
200 void EmitBlob(FplMessage& log_msg); //!< Helper for Process()
201};
202
203// ---------------------------------------------------------------------------------------------------------------------
204
205/**
206 * @brief Read log messages from logfile
207 */
208class FplFileReader
209{
210 public:
211 FplFileReader();
212
213 /**
214 * @brief Open logfile
215 *
216 * @param[in] path The logfile
217 *
218 * @returns true on success, false otherwise
219 */
220 bool Open(const std::string& path);
221
222 /**
223 * @brief Get next log message
224 *
225 * @param[out] log_msg The log message
226 *
227 * @returns true if a next log message was found, false at end of file (or other problems)
228 */
229 bool Next(FplMessage& log_msg);
230
231 /**
232 * @brief Get progress report
233 *
234 * @param[out] progress Progress in [%] (approximate with gzipped files)
235 * @param[out] rate Rate in [MiB/s]
236 *
237 * @returns true if is a good time to print the progress report, false otherwise
238 */
239 bool GetProgress(double& progress, double& rate);
240
241 private:
242 std::string path_; //!< Logfile path
243 std::unique_ptr<std::istream> fh_; //!< File handle
244 FplParser parser_; //!< Parser
245 std::vector<uint8_t> buf_; //!< Read buffer
246 std::size_t pos_; //!< Current position in logfile
247 std::size_t count_; //!< Number of messages
248 std::size_t size_; //!< Size of logfile
249 bool is_gz_; //!< File is gzipped
250 double last_progress_; //!< GetProgress() state
251 uint64_t last_pos_; //!< GetProgress() state
252 double last_secs_; //!< GetProgress() state
253};
254
255// ---------------------------------------------------------------------------------------------------------------------
256
257/**
258 * @brief Helper for extracting meta data
259 */
261{
262 LogMeta() = default; //!< Default ctor
263
264 /**
265 * @brief Constructor
266 *
267 * @param[in] log_msg .fpl log message
268 */
269 LogMeta(const FplMessage& log_msg);
270 bool valid_ = false; //!< Data valid, successfully extracted from message
271 std::string info_; //!< Stringification of (some of the) data, for debugging
272 std::string hw_uid_; //!< Hardware UID
273 std::string product_model_; //!< Product model
274 std::string sw_version_; //!< Software version
275 uint32_t log_start_time_posix_ = 0; //!< Start time of logging
276 std::string log_start_time_iso_; //!< Start time of logging
277 std::string log_profile_; //!< Logging configuration profile name
278 std::string log_target_; //!< Loging target name
279 std::string log_filename_; //!< Logfile name
280 std::string yaml_; //!< Raw meta data YAML
281};
282
283// ---------------------------------------------------------------------------------------------------------------------
284
285/**
286 * @brief Helper for extracting recording status data
287 */
289{
290 LogStatus() = default; //!< Default ctor
291
292 /**
293 * @brief Constructor
294 *
295 * @param[in] log_msg .fpl log message
296 */
297 LogStatus(const FplMessage& log_msg);
298 bool valid_; //!< Data valid, successfully extracted from message
299
300 // Version 1 and later
301 std::string info_; //!< Stringification of (some of the) data, for debugging
302 std::string state_; //!< Logging state: "stopped", "logging", "stopping"
303 uint32_t queue_size_ = 0; //!< Queue size
304 uint32_t queue_peak_ = 0; //!< Queue peak size
305 uint32_t queue_skip_ = 0; //!< Number of skipped messages (queue full)
306 uint32_t queue_bsize_ = 0; //!< Output queue size [bytes]
307 uint32_t queue_bpeak_ = 0; //!< Output queue peak size [bytes]
308
309 uint32_t log_count_ = 0; //!< Number of logged messages
310 uint32_t log_errors_ = 0; //!< Number of messages failed to log (failed to write/send)
311 uint64_t log_size_ = 0; //!< Total size of logged messages [bytes]
312 uint32_t log_duration_ = 0; //!< Duration of logging [s]
313
314 // Version 2 and later
315 uint32_t log_time_posix_ = 0; //!< Approximate time
316 std::string log_time_iso_; //!< Approximate time
317 int8_t pos_source_ = 0; //!< Approximate sensor position source (see POS_SOURCE_... below)
318 int8_t pos_fix_type_ = 0; //!< Approximate sensor position fix type (see fpsdk::common::gnss::FixType)
319 double pos_lat_ = 0.0; //!< Approximate sensor position latitude [deg]
320 double pos_lon_ = 0.0; //!< Approximate sensor position longitude [deg]
321 double pos_height_ = 0.0; //!< Approximate sensor position height [m]
322
323 static constexpr int8_t POS_SOURCE_UNKNOWN = 0; //!< Position source unknown resp. not available
324 static constexpr int8_t POS_SOURCE_GNSS = 1; //!< Position source is GNSS
325 static constexpr int8_t POS_SOURCE_FUSION = 2; //!< Position source is Fusion
326
327 std::string yaml_; //!< Raw status data YAML
328};
329
330// ---------------------------------------------------------------------------------------------------------------------
331
332/**
333 * @brief Helper for extracting ROS message definition (the relevant fields from the "connection header")
334 */
336{
337 RosMsgDef() = default; //!< Default ctor
338
339 /**
340 * @brief Constructor
341 *
342 * @param[in] log_msg .fpl log message
343 */
344 RosMsgDef(const FplMessage& log_msg);
345 bool valid_ = false; //!< Data valid, successfully extracted from message
346 std::string info_; //!< Stringification of (some of the) data, for debugging
347 std::string topic_name_; //!< The topic name
348 std::string msg_name_; //!< The message name (a.k.a. data type)
349 std::string msg_md5_; //!< The message definition MD5 sum
350 std::string msg_def_; //!< The message definition (the .msg file and also the defs for all the types)
351};
352
353// ---------------------------------------------------------------------------------------------------------------------
354
355/**
356 * @brief Helper for extracting a serialised ROS message
357 */
359{
360 RosMsgBin() = default; //!< Default ctor
361
362 /**
363 * @brief Constructor
364 *
365 * @param[in] log_msg .fpl log message
366 */
367 RosMsgBin(const FplMessage& log_msg);
368 bool valid_ = false; //!< Data valid, successfully extracted from message
369 std::string info_; //!< Stringification of (some of the) data, for debugging
370 std::string topic_name_; //!< The topic name
371 time::RosTime rec_time_; //!< Recording timestamp
372 std::vector<uint8_t> msg_data_; //!< Serialised ROS message data
373};
374
375// ---------------------------------------------------------------------------------------------------------------------
376
377/**
378 * @brief Helper for extracting data of a stream message (NMEA, RTCM3, etc.)
379 */
381{
382 StreamMsg() = default; //!< Default ctor
383
384 /**
385 * @brief Constructor
386 *
387 * @param[in] log_msg .fpl log message
388 */
389 StreamMsg(const FplMessage& log_msg);
390 bool valid_ = false; //!< Data valid, successfully extracted from message
391 std::string info_; //!< Stringification of (some of the) data, for debugging
392 time::RosTime rec_time_; //!< Recording timestamp
393 std::string stream_name_; //!< Stream name
394 std::vector<uint8_t> msg_data_; //!< Message data
395};
396
397// ---------------------------------------------------------------------------------------------------------------------
398
399/**
400 * @brief Helper for extracting data of a stream message (NMEA, RTCM3, etc.)
401 */
403{
404 /**
405 * @brief Constructor
406 *
407 * @param[in] log_msg .fpl log message
408 */
409 FileDump(const FplMessage& log_msg);
410 bool valid_; //!< Data valid, successfully extracted from message
411 std::string info_; //!< Stringification of (some of the) data, for debugging
412 std::string filename_; //!< Filename
413 time::Time mtime_; //!< File modification time
414 std::vector<uint8_t> data_; //!< File contents
415};
416
417/* ****************************************************************************************************************** */
418} // namespace fpl
419} // namespace common
420} // namespace fpsdk
421#endif // __FPSDK_COMMON_FPL_HPP__
bool Next(FplMessage &log_msg)
Get next log message.
bool GetProgress(double &progress, double &rate)
Get progress report.
bool Open(const std::string &path)
Open logfile.
One message in the log.
Definition fpl.hpp:74
const std::vector< uint8_t > & Raw() const
Get message.
const uint8_t * RawData() const
Get message data.
int Parse(const uint8_t *data, const uint32_t size)
Parse message from buffer.
void SetBlob(const uint8_t *data, const uint32_t size)
Make message a BLOB.
uint64_t file_size_
Size in the logfile of the log message.
Definition fpl.hpp:133
static constexpr std::size_t MAX_NAME_LEN
Maximum length of (file, topic, ...) names.
Definition fpl.hpp:137
uint32_t PayloadSize() const
Get payload size.
uint64_t file_seq_
Message sequence counter in logfile.
Definition fpl.hpp:134
const uint8_t * PayloadData() const
Get payload data.
uint32_t RawSize() const
Get message size.
uint64_t file_pos_
Offset in logfile of the log message.
Definition fpl.hpp:132
FplType PayloadType() const
Get payload (log) type.
static constexpr std::uint32_t MAX_SIZE
Maximum message size.
Definition fpl.hpp:136
bool Process(FplMessage &log_msg)
Process data in parser, return message.
bool Add(const uint8_t *data, const std::size_t size)
Add data to parser.
void Reset()
Reset parser.
.fpl utilities
Definition fpl.hpp:38
FplType
FplMessage types.
Definition fpl.hpp:45
@ INT_X
Fixposition internal use only.
Definition fpl.hpp:56
@ BLOB
Arbitrary data, not FplMessage framing.
Definition fpl.hpp:53
@ LOGSTATUS
Logging status.
Definition fpl.hpp:51
@ ROSMSGBIN
Serialised ROS message with timestamp.
Definition fpl.hpp:48
@ ROSMSGDEF
Message definition for a topic (a.k.a. "connection header" in rosbag speak)
Definition fpl.hpp:47
@ LOGMETA
Logfile meta data.
Definition fpl.hpp:49
@ INT_F
Fixposition internal use only.
Definition fpl.hpp:55
@ FILEDUMP
Dump of an entire (small) file.
Definition fpl.hpp:52
@ INT_D
Fixposition internal use only.
Definition fpl.hpp:54
@ STREAMMSG
Stream message raw data with timestamp.
Definition fpl.hpp:50
const char * FplTypeStr(const FplType type)
Stringify type.
File and path utilities.
Definition path.hpp:38
Fixposition SDK: Common library.
Definition doc.hpp:21
Fixposition SDK.
time::Time mtime_
File modification time.
Definition fpl.hpp:413
std::string info_
Stringification of (some of the) data, for debugging.
Definition fpl.hpp:411
std::vector< uint8_t > data_
File contents.
Definition fpl.hpp:414
FileDump(const FplMessage &log_msg)
Constructor.
std::string filename_
Filename.
Definition fpl.hpp:412
bool valid_
Data valid, successfully extracted from message.
Definition fpl.hpp:410
uint32_t log_start_time_posix_
Start time of logging.
Definition fpl.hpp:275
LogMeta()=default
Default ctor.
std::string info_
Stringification of (some of the) data, for debugging.
Definition fpl.hpp:271
std::string yaml_
Raw meta data YAML.
Definition fpl.hpp:280
std::string log_filename_
Logfile name.
Definition fpl.hpp:279
std::string sw_version_
Software version.
Definition fpl.hpp:274
LogMeta(const FplMessage &log_msg)
Constructor.
std::string log_target_
Loging target name.
Definition fpl.hpp:278
std::string product_model_
Product model.
Definition fpl.hpp:273
std::string log_start_time_iso_
Start time of logging.
Definition fpl.hpp:276
bool valid_
Data valid, successfully extracted from message.
Definition fpl.hpp:270
std::string log_profile_
Logging configuration profile name.
Definition fpl.hpp:277
std::string hw_uid_
Hardware UID.
Definition fpl.hpp:272
static constexpr int8_t POS_SOURCE_GNSS
Position source is GNSS.
Definition fpl.hpp:324
std::string state_
Logging state: "stopped", "logging", "stopping".
Definition fpl.hpp:302
bool valid_
Data valid, successfully extracted from message.
Definition fpl.hpp:298
static constexpr int8_t POS_SOURCE_FUSION
Position source is Fusion.
Definition fpl.hpp:325
uint32_t queue_size_
Queue size.
Definition fpl.hpp:303
uint32_t log_count_
Number of logged messages.
Definition fpl.hpp:309
LogStatus()=default
Default ctor.
std::string yaml_
Raw status data YAML.
Definition fpl.hpp:327
uint32_t queue_peak_
Queue peak size.
Definition fpl.hpp:304
uint32_t queue_skip_
Number of skipped messages (queue full)
Definition fpl.hpp:305
uint32_t queue_bpeak_
Output queue peak size [bytes].
Definition fpl.hpp:307
static constexpr int8_t POS_SOURCE_UNKNOWN
Position source unknown resp. not available.
Definition fpl.hpp:323
uint32_t queue_bsize_
Output queue size [bytes].
Definition fpl.hpp:306
int8_t pos_source_
Approximate sensor position source (see POS_SOURCE_... below)
Definition fpl.hpp:317
uint32_t log_duration_
Duration of logging [s].
Definition fpl.hpp:312
uint64_t log_size_
Total size of logged messages [bytes].
Definition fpl.hpp:311
std::string info_
Stringification of (some of the) data, for debugging.
Definition fpl.hpp:301
int8_t pos_fix_type_
Approximate sensor position fix type (see fpsdk::common::gnss::FixType)
Definition fpl.hpp:318
LogStatus(const FplMessage &log_msg)
Constructor.
double pos_height_
Approximate sensor position height [m].
Definition fpl.hpp:321
uint32_t log_errors_
Number of messages failed to log (failed to write/send)
Definition fpl.hpp:310
double pos_lon_
Approximate sensor position longitude [deg].
Definition fpl.hpp:320
uint32_t log_time_posix_
Approximate time.
Definition fpl.hpp:315
std::string log_time_iso_
Approximate time.
Definition fpl.hpp:316
double pos_lat_
Approximate sensor position latitude [deg].
Definition fpl.hpp:319
std::string topic_name_
The topic name.
Definition fpl.hpp:370
std::string info_
Stringification of (some of the) data, for debugging.
Definition fpl.hpp:369
std::vector< uint8_t > msg_data_
Serialised ROS message data.
Definition fpl.hpp:372
bool valid_
Data valid, successfully extracted from message.
Definition fpl.hpp:368
RosMsgBin()=default
Default ctor.
RosMsgBin(const FplMessage &log_msg)
Constructor.
time::RosTime rec_time_
Recording timestamp.
Definition fpl.hpp:371
RosMsgDef(const FplMessage &log_msg)
Constructor.
std::string info_
Stringification of (some of the) data, for debugging.
Definition fpl.hpp:346
RosMsgDef()=default
Default ctor.
std::string msg_name_
The message name (a.k.a. data type)
Definition fpl.hpp:348
bool valid_
Data valid, successfully extracted from message.
Definition fpl.hpp:345
std::string msg_md5_
The message definition MD5 sum.
Definition fpl.hpp:349
std::string topic_name_
The topic name.
Definition fpl.hpp:347
std::string msg_def_
The message definition (the .msg file and also the defs for all the types)
Definition fpl.hpp:350
bool valid_
Data valid, successfully extracted from message.
Definition fpl.hpp:390
std::string stream_name_
Stream name.
Definition fpl.hpp:393
std::string info_
Stringification of (some of the) data, for debugging.
Definition fpl.hpp:391
StreamMsg(const FplMessage &log_msg)
Constructor.
std::vector< uint8_t > msg_data_
Message data.
Definition fpl.hpp:394
StreamMsg()=default
Default ctor.
time::RosTime rec_time_
Recording timestamp.
Definition fpl.hpp:392
Minimal ros::Time() / rplcpp::Time implementation (that doesn't throw)
Definition time.hpp:156
Fixposition SDK: Time utilities.