ros_parser.cpp
Go to the documentation of this file.
1 #include "ros_parser.h"
2 #include "dialog_with_itemlist.h"
3 #include "geometry_twist_msg.h"
4 #include "diagnostic_msg.h"
5 #include "pal_statistics_msg.h"
6 #include "odometry_msg.h"
9 
11 {
12 }
13 
15 {
16  _plot_map.numeric.clear();
17  _registered_md5sum.clear();
19  _builtin_parsers.clear();
20  _warn_cancellation.clear();
21  _warn_max_arraysize.clear();
22 }
23 
25  const RosIntrospection::Variant& value,
26  const std::string& item_name)
27 {
28  if( value.getTypeID() == RosIntrospection::UINT64)
29  {
30  uint64_t val_i = value.extract<uint64_t>();
31  double val_d = static_cast<double>(val_i);
32  bool error = (val_i != static_cast<uint64_t>(val_d));
33  if(error && _warnings_enabled)
34  {
35  _warn_cancellation.insert( item_name );
36  }
37  return val_d;
38  }
39 
40  if( value.getTypeID() == RosIntrospection::INT64)
41  {
42  int64_t val_i = value.extract<int64_t>();
43  double val_d = static_cast<double>(val_i);
44  bool error = (val_i != static_cast<int64_t>(val_d));
45  if(error && _warnings_enabled)
46  {
47  _warn_cancellation.insert( item_name );
48  }
49  return val_d;
50  }
51 
52  double val_d = value.convert<double>();
53  return val_d;
54 }
55 
56 
57 
58 void RosMessageParser::setMaxArrayPolicy(size_t max_array_size, bool discard_entire_array)
59 {
60  _max_array_size = max_array_size;
61  _discard_large_array = discard_entire_array;
62  _introspection_parser->setMaxArrayPolicy( discard_entire_array );
63 }
64 
65 template <typename T>
67  const std::string &topic_name,
68  const std::string &md5sum)
69 {
70  if( md5sum != T::getCompatibleKey() )
71  {
72  return false;
73  }
74  if( parsers.find(topic_name) == parsers.end())
75  {
76  parsers.emplace( std::piecewise_construct,
77  std::forward_as_tuple(topic_name),
78  std::forward_as_tuple(new T()) );
79  }
80  return true;
81 }
82 
83 bool RosMessageParser::registerSchema(const std::string &topic_name,
84  const std::string &md5sum,
86  const std::string &definition)
87 {
88  _registered_md5sum.insert( md5sum );
89 
90  bool inserted =
91  InsertParser<GeometryMsgTwist>( _builtin_parsers, topic_name, md5sum ) ||
92  InsertParser<OdometryMsgParser>( _builtin_parsers, topic_name, md5sum ) ||
93  InsertParser<DiagnosticMsg>( _builtin_parsers, topic_name, md5sum ) ||
94  InsertParser<FiveAiDiagnosticMsg>( _builtin_parsers, topic_name, md5sum ) ||
95  InsertParser<PalStatisticsNamesParser>( _builtin_parsers, topic_name, md5sum ) ||
96  InsertParser<PalStatisticsValuesParser>( _builtin_parsers, topic_name, md5sum );
97 
98  if( !inserted ) {
99  _introspection_parser->registerMessageDefinition(topic_name, type, definition);
100  }
101  return inserted;
102 }
103 
104 void RosMessageParser::pushMessageRef(const std::string &topic_name,
105  const MessageRef &msg,
106  double timestamp)
107 {
108  auto builtin_it = _builtin_parsers.find( topic_name );
109  if( builtin_it != _builtin_parsers.end() )
110  {
111  builtin_it->second->pushMessageRef( builtin_it->first, msg, timestamp );
112  return;
113  }
114 
115  using namespace RosIntrospection;
116 
117  FlatMessage flat_container;
118  RenamedValues renamed_values;
119 
120  absl::Span<uint8_t> msg_view ( const_cast<uint8_t*>(msg.data()), msg.size() );
121 
122  bool max_size_ok = _introspection_parser->deserializeIntoFlatContainer(
123  topic_name,
124  msg_view,
125  &flat_container,
126  _max_array_size );
127 
128  if( !max_size_ok && _warnings_enabled )
129  {
130  _warn_max_arraysize.insert(topic_name);
131  }
132 
133  _introspection_parser->applyNameTransform( topic_name,
134  flat_container,
135  &renamed_values );
137  {
138  for (const auto& it: flat_container.value)
139  {
140  if( it.second.getTypeID() != RosIntrospection::TIME)
141  {
142  continue;
143  }
144  const RosIntrospection::StringTreeNode* leaf1 = it.first.node_ptr;
145  const RosIntrospection::StringTreeNode* leaf2 = leaf1->parent();
146  if( leaf2 && leaf2->value() == "header" && leaf1->value() == "stamp")
147  {
148  double heder_stamp = it.second.convert<double>();
149 
150  if( heder_stamp > 0 ) {
151  timestamp = heder_stamp;
152  }
153  break;
154  }
155  }
156  }
157 
158  //----------------------------
159  // the KeyValue message is pretty common in ROS.
160  // http://docs.ros.org/melodic/api/diagnostic_msgs/html/msg/KeyValue.html
161  // Try to convert value to double
162 // for( size_t n = 0; n+1 < flat_container.name.size(); n++ )
163 // {
164 // auto key_ptr = flat_container.name[n].first.node_ptr;
165 // auto val_ptr = flat_container.name[n+1].first.node_ptr;
166 
167 // if( key_ptr->parent() == val_ptr->parent() &&
168 // key_ptr->parent()->value() == "#" &&
169 // key_ptr->value() == "key" &&
170 // val_ptr->value() == "value" )
171 // {
172 // const std::string str_value = flat_container.name[n+1].second;
173 // const char *start_ptr = str_value.data();
174 // double num = 0;
175 // auto res = absl::from_chars (start_ptr, start_ptr + str_value.size(), num);
176 // if( start_ptr == res.ptr ) continue;
177 
178 // RosIntrospection::StringTreeLeaf temp_leaf;
179 // temp_leaf.node_ptr = key_ptr->parent()->parent();
180 // if( !temp_leaf.node_ptr ) continue;
181 // temp_leaf.node_ptr = temp_leaf.node_ptr->parent();
182 // if( !temp_leaf.node_ptr ) continue;
183 
184 // renamed_values.push_back( { absl::StrCat( temp_leaf.toStdString(), "/", flat_container.name[n].second), num } );
185 // }
186 // }
187 
188  //----------------------------
189 
190  for(const auto& it: renamed_values )
191  {
192  const auto& field_name = it.first;
193 
194  const RosIntrospection::Variant& value = it.second;
195 
196  auto plot_pair = _plot_map.numeric.find( field_name );
197  if( (plot_pair == _plot_map.numeric.end()) )
198  {
199  plot_pair = _plot_map.addNumeric( field_name );
200  }
201 
202  PlotData& plot_data = plot_pair->second;
203  size_t data_size = plot_data.size();
204 
205  try {
206  double val_d = extractRealValue(value , field_name);
207  if( !std::isnan(val_d) && !std::isinf(val_d) )
208  {
209  plot_data.pushBack( PlotData::Point(timestamp, val_d) );
210  }
211  } catch (...) {}
212  }
213 }
214 
216 {
217  if( !_warn_max_arraysize.empty() )
218  {
219  QString message = QString("The following topics contain arrays with more than %1 elements.\n").arg(_max_array_size);
221  {
222  message += QString("The fields containing the extra large arrays have been discarded\n");
223  }
224  else{
225  message += QString("These arrays were trunkated to the maximum size %1\n").arg(_max_array_size);
226  }
228  }
229 
230  if( !_warn_cancellation.empty() )
231  {
232  QString message = "During the parsing process, one or more conversions to double failed"
233  " because of numerical cancellation.\n"
234  "This happens when the absolute value of a long integer exceed 2^52.\n\n"
235  "You have been warned... don't trust the following timeseries\n";
237  }
238 }
239 
240 void RosMessageParser::extractData(PlotDataMapRef &destination, const std::string &prefix)
241 {
242  for (auto& it: _plot_map.numeric)
243  {
244  appendData( destination, prefix + it.first, it.second );
245  }
246  _plot_map.numeric.clear();
247 
248  for (auto& it: _builtin_parsers)
249  {
250  it.second->extractData( destination, prefix + it.first );
251  }
252 }
253 
std::unordered_set< std::string > _warn_cancellation
Definition: ros_parser.h:60
std::unordered_map< std::string, PlotData > numeric
Definition: plotdata.h:144
double extractRealValue(const RosIntrospection::Variant &value, const std::string &item_name)
Definition: ros_parser.cpp:24
PlotDataMapRef _plot_map
Definition: ros_parser.h:52
std::unordered_set< std::string > _registered_md5sum
Definition: ros_parser.h:50
void pushBack(Point p)
Definition: plotdata.h:214
std::unordered_set< std::string > _warn_max_arraysize
Definition: ros_parser.h:61
bool _discard_large_array
Definition: ros_parser.h:58
const TreeNode * parent() const
size_t size() const
void setMaxArrayPolicy(size_t max_array_size, bool discard_entire_array)
Definition: ros_parser.cpp:58
void pushMessageRef(const std::string &topic_name, const MessageRef &msg, double timestamp) override
Definition: ros_parser.cpp:104
std::vector< std::pair< StringTreeLeaf, Variant > > value
T value
BuiltinType getTypeID() const
virtual void extractData(PlotDataMapRef &destination, const std::string &prefix) override
Definition: ros_parser.cpp:240
const uint8_t * data() const
virtual size_t size() const
Definition: plotdata.h:308
uint32_t _max_array_size
Definition: ros_parser.h:56
bool _warnings_enabled
Definition: ros_parser.h:57
std::unordered_map< std::string, std::unique_ptr< RosParserBase > > ParsersMap
Definition: ros_parser.h:47
bool InsertParser(RosMessageParser::ParsersMap &parsers, const std::string &topic_name, const std::string &md5sum)
Definition: ros_parser.cpp:66
ParsersMap _builtin_parsers
Definition: ros_parser.h:54
std::vector< std::pair< std::string, Variant > > RenamedValues
static void warning(const QString &message, std::unordered_set< std::string > list)
std::unordered_map< std::string, PlotData >::iterator addNumeric(const std::string &name)
Definition: plotdata.h:147
static void appendData(PlotDataMapRef &destination_plot_map, const std::string &field_name, PlotData &in_data)
std::unique_ptr< RosIntrospection::Parser > _introspection_parser
Definition: ros_parser.h:51
bool registerSchema(const std::string &topic_name, const std::string &md5sum, RosIntrospection::ROSType type, const std::string &definition)
Definition: ros_parser.cpp:83


plotjuggler
Author(s): Davide Faconti
autogenerated on Sat Jul 6 2019 03:44:18