ulog_parser.cpp
Go to the documentation of this file.
1 #include "ulog_parser.h"
2 #include "ulog_messages.h"
3 
4 #include <string.h>
5 #include <iosfwd>
6 #include <sstream>
7 #include <iomanip>
8 #include <QDebug>
9 
10 using ios = std::ios;
11 
12 ULogParser::ULogParser(DataStream& datastream) : _file_start_time(0)
13 {
14  bool ret = readFileHeader(datastream);
15 
16  if (!ret)
17  {
18  throw std::runtime_error("ULog: wrong header");
19  }
20 
21  if (!readFileDefinitions(datastream))
22  {
23  throw std::runtime_error("ULog: error loading definitions");
24  }
25 
26  datastream.offset = _data_section_start;
27 
28  while (datastream)
29  {
30  ulog_message_header_s message_header;
31  datastream.read((char*)&message_header, ULOG_MSG_HEADER_LEN);
32 
33  _read_buffer.reserve(message_header.msg_size + 1);
34  char* message = (char*)_read_buffer.data();
35  datastream.read(message, message_header.msg_size);
36  message[message_header.msg_size] = '\0';
37 
38  switch (message_header.msg_type)
39  {
41  Subscription sub;
42 
43  sub.multi_id = *reinterpret_cast<uint8_t*>(message);
44  sub.msg_id = *reinterpret_cast<uint16_t*>(message + 1);
45  message += 3;
46  sub.message_name.assign(message, message_header.msg_size - 3);
47 
48  const auto it = _formats.find(sub.message_name);
49  if (it != _formats.end())
50  {
51  sub.format = &it->second;
52  }
53  _subscriptions.insert({ sub.msg_id, sub });
54 
55  if (sub.multi_id > 0)
56  {
58  }
59 
60  // printf("ADD_LOGGED_MSG: %d %d %s\n", sub.msg_id, sub.multi_id,
61  // sub.message_name.c_str() ); std::cout << std::endl;
62  }
63  break;
65  printf("REMOVE_LOGGED_MSG\n");
66  {
67  uint16_t msg_id = *reinterpret_cast<uint16_t*>(message);
68  _subscriptions.erase(msg_id);
69  }
70  break;
71  case (int)ULogMessageType::DATA: {
72  uint16_t msg_id = *reinterpret_cast<uint16_t*>(message);
73  message += 2;
74  auto sub_it = _subscriptions.find(msg_id);
75  if (sub_it == _subscriptions.end())
76  {
77  continue;
78  }
79  const Subscription& sub = sub_it->second;
80 
81  parseDataMessage(sub, message);
82  }
83  break;
84 
85  case (int)ULogMessageType::LOGGING: {
87  msg.level = static_cast<char>(message[0]);
88  message += sizeof(char);
89  msg.timestamp = *reinterpret_cast<uint64_t*>(message);
90  message += sizeof(uint64_t);
91  msg.msg.assign(message, message_header.msg_size - 9);
92  // printf("LOG %c (%ld): %s\n", msg.level, msg.timestamp, msg.msg.c_str() );
93  _message_logs.push_back(std::move(msg));
94  }
95  break;
96  case (int)ULogMessageType::SYNC: // printf("SYNC\n" );
97  break;
98  case (int)ULogMessageType::DROPOUT: // printf("DROPOUT\n" );
99  break;
100  case (int)ULogMessageType::INFO: // printf("INFO\n" );
101  break;
102  case (int)ULogMessageType::INFO_MULTIPLE: // printf("INFO_MULTIPLE\n" );
103  break;
104  case (int)ULogMessageType::PARAMETER_DEFAULT: // printf("PARAMETER_DEFAULT\n" );
105  break;
106  case (int)ULogMessageType::PARAMETER:
107  Parameter new_param;
108  new_param.readFromBuffer(message);
109  bool found = false;
110  for (auto& prev_param : _parameters)
111  {
112  if (prev_param.name == new_param.name)
113  {
114  prev_param = std::move(new_param);
115  found = true;
116  break;
117  }
118  }
119  if (!found)
120  {
121  _parameters.push_back(new_param);
122  }
123  break;
124  }
125  }
126 }
127 
129 {
130  size_t other_fields_count = 0;
131  std::string ts_name = sub.message_name;
132 
133  for (const auto& field : sub.format->fields)
134  {
135  if (field.type == OTHER)
136  {
137  other_fields_count++;
138  }
139  }
140 
141  if (_message_name_with_multi_id.count(ts_name) > 0)
142  {
143  char buff[16];
144  sprintf(buff, ".%02d", sub.multi_id);
145  ts_name += std::string(buff);
146  }
147 
148  // get the timeseries or create if if it doesn't exist
149  auto ts_it = _timeseries.find(ts_name);
150  if (ts_it == _timeseries.end())
151  {
152  ts_it = _timeseries.insert({ ts_name, createTimeseries(sub.format) }).first;
153  }
154  Timeseries& timeseries = ts_it->second;
155 
156  uint64_t time_val = *reinterpret_cast<uint64_t*>(message);
157  timeseries.timestamps.push_back(time_val);
158  message += sizeof(uint64_t);
159 
160  size_t index = 0;
161  parseSimpleDataMessage(timeseries, sub.format, message, &index);
162 }
163 
165  char* message, size_t* index)
166 {
167  for (const auto& field : format->fields)
168  {
169  // skip _padding messages which are one byte in size
170  if (StringView(field.field_name).starts_with("_padding"))
171  {
172  message += field.array_size;
173  continue;
174  }
175 
176  for (int array_pos = 0; array_pos < field.array_size; array_pos++)
177  {
178  double value = 0;
179  switch (field.type)
180  {
181  case UINT8: {
182  value = static_cast<double>(*reinterpret_cast<uint8_t*>(message));
183  message += 1;
184  }
185  break;
186  case INT8: {
187  value = static_cast<double>(*reinterpret_cast<int8_t*>(message));
188  message += 1;
189  }
190  break;
191  case UINT16: {
192  value = static_cast<double>(*reinterpret_cast<uint16_t*>(message));
193  message += 2;
194  }
195  break;
196  case INT16: {
197  value = static_cast<double>(*reinterpret_cast<int16_t*>(message));
198  message += 2;
199  }
200  break;
201  case UINT32: {
202  value = static_cast<double>(*reinterpret_cast<uint32_t*>(message));
203  message += 4;
204  }
205  break;
206  case INT32: {
207  value = static_cast<double>(*reinterpret_cast<int32_t*>(message));
208  message += 4;
209  }
210  break;
211  case UINT64: {
212  value = static_cast<double>(*reinterpret_cast<uint64_t*>(message));
213  message += 8;
214  }
215  break;
216  case INT64: {
217  value = static_cast<double>(*reinterpret_cast<int64_t*>(message));
218  message += 8;
219  }
220  break;
221  case FLOAT: {
222  value = static_cast<double>(*reinterpret_cast<float*>(message));
223  message += 4;
224  }
225  break;
226  case DOUBLE: {
227  value = (*reinterpret_cast<double*>(message));
228  message += 8;
229  }
230  break;
231  case CHAR: {
232  value = static_cast<double>(*reinterpret_cast<char*>(message));
233  message += 1;
234  }
235  break;
236  case BOOL: {
237  value = static_cast<double>(*reinterpret_cast<bool*>(message));
238  message += 1;
239  }
240  break;
241  case OTHER: {
242  // recursion!!!
243  auto child_format = _formats.at(field.other_type_ID);
244  message += sizeof(uint64_t); // skip timestamp
245  message = parseSimpleDataMessage(timeseries, &child_format, message, index);
246  }
247  break;
248 
249  } // end switch
250 
251  if (field.type != OTHER)
252  {
253  timeseries.data[(*index)++].second.push_back(value);
254  }
255  } // end for
256  }
257  return message;
258 }
259 
260 const std::map<std::string, ULogParser::Timeseries>& ULogParser::getTimeseriesMap() const
261 {
262  return _timeseries;
263 }
264 
265 const std::vector<ULogParser::Parameter>& ULogParser::getParameters() const
266 {
267  return _parameters;
268 }
269 
270 const std::map<std::string, std::string>& ULogParser::getInfo() const
271 {
272  return _info;
273 }
274 
275 const std::vector<ULogParser::MessageLog>& ULogParser::getLogs() const
276 {
277  return _message_logs;
278 }
279 
280 bool ULogParser::readSubscription(DataStream& datastream, uint16_t msg_size)
281 {
282  _read_buffer.reserve(msg_size + 1);
283  char* message = (char*)_read_buffer.data();
284 
285  datastream.read(message, msg_size);
286  message[msg_size] = 0;
287 
288  if (!datastream)
289  {
290  return false;
291  }
292 
293  return true;
294 }
295 
297 {
298  size_t count = 0;
299  for (const auto& field : format.fields)
300  {
301  if (field.type == OTHER)
302  {
303  // recursion!
304  count += fieldsCount(_formats.at(field.other_type_ID));
305  }
306  else
307  {
308  count += size_t(field.array_size);
309  }
310  }
311  return count;
312 }
313 
314 std::vector<StringView> ULogParser::splitString(const StringView& strToSplit,
315  char delimeter)
316 {
317  std::vector<StringView> splitted_strings;
318  splitted_strings.reserve(4);
319 
320  size_t pos = 0;
321  while (pos < strToSplit.size())
322  {
323  size_t new_pos = strToSplit.find_first_of(delimeter, pos);
324  if (new_pos == std::string::npos)
325  {
326  new_pos = strToSplit.size();
327  }
328  StringView sv = { &strToSplit.data()[pos], new_pos - pos };
329  splitted_strings.push_back(sv);
330  pos = new_pos + 1;
331  }
332  return splitted_strings;
333 }
334 
336 {
337  ulog_file_header_s msg_header;
338  datastream.read((char*)&msg_header, sizeof(msg_header));
339 
340  if (!datastream)
341  {
342  return false;
343  }
344 
345  _file_start_time = msg_header.timestamp;
346 
347  // verify it's an ULog file
348  char magic[8];
349  magic[0] = 'U';
350  magic[1] = 'L';
351  magic[2] = 'o';
352  magic[3] = 'g';
353  magic[4] = 0x01;
354  magic[5] = 0x12;
355  magic[6] = 0x35;
356  return memcmp(magic, msg_header.magic, 7) == 0;
357 }
358 
360 {
361  ulog_message_header_s message_header;
362 
363  while (true)
364  {
365  // qDebug() <<"\noffset before" << datastream.offset;
366  datastream.read((char*)&message_header, ULOG_MSG_HEADER_LEN);
367  // qDebug() <<"msg_size" << message_header.msg_size;
368  // qDebug() <<"type" << char(message_header.msg_type);
369  // qDebug() <<"offset after" << datastream.offset;
370 
371  if (!datastream)
372  {
373  return false;
374  }
375 
376  switch (message_header.msg_type)
377  {
378  case (int)ULogMessageType::FLAG_BITS:
379  if (!readFlagBits(datastream, message_header.msg_size))
380  {
381  return false;
382  }
383  break;
384 
385  case (int)ULogMessageType::FORMAT:
386  if (!readFormat(datastream, message_header.msg_size))
387  {
388  return false;
389  }
390 
391  break;
392 
393  case (int)ULogMessageType::PARAMETER:
394  if (!readParameter(datastream, message_header.msg_size))
395  {
396  return false;
397  }
398 
399  break;
400 
403  return true;
404  }
405 
406  case (int)ULogMessageType::INFO: {
407  if (!readInfo(datastream, message_header.msg_size))
408  {
409  return false;
410  }
411  }
412  break;
413  case (int)ULogMessageType::INFO_MULTIPLE: // skip
414  case (int)ULogMessageType::PARAMETER_DEFAULT: // skip
415  datastream.offset += message_header.msg_size;
416  break;
417 
418  default:
419  printf("unknown log definition type %i, size %i (offset %i)\n",
420  (int)message_header.msg_type, (int)message_header.msg_size,
421  (int)datastream.offset);
422  datastream.offset += message_header.msg_size;
423  break;
424  }
425  }
426  return true;
427 }
428 
429 bool ULogParser::readFlagBits(DataStream& datastream, uint16_t msg_size)
430 {
431  if (msg_size != 40)
432  {
433  printf("unsupported message length for FLAG_BITS message (%i)", msg_size);
434  return false;
435  }
436 
437  _read_buffer.reserve(msg_size);
438  uint8_t* message = (uint8_t*)_read_buffer.data();
439  datastream.read((char*)message, msg_size);
440 
441  // uint8_t *compat_flags = message;
442  uint8_t* incompat_flags = message + 8;
443 
444  // handle & validate the flags
445  bool contains_appended_data =
446  incompat_flags[0] & ULOG_INCOMPAT_FLAG0_DATA_APPENDED_MASK;
447  bool has_unknown_incompat_bits = false;
448 
449  if (incompat_flags[0] & ~0x1)
450  {
451  has_unknown_incompat_bits = true;
452  }
453 
454  for (int i = 1; i < 8; ++i)
455  {
456  if (incompat_flags[i])
457  {
458  has_unknown_incompat_bits = true;
459  }
460  }
461 
462  if (has_unknown_incompat_bits)
463  {
464  printf("Log contains unknown incompat bits set. Refusing to parse");
465  return false;
466  }
467 
468  if (contains_appended_data)
469  {
470  uint64_t appended_offsets[3];
471  memcpy(appended_offsets, message + 16, sizeof(appended_offsets));
472 
473  if (appended_offsets[0] > 0)
474  {
475  // the appended data is currently only used for hardfault dumps, so it's safe to
476  // ignore it.
477  // LOG_INFO("Log contains appended data. Replay will ignore this data" );
478  _read_until_file_position = appended_offsets[0];
479  }
480  }
481  return true;
482 }
483 
484 bool ULogParser::readFormat(DataStream& datastream, uint16_t msg_size)
485 {
486  static int count = 0;
487 
488  _read_buffer.reserve(msg_size + 1);
489  char* buffer = (char*)_read_buffer.data();
490  datastream.read(buffer, msg_size);
491  buffer[msg_size] = 0;
492 
493  if (!datastream)
494  {
495  return false;
496  }
497 
498  std::string str_format(buffer);
499  size_t pos = str_format.find(':');
500 
501  if (pos == std::string::npos)
502  {
503  return false;
504  }
505 
506  std::string name = str_format.substr(0, pos);
507  std::string fields = str_format.substr(pos + 1);
508 
509  Format format;
510  auto fields_split = splitString(fields, ';');
511  format.fields.reserve(fields_split.size());
512  for (auto field_section : fields_split)
513  {
514  auto field_pair = splitString(field_section, ' ');
515  auto field_type = field_pair.at(0);
516  auto field_name = field_pair.at(1);
517 
518  Field field;
519  if (field_type.starts_with("int8_t"))
520  {
521  field.type = INT8;
522  field_type.remove_prefix(6);
523  }
524  else if (field_type.starts_with("int16_t"))
525  {
526  field.type = INT16;
527  field_type.remove_prefix(7);
528  }
529  else if (field_type.starts_with("int32_t"))
530  {
531  field.type = INT32;
532  field_type.remove_prefix(7);
533  }
534  else if (field_type.starts_with("int64_t"))
535  {
536  field.type = INT64;
537  field_type.remove_prefix(7);
538  }
539  else if (field_type.starts_with("uint8_t"))
540  {
541  field.type = UINT8;
542  field_type.remove_prefix(7);
543  }
544  else if (field_type.starts_with("uint16_t"))
545  {
546  field.type = UINT16;
547  field_type.remove_prefix(8);
548  }
549  else if (field_type.starts_with("uint32_t"))
550  {
551  field.type = UINT32;
552  field_type.remove_prefix(8);
553  }
554  else if (field_type.starts_with("uint64_t"))
555  {
556  field.type = UINT64;
557  field_type.remove_prefix(8);
558  }
559  else if (field_type.starts_with("double"))
560  {
561  field.type = DOUBLE;
562  field_type.remove_prefix(6);
563  }
564  else if (field_type.starts_with("float"))
565  {
566  field.type = FLOAT;
567  field_type.remove_prefix(5);
568  }
569  else if (field_type.starts_with("bool"))
570  {
571  field.type = BOOL;
572  field_type.remove_prefix(4);
573  }
574  else if (field_type.starts_with("char"))
575  {
576  field.type = CHAR;
577  field_type.remove_prefix(4);
578  }
579  else
580  {
581  field.type = OTHER;
582 
583  if (field_type.ends_with("]"))
584  {
585  StringView helper = field_type;
586  while (!helper.ends_with("["))
587  {
588  helper.remove_suffix(1);
589  }
590 
591  helper.remove_suffix(1);
592  field.other_type_ID = helper.to_string();
593 
594  while (!field_type.starts_with("["))
595  {
596  field_type.remove_prefix(1);
597  }
598  }
599  else
600  {
601  field.other_type_ID = field_type.to_string();
602  }
603  }
604 
605  field.array_size = 1;
606 
607  if (field_type.size() > 0 && field_type[0] == '[')
608  {
609  field_type.remove_prefix(1);
610  field.array_size = field_type[0] - '0';
611  field_type.remove_prefix(1);
612 
613  while (field_type[0] != ']')
614  {
615  field.array_size = 10 * field.array_size + field_type[0] - '0';
616  field_type.remove_prefix(1);
617  }
618  }
619 
620  if (field.type == UINT64 && field_name == StringView("timestamp"))
621  {
622  // skip
623  }
624  else
625  {
626  field.field_name = field_name.to_string();
627  format.fields.push_back(field);
628  }
629  }
630 
631  format.name = name;
632  _formats[name] = std::move(format);
633 
634  return true;
635 }
636 
637 template <typename T>
638 std::string int_to_hex(T i)
639 {
640  std::stringstream stream;
641  stream << "0x" << std::setfill('0') << std::setw(sizeof(T) * 2) << std::hex << i;
642  return stream.str();
643 }
644 
645 bool ULogParser::readInfo(DataStream& datastream, uint16_t msg_size)
646 {
647  _read_buffer.reserve(msg_size);
648  uint8_t* message = (uint8_t*)_read_buffer.data();
649  datastream.read((char*)message, msg_size);
650 
651  if (!datastream)
652  {
653  return false;
654  }
655  uint8_t key_len = message[0];
656  message++;
657  std::string raw_key((char*)message, key_len);
658  message += key_len;
659  std::string raw_value((char*)message, msg_size - key_len - 1);
660 
661  auto key_parts = splitString(raw_key, ' ');
662 
663  std::string key = key_parts[1].to_string();
664  std::string value;
665 
666  if (key_parts[0].starts_with("char["))
667  {
668  value = raw_value;
669  }
670  else if (key_parts[0] == StringView("bool"))
671  {
672  bool val = *reinterpret_cast<const bool*>(raw_value.data());
673  value = std::to_string(val);
674  }
675  else if (key_parts[0] == StringView("uint8_t"))
676  {
677  uint8_t val = *reinterpret_cast<const uint8_t*>(raw_value.data());
678  value = std::to_string(val);
679  }
680  else if (key_parts[0] == StringView("int8_t"))
681  {
682  int8_t val = *reinterpret_cast<const int8_t*>(raw_value.data());
683  value = std::to_string(val);
684  }
685  else if (key_parts[0] == StringView("uint16_t"))
686  {
687  uint16_t val = *reinterpret_cast<const uint16_t*>(raw_value.data());
688  value = std::to_string(val);
689  }
690  else if (key_parts[0] == StringView("int16_t"))
691  {
692  int16_t val = *reinterpret_cast<const int16_t*>(raw_value.data());
693  value = std::to_string(val);
694  }
695  else if (key_parts[0] == StringView("uint32_t"))
696  {
697  uint32_t val = *reinterpret_cast<const uint32_t*>(raw_value.data());
698  if (key_parts[1].starts_with("ver_") && key_parts[1].ends_with("_release"))
699  {
700  value = int_to_hex(val);
701  }
702  else
703  {
704  value = std::to_string(val);
705  }
706  }
707  else if (key_parts[0] == StringView("int32_t"))
708  {
709  int32_t val = *reinterpret_cast<const int32_t*>(raw_value.data());
710  value = std::to_string(val);
711  }
712  else if (key_parts[0] == StringView("float"))
713  {
714  float val = *reinterpret_cast<const float*>(raw_value.data());
715  value = std::to_string(val);
716  }
717  else if (key_parts[0] == StringView("double"))
718  {
719  double val = *reinterpret_cast<const double*>(raw_value.data());
720  value = std::to_string(val);
721  }
722  else if (key_parts[0] == StringView("uint64_t"))
723  {
724  uint64_t val = *reinterpret_cast<const uint64_t*>(raw_value.data());
725  value = std::to_string(val);
726  }
727  else if (key_parts[0] == StringView("int64_t"))
728  {
729  int64_t val = *reinterpret_cast<const int64_t*>(raw_value.data());
730  value = std::to_string(val);
731  }
732 
733  _info.insert({ key, value });
734  return true;
735 }
736 
737 bool ULogParser::readParameter(DataStream& datastream, uint16_t msg_size)
738 {
739  _read_buffer.reserve(msg_size);
740  char* message = (char*)_read_buffer.data();
741  datastream.read((char*)message, msg_size);
742  if (!datastream)
743  {
744  return false;
745  }
746 
748  param.readFromBuffer(message);
749  _parameters.push_back(param);
750  return true;
751 }
752 
754 {
755  std::function<void(const Format& format, const std::string& prefix)> appendVector;
756 
757  Timeseries timeseries;
758 
759  appendVector = [&appendVector, this, &timeseries](const Format& format,
760  const std::string& prefix) {
761  for (const auto& field : format.fields)
762  {
763  // skip padding messages
764  if (StringView(field.field_name).starts_with("_padding"))
765  {
766  continue;
767  }
768 
769  std::string new_prefix = prefix + "/" + field.field_name;
770  for (int i = 0; i < field.array_size; i++)
771  {
772  std::string array_suffix = "";
773  if (field.array_size > 1)
774  {
775  char buff[16];
776  sprintf(buff, ".%02d", i);
777  array_suffix = buff;
778  }
779  if (field.type != OTHER)
780  {
781  timeseries.data.push_back({ new_prefix + array_suffix, std::vector<double>() });
782  }
783  else
784  {
785  appendVector(this->_formats.at(field.other_type_ID), new_prefix + array_suffix);
786  }
787  }
788  }
789  };
790 
791  appendVector(*format, {});
792  return timeseries;
793 }
794 
795 bool ULogParser::Parameter::readFromBuffer(const char* message)
796 {
797  const uint8_t key_len = static_cast<uint8_t>(message[0]);
798  message++;
799  std::string key((char*)message, key_len);
800 
801  const size_t pos = key.find(' ');
802  if (pos == std::string::npos)
803  {
804  return false;
805  }
806 
807  const std::string type = key.substr(0, pos);
808  this->name = key.substr(pos + 1);
809  message += key_len;
810 
811  if (type == "int32_t")
812  {
813  this->value.val_int = *reinterpret_cast<const int32_t*>(message);
814  this->val_type = INT32;
815  }
816  else if (type == "float")
817  {
818  this->value.val_real = *reinterpret_cast<const float*>(message);
819  this->val_type = FLOAT;
820  }
821  else
822  {
823  throw std::runtime_error("unknown parameter type");
824  }
825  return true;
826 }
ULogParser::Format::fields
std::vector< Field > fields
Definition: ulog_parser.h:86
ULogParser::readParameter
bool readParameter(DataStream &datastream, uint16_t msg_size)
Definition: ulog_parser.cpp:737
ULogParser::readFileDefinitions
bool readFileDefinitions(DataStream &datastream)
Definition: ulog_parser.cpp:359
detail::first
auto first(const T &value, const Tail &...) -> const T &
Definition: compile.h:60
ULogParser::_file_start_time
uint64_t _file_start_time
Definition: ulog_parser.h:145
ULogParser::Timeseries::data
std::vector< std::pair< std::string, std::vector< double > > > data
Definition: ulog_parser.h:112
ULogMessageType::ADD_LOGGED_MSG
@ ADD_LOGGED_MSG
ULogParser::Parameter::val_type
FormatType val_type
Definition: ulog_parser.h:75
ULogParser::_subscriptions
std::map< uint16_t, Subscription > _subscriptions
Definition: ulog_parser.h:162
printf
auto printf(string_view fmt, const T &... args) -> int
Definition: printf.h:663
ULogParser::_timeseries
std::map< std::string, Timeseries > _timeseries
Definition: ulog_parser.h:164
ios
std::ios ios
Definition: ulog_parser.cpp:10
backward::ColorMode::type
type
Definition: backward.hpp:3600
nonstd::span_lite::size_t
span_CONFIG_SIZE_TYPE size_t
Definition: span.hpp:576
ULogParser::UINT8
@ UINT8
Definition: ulog_parser.h:41
str_format
static int str_format(lua_State *L)
Definition: lstrlib.c:1227
ULogParser::getParameters
const std::vector< Parameter > & getParameters() const
Definition: ulog_parser.cpp:265
ULogParser::Subscription::multi_id
uint8_t multi_id
Definition: ulog_parser.h:104
ULogParser::createTimeseries
Timeseries createTimeseries(const Format *format)
Definition: ulog_parser.cpp:753
ULogParser::DataStream::offset
size_t offset
Definition: ulog_parser.h:21
ULogParser::Parameter::value
union ULogParser::Parameter::@57 value
ULogParser::UINT32
@ UINT32
Definition: ulog_parser.h:43
ULogParser::splitString
std::vector< StringView > splitString(const StringView &strToSplit, char delimeter)
Definition: ulog_parser.cpp:314
ULogParser::_message_logs
std::vector< MessageLog > _message_logs
Definition: ulog_parser.h:170
ULogParser::DataStream::read
void read(char *dst, int len)
Definition: ulog_parser.h:27
ULogParser::CHAR
@ CHAR
Definition: ulog_parser.h:52
ULogParser::_data_section_start
std::streampos _data_section_start
first ADD_LOGGED_MSG message
Definition: ulog_parser.h:151
ULogParser::Format
Definition: ulog_parser.h:80
ULogParser::fieldsCount
size_t fieldsCount(const Format &format) const
Definition: ulog_parser.cpp:296
mqtt_test_proto.msg
msg
Definition: mqtt_test_proto.py:43
ULogParser::_parameters
std::vector< Parameter > _parameters
Definition: ulog_parser.h:147
ULOG_INCOMPAT_FLAG0_DATA_APPENDED_MASK
#define ULOG_INCOMPAT_FLAG0_DATA_APPENDED_MASK
Definition: ulog_messages.h:195
ULogParser::getTimeseriesMap
const std::map< std::string, Timeseries > & getTimeseriesMap() const
Definition: ulog_parser.cpp:260
ULogParser::UINT64
@ UINT64
Definition: ulog_parser.h:44
ULogParser::readSubscription
bool readSubscription(DataStream &datastream, uint16_t msg_size)
Definition: ulog_parser.cpp:280
ULogParser::INT32
@ INT32
Definition: ulog_parser.h:47
ULogParser::MessageLog
Definition: ulog_parser.h:90
detail::count
constexpr auto count() -> size_t
Definition: core.h:1222
ULogParser::BOOL
@ BOOL
Definition: ulog_parser.h:51
ulog_message_header_s
Definition: ulog_messages.h:66
StringView
nonstd::string_view StringView
Definition: ulog_parser.h:12
ULogMessageType::DROPOUT
@ DROPOUT
backward::details::move
const T & move(const T &v)
Definition: backward.hpp:394
ULogParser::_info
std::map< std::string, std::string > _info
Definition: ulog_parser.h:160
int_to_hex
std::string int_to_hex(T i)
Definition: ulog_parser.cpp:638
ULogParser::_read_until_file_position
int64_t _read_until_file_position
read limit if log contains appended data
Definition: ulog_parser.h:153
ULogMessageType::INFO
@ INFO
ULogParser::Timeseries
Definition: ulog_parser.h:109
ULogParser::getLogs
const std::vector< MessageLog > & getLogs() const
Definition: ulog_parser.cpp:275
ULogParser::Timeseries::timestamps
std::vector< uint64_t > timestamps
Definition: ulog_parser.h:111
nlohmann::detail::void
j template void())
Definition: json.hpp:4061
ULogMessageType::SYNC
@ SYNC
ULogParser::Field
Definition: ulog_parser.h:56
ULogParser::Subscription::message_name
std::string message_name
Definition: ulog_parser.h:105
ULogMessageType::LOGGING
@ LOGGING
ULogParser::Subscription
Definition: ulog_parser.h:97
ULogParser::UINT16
@ UINT16
Definition: ulog_parser.h:42
ULogParser::INT8
@ INT8
Definition: ulog_parser.h:45
ulog_messages.h
format
auto format(const text_style &ts, const S &format_str, const Args &... args) -> std::basic_string< Char >
Definition: color.h:543
ULogMessageType::PARAMETER_DEFAULT
@ PARAMETER_DEFAULT
ULogParser::_formats
std::map< std::string, Format > _formats
Definition: ulog_parser.h:158
ULogMessageType::REMOVE_LOGGED_MSG
@ REMOVE_LOGGED_MSG
ULOG_MSG_HEADER_LEN
#define ULOG_MSG_HEADER_LEN
Definition: ulog_messages.h:65
ULogParser::parseSimpleDataMessage
char * parseSimpleDataMessage(Timeseries &timeseries, const Format *format, char *message, size_t *index)
Definition: ulog_parser.cpp:164
ULogParser::ULogParser
ULogParser(DataStream &datastream)
Definition: ulog_parser.cpp:12
ULogMessageType::FORMAT
@ FORMAT
ULogParser::DataStream
Definition: ulog_parser.h:17
ULogMessageType::FLAG_BITS
@ FLAG_BITS
ULogParser::Parameter
Definition: ulog_parser.h:67
ULogParser::parseDataMessage
void parseDataMessage(const Subscription &sub, char *message)
Definition: ulog_parser.cpp:128
ULogParser::DOUBLE
@ DOUBLE
Definition: ulog_parser.h:50
ULogParser::Parameter::readFromBuffer
bool readFromBuffer(const char *message)
Definition: ulog_parser.cpp:795
field_type
def field_type(f)
ULogParser::readFlagBits
bool readFlagBits(DataStream &datastream, uint16_t msg_size)
Definition: ulog_parser.cpp:429
ULogParser::INT64
@ INT64
Definition: ulog_parser.h:48
ULogParser::_message_name_with_multi_id
std::set< std::string > _message_name_with_multi_id
Definition: ulog_parser.h:168
ULogMessageType::INFO_MULTIPLE
@ INFO_MULTIPLE
field
static void field(LexState *ls, ConsControl *cc)
Definition: lparser.c:891
ULogParser::readFileHeader
bool readFileHeader(DataStream &datastream)
Definition: ulog_parser.cpp:335
param
T param(const std::string &param_name, const T &default_val)
ULogMessageType::PARAMETER
@ PARAMETER
ULogParser::_read_buffer
std::vector< uint8_t > _read_buffer
Definition: ulog_parser.h:149
ULogParser::readFormat
bool readFormat(DataStream &datastream, uint16_t msg_size)
Definition: ulog_parser.cpp:484
ULogMessageType::DATA
@ DATA
ULogParser::INT16
@ INT16
Definition: ulog_parser.h:46
ulog_parser.h
ULogParser::Parameter::name
std::string name
Definition: ulog_parser.h:69
ULogParser::Subscription::format
const Format * format
Definition: ulog_parser.h:106
sprintf
auto sprintf(const S &fmt, const T &... args) -> std::basic_string< Char >
Definition: printf.h:612
ULogParser::FLOAT
@ FLOAT
Definition: ulog_parser.h:49
ulog_file_header_s
Definition: ulog_messages.h:59
ULogParser::getInfo
const std::map< std::string, std::string > & getInfo() const
Definition: ulog_parser.cpp:270
ULogParser::Subscription::msg_id
uint16_t msg_id
Definition: ulog_parser.h:103
ULogParser::readInfo
bool readInfo(DataStream &datastream, uint16_t msg_size)
Definition: ulog_parser.cpp:645
mqtt_test.ret
ret
Definition: mqtt_test.py:30
ULogParser::OTHER
@ OTHER
Definition: ulog_parser.h:53


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Aug 11 2024 02:24:26