iCub-main
serviceParserMultipleFt.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2022 Istituto Italiano di Tecnologia (IIT)
3  * All rights reserved.
4  * Author: Luca Tricerri
5  * This software may be modified and distributed under the terms of the
6  * BSD-3-Clause license. See the accompanying LICENSE file for details.
7  */
8 
10 
11 #include <yarp/os/Log.h>
12 #include <yarp/os/LogStream.h>
13 
15 {
16 }
17 
19 {
20  Bottle propertyCanBoard = Bottle(property.findGroup("CANBOARDS"));
21  if (propertyCanBoard.isNull())
22  {
23  yError() << "ServiceParserMultipleFt::check() cannot find PROPERTIES.CANBOARDS";
24  return false;
25  }
26 
27  Bottle propertyCanBoardType = propertyCanBoard.findGroup("type");
28  if (propertyCanBoardType.isNull())
29  {
30  yError() << "ServiceParserMultipleFt::checkPropertyCanBoards() cannot find "
31  "PROPERTIES.CANBOARDS.type";
32  return false;
33  }
34 
35  Bottle propertyCanBoardProtocol = Bottle(propertyCanBoard.findGroup("PROTOCOL"));
36  if (propertyCanBoardProtocol.isNull())
37  {
38  yError() << "ServiceParserMultipleFt::checkPropertyCanBoards() cannot find "
39  "PROPERTIES.CANBOARDS.PROTOCOL";
40  return false;
41  }
42 
43  Bottle propertyCanBoardProtocolMajor = Bottle(propertyCanBoardProtocol.findGroup("major"));
44  if (propertyCanBoardProtocolMajor.isNull())
45  {
46  yError() << "ServiceParserMultipleFt::checkPropertyCanBoards() cannot find "
47  "PROPERTIES.CANBOARDS.PROTOCOL.major";
48  return false;
49  }
50 
51  Bottle propertyCanBoardProtocolMinor = Bottle(propertyCanBoardProtocol.findGroup("minor"));
52  if (propertyCanBoardProtocolMinor.isNull())
53  {
54  yError() << "ServiceParserMultipleFt::checkPropertyCanBoards() cannot find "
55  "PROPERTIES.CANBOARDS.PROTOCOL.minor";
56  return false;
57  }
58 
59  Bottle propertyCanBoardFirmware = Bottle(propertyCanBoard.findGroup("FIRMWARE"));
60  if (propertyCanBoardFirmware.isNull())
61  {
62  yError() << "ServiceParserMultipleFt::checkPropertyCanBoards() cannot find "
63  "PROPERTIES.CANBOARDS.FIRMWARE";
64  return false;
65  }
66 
67  Bottle propertyCanBoardFirmwareMajor = Bottle(propertyCanBoardFirmware.findGroup("major"));
68  if (propertyCanBoardFirmwareMajor.isNull())
69  {
70  yError() << "ServiceParserMultipleFt::checkPropertyCanBoards() cannot find "
71  "PROPERTIES.CANBOARDS.FIRMWARE.major";
72  return false;
73  }
74 
75  Bottle propertyCanBoardFirmwareMinor = Bottle(propertyCanBoardFirmware.findGroup("minor"));
76  if (propertyCanBoardFirmwareMinor.isNull())
77  {
78  yError() << "ServiceParserMultipleFt::checkPropertyCanBoards() cannot find "
79  "PROPERTIES.CANBOARDS.FIRMWARE.minor";
80  return false;
81  }
82 
83  Bottle propertyCanBoardFirmwareBuild = Bottle(propertyCanBoardFirmware.findGroup("build"));
84  if (propertyCanBoardFirmwareBuild.isNull())
85  {
86  yError() << "ServiceParserMultipleFt::checkPropertyCanBoards() cannot find "
87  "PROPERTIES.CANBOARDS.FIRMWARE.build";
88  return false;
89  }
90 
91  // Check size
92  if (propertyCanBoardType.size() != propertyCanBoardProtocolMajor.size())
93  {
94  yError() << "ServiceParserMultipleFt::checkPropertyCanBoards --> protocol major size";
95  return false;
96  }
97  if (propertyCanBoardProtocolMajor.size() != propertyCanBoardProtocolMinor.size())
98  {
99  yError() << "ServiceParserMultipleFt::checkPropertyCanBoards --> protocol minor size";
100  return false;
101  }
102  if (propertyCanBoardProtocolMinor.size() != propertyCanBoardFirmwareMajor.size())
103  {
104  yError() << "ServiceParserMultipleFt::checkPropertyCanBoards --> firmware major size";
105  return false;
106  }
107  if (propertyCanBoardFirmwareMajor.size() != propertyCanBoardFirmwareMinor.size())
108  {
109  yError() << "ServiceParserMultipleFt::checkPropertyCanBoards --> firmware minor size";
110  return false;
111  }
112  if (propertyCanBoardFirmwareMinor.size() != propertyCanBoardFirmwareBuild.size())
113  {
114  yError() << "ServiceParserMultipleFt::checkPropertyCanBoards --> firmware build size";
115  return false;
116  }
117 
118  size_t size = propertyCanBoardType.size();
119  for (int index = 1; index < size; ++index)
120  {
121  std::string boardType = propertyCanBoardType.get(index).asString();
122 
123  eObrd_type_t currentBoard = checkBoardType(boardType);
124  if (currentBoard == eobrd_unknown)
125  return false;
126 
127  int protocolMajor = propertyCanBoardProtocolMajor.get(index).asInt32();
128  int protocolMinor = propertyCanBoardProtocolMinor.get(index).asInt32();
129  int firmwareMajor = propertyCanBoardFirmwareMajor.get(index).asInt32();
130  int firmwareMinor = propertyCanBoardFirmwareMinor.get(index).asInt32();
131  int firmwareBuild = propertyCanBoardFirmwareBuild.get(index).asInt32();
132 
133  for (auto &[key, current] : ftInfo_)
134  {
135  if (current.board != currentBoard)
136  continue;
137  current.majorProtocol = protocolMajor;
138  current.minorProtocol = protocolMinor;
139  current.majorFirmware = firmwareMajor;
140  current.minorFirmware = firmwareMinor;
141  current.buildFirmware = firmwareBuild;
142  }
143  }
144 
145  return true;
146 }
147 
149 {
150  Bottle propertySensors = Bottle(property.findGroup("SENSORS"));
151  if (propertySensors.isNull())
152  {
153  yError() << "ServiceParserMultipleFt::checkPropertySensors() cannot find "
154  "PROPERTIES.SENSORS";
155  return false;
156  }
157 
158  Bottle propertySensorsId = Bottle(propertySensors.findGroup("id"));
159  if (propertySensorsId.isNull())
160  {
161  yError() << "ServiceParserMultipleFt::checkPropertySensors() cannot find "
162  "PROPERTIES.SENSORS.id";
163  return false;
164  }
165 
166  Bottle propertySensorsBoard = Bottle(propertySensors.findGroup("board"));
167  if (propertySensorsBoard.isNull())
168  {
169  yError() << "ServiceParserMultipleFt::checkPropertySensors() cannot find "
170  "PROPERTIES.SENSORS.type";
171  return false;
172  }
173 
174  Bottle propertySensorsLocation = Bottle(propertySensors.findGroup("location"));
175  if (propertySensorsLocation.isNull())
176  {
177  yError() << "ServiceParserMultipleFt::checkPropertySensors() cannot find "
178  "PROPERTIES.SENSORS.location";
179  return false;
180  }
181 
182  Bottle propertySensorsFrameName = Bottle(propertySensors.findGroup("framename"));
183  if (propertySensorsFrameName.isNull())
184  {
185  yWarning() << "ServiceParserMultipleFt::checkPropertySensors() cannot find "
186  "PROPERTIES.SENSORS.frameName";
187  }
188 
189  // CHECK size
190  if (propertySensorsId.size() != propertySensorsBoard.size())
191  {
192  yError() << "ServiceParserMultipleFt::checkPropertySensors --> board size";
193  return false;
194  }
195  if (propertySensorsBoard.size() != propertySensorsLocation.size())
196  {
197  yError() << "ServiceParserMultipleFt::checkPropertySensors --> location size";
198  return false;
199  }
200  if (!propertySensorsFrameName.isNull())
201  {
202  if (propertySensorsLocation.size() != propertySensorsFrameName.size())
203  {
204  yError() << "ServiceParserMultipleFt::checkPropertySensors --> framename size";
205  return false;
206  }
207  }
208 
209  size_t sensorSize = propertySensorsId.size();
210  for (size_t index = 1 /*first is tagname*/; index < sensorSize; index++)
211  {
212  std::string id = propertySensorsId.get(index).asString();
213  std::string board = propertySensorsBoard.get(index).asString();
214  eObrd_type_t currentBoard = checkBoardType(board);
215  if (currentBoard == eobrd_unknown)
216  return false;
217 
218  std::string location = propertySensorsLocation.get(index).asString();
219  std::string frameName;
220  if (!propertySensorsFrameName.isNull())
221  {
222  frameName = propertySensorsFrameName.get(index).asString();
223  }
224  if (ftInfo_.find(id) == ftInfo_.end())
225  continue;
226  auto &currentFt = ftInfo_.at(id);
227 
228  try
229  {
230  currentFt.port = std::stoi(location.substr(3, 1));
231  }
232  catch (const std::exception &)
233  {
234  yError() << "ServiceParser::checkPropertySensors() invalid can port";
235  return false;
236  }
237  try
238  {
239  currentFt.address = std::stoi(location.substr(5, location.size() - 5));
240  }
241  catch (const std::exception &)
242  {
243  yError() << "ServiceParser::checkPropertySensors() invalid can address";
244  return false;
245  }
246 
247  currentFt.board = currentBoard;
248  currentFt.frameName = frameName;
249  }
250 
251  // Check missing SENSORS but enabled in SETTINGS
252  for (const auto &[id, data] : ftInfo_)
253  {
254  bool found = false;
255  for (int index = 0; index < propertySensorsId.size(); ++index)
256  {
257  if (id == propertySensorsId.get(index).asString())
258  {
259  found = true;
260  }
261  }
262  if (!found)
263  {
264  yError() << "ServiceParser::checkPropertySensors() try to enable not existing sensor:" << id;
265  return false;
266  }
267  }
268 
269  return true;
270 }
271 
272 bool ServiceParserMultipleFt::checkSettings(const Bottle &service)
273 {
274  Bottle settings = Bottle(service.findGroup("SETTINGS"));
275  if (settings.isNull())
276  {
277  yError() << "ServiceParserMultipleFt::checkSettings() cannot find SETTINGS";
278  return false;
279  }
280 
281  Bottle settingsFtPeriod = Bottle(settings.findGroup("ftPeriod"));
282  if (settingsFtPeriod.isNull())
283  {
284  yError() << "ServiceParserMultipleFt::checkSettings() cannot find "
285  "SETTINGS.ftPeriod";
286  return false;
287  }
288 
289  Bottle settingsTemperaturePeriod = Bottle(settings.findGroup("temperaturePeriod"));
290  if (settingsTemperaturePeriod.isNull())
291  {
292  yError() << "ServiceParserMultipleFt::checkSettings() for embObjMultipleFTsensors "
293  "device cannot find SETTINGS.temperaturePeriod";
294  return false;
295  }
296 
297  Bottle settingsUseCalibration = Bottle(settings.findGroup("useCalibration"));
298  if (settingsUseCalibration.isNull())
299  {
300  yError() << "ServiceParserMultipleFt::checkSettings() cannot find "
301  "FT_SETTINGS.useCalibration";
302  return false;
303  }
304 
305  Bottle settingsEnabledSensors = Bottle(settings.findGroup("enabledSensors"));
306  if (settingsEnabledSensors.isNull())
307  {
308  yError() << "ServiceParserMultipleFt::checkSettings() cannot find "
309  "SETTINGS.enabledSensors";
310  return false;
311  }
312 
313  // Check size
314  if (settingsEnabledSensors.size() != settingsFtPeriod.size())
315  {
316  yError() << "ServiceParserMultipleFt::checkSettings --> FtPeriod size";
317  return false;
318  }
319  if (settingsFtPeriod.size() != settingsTemperaturePeriod.size())
320  {
321  yError() << "ServiceParserMultipleFt::checkSettings --> "
322  "temperaturePeriod size";
323  return false;
324  }
325  if (settingsTemperaturePeriod.size() != settingsUseCalibration.size())
326  {
327  yError() << "ServiceParserMultipleFt::checkSettings --> usecalibration size";
328  return false;
329  }
330 
331  size_t enabledSensorSize = settingsEnabledSensors.size();
332  if (enabledSensorSize > 4)
333  {
334  yError() << "ServiceParserMultipleFt::checkSettings --> too many sensors";
335  return false;
336  }
337 
338  for (size_t index = 1 /*first is tagname*/; index < enabledSensorSize; index++)
339  {
340  std::string id = settingsEnabledSensors.get(index).asString();
341  uint8_t acquisitionRate = (uint8_t)settingsFtPeriod.get(index).asInt8();
342  uint32_t acquisitionTempRate = (uint32_t)settingsTemperaturePeriod.get(index).asInt32();
343  bool useCalibration = settingsUseCalibration.get(index).asBool();
344  eOas_ft_mode_t calib = eoas_ft_mode_calibrated;
345  if (!useCalibration)
346  {
347  calib = eoas_ft_mode_raw;
348  }
349  FtInfo currentSensor{acquisitionRate, acquisitionTempRate, calib};
350  ftInfo_[id] = currentSensor;
351  }
352 
353  // Duplicate name check
354  if (settingsEnabledSensors.size() - 1 != ftInfo_.size())
355  {
356  yError() << "ServiceParserMultipleFt::checkSettings --> id duplicate name";
357  return false;
358  }
359 
360  return true;
361 }
362 
363 bool ServiceParserMultipleFt::checkServiceType(const Bottle &service)
364 {
365  if (false == service.check("type"))
366  {
367  yError() << "ServiceParserMultipleFt::check() cannot find SERVICE.type";
368  return false;
369  }
370  std::string serviceType = service.find("type").asString();
371  eOmn_serv_type_t serviceTypeEomn = eomn_string2servicetype(serviceType.c_str());
372 
373  if (eomn_serv_AS_ft != serviceTypeEomn)
374  {
375  yError() << "ServiceParserMultipleFt::check() has found wrong SERVICE.type = " << serviceType << "it must be eomn_serv_AS_ft";
376  return false;
377  }
378  return true;
379 }
380 
381 bool ServiceParserMultipleFt::checkCanMonitor(const Bottle &service)
382 {
383  Bottle canMonitor = Bottle(service.findGroup("CANMONITOR"));
384  if (canMonitor.isNull())
385  {
386  yError() << "ServiceParserMultipleFt::check() cannot find PROPERTIES.CANMONITOR";
387  return false;
388  }
389 
390  if (false == canMonitor.check("checkPeriod"))
391  {
392  yError() << "ServiceParserMultipleFt::check() cannot find canMonitor.checkrate";
393  return false;
394  }
395  if (false == canMonitor.check("ratePeriod"))
396  {
397  yError() << "ServiceParserMultipleFt::check() cannot find "
398  "canMonitor.periodicreportrate";
399  return false;
400  }
401  if (false == canMonitor.check("reportMode"))
402  {
403  yError() << "ServiceParserMultipleFt::check() cannot find canMonitor.reportmode";
404  return false;
405  }
406 
407  int checkPeriod = canMonitor.find("checkPeriod").asInt32();
408  if (checkPeriod > 254)
409  {
410  yError() << "ServiceParserMultipleFt::check() wrong canMonitor.checkPeriod "
411  "too big";
412  return false;
413  }
414  int periodicreportrate = canMonitor.find("ratePeriod").asInt32();
415  if (periodicreportrate > 65535)
416  {
417  yError() << "ServiceParserMultipleFt::check() wrong canMonitor.ratePeriod "
418  "too big";
419  return false;
420  }
421  std::string reportmode = canMonitor.find("reportMode").asString();
422  eObrd_canmonitor_reportmode_t reportmodeEobrd = (eObrd_canmonitor_reportmode_t)eoboards_string2reportmode(reportmode.c_str(), 1);
423 
424  if (reportmodeEobrd == eobrd_canmonitor_reportmode_unknown)
425  {
426  yError() << "ServiceParserMultipleFt::check() wrong canMonitor.reportmode";
427  return false;
428  }
429 
430  canMonitor_ = {(uint8_t)checkPeriod, (uint8_t)reportmodeEobrd, (uint16_t)periodicreportrate};
431 
432  return true;
433 }
434 
435 bool ServiceParserMultipleFt::parse(const yarp::os::Searchable &config)
436 {
437  Bottle service(config.findGroup("SERVICE"));
438  if (service.isNull())
439  {
440  yError() << "ServiceParser::check() cannot find SERVICE group";
441  return false;
442  }
443 
444  Bottle properties = Bottle(service.findGroup("PROPERTIES"));
445  if (properties.isNull())
446  {
447  yError() << "ServiceParser::check() cannot find PROPERTIES";
448  return false;
449  }
450 
451  if (!checkServiceType(service))
452  return false;
453 
454  if (!checkSettings(service))
455  return false;
456 
457  if (!checkPropertySensors(properties))
458  return false;
459 
460  if (!checkPropertyCanBoards(properties))
461  return false;
462 
463  if (!checkCanMonitor(service))
464  return false;
465 
466  return true;
467 }
468 
469 bool ServiceParserMultipleFt::toEomn(eOmn_serv_config_data_as_ft_t &out) const
470 {
471  out.canmonitorconfig = canMonitor_;
472 
473  EOarray *ar = eo_array_New(eOas_ft_sensors_maxnumber, sizeof(eOas_ft_sensordescriptor_t), (void *)(&(out.arrayofsensors)));
474 
475  for (const auto &[key, value] : ftInfo_)
476  {
477  eOas_ft_sensordescriptor_t item;
478  if (!value.toEomn(item))
479  {
480  yError() << "ServiceParserMultipleFt::toEomn() wrong data for sensor";
481  return false;
482  }
483  eo_array_PushBack(ar, &item);
484  }
485  return true;
486 }
487 
488 std::map<std::string, FtInfo> &ServiceParserMultipleFt::getFtInfo()
489 {
490  return ftInfo_;
491 }
492 
493 eObrd_type_t ServiceParserMultipleFt::checkBoardType(const std::string &boardType)
494 {
495  eObrd_type_t type = eoboards_string2type2(boardType.c_str(), eobool_true);
496  if (!eoas_ft_isboardvalid(eoboards_type2cantype(type)))
497  {
498  type = eoboards_string2type2(boardType.c_str(), eobool_false);
499  if (!eoas_ft_isboardvalid(eoboards_type2cantype(type)))
500  {
501  yError() << "checkBoardType --> unsupported board type:" << boardType;
502  return type;
503  }
504  }
505  return type;
506 }
@ data
Definition: ftInfo.h:17
eObrd_canmonitor_cfg_t canMonitor_
virtual eObrd_type_t checkBoardType(const std::string &boardType)
virtual bool checkCanMonitor(const Bottle &service)
virtual bool checkPropertyCanBoards(const Bottle &bPropertiesCanBoards)
bool parse(const yarp::os::Searchable &config)
virtual bool checkSettings(const Bottle &settings)
virtual bool checkPropertySensors(const Bottle &property)
std::map< std::string, FtInfo > & getFtInfo()
bool toEomn(eOmn_serv_config_data_as_ft_t &out) const
std::map< std::string, FtInfo > ftInfo_
virtual bool checkServiceType(const Bottle &service)
uint8_t board
out
Definition: sine.m:8