iCub-main
serviceParser.cpp
Go to the documentation of this file.
1 
2 // -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-
3 
4 /*
5 * Copyright (C) 2016 Robotcub Consortium
6 * Author: Marco Accame
7 * CopyPolicy: Released under the terms of the GNU GPL v2.0.
8 *
9 */
10 
11 // general purpose stuff.
12 #include <string>
13 #include <iostream>
14 #include <string.h>
15 
16 // Yarp Includes
17 #include <yarp/os/Time.h>
18 #include <yarp/os/Log.h>
19 #include <yarp/os/LogStream.h>
20 #include <stdarg.h>
21 #include <stdio.h>
22 #include <yarp/dev/PolyDriver.h>
23 #include <ace/config.h>
24 #include <ace/Log_Msg.h>
25 
26 
27 // specific to this device driver.
28 #include <serviceParser.h>
29 
30 #include <yarp/os/LogStream.h>
31 #include "EoAnalogSensors.h"
32 
33 #include "EoProtocol.h"
34 #include "EoProtocolMN.h"
35 #include "EoProtocolAS.h"
36 
37 #include <yarp/os/NetType.h>
38 
39 #ifdef WIN32
40 #pragma warning(once:4355)
41 #endif
42 
43 
44 
45 using namespace yarp;
46 using namespace yarp::os;
47 using namespace yarp::dev;
48 using namespace std;
49 
50 
52 {
53  // how do i reset variable as_service?
54 
55 
56  as_service.type = eomn_serv_NONE;
57 
58  as_service.properties.canboards.resize(0);
59  as_service.properties.sensors.resize(0);
60 
61  as_service.settings.acquisitionrate = 0;
62  as_service.settings.enabledsensors.resize(0);
63 }
64 
65 bool ServiceParser::convert(std::string const &fromstring, eOmn_serv_type_t& toservicetype, bool& formaterror)
66 {
67  const char *t = fromstring.c_str();
68 
69  toservicetype = eomn_string2servicetype(t);
70 
71  if(eomn_serv_UNKNOWN == toservicetype)
72  {
73  yWarning() << "ServiceParser::convert():" << t << "is not a legal string for eOmn_serv_type_t";
74  formaterror = true;
75  return false;
76  }
77 
78  return true;
79 
80 }
81 
82 bool ServiceParser::convert(std::string const &fromstring, eOmn_serv_diagn_mode_t &todiagnmode, bool &formaterror)
83 {
84  const char *t = fromstring.c_str();
85 
86  todiagnmode = eomn_string2servicediagnmode(t);
87 
88  if(eomn_serv_diagn_mode_UNKNOWN == todiagnmode)
89  {
90  yWarning() << "ServiceParser::convert():" << t << "is not a legal string for eOmn_serv_diagn_mode_t";
91  formaterror = true;
92  return false;
93  }
94 
95  return true;
96 }
97 
98 
99 
100 // bool ServiceParser::convert(std::string const &fromstring, eOmc_ctrlboard_t &controllerboard, bool &formaterror)
101 // {
102 // const char *t = fromstring.c_str();
103 // eObool_t usecompactstring = eobool_false;
104 // controllerboard = eomc_string2controllerboard(t, usecompactstring);
105 //
106 // if(eomc_ctrlboard_unknown == controllerboard)
107 // { // attempting to retrieve the compact form
108 // usecompactstring = eobool_true;
109 // controllerboard = eomc_string2controllerboard(t, usecompactstring);
110 // }
111 //
112 // if(eomc_ctrlboard_unknown == controllerboard)
113 // {
114 // yWarning() << "ServiceParser::convert():" << t << "is not a legal string for eOmc_ctrlboard_t";
115 // formaterror = true;
116 // return false;
117 // }
118 //
119 // return true;
120 // }
121 
122 bool ServiceParser::convert(std::string const &fromstring, eOas_sensor_t &tosensortype, bool &formaterror)
123 {
124  const char *t = fromstring.c_str();
125 
126  tosensortype = eoas_string2sensor(t);
127 
128  if(eoas_unknown == tosensortype)
129  {
130  yWarning() << "ServiceParser::convert():" << t << "is not a legal string for eOas_sensor_t";
131  formaterror = true;
132  return false;
133  }
134 
135  return true;
136 }
137 
138 
139 bool ServiceParser::convert(std::string const &fromstring, eObrd_type_t& tobrdtype, bool& formaterror)
140 {
141  const char *t = fromstring.c_str();
142 
143  eObool_t usecompactstring = eobool_false;
144  tobrdtype = eoboards_string2type2(t, usecompactstring);
145 
146  if(eobrd_unknown == tobrdtype)
147  {
148  usecompactstring = eobool_true;
149  tobrdtype = eoboards_string2type2(t, usecompactstring);
150  }
151 
152  if(eobrd_unknown == tobrdtype)
153  {
154  yWarning() << "ServiceParser::convert(): string" << t << "cannot be converted into a proper eObrd_type_t";
155  formaterror = true;
156  return false;
157  }
158 
159  return true;
160 }
161 
162 
163 bool ServiceParser::convert(std::string const &fromstring, eOmc_pidoutputtype_t& pidoutputtype, bool& formaterror)
164 {
165  const char *t = fromstring.c_str();
166 
167  eObool_t usecompactstring = eobool_false;
168  pidoutputtype = eomc_string2pidoutputtype(t, usecompactstring);
169 
170  if(eomc_pidoutputtype_unknown == pidoutputtype)
171  {
172  usecompactstring = eobool_true;
173  pidoutputtype = eomc_string2pidoutputtype(t, usecompactstring);
174  }
175 
176  if(eomc_pidoutputtype_unknown == pidoutputtype)
177  {
178  yWarning() << "ServiceParser::convert(): string" << t << "cannot be converted into a proper eOmc_pidoutputtype_t";
179  formaterror = true;
180  return false;
181  }
182 
183  return true;
184 }
185 
186 bool ServiceParser::convert(std::string const &fromstring, eOmc_jsetconstraint_t &jsetconstraint, bool& formaterror)
187 {
188  const char *t = fromstring.c_str();
189 
190  eObool_t usecompactstring = eobool_false;
191  jsetconstraint = eomc_string2jsetconstraint(t, usecompactstring);
192 
193  if(eomc_jsetconstraint_unknown == jsetconstraint)
194  {
195  usecompactstring = eobool_true;
196  jsetconstraint = eomc_string2jsetconstraint(t, usecompactstring);
197  }
198 
199  if(eomc_jsetconstraint_unknown == jsetconstraint)
200  {
201  yWarning() << "ServiceParser::convert(): string" << t << "cannot be converted into a proper eOmc_jsetconstraint_t";
202  formaterror = true;
203  return false;
204  }
205 
206  return true;
207 }
208 
209 bool ServiceParser::convert(std::string const &fromstring, eObrd_cantype_t& tobrdcantype, bool& formaterror)
210 {
211  const char *t = fromstring.c_str();
212 
213  eObool_t usecompactstring = eobool_false;
214  eObrd_type_t type = eoboards_string2type2(t, usecompactstring);
215 
216  if(eobrd_unknown == type)
217  {
218  usecompactstring = eobool_true;
219  type = eoboards_string2type2(t, usecompactstring);
220  }
221 
222  if(eobrd_unknown == type)
223  {
224  yWarning() << "ServiceParser::convert(): string" << t << "cannot be converted into a proper eObrd_type_t";
225  formaterror = true;
226  return false;
227  }
228 
229  tobrdcantype = eoboards_type2cantype(type);
230  if(eobrd_cantype_unknown == tobrdcantype)
231  {
232  yWarning() << "ServiceParser::convert():" << t << "is not a legal string for eObrd_cantype_t";
233  formaterror = true;
234  return false;
235  }
236 
237  return true;
238 }
239 
240 bool ServiceParser::convert(std::string const &fromstring, eObrd_ethtype_t& tobrdethtype, bool& formaterror)
241 {
242  const char *t = fromstring.c_str();
243 
244  eObool_t usecompactstring = eobool_false;
245  eObrd_type_t type = eoboards_string2type2(t, usecompactstring);
246 
247  if(eobrd_unknown == type)
248  {
249  usecompactstring = eobool_true;
250  type = eoboards_string2type2(t, usecompactstring);
251  }
252 
253  if(eobrd_unknown == type)
254  {
255  yWarning() << "ServiceParser::convert(): string" << t << "cannot be converted into a proper eObrd_type_t";
256  formaterror = true;
257  return false;
258  }
259 
260  tobrdethtype = eoboards_type2ethtype(type);
261  if(eobrd_ethtype_unknown == tobrdethtype)
262  {
263  yWarning() << "ServiceParser::convert():" << t << "is not a legal string for eObrd_ethtype_t";
264  formaterror = true;
265  return false;
266  }
267 
268  return true;
269 }
270 
271 
272 bool ServiceParser::convert(std::string const &fromstring, bool& tobool, bool& formaterror)
273 {
274  const char *t = fromstring.c_str();
275 
276  if(0 == strcmp(t, "true"))
277  {
278  tobool = true;
279  }
280  else if(0 == strcmp(t, "false"))
281  {
282  tobool = false;
283  }
284  else if(0 == strcmp(t, "TRUE"))
285  {
286  tobool = true;
287  }
288  else if(0 == strcmp(t, "FALSE"))
289  {
290  tobool = false;
291  }
292  else if(0 == strcmp(t, "1"))
293  {
294  tobool = true;
295  }
296  else if(0 == strcmp(t, "0"))
297  {
298  tobool = false;
299  }
300  else
301  {
302  yWarning() << "ServiceParser::convert():" << t << "is not a legal string for bool";
303  tobool = false;
304  formaterror = true;
305  return false;
306  }
307 
308  return true;
309 }
310 
311 
312 bool ServiceParser::convert(const int number, uint8_t& tou8, bool& formaterror)
313 {
314  if((number >= 0) && (number < 256))
315  {
316  tou8 = number;
317  }
318  else
319  {
320  yWarning() << "ServiceParser::convert():" << number << "is not a legal value for uint8_t";
321  tou8 = 0;
322  formaterror = true;
323  return false;
324  }
325 
326  return true;
327 }
328 
329 bool ServiceParser::convert(const int number, uint16_t& tou16, bool& formaterror)
330 {
331  if((number >= 0) && (number < (64*1024)))
332  {
333  tou16 = number;
334  }
335  else
336  {
337  yWarning() << "ServiceParser::convert():" << number << "is not a legal value for uint16_t";
338  tou16 = 0;
339  formaterror = true;
340  return false;
341  }
342 
343  return true;
344 }
345 
346 
347 
348 bool ServiceParser::convert(std::string const &fromstring, const uint8_t strsize, char *str, bool &formaterror)
349 {
350  const char *t = fromstring.c_str();
351 
352  if((NULL == str) || (0 == strsize))
353  {
354  yWarning() << "ServiceParser::convert(): there is an attempt to convert string" << t << "into a NULL or zero-sized char *str: len = " << strsize;
355  formaterror = true;
356  return false;
357  }
358 
359  if(strsize >= strlen(t))
360  {
361  snprintf(str, strsize, "%s", t);
362  }
363  else
364  {
365  yWarning() << "ServiceParser::convert():" << t << "is not a legal string for a char[] of max size" << strsize;
366  formaterror = true;
367  return false;
368  }
369 
370  return true;
371 }
372 
373 
374 bool ServiceParser::convert(std::string const &fromstring, string &str, bool &formaterror)
375 {
376  const char *t = fromstring.c_str();
377 
378  if(0 != strlen(t))
379  {
380  str = t;
381  }
382  else
383  {
384  yWarning() << "ServiceParser::convert():" << t << "is not a legal string";
385  formaterror = true;
386  return false;
387  }
388 
389  return true;
390 }
391 
392 
393 
394 bool ServiceParser::convert(std::string const &fromstring, eObrd_location_t &location, bool &formaterror)
395 {
396  // it is actually a micro-parser: PRE-num
397  // at
398 
399  const char *t = fromstring.c_str();
400  int len = strlen(t);
401 
402  if(len > 15)
403  {
404  yWarning() << "ServiceParser::convert():" << t << "is not a legal string for a eObrd_location_t because it is too long with size = " << len;
405  formaterror = true;
406  return false;
407  }
408 
409  char prefix[16] = {0};
410  sscanf(t, "%3c", prefix);
411  if(0 == strcmp(prefix, "ETH"))
412  {
413  int adr = 0;
414  sscanf(t, "%3c:%d", prefix, &adr);
415  location.any.place = eobrd_place_eth;
416  location.eth.id = adr;
417  }
418  else if(0 == strcmp(prefix, "CAN"))
419  {
420  int bus = 0;
421  int adr = 0;
422  char cc = 'x';
423  int sub = 9;
424  int numberofreaditems = sscanf(t, "%3c%d:%d%c%d", prefix, &bus, &adr, &cc, &sub);
425 
426  if((3 != numberofreaditems) && (5 != numberofreaditems))
427  {
428  yWarning() << "ServiceParser::convert():" << t << "is not a legal string for a eObrd_location_t because we dont have correct number of sections separated by :";
429  formaterror = true;
430  return false;
431  }
432 
433  // verify bus being eitehr 1 or 2, and adr being 1 ----- 14
434  if((1 != bus) && (2 != bus))
435  {
436  yWarning() << "ServiceParser::convert():" << t << "is not a legal string for a eObrd_location_t because we can have either CAN1 or CAN2";
437  formaterror = true;
438  return false;
439  }
440  if((0 == adr) || (adr > 14))
441  {
442  yWarning() << "ServiceParser::convert():" << t << "is not a legal string for a eObrd_location_t because CAN address is in range [1, 14]";
443  formaterror = true;
444  return false;
445  }
446 
447  location.any.place = (3 == numberofreaditems) ? (eobrd_place_can) : (eobrd_place_extcan);
448  if(eobrd_place_can == location.any.place)
449  {
450  location.can.port = (1 == bus) ? (eOcanport1) : (eOcanport2);
451  location.can.addr = adr;
452  location.can.ffu = 0;
453  }
454  else
455  {
456  location.extcan.port = (1 == bus) ? (eOcanport1) : (eOcanport2);
457  location.extcan.addr = adr;
458  if((eobrd_caninsideindex_first != sub) && (eobrd_caninsideindex_second != sub) && (eobrd_caninsideindex_third != sub) && (eobrd_caninsideindex_fourth != sub))
459  {
460  yWarning() << "ServiceParser::convert():" << t << "is not a legal string for a eObrd_location_t because in CANx:adr:SUB, SUB address must be in range [0, 3]";
461  formaterror = true;
462  return false;
463  }
464  location.extcan.index = sub;
465  }
466 
467  }
468  else if(0 == strcmp(prefix, "LOC"))
469  {
470  //Add here parsing for local port (both PWM port (P7, P8, etc and "index_proximal"for hand))
471  //in xml file we have: LOC:P7 or LOC:index_proximal
472 
473  }
474  else
475  {
476  yWarning() << "ServiceParser::convert():" << t << "is not a legal string for a eObrd_location_t because it does not begin with ETH or CAN";
477  formaterror = true;
478  return false;
479  }
480 
481  return true;
482 }
483 
484 bool ServiceParser::convert(eObrd_location_t const &loc, char *str, int len)
485 {
486  if((NULL == str) || (0 == len))
487  {
488  return false;
489  }
490 
491  if(eobrd_place_can == loc.any.place)
492  {
493  snprintf(str, len, "CAN%d:%d", (eOcanport1 == loc.can.port) ? 1 : 2, loc.can.addr);
494  }
495  else if(eobrd_place_extcan == loc.any.place)
496  {
497  snprintf(str, len, "CAN%d:%d:%d", (eOcanport1 == loc.extcan.port) ? 1 : 2, loc.extcan.addr, loc.extcan.index);
498  }
499  else if(eobrd_place_eth == loc.any.place)
500  { // it must be eobrd_place_eth
501  snprintf(str, len, "ETH:%d", loc.eth.id);
502  }
503  else
504  {
505  return false;
506  }
507 
508  return true;
509 }
510 
511 bool ServiceParser::convert(std::string const &fromstring, eOlocation_t &location, bool &formaterror)
512 {
513  // it is actually a micro-parser: PRE-num
514 
515  const char *t = fromstring.c_str();
516  int len = strlen(t);
517 
518  if(len > 15)
519  {
520  yWarning() << "ServiceParser::convert():" << t << "is not a legal string for a eOlocation_t because it is too long with size = " << len;
521  formaterror = true;
522  return false;
523  }
524 
525  char prefix[16] = {0};
526  sscanf(t, "%3c", prefix);
527  if(0 == strcmp(prefix, "LOC"))
528  {
529  int adr = 0;
530  sscanf(t, "%3c:%d", prefix, &adr);
531  location.bus = eobus_local;
532  location.ffu = 0;
533  location.adr = adr;
534  }
535  else if((0 == strcmp(prefix, "CAN")) || (0 == strcmp(prefix, "ICC")))
536  {
537  int bus = 0;
538  int adr = 0;
539  int numberofreaditems = sscanf(t, "%3c%d:%d", prefix, &bus, &adr);
540 
541  if(3 != numberofreaditems)
542  {
543  yWarning() << "ServiceParser::convert():" << t << "is not a legal string for a eOlocation_t because we dont have correct number of sections separated by :";
544  formaterror = true;
545  return false;
546  }
547 
548  // verify bus being eitehr 1 or 2, and adr being 1 ----- 14
549  if((1 != bus) && (2 != bus))
550  {
551  yWarning() << "ServiceParser::convert():" << t << "is not a legal string for a eOlocation_t because we can have either ---1 or ---2";
552  formaterror = true;
553  return false;
554  }
555 
556  if((0 == adr) || (adr > 14))
557  {
558  yWarning() << "ServiceParser::convert():" << t << "is not a legal string for a eOlocation_t because address is not in range [1, 14]";
559  formaterror = true;
560  return false;
561  }
562 
563  location.ffu = 0;
564  if(0 == strcmp(prefix, "CAN"))
565  {
566  location.bus = (1 == bus) ? eobus_can1 : eobus_can2;
567  }
568  else if(0 == strcmp(prefix, "ICC"))
569  {
570  location.bus = (1 == bus) ? eobus_icc1 : eobus_icc2;
571  }
572 
573  location.adr = adr;
574 
575  }
576  else
577  {
578  yWarning() << "ServiceParser::convert():" << t << "is not a legal string for a eOlocation_t because it does not begin with LOC, CAN, ICC";
579  formaterror = true;
580  return false;
581  }
582 
583  return true;
584 }
585 
586 bool ServiceParser::convert(eOlocation_t const &loc, char *str, int len)
587 {
588  if((NULL == str) || (0 == len))
589  {
590  return false;
591  }
592 
593  if(eobus_can1 == loc.bus)
594  {
595  snprintf(str, len, "CAN1:%d", loc.adr);
596  }
597  else if(eobus_can2 == loc.bus)
598  {
599  snprintf(str, len, "CAN2:%d", loc.adr);
600  }
601  else if(eobus_local == loc.bus)
602  {
603  snprintf(str, len, "LOC:%d", loc.adr);
604  }
605  else if(eobus_icc1 == loc.bus)
606  {
607  snprintf(str, len, "ICC1:%d", loc.adr);
608  }
609  else if(eobus_icc2 == loc.bus)
610  {
611  snprintf(str, len, "ICC2:%d", loc.adr);
612  }
613  else
614  {
615  return false;
616  }
617 
618  return true;
619 }
620 
621 bool ServiceParser::convert(eObrd_canlocation_t const &canloc, char *str, int len)
622 {
623  if((NULL == str) || (0 == len))
624  {
625  return false;
626  }
627 
628  if(eobrd_caninsideindex_none == canloc.insideindex)
629  {
630  snprintf(str, len, "CAN%d:%d", (eOcanport1 == canloc.port) ? 1 : 2, canloc.addr);
631  }
632  else
633  {
634  snprintf(str, len, "CAN%d:%d:%d", (eOcanport1 == canloc.port) ? 1 : 2, canloc.addr, canloc.insideindex);
635  }
636 
637  return true;
638 }
639 
640 bool ServiceParser::convert(eObrd_firmwareversion_t const &firm, char *str, int len)
641 {
642  if((NULL == str) || (0 == len))
643  {
644  return false;
645  }
646 
647  snprintf(str, len, "(%d, %d, %d)", firm.major, firm.minor, firm.build);
648 
649  return true;
650 }
651 
652 bool ServiceParser::convert(eObrd_protocolversion_t const &prot, char *str, int len)
653 {
654  if((NULL == str) || (0 == len))
655  {
656  return false;
657  }
658 
659  snprintf(str, len, "(%d, %d)", prot.major, prot.minor);
660 
661  return true;
662 }
663 
664 bool ServiceParser::check_analog(Searchable &config, eOmn_serv_type_t type)
665 {
666  bool formaterror = false;
667  // so far we check for eomn_serv_AS_mais / strain / inertials3 / psc / pos only
668  if((eomn_serv_AS_mais != type) && (eomn_serv_AS_strain != type) &&
669  (eomn_serv_AS_inertials3 != type) && (eomn_serv_AS_psc != type) && (eomn_serv_AS_pos != type))
670  {
671  yError() << "ServiceParser::check_analog() is called with wrong type";
672  return false;
673  }
674 
675  // i parse the global board versions. if section is not found we can safely continue but we have boards.size() equal to zero.
676 
677  // format is SERVICE{ type, PROPERTIES{ CANBOARDS, SENSORS }, SETTINGS }
678 
679  Bottle b_SERVICE(config.findGroup("SERVICE"));
680  if(b_SERVICE.isNull())
681  {
682  yError() << "ServiceParser::check_analog() cannot find SERVICE group";
683  return false;
684  }
685 
686  // check whether we have the proper type
687 
688  if(false == b_SERVICE.check("type"))
689  {
690  yError() << "ServiceParser::check_analog() cannot find SERVICE.type";
691  return false;
692  }
693  else
694  {
695  Bottle b_type(b_SERVICE.find("type").asString());
696  if(false == convert(b_type.toString(), as_service.type, formaterror))
697  {
698  yError() << "ServiceParser::check_analog() has found unknown SERVICE.type = " << b_type.toString();
699  return false;
700  }
701  if(type != as_service.type)
702  {
703  yError() << "ServiceParser::check_analog() has found wrong SERVICE.type = " << as_service.type << "it must be" << "TODO: tostring() function";
704  return false;
705  }
706  }
707 
708  // check whether we have the proper groups
709 
710  Bottle b_PROPERTIES = Bottle(b_SERVICE.findGroup("PROPERTIES"));
711  if(b_PROPERTIES.isNull())
712  {
713  yError() << "ServiceParser::check_analog() cannot find PROPERTIES";
714  return false;
715  }
716  else
717  {
718  Bottle b_PROPERTIES_CANBOARDS = Bottle(b_PROPERTIES.findGroup("CANBOARDS"));
719  if(b_PROPERTIES_CANBOARDS.isNull())
720  {
721  yError() << "ServiceParser::check() cannot find PROPERTIES.CANBOARDS";
722  return false;
723  }
724  else
725  {
726  // now get type, PROTOCOL.major/minor, FIRMWARE.major/minor/build and see their sizes. the must be all equal.
727  // for mais and strain and so far for intertials it must be numboards = 1.
728 
729  Bottle b_PROPERTIES_CANBOARDS_type = b_PROPERTIES_CANBOARDS.findGroup("type");
730  if(b_PROPERTIES_CANBOARDS_type.isNull())
731  {
732  yError() << "ServiceParser::check() cannot find PROPERTIES.CANBOARDS.type";
733  return false;
734  }
735  Bottle b_PROPERTIES_CANBOARDS_PROTOCOL = Bottle(b_PROPERTIES_CANBOARDS.findGroup("PROTOCOL"));
736  if(b_PROPERTIES_CANBOARDS_PROTOCOL.isNull())
737  {
738  yError() << "ServiceParser::check() cannot find PROPERTIES.CANBOARDS.PROTOCOL";
739  return false;
740  }
741  Bottle b_PROPERTIES_CANBOARDS_PROTOCOL_major = Bottle(b_PROPERTIES_CANBOARDS_PROTOCOL.findGroup("major"));
742  if(b_PROPERTIES_CANBOARDS_PROTOCOL_major.isNull())
743  {
744  yError() << "ServiceParser::check() cannot find PROPERTIES.CANBOARDS.PROTOCOL.major";
745  return false;
746  }
747  Bottle b_PROPERTIES_CANBOARDS_PROTOCOL_minor = Bottle(b_PROPERTIES_CANBOARDS_PROTOCOL.findGroup("minor"));
748  if(b_PROPERTIES_CANBOARDS_PROTOCOL_minor.isNull())
749  {
750  yError() << "ServiceParser::check() cannot find PROPERTIES.CANBOARDS.PROTOCOL.minor";
751  return false;
752  }
753  Bottle b_PROPERTIES_CANBOARDS_FIRMWARE = Bottle(b_PROPERTIES_CANBOARDS.findGroup("FIRMWARE"));
754  if(b_PROPERTIES_CANBOARDS_FIRMWARE.isNull())
755  {
756  yError() << "ServiceParser::check() cannot find PROPERTIES.CANBOARDS.FIRMWARE";
757  return false;
758  }
759  Bottle b_PROPERTIES_CANBOARDS_FIRMWARE_major = Bottle(b_PROPERTIES_CANBOARDS_FIRMWARE.findGroup("major"));
760  if(b_PROPERTIES_CANBOARDS_FIRMWARE_major.isNull())
761  {
762  yError() << "ServiceParser::check() cannot find PROPERTIES.CANBOARDS.FIRMWARE.major";
763  return false;
764  }
765  Bottle b_PROPERTIES_CANBOARDS_FIRMWARE_minor = Bottle(b_PROPERTIES_CANBOARDS_FIRMWARE.findGroup("minor"));
766  if(b_PROPERTIES_CANBOARDS_FIRMWARE_minor.isNull())
767  {
768  yError() << "ServiceParser::check() cannot find PROPERTIES.CANBOARDS.FIRMWARE.minor";
769  return false;
770  }
771  Bottle b_PROPERTIES_CANBOARDS_FIRMWARE_build = Bottle(b_PROPERTIES_CANBOARDS_FIRMWARE.findGroup("build"));
772  if(b_PROPERTIES_CANBOARDS_FIRMWARE_build.isNull())
773  {
774  yError() << "ServiceParser::check() cannot find PROPERTIES.CANBOARDS.FIRMWARE.build";
775  return false;
776  }
777 
778  size_t tmp = b_PROPERTIES_CANBOARDS_type.size();
779  int numboards = tmp - 1; // first position of bottle contains the tag "type"
780 
781  // check if all other fields have the same size.
782  if( (tmp != b_PROPERTIES_CANBOARDS_PROTOCOL_major.size()) ||
783  (tmp != b_PROPERTIES_CANBOARDS_PROTOCOL_minor.size()) ||
784  (tmp != b_PROPERTIES_CANBOARDS_FIRMWARE_major.size()) ||
785  (tmp != b_PROPERTIES_CANBOARDS_FIRMWARE_minor.size()) ||
786  (tmp != b_PROPERTIES_CANBOARDS_FIRMWARE_build.size())
787  )
788  {
789  yError() << "ServiceParser::check_analog() in PROPERTIES.CANBOARDS some param has inconsistent length";
790  return false;
791  }
792 
793 
794  as_service.properties.canboards.resize(0);
795 
796  formaterror = false;
797  for(int i=0; i<numboards; i++)
798  {
799  servCanBoard_t item;
800 
801  convert(b_PROPERTIES_CANBOARDS_type.get(i+1).asString(), item.type, formaterror);
802  convert(b_PROPERTIES_CANBOARDS_PROTOCOL_major.get(i+1).asInt32(), item.protocol.major, formaterror);
803  convert(b_PROPERTIES_CANBOARDS_PROTOCOL_minor.get(i+1).asInt32(), item.protocol.minor, formaterror);
804 
805  convert(b_PROPERTIES_CANBOARDS_FIRMWARE_major.get(i+1).asInt32(), item.firmware.major, formaterror);
806  convert(b_PROPERTIES_CANBOARDS_FIRMWARE_minor.get(i+1).asInt32(), item.firmware.minor, formaterror);
807  convert(b_PROPERTIES_CANBOARDS_FIRMWARE_build.get(i+1).asInt32(), item.firmware.build, formaterror);
808 
809  as_service.properties.canboards.push_back(item);
810  }
811 
812  // in here we could decide to return false if any previous conversion function has returned error
813  // bool fromStringToBoolean(string str, bool &anyerror); // inside: if error then .... be sure to set error = true. dont set it to false.
814 
815  if(true == formaterror)
816  {
817  yError() << "ServiceParser::check_analog() has detected an illegal format for some of the params of PROPERTIES.CANBOARDS some param has inconsistent length";
818  return false;
819  }
820  }
821 
822  Bottle b_PROPERTIES_SENSORS = Bottle(b_PROPERTIES.findGroup("SENSORS"));
823  if(b_PROPERTIES_SENSORS.isNull())
824  {
825  yError() << "ServiceParser::check_analog() cannot find PROPERTIES.SENSORS";
826  return false;
827  }
828  else
829  {
830 
831  Bottle b_PROPERTIES_SENSORS_id = Bottle(b_PROPERTIES_SENSORS.findGroup("id"));
832  if(b_PROPERTIES_SENSORS_id.isNull())
833  {
834  yError() << "ServiceParser::check_analog() cannot find PROPERTIES.SENSORS.id";
835  return false;
836  }
837  Bottle b_PROPERTIES_SENSORS_type = Bottle(b_PROPERTIES_SENSORS.findGroup("type"));
838  if(b_PROPERTIES_SENSORS_type.isNull())
839  {
840  yError() << "ServiceParser::check_analog() cannot find PROPERTIES.SENSORS.type";
841  return false;
842  }
843  Bottle b_PROPERTIES_SENSORS_location = Bottle(b_PROPERTIES_SENSORS.findGroup("location"));
844  if(b_PROPERTIES_SENSORS_location.isNull())
845  {
846  yError() << "ServiceParser::check_analog() cannot find PROPERTIES.SENSORS.location";
847  return false;
848  }
849  Bottle b_PROPERTIES_SENSORS_frameName = Bottle(b_PROPERTIES_SENSORS.findGroup("framename"));
850  if(b_PROPERTIES_SENSORS_frameName.isNull() && eoas_string2sensor(b_PROPERTIES_SENSORS_type.get(1).asString().c_str())==eoas_strain)
851  {
852  yWarning() << "ServiceParser::check_analog() cannot find PROPERTIES.SENSORS.framename";
853  }
854  Bottle b_PROPERTIES_SENSORS_sensorName = Bottle(b_PROPERTIES_SENSORS.findGroup("sensorName"));
855  if(b_PROPERTIES_SENSORS_sensorName.isNull())
856  {
857  yWarning() << "ServiceParser::check_analog() cannot find PROPERTIES.SENSORS.sensorName";
858  }
859  Bottle b_PROPERTIES_SENSORS_boardType;
860  if((eomn_serv_AS_inertials3 == type) || (eomn_serv_AS_pos == type))
861  {
862 
863  b_PROPERTIES_SENSORS_boardType = Bottle(b_PROPERTIES_SENSORS.findGroup("boardType"));
864  if(b_PROPERTIES_SENSORS_boardType.isNull())
865  {
866  yError() << "ServiceParser::check_analog() cannot find PROPERTIES.SENSORS.boardType";
867  return false;
868  }
869  }
870  else
871  {
872  b_PROPERTIES_SENSORS_boardType.clear();
873  }
874 
875  Bottle b_PROPERTIES_SENSORS_pos_port;
876  Bottle b_PROPERTIES_SENSORS_pos_connector;
877  Bottle b_PROPERTIES_SENSORS_pos_CALIBRATION;
878  Bottle b_PROPERTIES_SENSORS_pos_CALIBRATION_type;
879  Bottle b_PROPERTIES_SENSORS_pos_CALIBRATION_rotation;
880  Bottle b_PROPERTIES_SENSORS_pos_CALIBRATION_offset;
881  Bottle b_PROPERTIES_SENSORS_pos_CALIBRATION_invertDirection;
882 
883  // add params proper only of POS
884  if(type == eomn_serv_AS_pos)
885  {
886  b_PROPERTIES_SENSORS_pos_port = Bottle(b_PROPERTIES_SENSORS.findGroup("port"));
887  if(b_PROPERTIES_SENSORS_pos_port.isNull())
888  {
889  yError() << "ServiceParser::check_analog() cannot find PROPERTIES.SENSORS.port";
890  return false;
891  }
892 
893  b_PROPERTIES_SENSORS_pos_connector = Bottle(b_PROPERTIES_SENSORS.findGroup("connector"));
894  if(b_PROPERTIES_SENSORS_pos_connector.isNull())
895  {
896  yError() << "ServiceParser::check_analog() cannot find PROPERTIES.SENSORS.connector";
897  return false;
898  }
899 
900  b_PROPERTIES_SENSORS_pos_CALIBRATION = Bottle(b_PROPERTIES_SENSORS.findGroup("CALIBRATION"));
901  if(b_PROPERTIES_SENSORS_pos_CALIBRATION.isNull())
902  {
903  yWarning() << "ServiceParser::check_analog() cannot find PROPERTIES.SENSORS.CALIBRATION. Using neutral values (ROT:zero, 0.0, false)";
904  }
905  else
906  {
907  b_PROPERTIES_SENSORS_pos_CALIBRATION_type = Bottle(b_PROPERTIES_SENSORS_pos_CALIBRATION.findGroup("type"));
908  if(b_PROPERTIES_SENSORS_pos_CALIBRATION_type.isNull())
909  {
910  yWarning() << "ServiceParser::check_analog() cannot find PROPERTIES.SENSORS.CALIBRATION.type. Using value TYPE::decideg";
911  }
912 
913  b_PROPERTIES_SENSORS_pos_CALIBRATION_rotation = Bottle(b_PROPERTIES_SENSORS_pos_CALIBRATION.findGroup("rotation"));
914  if(b_PROPERTIES_SENSORS_pos_CALIBRATION_rotation.isNull())
915  {
916  yWarning() << "ServiceParser::check_analog() cannot find PROPERTIES.SENSORS.CALIBRATION.rotation. Using value ROT::zero";
917  }
918  b_PROPERTIES_SENSORS_pos_CALIBRATION_offset = Bottle(b_PROPERTIES_SENSORS_pos_CALIBRATION.findGroup("offset"));
919  if(b_PROPERTIES_SENSORS_pos_CALIBRATION_offset.isNull())
920  {
921  yWarning() << "ServiceParser::check_analog() cannot find PROPERTIES.SENSORS.CALIBRATION.offset. Using value 0.0";
922  }
923  b_PROPERTIES_SENSORS_pos_CALIBRATION_invertDirection = Bottle(b_PROPERTIES_SENSORS_pos_CALIBRATION.findGroup("invertDirection"));
924  if(b_PROPERTIES_SENSORS_pos_CALIBRATION_invertDirection.isNull())
925  {
926  yWarning() << "ServiceParser::check_analog() cannot find PROPERTIES.SENSORS.CALIBRATION.invertDirection. Using value false";
927  }
928  }
929 
930 
931  }
932  else
933  {
934  b_PROPERTIES_SENSORS_pos_port.clear();
935  b_PROPERTIES_SENSORS_pos_connector.clear();
936  b_PROPERTIES_SENSORS_pos_CALIBRATION.clear();
937  b_PROPERTIES_SENSORS_pos_CALIBRATION_type.clear();
938  b_PROPERTIES_SENSORS_pos_CALIBRATION_rotation.clear();
939  b_PROPERTIES_SENSORS_pos_CALIBRATION_offset.clear();
940  b_PROPERTIES_SENSORS_pos_CALIBRATION_invertDirection.clear();
941  }
942 
943  size_t tmp = b_PROPERTIES_SENSORS_id.size();
944  int numsensors = tmp - 1; // first position of bottle contains the tag "id"
945 
946  // check if all other fields have the same size.
947  if( (tmp != b_PROPERTIES_SENSORS_type.size()) ||
948  (tmp != b_PROPERTIES_SENSORS_location.size()) ||
949  (((eomn_serv_AS_inertials3 == type) || (eomn_serv_AS_pos == type)) && (b_PROPERTIES_SENSORS_boardType.size() != tmp))
950  )
951  {
952  yError() << "ServiceParser::check_analog() xx in PROPERTIES.SENSORS some param has inconsistent length";
953  return false;
954  }
955 
956 
957  as_service.properties.sensors.resize(0);
958 
959  formaterror = false;
960  for(int i=0; i<numsensors; i++)
961  {
962  servAnalogSensor_t item {};
963  item.clear();
964 
965  convert(b_PROPERTIES_SENSORS_id.get(i+1).asString(), item.id, formaterror);
966  convert(b_PROPERTIES_SENSORS_type.get(i+1).asString(), item.type, formaterror);
967  convert(b_PROPERTIES_SENSORS_location.get(i+1).asString(), item.location, formaterror);
968  if(!b_PROPERTIES_SENSORS_frameName.isNull())
969  {
970  convert(b_PROPERTIES_SENSORS_frameName.get(i+1).asString(), item.frameName, formaterror);
971  }
972  if(!b_PROPERTIES_SENSORS_sensorName.isNull())
973  {
974  convert(b_PROPERTIES_SENSORS_sensorName.get(i+1).asString(), item.sensorName, formaterror);
975  }
976  if((eomn_serv_AS_inertials3 == type) || (eomn_serv_AS_pos == type))
977  {
978  convert(b_PROPERTIES_SENSORS_boardType.get(i+1).asString(), item.boardtype, formaterror);
979  }
980 
981  if(eomn_serv_AS_pos == type)
982  {
983  // part which is present only in POS service
984  parse_POS_port(b_PROPERTIES_SENSORS_pos_port.get(i+1).asString(), item.pos.port, formaterror);
985  parse_POS_connector(b_PROPERTIES_SENSORS_pos_connector.get(i+1).asString(), item.boardtype, item.pos.connector, formaterror);
986 
987  bool wehaveCALIBRATION = b_PROPERTIES_SENSORS_pos_CALIBRATION.isNull() ? false : true;
988 
989  item.pos.calibration.clear();
990  item.pos.calibration.type = eoas_pos_TYPE_decideg;
991 
992  if(wehaveCALIBRATION)
993  {
994  // then we need to parse four values: type, rotation, offset, invertDirection
995 
996  // type
997  if(false == b_PROPERTIES_SENSORS_pos_CALIBRATION_type.isNull())
998  {
999  parse_POS_CALIB_type(b_PROPERTIES_SENSORS_pos_CALIBRATION_type.get(i+1).asString(), item.pos.calibration.type, formaterror);
1000  }
1001 
1002  // rotation
1003  if(false == b_PROPERTIES_SENSORS_pos_CALIBRATION_rotation.isNull())
1004  {
1005  parse_POS_CALIB_rotation(b_PROPERTIES_SENSORS_pos_CALIBRATION_rotation.get(i+1).asString(), item.pos.calibration.rotation, formaterror);
1006  }
1007 
1008  // offset
1009  if(false == b_PROPERTIES_SENSORS_pos_CALIBRATION_offset.isNull())
1010  {
1011  item.pos.calibration.offset = b_PROPERTIES_SENSORS_pos_CALIBRATION_offset.get(i+1).asFloat32();
1012  }
1013 
1014  // invertdirection
1015  if(false == b_PROPERTIES_SENSORS_pos_CALIBRATION_invertDirection.isNull())
1016  {
1017  item.pos.calibration.invertdirection = b_PROPERTIES_SENSORS_pos_CALIBRATION_invertDirection.get(i+1).asBool();
1018  }
1019 
1020  }
1021 
1022  }
1023 
1024  as_service.properties.sensors.push_back(item);
1025  }
1026 
1027  // in here we could decide to return false if any previous conversion function has returned error
1028  // bool fromStringToBoolean(string str, bool &anyerror); // inside: if error then .... be sure to set error = true. dont set it to false.
1029 
1030  if(true == formaterror)
1031  {
1032  yError() << "ServiceParser::check_analog() has detected an illegal format for some of the params of PROPERTIES.SENSORS some param has inconsistent length";
1033  return false;
1034  }
1035 
1036  }
1037 
1038  }
1039 
1040  Bottle b_SETTINGS = Bottle(b_SERVICE.findGroup("SETTINGS"));
1041  if(b_SETTINGS.isNull())
1042  {
1043  yError() << "ServiceParser::check_analog() cannot find SETTINGS";
1044  return false;
1045  }
1046  else
1047  {
1048 
1049  Bottle b_SETTINGS_acquisitionRate = Bottle(b_SETTINGS.findGroup("acquisitionRate"));
1050  if(b_SETTINGS_acquisitionRate.isNull())
1051  {
1052  yError() << "ServiceParser::check_analog() cannot find SETTINGS.acquisitionRate";
1053  return false;
1054  }
1055  Bottle b_SETTINGS_enabledSensors = Bottle(b_SETTINGS.findGroup("enabledSensors"));
1056  if(b_SETTINGS_enabledSensors.isNull())
1057  {
1058  yError() << "ServiceParser::check_analog() cannot find SETTINGS.enabledSensors";
1059  return false;
1060  }
1061 
1062  size_t s = b_SETTINGS_enabledSensors.size();
1063  size_t numenabledsensors = (0 == s) ? (0) : (s - 1) ; // first position of bottle contains the tag "enabledSensors"
1064 
1065  // the enabled must be <= the sensors.
1066  if( numenabledsensors > as_service.properties.sensors.size() )
1067  {
1068  yError() << "ServiceParser::check_analog() in SETTINGS.enabledSensors there are too many items with respect to supported sensors:" << numenabledsensors << "vs." << as_service.properties.sensors.size();
1069  return false;
1070  }
1071 
1072  convert(b_SETTINGS_acquisitionRate.get(1).asInt32(), as_service.settings.acquisitionrate, formaterror);
1073 
1074 
1075  as_service.settings.enabledsensors.resize(0);
1076 
1077  for(size_t i=0; i<numenabledsensors; i++)
1078  {
1079  servAnalogSensor_t founditem;
1080 
1081  std::string s_enabled_id = b_SETTINGS_enabledSensors.get(i+1).asString();
1082 // const char *str = s_enabled_id.c_str();
1083 // std::string cpp_str = str;
1084 
1085  // we must now search inside the whole vector<> as_service.properties.sensors if we find an id which matches s_enabled_id ....
1086  // if we dont, ... we issue a warning.
1087  // if we find, ... we do a pushback of it inside
1088  bool found = false;
1089  // i decide to use a brute force search ... for now
1090  for(size_t n=0; n<as_service.properties.sensors.size(); n++)
1091  {
1092  servAnalogSensor_t item = as_service.properties.sensors.at(n);
1093  //if(item.id == cpp_str)
1094  if(item.id == s_enabled_id)
1095  {
1096  found = true;
1097  founditem = item;
1098  break;
1099  }
1100  }
1101 
1102  if(true == found)
1103  {
1104  as_service.settings.enabledsensors.push_back(founditem);
1105  }
1106 
1107  }
1108 
1109  // in here we issue an error if we dont have at least one enabled sensor
1110 
1111  if(0 == as_service.settings.enabledsensors.size())
1112  {
1113  yError() << "ServiceParser::check_analog() could not find any item in SETTINGS.enabledSensors which matches what in PROPERTIES.SENSORS.id";
1114  return false;
1115  }
1116 
1117  }
1118 
1119  // now we may have one or more sections which are specific of the device ...
1120 
1121  // only strain so far.
1122 
1123  if(eomn_serv_AS_strain == type)
1124  {
1125  Bottle b_STRAIN_SETTINGS = Bottle(b_SERVICE.findGroup("STRAIN_SETTINGS"));
1126  if(b_STRAIN_SETTINGS.isNull())
1127  {
1128  yError() << "ServiceParser::check_analog() cannot find STRAIN_SETTINGS";
1129  return false;
1130  }
1131  else
1132  {
1133 
1134  Bottle b_STRAIN_SETTINGS_useCalibration = Bottle(b_STRAIN_SETTINGS.findGroup("useCalibration"));
1135  if(b_STRAIN_SETTINGS_useCalibration.isNull())
1136  {
1137  yError() << "ServiceParser::check_analog() cannot find STRAIN_SETTINGS.useCalibration";
1138  return false;
1139  }
1140 
1141  formaterror = false;
1142  convert(b_STRAIN_SETTINGS_useCalibration.get(1).asString(), as_strain_settings.useCalibration, formaterror);
1143 
1144  if(true == formaterror)
1145  {
1146  yError() << "ServiceParser::check_analog() has detected an illegal format for paramf STRAIN_SETTINGS.useCalibration";
1147  return false;
1148  }
1149  }
1150  }
1151 
1152 
1153 
1154 
1155  // we we are in here we have the struct filled with all variables ... some validations are still due to the calling device.
1156  // for instance, if embObjMais
1157 
1158  return true;
1159 }
1160 
1161 bool ServiceParser::check_skin(Searchable &config)
1162 {
1163  const eOmn_serv_type_t type = eomn_serv_SK_skin;
1164  bool formaterror = false;
1165 
1166  // the format so far is:
1167  // SERVICE{ type, PROPERTIES{ CANBOARDS } }
1168  // later on we can add SERVICE.PROPERTIES.SENSORS and SERVICE.SETTINGS
1169 
1170  // however: if w dont have the SERVICE group we return false so that the caller can use default values
1171 
1172 
1173  Bottle b_SERVICE(config.findGroup("SERVICE"));
1174  if(b_SERVICE.isNull())
1175  {
1176  // yWarning() << "ServiceParser::check_skin() cannot find SERVICE group";
1177  return false;
1178  }
1179 
1180  // check whether we have the proper type
1181 
1182  if(false == b_SERVICE.check("type"))
1183  {
1184  // yWarning() << "ServiceParser::check_skin() cannot find SERVICE.type";
1185  return false;
1186  }
1187  else
1188  {
1189  Bottle b_type(b_SERVICE.find("type").asString());
1190  if(false == convert(b_type.toString(), sk_service.type, formaterror))
1191  {
1192  yWarning() << "ServiceParser::check_skin() has found unknown SERVICE.type = " << b_type.toString();
1193  return false;
1194  }
1195  if(type != sk_service.type)
1196  {
1197  yWarning() << "ServiceParser::check_skin() has found wrong SERVICE.type = " << sk_service.type << "it must be" << "TODO: tostring() function";
1198  return false;
1199  }
1200  }
1201 
1202  // check whether we have the proper groups
1203 
1204  Bottle b_PROPERTIES = Bottle(b_SERVICE.findGroup("PROPERTIES"));
1205  if(b_PROPERTIES.isNull())
1206  {
1207  yWarning() << "ServiceParser::check_skin() cannot find PROPERTIES";
1208  return false;
1209  }
1210  else
1211  {
1212  Bottle b_PROPERTIES_CANBOARDS = Bottle(b_PROPERTIES.findGroup("CANBOARDS"));
1213  if(b_PROPERTIES_CANBOARDS.isNull())
1214  {
1215  yWarning() << "ServiceParser::check() cannot find PROPERTIES.CANBOARDS";
1216  return false;
1217  }
1218  else
1219  {
1220  // now get type, PROTOCOL.major/minor, FIRMWARE.major/minor/build and see their sizes. the must be all equal.
1221  // for skin it must be numboards = 1.
1222 
1223  Bottle b_PROPERTIES_CANBOARDS_type = b_PROPERTIES_CANBOARDS.findGroup("type");
1224  if(b_PROPERTIES_CANBOARDS_type.isNull())
1225  {
1226  yError() << "ServiceParser::check_skin() cannot find PROPERTIES.CANBOARDS.type";
1227  return false;
1228  }
1229  Bottle b_PROPERTIES_CANBOARDS_PROTOCOL = Bottle(b_PROPERTIES_CANBOARDS.findGroup("PROTOCOL"));
1230  if(b_PROPERTIES_CANBOARDS_PROTOCOL.isNull())
1231  {
1232  yError() << "ServiceParser::check_skin() cannot find PROPERTIES.CANBOARDS.PROTOCOL";
1233  return false;
1234  }
1235  Bottle b_PROPERTIES_CANBOARDS_PROTOCOL_major = Bottle(b_PROPERTIES_CANBOARDS_PROTOCOL.findGroup("major"));
1236  if(b_PROPERTIES_CANBOARDS_PROTOCOL_major.isNull())
1237  {
1238  yError() << "ServiceParser::check_skin() cannot find PROPERTIES.CANBOARDS.PROTOCOL.major";
1239  return false;
1240  }
1241  Bottle b_PROPERTIES_CANBOARDS_PROTOCOL_minor = Bottle(b_PROPERTIES_CANBOARDS_PROTOCOL.findGroup("minor"));
1242  if(b_PROPERTIES_CANBOARDS_PROTOCOL_minor.isNull())
1243  {
1244  yError() << "ServiceParser::check_skin() cannot find PROPERTIES.CANBOARDS.PROTOCOL.minor";
1245  return false;
1246  }
1247  Bottle b_PROPERTIES_CANBOARDS_FIRMWARE = Bottle(b_PROPERTIES_CANBOARDS.findGroup("FIRMWARE"));
1248  if(b_PROPERTIES_CANBOARDS_FIRMWARE.isNull())
1249  {
1250  yError() << "ServiceParser::check_skin() cannot find PROPERTIES.CANBOARDS.FIRMWARE";
1251  return false;
1252  }
1253  Bottle b_PROPERTIES_CANBOARDS_FIRMWARE_major = Bottle(b_PROPERTIES_CANBOARDS_FIRMWARE.findGroup("major"));
1254  if(b_PROPERTIES_CANBOARDS_FIRMWARE_major.isNull())
1255  {
1256  yError() << "ServiceParser::check_skin() cannot find PROPERTIES.CANBOARDS.FIRMWARE.major";
1257  return false;
1258  }
1259  Bottle b_PROPERTIES_CANBOARDS_FIRMWARE_minor = Bottle(b_PROPERTIES_CANBOARDS_FIRMWARE.findGroup("minor"));
1260  if(b_PROPERTIES_CANBOARDS_FIRMWARE_minor.isNull())
1261  {
1262  yError() << "ServiceParser::check_skin() cannot find PROPERTIES.CANBOARDS.FIRMWARE.minor";
1263  return false;
1264  }
1265  Bottle b_PROPERTIES_CANBOARDS_FIRMWARE_build = Bottle(b_PROPERTIES_CANBOARDS_FIRMWARE.findGroup("build"));
1266  if(b_PROPERTIES_CANBOARDS_FIRMWARE_build.isNull())
1267  {
1268  yError() << "ServiceParser::check_skin() cannot find PROPERTIES.CANBOARDS.FIRMWARE.build";
1269  return false;
1270  }
1271 
1272  size_t tmp = b_PROPERTIES_CANBOARDS_type.size();
1273  size_t numboards = (0 == tmp) ? 0 : (tmp - 1); // first position of bottle contains the tag "type"
1274 
1275  // check if all other fields have the same size.
1276  if( (tmp != b_PROPERTIES_CANBOARDS_PROTOCOL_major.size()) ||
1277  (tmp != b_PROPERTIES_CANBOARDS_PROTOCOL_minor.size()) ||
1278  (tmp != b_PROPERTIES_CANBOARDS_FIRMWARE_major.size()) ||
1279  (tmp != b_PROPERTIES_CANBOARDS_FIRMWARE_minor.size()) ||
1280  (tmp != b_PROPERTIES_CANBOARDS_FIRMWARE_build.size())
1281  )
1282  {
1283  yError() << "ServiceParser::check_skin() in PROPERTIES.CANBOARDS some param has inconsistent length";
1284  return false;
1285  }
1286 
1287  if(1 != numboards)
1288  {
1289  yError() << "ServiceParser::check_skin() in PROPERTIES.CANBOARDS has found more than one board";
1290  return false;
1291  }
1292 
1293  formaterror = false;
1294 
1295  sk_service.properties.canboard.clear();
1296 
1297  convert(b_PROPERTIES_CANBOARDS_type.get(1).asString(), sk_service.properties.canboard.type, formaterror);
1298  convert(b_PROPERTIES_CANBOARDS_PROTOCOL_major.get(1).asInt32(), sk_service.properties.canboard.protocol.major, formaterror);
1299  convert(b_PROPERTIES_CANBOARDS_PROTOCOL_minor.get(1).asInt32(), sk_service.properties.canboard.protocol.minor, formaterror);
1300 
1301  convert(b_PROPERTIES_CANBOARDS_FIRMWARE_major.get(1).asInt32(), sk_service.properties.canboard.firmware.major, formaterror);
1302  convert(b_PROPERTIES_CANBOARDS_FIRMWARE_minor.get(1).asInt32(), sk_service.properties.canboard.firmware.minor, formaterror);
1303  convert(b_PROPERTIES_CANBOARDS_FIRMWARE_build.get(1).asInt32(), sk_service.properties.canboard.firmware.build, formaterror);
1304 
1305 
1306 
1307  // in here we could decide to return false if any previous conversion function has returned error
1308  // bool fromStringToBoolean(string str, bool &anyerror); // inside: if error then .... be sure to set error = true. dont set it to false.
1309 
1310  if(true == formaterror)
1311  {
1312  yError() << "ServiceParser::check_skin() has detected an illegal format for some of the params of PROPERTIES.CANBOARDS some param has inconsistent length";
1313  return false;
1314  }
1315  }
1316 
1317 #if 0
1318  // we dont have this group yet
1319 
1320  Bottle b_PROPERTIES_SENSORS = Bottle(b_PROPERTIES.findGroup("SENSORS"));
1321  if(b_PROPERTIES_SENSORS.isNull())
1322  {
1323  yError() << "ServiceParser::check() cannot find PROPERTIES.SENSORS";
1324  return false;
1325  }
1326  else
1327  {
1328 
1329  Bottle b_PROPERTIES_SENSORS_id = Bottle(b_PROPERTIES_SENSORS.findGroup("id"));
1330  if(b_PROPERTIES_SENSORS_id.isNull())
1331  {
1332  yError() << "ServiceParser::check() cannot find PROPERTIES.SENSORS.id";
1333  return false;
1334  }
1335  Bottle b_PROPERTIES_SENSORS_type = Bottle(b_PROPERTIES_SENSORS.findGroup("type"));
1336  if(b_PROPERTIES_SENSORS_type.isNull())
1337  {
1338  yError() << "ServiceParser::check() cannot find PROPERTIES.SENSORS.type";
1339  return false;
1340  }
1341  Bottle b_PROPERTIES_SENSORS_location = Bottle(b_PROPERTIES_SENSORS.findGroup("location"));
1342  if(b_PROPERTIES_SENSORS_location.isNull())
1343  {
1344  yError() << "ServiceParser::check() cannot find PROPERTIES.SENSORS.location";
1345  return false;
1346  }
1347  Bottle b_PROPERTIES_SENSORS_boardtype;
1348  if(type == eomn_serv_AS_inertials3)
1349  {
1350 
1351  b_PROPERTIES_SENSORS_boardtype = Bottle(b_PROPERTIES_SENSORS.findGroup("boardType"));
1352  if(b_PROPERTIES_SENSORS_boardtype.isNull())
1353  {
1354  yError() << "ServiceParser::check() cannot find PROPERTIES.SENSORS.boardType";
1355  return false;
1356  }
1357  }
1358  else
1359  {
1360  b_PROPERTIES_SENSORS_boardtype.clear();
1361  }
1362 
1363  int tmp = b_PROPERTIES_SENSORS_id.size();
1364  int numsensors = tmp - 1; // first position of bottle contains the tag "id"
1365 
1366  // check if all other fields have the same size.
1367  if( (tmp != b_PROPERTIES_SENSORS_type.size()) ||
1368  (tmp != b_PROPERTIES_SENSORS_location.size()) ||
1369  ((type == eomn_serv_AS_inertials3) && (b_PROPERTIES_SENSORS_boardtype.size() != tmp))
1370  )
1371  {
1372  yError() << "ServiceParser::check() in PROPERTIES.SENSORS some param has inconsistent length";
1373  return false;
1374  }
1375 
1376 
1377  sk_service.properties.sensors.resize(0);
1378 
1379  formaterror = false;
1380  for(int i=0; i<numsensors; i++)
1381  {
1382  servAnalogSensor_t item;
1383  item.type = eoas_none;
1384  item.location.any.place = eobrd_place_none;
1385 
1386  convert(b_PROPERTIES_SENSORS_id.get(i+1).asString(), item.id, formaterror);
1387  convert(b_PROPERTIES_SENSORS_type.get(i+1).asString(), item.type, formaterror);
1388  convert(b_PROPERTIES_SENSORS_location.get(i+1).asString(), item.location, formaterror);
1389  if(type == eomn_serv_AS_inertials3)
1390  {
1391  convert(b_PROPERTIES_SENSORS_boardtype.get(i+1).asString(), item.boardtype, formaterror);
1392  }
1393  else
1394  {
1395  item.boardtype = eobrd_none;
1396  }
1397 
1398  sk_service.properties.sensors.push_back(item);
1399  }
1400 
1401  // in here we could decide to return false if any previous conversion function has returned error
1402  // bool fromStringToBoolean(string str, bool &anyerror); // inside: if error then .... be sure to set error = true. dont set it to false.
1403 
1404  if(true == formaterror)
1405  {
1406  yError() << "ServiceParser::check() has detected an illegal format for some of the params of PROPERTIES.SENSORS some param has inconsistent length";
1407  return false;
1408  }
1409 
1410  }
1411 
1412 #endif
1413 
1414  }
1415 
1416 #if 0
1417 
1418  // we dont have this group yet
1419 
1420  Bottle b_SETTINGS = Bottle(b_SERVICE.findGroup("SETTINGS"));
1421  if(b_SETTINGS.isNull())
1422  {
1423  yError() << "ServiceParser::check() cannot find SETTINGS";
1424  return false;
1425  }
1426  else
1427  {
1428 
1429  Bottle b_SETTINGS_acquisitionRate = Bottle(b_SETTINGS.findGroup("acquisitionRate"));
1430  if(b_SETTINGS_acquisitionRate.isNull())
1431  {
1432  yError() << "ServiceParser::check() cannot find SETTINGS.acquisitionRate";
1433  return false;
1434  }
1435  Bottle b_SETTINGS_enabledSensors = Bottle(b_SETTINGS.findGroup("enabledSensors"));
1436  if(b_SETTINGS_enabledSensors.isNull())
1437  {
1438  yError() << "ServiceParser::check() cannot find SETTINGS.enabledSensors";
1439  return false;
1440  }
1441 
1442  int numenabledsensors = b_SETTINGS_enabledSensors.size() - 1; // first position of bottle contains the tag "enabledSensors"
1443 
1444  // the enabled must be <= the sensors.
1445  if( numenabledsensors > sk_service.properties.sensors.size() )
1446  {
1447  yError() << "ServiceParser::check() in SETTINGS.enabledSensors there are too many items with respect to supported sensors:" << numenabledsensors << "vs." << sk_service.properties.sensors.size();
1448  return false;
1449  }
1450 
1451  convert(b_SETTINGS_acquisitionRate.get(1).asInt32(), sk_service.settings.acquisitionrate, formaterror);
1452 
1453 
1454  sk_service.settings.enabledsensors.resize(0);
1455 
1456  for(int i=0; i<numenabledsensors; i++)
1457  {
1458  servAnalogSensor_t founditem;
1459 
1460  std::string s_enabled_id = b_SETTINGS_enabledSensors.get(i+1).asString();
1461 // const char *str = s_enabled_id.c_str();
1462 // std::string cpp_str = str;
1463 
1464  // we must now search inside the whole vector<> sk_service.properties.sensors if we find an id which matches s_enabled_id ....
1465  // if we dont, ... we issue a warning.
1466  // if we find, ... we do a pushback of it inside
1467  bool found = false;
1468  // i decide to use a brute force search ... for now
1469  for(size_t n=0; n<sk_service.properties.sensors.size(); n++)
1470  {
1471  servAnalogSensor_t item = sk_service.properties.sensors.at(n);
1472  //if(item.id == cpp_str)
1473  if(item.id == s_enabled_id)
1474  {
1475  found = true;
1476  founditem = item;
1477  break;
1478  }
1479  }
1480 
1481  if(true == found)
1482  {
1483  sk_service.settings.enabledsensors.push_back(founditem);
1484  }
1485 
1486  }
1487 
1488  // in here we issue an error if we dont have at least one enabled sensor
1489 
1490  if(0 == sk_service.settings.enabledsensors.size())
1491  {
1492  yError() << "ServiceParser::check() could not find any item in SETTINGS.enabledSensors which matches what in PROPERTIES.SENSORS.id";
1493  return false;
1494  }
1495 
1496  }
1497 
1498 #endif
1499 
1500 
1501 #if 0
1502  // we dont have this group yet
1503  // now we may have one or more sections which are specific of the device ...
1504 
1505 
1506 
1507  if(eomn_serv_AS_strain == type)
1508  {
1509  Bottle b_STRAIN_SETTINGS = Bottle(b_SERVICE.findGroup("STRAIN_SETTINGS"));
1510  if(b_STRAIN_SETTINGS.isNull())
1511  {
1512  yError() << "ServiceParser::check() cannot find STRAIN_SETTINGS";
1513  return false;
1514  }
1515  else
1516  {
1517 
1518  Bottle b_STRAIN_SETTINGS_useCalibration = Bottle(b_STRAIN_SETTINGS.findGroup("useCalibration"));
1519  if(b_STRAIN_SETTINGS_useCalibration.isNull())
1520  {
1521  yError() << "ServiceParser::check() cannot find STRAIN_SETTINGS.useCalibration";
1522  return false;
1523  }
1524 
1525  formaterror = false;
1526  convert(b_STRAIN_SETTINGS_useCalibration.get(1).asString(), sk_skin_settings.useCalibration, formaterror);
1527 
1528  if(true == formaterror)
1529  {
1530  yError() << "ServiceParser::check() has detected an illegal format for paramf STRAIN_SETTINGS.useCalibration";
1531  return false;
1532  }
1533  }
1534  }
1535 
1536 
1537 #endif
1538 
1539 
1540  // we we are in here we have the struct filled with all variables ... some validations are still due to the calling device.
1541 
1542  return true;
1543 }
1544 
1545 
1546 
1547 bool ServiceParser::parseService(Searchable &config, servConfigMais_t &maisconfig)
1548 {
1549  if(false == check_analog(config, eomn_serv_AS_mais))
1550  {
1551  yError() << "ServiceParser::parseService() has received an invalid SERVICE group for mais";
1552  return false;
1553  }
1554 
1555  // now we extract values ... so far we dont make many checks ... we just assume the vector<> are of size 1.
1556  servCanBoard_t themais_props = as_service.properties.canboards.at(0);
1557  servAnalogSensor_t themais_sensor = as_service.settings.enabledsensors.at(0);
1558 
1559 
1560  // first check we do is about themais_props.type
1561  if(eobrd_cantype_mais != themais_props.type)
1562  {
1563  yError() << "ServiceParser::parseService() has detected an invalid type of board. it should be a eobrd_mais but is a:" << eoboards_type2string2(eoboards_cantype2type(themais_props.type), eobool_false);
1564  return false;
1565  }
1566 
1567  maisconfig.acquisitionrate = as_service.settings.acquisitionrate;
1568 
1569  maisconfig.nameOfMais = themais_sensor.id;
1570 
1571  memset(&maisconfig.ethservice.configuration, 0, sizeof(maisconfig.ethservice.configuration));
1572 
1573  maisconfig.ethservice.configuration.type = eomn_serv_AS_mais;
1574  memcpy(&maisconfig.ethservice.configuration.data.as.mais.version.protocol, &themais_props.protocol, sizeof(eObrd_protocolversion_t));
1575  memcpy(&maisconfig.ethservice.configuration.data.as.mais.version.firmware, &themais_props.firmware, sizeof(eObrd_firmwareversion_t));
1576 
1577  // second check we do is about themais_sensor.location
1578  if(eobrd_place_can != themais_sensor.location.any.place)
1579  {
1580  yError() << "ServiceParser::parseService() has received an invalid location for its mais. it is not a CANx:adr location";
1581  return false;
1582  }
1583  maisconfig.ethservice.configuration.data.as.mais.canloc.port = themais_sensor.location.can.port;
1584  maisconfig.ethservice.configuration.data.as.mais.canloc.addr = themais_sensor.location.can.addr;
1585  maisconfig.ethservice.configuration.data.as.mais.canloc.insideindex = eobrd_caninsideindex_none;
1586 
1587 
1588  return true;
1589 }
1590 
1591 
1592 bool ServiceParser::parseService(Searchable &config, servConfigStrain_t &strainconfig)
1593 {
1594  if(false == check_analog(config, eomn_serv_AS_strain))
1595  {
1596  yError() << "ServiceParser::parseService() has received an invalid SERVICE group for strain";
1597  return false;
1598  }
1599 
1600  // now we extract values ... so far we dont make many checks ... we just assume the vector<> are of size 1.
1601  servCanBoard_t thestrain_props = as_service.properties.canboards.at(0);
1602  servAnalogSensor_t thestrain_sensor = as_service.settings.enabledsensors.at(0);
1603 
1604  // first check we do is about thestrain_props.type
1605  if((eobrd_cantype_strain != thestrain_props.type) && (eobrd_cantype_strain2 != thestrain_props.type) && (eobrd_cantype_strain2c != thestrain_props.type))
1606  {
1607  yError() << "ServiceParser::parseService() has detected an invalid type of board. it should be a eobrd_strain, eobrd_strain2 or eobrd_strain2c but is a:" << eoboards_type2string2(eoboards_cantype2type(thestrain_props.type), eobool_false);
1608  return false;
1609  }
1610 
1611  strainconfig.acquisitionrate = as_service.settings.acquisitionrate;
1612  strainconfig.useCalibration = as_strain_settings.useCalibration;
1613  strainconfig.nameOfStrain = thestrain_sensor.id;
1614 
1615  memset(&strainconfig.ethservice.configuration, 0, sizeof(strainconfig.ethservice.configuration));
1616 
1617  strainconfig.ethservice.configuration.type = eomn_serv_AS_strain;
1618  strainconfig.ethservice.configuration.data.as.strain.boardtype.type = thestrain_props.type;
1619  memcpy(&strainconfig.ethservice.configuration.data.as.strain.boardtype.protocol, &thestrain_props.protocol, sizeof(eObrd_protocolversion_t));
1620  memcpy(&strainconfig.ethservice.configuration.data.as.strain.boardtype.firmware, &thestrain_props.firmware, sizeof(eObrd_firmwareversion_t));
1621 
1622  // second check we do is about thestrain_sensor.location
1623  if(eobrd_place_can != thestrain_sensor.location.any.place)
1624  {
1625  yError() << "ServiceParser::parseService() has received an invalid location for strain. it is not a CANx:adr location";
1626  return false;
1627  }
1628  strainconfig.ethservice.configuration.data.as.strain.canloc.port = thestrain_sensor.location.can.port;
1629  strainconfig.ethservice.configuration.data.as.strain.canloc.addr = thestrain_sensor.location.can.addr;
1630  strainconfig.ethservice.configuration.data.as.strain.canloc.insideindex = eobrd_caninsideindex_none;
1631 
1632 
1633 
1634  return true;
1635 }
1636 
1637 bool ServiceParser::parseService(Searchable &config, servConfigFTsensor_t &ftconfig)
1638 {
1639  if(false == check_analog(config, eomn_serv_AS_strain))
1640  {
1641  yError() << "ServiceParser::parseService() has received an invalid SERVICE group for strain";
1642  return false;
1643  }
1644 
1645  // now we extract values ... so far we dont make many checks ... we just assume the vector<> are of size 1.
1646  servCanBoard_t thestrain_props = as_service.properties.canboards.at(0);
1647  servAnalogSensor_t thestrain_sensor = as_service.settings.enabledsensors.at(0);
1648 
1649  // first check we do is about thestrain_props.type
1650  if( (eobrd_cantype_strain != thestrain_props.type) && (eobrd_cantype_strain2 != thestrain_props.type) && (eobrd_cantype_strain2c != thestrain_props.type))
1651  {
1652  yError() << "ServiceParser::parseService() for embObjFTsensor has detected an invalid type of board. it should be a eobrd_strain2 or a eobrd_strain2c but is a:" << eoboards_type2string2(eoboards_cantype2type(thestrain_props.type), eobool_false);
1653  return false;
1654  }
1655 
1656  ftconfig.acquisitionrate = as_service.settings.acquisitionrate;
1657  ftconfig.useCalibration = as_strain_settings.useCalibration;
1658  ftconfig.nameOfStrain = thestrain_sensor.id;
1659  ftconfig.frameName = thestrain_sensor.frameName;
1660 
1661  memset(&ftconfig.ethservice.configuration, 0, sizeof(ftconfig.ethservice.configuration));
1662 
1663  ftconfig.ethservice.configuration.type = eomn_serv_AS_strain;
1664  ftconfig.ethservice.configuration.data.as.strain.boardtype.type = thestrain_props.type;
1665  memcpy(&ftconfig.ethservice.configuration.data.as.strain.boardtype.protocol, &thestrain_props.protocol, sizeof(eObrd_protocolversion_t));
1666  memcpy(&ftconfig.ethservice.configuration.data.as.strain.boardtype.firmware, &thestrain_props.firmware, sizeof(eObrd_firmwareversion_t));
1667 
1668  // second check we do is about thestrain_sensor.location
1669  if(eobrd_place_can != thestrain_sensor.location.any.place)
1670  {
1671  yError() << "ServiceParser::parseService() has received an invalid location for strain. it is not a CANx:adr location";
1672  return false;
1673  }
1674  ftconfig.ethservice.configuration.data.as.strain.canloc.port = thestrain_sensor.location.can.port;
1675  ftconfig.ethservice.configuration.data.as.strain.canloc.addr = thestrain_sensor.location.can.addr;
1676  ftconfig.ethservice.configuration.data.as.strain.canloc.insideindex = eobrd_caninsideindex_none;
1677 
1678 
1679 
1680  Bottle b_SERVICE(config.findGroup("SERVICE")); //b_SERVICE and b_SETTINGS could not be null, otherwise parseService function would have returned false
1681  Bottle b_SETTINGS = Bottle(b_SERVICE.findGroup("SETTINGS"));
1682  Bottle b_SETTINGS_temp = Bottle(b_SETTINGS.findGroup("temperature-acquisitionRate"));
1683  // Only strain2 and strain2c has temperature sensors.
1684  if(b_SETTINGS_temp.isNull())
1685  {
1686  if (eobrd_cantype_strain != thestrain_props.type) {
1687  yError() << "ServiceParser::parseService() for embObjFTsensor device cannot find SETTINGS.temperature-acquisitionRate";
1688  return false;
1689  }
1690  else {
1691  // If set to -1, embObjFTSensor disable the temperature.
1692  ftconfig.temperatureAcquisitionrate = -1;
1693  }
1694  }
1695  else
1696  {
1697  ftconfig.temperatureAcquisitionrate = b_SETTINGS_temp.get(1).asInt32();
1698  //TODO: chek that the acquisition rate is inside a reasonable range
1699  }
1700 
1701  return true;
1702 }
1703 
1704 bool ServiceParser::parseService(Searchable &config, servConfigImu_t &imuconfig)
1705 {
1706  if(false == check_analog(config, eomn_serv_AS_inertials3))
1707  {
1708  yError() << "ServiceParser::parseService(IMU) has received an invalid SERVICE group for IMU";
1709  return false;
1710  }
1711 
1712 
1713  //check the num of type of boards. At max we have 4 board type (see eOas_inertials3_boardinfos_maxnumber)
1714 
1715  if(as_service.properties.canboards.size() > eOas_inertials3_boardinfos_maxnumber)
1716  {
1717  yError() << "ServiceParser::parseService(IMU): too many type board info are configured. The max num is " << eOas_inertials3_boardinfos_maxnumber;
1718  return false;
1719  }
1720 
1721  //reset configuration service
1722  memset(&imuconfig.ethservice.configuration, 0, sizeof(imuconfig.ethservice.configuration));
1723 
1724  //set type of service
1725  imuconfig.ethservice.configuration.type = eomn_serv_AS_inertials3;
1726 
1727 
1728  //get acquisition rate
1729  imuconfig.acquisitionrate = as_service.settings.acquisitionrate;
1730 
1731  //get enabled sensor and fill canboard array. Note that we get only the enabled sensor, not all configured sensors !!!
1732 
1733  imuconfig.inertials.resize(0);
1734 
1735  eOas_inertial3_setof_boardinfos_t * boardInfoSet_ptr = &imuconfig.ethservice.configuration.data.as.inertial3.setofboardinfos;
1736  eOresult_t res = eoas_inertial3_setof_boardinfos_clear(boardInfoSet_ptr);
1737  if(res != eores_OK)
1738  {
1739  yError() << "ServiceParser::parseService(IMU). Error in eoas_inertial3_setof_boardinfos_clear()";
1740  return false;
1741  }
1742 
1743  EOarray* array = eo_array_New(eOas_inertials3_descriptors_maxnumber, sizeof(eOas_inertial3_descriptor_t), &imuconfig.ethservice.configuration.data.as.inertial3.arrayofdescriptor);
1744  for(size_t i=0; i<as_service.settings.enabledsensors.size(); i++)
1745  {
1746  servAnalogSensor_t sensor = as_service.settings.enabledsensors.at(i);
1747  eOas_sensor_t type = sensor.type;
1748 
1749  //TODO: temperature???
1750  if( (eoas_imu_acc != type) && (eoas_imu_mag != type) && (eoas_imu_gyr != type) && (eoas_imu_eul != type) &&
1751  (eoas_imu_qua != type) && (eoas_imu_lia != type) && (eoas_imu_grv != type) && (eoas_imu_status != type) &&
1752  (eoas_accel_mtb_int != type) && (eoas_accel_mtb_ext != type) && (eoas_gyros_mtb_ext != type) &&
1753  (eoas_gyros_st_l3g4200d != type))
1754  {
1755  yWarning() << "ServiceParser::parseService() has detected a wrong inertial sensor:" << eoas_sensor2string(type) << " ... we drop it";
1756  continue;
1757  }
1758  // if ok, i copy it inside ...
1759 
1760  eOas_inertial3_descriptor_t des = {};
1761  des.typeofsensor = type;
1762  memcpy(&des.on, &sensor.location, sizeof(eObrd_location_t));
1763 
1764  const eObrd_info_t *boardInfo_ptr = eoas_inertial3_setof_boardinfos_find(boardInfoSet_ptr, eoboards_type2cantype(sensor.boardtype));
1765  if(nullptr == boardInfo_ptr && sensor.boardtype != eobrd_ems4) // If the sensor is an ems, it does not make sense to find it in can boards
1766  //if I did not already insert the borad info with type == sensor.boardtype, now I insert it
1767  {
1768  // first of all I need to find the board info for this board type
1769  bool found = false;
1770  size_t b = 0;
1771  for(b=0; b<as_service.properties.canboards.size(); b++)
1772  {
1773  if(as_service.properties.canboards.at(b).type == eoboards_type2cantype(sensor.boardtype))
1774  {
1775  found = true;
1776  break;
1777  }
1778  }
1779  if(!found)
1780  {
1781  yError() << "ServiceParser::parseService(IMU). The sensor " << sensor.boardtype << "with type "<< eoas_sensor2string(static_cast<eOas_sensor_t> (des.typeofsensor)) << "has borad type " << eoboards_type2string2(sensor.boardtype, false) << " that is not declared in the SERVICE.PROPERTIES.CANBOARDS tag";
1782  return false;
1783  }
1784  eObrd_info_t boardInfo = {};
1785  boardInfo.type = as_service.properties.canboards.at(b).type;
1786  memcpy(&boardInfo.protocol , &as_service.properties.canboards.at(b).protocol, sizeof(eObrd_protocolversion_t));
1787  memcpy(&boardInfo.firmware, &as_service.properties.canboards.at(b).firmware, sizeof(eObrd_firmwareversion_t));
1788  res = eoas_inertial3_setof_boardinfos_add(boardInfoSet_ptr, &boardInfo);
1789  if(eores_OK != res)
1790  {
1791  yError() << "ServiceParser::parseService(IMU). Error in eoas_inertial3_setof_boardinfos_add()";
1792  return false;
1793  }
1794  }
1795  des.typeofboard = sensor.boardtype;
1796 
1797  eo_array_PushBack(array, &des);
1798  imuconfig.inertials.push_back(des);
1799  imuconfig.id.push_back(sensor.id);
1800  imuconfig.sensorName.push_back(sensor.sensorName);
1801  }
1802 
1803 
1804  return true;
1805 }
1806 
1807 
1808 bool ServiceParser::parseService(Searchable &config, servConfigSkin_t &skinconfig)
1809 {
1810 
1811  skinconfig.canboard.type = eobrd_cantype_mtb;
1812  skinconfig.canboard.firmware.major = 0;
1813  skinconfig.canboard.firmware.minor = 0;
1814  skinconfig.canboard.firmware.build = 0;
1815  skinconfig.canboard.protocol.major = 0;
1816  skinconfig.canboard.protocol.minor = 0;
1817 
1818 
1819  if(false == check_skin(config))
1820  {
1821  yWarning() << "ServiceParser::parseService(SKIN) has received an invalid SERVICE group: using defaults";
1822  return true;
1823  }
1824 
1825 
1826  //check the type of board. it must be mtb / mtb4 / mtb4c / psc
1827 
1828  if((eobrd_cantype_mtb != sk_service.properties.canboard.type) && (eobrd_cantype_mtb4 != sk_service.properties.canboard.type) && (eobrd_cantype_psc != sk_service.properties.canboard.type) && (eobrd_cantype_mtb4c != sk_service.properties.canboard.type))
1829  {
1830  yError() << "ServiceParser::parseService(SK): only mtb / mtb4 / mtb4c / psc boards are allowed: using defaults";
1831  return false;
1832  }
1833 
1834 
1835  // fill canboard
1836  skinconfig.canboard.type = sk_service.properties.canboard.type;
1837  skinconfig.canboard.firmware.major = sk_service.properties.canboard.firmware.major;
1838  skinconfig.canboard.firmware.minor = sk_service.properties.canboard.firmware.minor;
1839  skinconfig.canboard.firmware.build = sk_service.properties.canboard.firmware.build;
1840  skinconfig.canboard.protocol.major = sk_service.properties.canboard.protocol.major;
1841  skinconfig.canboard.protocol.minor = sk_service.properties.canboard.protocol.minor;
1842 
1843  return true;
1844 }
1845 
1846 
1847 bool ServiceParser::parseService(Searchable &config, servConfigPSC_t &pscconfig)
1848 {
1849  if(false == check_analog(config, eomn_serv_AS_psc))
1850  {
1851  yError() << "ServiceParser::parseService(PSC) has received an invalid SERVICE group for PSC";
1852  return false;
1853  }
1854 
1855 
1856  //check the num of type of boards. At max we have 1 board type
1857 
1858  if(as_service.properties.canboards.size() > 1)
1859  {
1860  yError() << "ServiceParser::parseService(PSC): too many type board info are configured. The max num is " << 1;
1861  return false;
1862  }
1863 
1864  if(as_service.settings.enabledsensors.size() > eOas_psc_boards_maxnumber)
1865  {
1866  yError() << "ServiceParser::parseService(PSC): too many enabled sensors are configured. The max num is " << eOas_psc_boards_maxnumber;
1867  return false;
1868  }
1869 
1870  //reset configuration service
1871  memset(&pscconfig.ethservice.configuration, 0, sizeof(pscconfig.ethservice.configuration));
1872 
1873  //set type of service
1874  pscconfig.ethservice.configuration.type = eomn_serv_AS_psc;
1875 
1876 
1877  //get acquisition rate
1878  pscconfig.acquisitionrate = as_service.settings.acquisitionrate;
1879 
1880  servCanBoard_t *asServBoardInfo_ptr = &as_service.properties.canboards[0];
1881  eOmn_serv_config_data_as_psc_t *pscBoardConfig_ptr = &pscconfig.ethservice.configuration.data.as.psc;
1882 
1883  //get firmware and protocol info
1884  pscBoardConfig_ptr->version.firmware.major = asServBoardInfo_ptr->firmware.major;
1885  pscBoardConfig_ptr->version.firmware.minor = asServBoardInfo_ptr->firmware.minor;
1886  pscBoardConfig_ptr->version.firmware.build = asServBoardInfo_ptr->firmware.build;
1887  pscBoardConfig_ptr->version.protocol.major = asServBoardInfo_ptr->protocol.major;
1888  pscBoardConfig_ptr->version.protocol.minor = asServBoardInfo_ptr->protocol.minor;
1889 
1890  for(size_t i=0; i<as_service.settings.enabledsensors.size(); i++)
1891  {
1892  servAnalogSensor_t sensor = as_service.settings.enabledsensors.at(i);
1893 
1894  if(eoas_psc_angle != sensor.type)
1895  {
1896  yWarning() << "ServiceParser::parseService() has detected a wrong psc sensor:" << eoas_sensor2string(sensor.type) << " ... we drop it";
1897  continue;
1898  }
1899 
1900  // if ok, i copy it inside ...
1901  pscBoardConfig_ptr->boardInfo.canloc[i].addr= sensor.location.can.addr;
1902  pscBoardConfig_ptr->boardInfo.canloc[i].port= sensor.location.can.port;
1903 
1904  }
1905 
1906  return true;
1907 }
1908 
1909 
1910 bool ServiceParser::parseService(Searchable &config, servConfigPOS_t &posconfig)
1911 {
1912  if(false == check_analog(config, eomn_serv_AS_pos))
1913  {
1914  yError() << "ServiceParser::parseService(POS) has received an invalid SERVICE group for POS";
1915  return false;
1916  }
1917 
1918 
1919  if(as_service.settings.enabledsensors.size() > eOas_pos_sensorsinboard_maxnumber)
1920  {
1921  yError() << "ServiceParser::parseService(POS): too many enabled sensors are configured. The max num is " << eOas_pos_sensorsinboard_maxnumber;
1922  return false;
1923  }
1924 
1925  // check that the enabledsensors have a board type which is the same for all of them and on the same location
1926 
1927  eObrd_type_t boardtype = eobrd_none;
1928  eObrd_location_t location = {};
1929  for(size_t i=0; i<as_service.settings.enabledsensors.size(); i++)
1930  {
1931  if(eobrd_none == boardtype)
1932  {
1933  boardtype = as_service.settings.enabledsensors[i].boardtype;
1934  location = as_service.settings.enabledsensors[i].location;
1935  bool validBoardForPOS = (eobrd_mtb4 == boardtype) || (eobrd_mtb4c == boardtype) || (eobrd_pmc == boardtype);
1936  if(validBoardForPOS)
1937  {
1938  // ok
1939  }
1940  else
1941  {
1942  yError() << "ServiceParser::parseService(POS): sensors must have the correct boardtype (mtb4, mtb4c or pmc).";
1943  return false;
1944  }
1945 
1946  }
1947 
1948  if(boardtype != as_service.settings.enabledsensors[i].boardtype)
1949  {
1950  yError() << "ServiceParser::parseService(POS): all sensors must have the same boardtype. See SENSORS::boardType values";
1951  return false;
1952  }
1953 
1954  if((location.can.port != as_service.settings.enabledsensors[i].location.can.port) || (location.can.addr != as_service.settings.enabledsensors[i].location.can.addr))
1955  {
1956  yError() << "ServiceParser::parseService(POS): all sensors must have the same can location. See SENSORS::location values";
1957  return false;
1958  }
1959  }
1960 
1961  // look for the boardtype inside the as_service.properties.canboards
1962  servCanBoard_t *board = nullptr;
1963  for(size_t i=0; i<as_service.properties.canboards.size(); i++)
1964  {
1965  if(static_cast<eObrd_cantype_t>(boardtype) == as_service.properties.canboards[i].type)
1966  {
1967  board = &as_service.properties.canboards[0];
1968  }
1969  }
1970 
1971  if(nullptr == board)
1972  {
1973  yError() << "ServiceParser::parseService(POS): cannot find the boardtype " << eoboards_type2string2(boardtype, eobool_true) << " of SENSORS::boardType inside CANBOARDS::type";
1974  return false;
1975  }
1976 
1977  // reset configuration service
1978  memset(&posconfig.ethservice.configuration, 0, sizeof(posconfig.ethservice.configuration));
1979 
1980  // set type of service
1981  posconfig.ethservice.configuration.type = eomn_serv_AS_pos;
1982 
1983 
1984  //get acquisition rate
1985  posconfig.acquisitionrate = as_service.settings.acquisitionrate;
1986 
1987 
1988  // get firmware and protocol info
1989  eOmn_serv_config_data_as_pos_t *pos = &posconfig.ethservice.configuration.data.as.pos;
1990  for(size_t b=0; b<eOas_pos_boards_maxnumber; b++)
1991  {
1992  pos->config.boardconfig[b].boardinfo.type = boardtype;
1993  pos->config.boardconfig[b].boardinfo.firmware.major = board->firmware.major;
1994  pos->config.boardconfig[b].boardinfo.firmware.minor = board->firmware.minor;
1995  pos->config.boardconfig[b].boardinfo.firmware.build = board->firmware.build;
1996  pos->config.boardconfig[b].boardinfo.protocol.major = board->protocol.major;
1997  pos->config.boardconfig[b].boardinfo.protocol.minor = board->protocol.minor;
1998 
1999  pos->config.boardconfig[b].canloc.addr = location.can.addr;
2000  pos->config.boardconfig[b].canloc.port = location.can.port;
2001 
2002  for(size_t s=0; s<as_service.settings.enabledsensors.size(); s++)
2003  {
2004  servAnalogSensor_t snsr = as_service.settings.enabledsensors[s];
2005  pos->config.boardconfig[b].sensors[s].connector = snsr.pos.connector;
2006  pos->config.boardconfig[b].sensors[s].type = snsr.pos.calibration.type;
2007  pos->config.boardconfig[b].sensors[s].port = snsr.pos.port;
2008  pos->config.boardconfig[b].sensors[s].enabled = 1;
2009  pos->config.boardconfig[b].sensors[s].invertdirection = snsr.pos.calibration.invertdirection;
2010  pos->config.boardconfig[b].sensors[s].rotation = snsr.pos.calibration.rotation;
2011  pos->config.boardconfig[b].sensors[s].offset = static_cast<int16_t>(10 * snsr.pos.calibration.offset);
2012  }
2013 
2014  }
2015 
2016  return true;
2017 }
2018 
2019 #if defined(SERVICE_PARSER_USE_MC)
2020 
2021 
2022 bool ServiceParser::parse_encoder_port(std::string const &fromstring, eObrd_ethtype_t const ethboard, eOmc_encoder_t type, uint8_t &toport, bool &formaterror)
2023 {
2024  const char *t = fromstring.c_str();
2025  bool ret = false;
2026  switch(type)
2027  {
2028  case eomc_enc_unknown:
2029  {
2030  yWarning() << "ServiceParser::parse_encoder_port():" << t << "cannot be converted into a port because argument type is" << eomc_encoder2string(type, eobool_false);
2031  toport = eobrd_port_none;
2032  ret = false;
2033  } break;
2034 
2035 
2036  case eomc_enc_none:
2037  {
2038  toport = eobrd_port_none;
2039  ret = true;
2040  } break;
2041 
2042  case eomc_enc_aea:
2043  case eomc_enc_aea3:
2044  case eomc_enc_aksim2:
2045  case eomc_enc_amo:
2046  case eomc_enc_qenc:
2047  case eomc_enc_spichainof2:
2048  case eomc_enc_absanalog:
2049  case eomc_enc_spichainof3:
2050  {
2051  uint8_t toport1 = eobrd_port_unknown;
2052  bool result = parse_port_conn(fromstring, static_cast<eObrd_type_t>(ethboard), toport1, formaterror);
2053 
2054  if(false == result)
2055  {
2056  yWarning() << "ServiceParser::parse_encoder_port():" << t << "is not a legal string for an encoder connector port";
2057  formaterror = true;
2058  ret = false;
2059  }
2060  else
2061  {
2062  toport = toport1;
2063  ret = true;
2064  }
2065 
2066  } break;
2067 
2068 
2069  case eomc_enc_mais:
2070  {
2071  uint8_t toport1 = eobrd_port_unknown;
2072  bool result = parse_port_mais(fromstring, toport1, formaterror);
2073 
2074  if(false == result)
2075  {
2076  yWarning() << "ServiceParser::parse_encoder_port():" << t << "is not a legal string for an encoder connector port";
2077  formaterror = true;
2078  ret = false;
2079  }
2080  else
2081  {
2082  toport = toport1;
2083  ret = true;
2084  }
2085 
2086  } break;
2087 
2088  case eomc_enc_psc:
2089  {
2090  uint8_t toport1 = eobrd_port_unknown;
2091  bool result = parse_port_psc(fromstring, toport1, formaterror);
2092 
2093  if(false == result)
2094  {
2095  yWarning() << "ServiceParser::parse_encoder_port():" << t << "is not a legal string for an encoder connector port";
2096  formaterror = true;
2097  ret = false;
2098  }
2099  else
2100  {
2101  toport = toport1;
2102  ret = true;
2103  }
2104 
2105  } break;
2106 
2107  case eomc_enc_pos:
2108  {
2109  uint8_t toport1 = eobrd_port_unknown;
2110  bool result = parse_port_pos(fromstring, toport1, formaterror);
2111 
2112  if(false == result)
2113  {
2114  yWarning() << "ServiceParser::parse_encoder_port():" << t << "is not a legal string for an encoder connector port";
2115  formaterror = true;
2116  ret = false;
2117  }
2118  else
2119  {
2120  toport = toport1;
2121  ret = true;
2122  }
2123 
2124  } break;
2125 
2126  default:
2127  {
2128  int len = strlen(t);
2129 
2130  if(len > 15)
2131  {
2132  yWarning() << "ServiceParser::parse_encoder_port():" << t << "is not a legal string for a encoder port because it is too long with size =" << len;
2133  formaterror = true;
2134  return false;
2135  }
2136  char prefix[16] = {0};
2137  sscanf(t, "%3c", prefix);
2138  if(0 == strcmp(prefix, "CAN"))
2139  {
2140  toport = eobrd_port_nolocal;
2141  ret = true;
2142  }
2143  else
2144  {
2145  toport = eobrd_port_none;
2146  yWarning() << "ServiceParser::parse_encoder_port():" << t << "is not a legal string for a encoder port!";
2147  formaterror = true;
2148  return false;
2149  }
2150  }break;
2151  }
2152  return ret;
2153 }
2154 
2155 
2156 bool ServiceParser::parse_port_conn(std::string const &fromstring, eObrd_type_t const board, uint8_t &toport, bool &formaterror)
2157 {
2158  const char *t = fromstring.c_str();
2159  bool ret = false;
2160 
2161  // format of string is CONN:P4 or CONN:eobrd_conn_P4 ... the parse function verifies presence of CONN:
2162  eObrd_connector_t conn = eobrd_conn_unknown;
2163  bool result = parse_connector(fromstring, conn, formaterror);
2164 
2165  if(false == result)
2166  {
2167  yWarning() << "ServiceParser::parse_port_conn():" << t << "is not a legal string for a eObrd_connector_t";
2168  formaterror = true;
2169  ret = false;
2170  }
2171  else
2172  {
2173  eObrd_port_t port = eoboards_connector2port(conn, board);
2174  if(eobrd_port_unknown == port)
2175  {
2176  yWarning() << "ServiceParser::parse_port_conn():" << t << "does not convert to a legal port for connector" << eoboards_connector2string(conn, eobool_false) << "and parsed board";
2177  formaterror = true;
2178  ret = false;
2179  }
2180  else
2181  {
2182  toport = port;
2183  ret = true;
2184  }
2185  }
2186 
2187  return ret;
2188 }
2189 
2190 
2191 
2192 bool ServiceParser::parse_port_mais(std::string const &fromstring, uint8_t &toport, bool &formaterror)
2193 {
2194  const char *t = fromstring.c_str();
2195  bool ret = false;
2196 
2197  // format of string is MAIS:eobrd_portmais_thumbproximal or MAIS:thumbproximal
2198  eObrd_portmais_t pmais = eobrd_portmais_unknown;
2199  bool result = parse_mais(fromstring, pmais, formaterror);
2200 
2201  if(false == result)
2202  {
2203  yWarning() << "ServiceParser::parse_port_mais():" << t << "is not a legal string for a port mais";
2204  formaterror = true;
2205  ret = false;
2206  }
2207  else
2208  {
2209  toport = pmais;
2210  ret = true;
2211  }
2212 
2213  return ret;
2214 }
2215 
2216 
2217 bool ServiceParser::parse_port_psc(std::string const &fromstring, uint8_t &toport, bool &formaterror)
2218 {
2219  const char *t = fromstring.c_str();
2220  bool ret = false;
2221 
2222  // format of string is PSC:finger0 or finger0
2223  eObrd_portpsc_t ppsc = eobrd_portpsc_unknown;
2224  bool result = parse_psc(fromstring, ppsc, formaterror);
2225 
2226  if(false == result)
2227  {
2228  yWarning() << "ServiceParser::parse_port_psc():" << t << "is not a legal string for a port psc";
2229  formaterror = true;
2230  ret = false;
2231  }
2232  else
2233  {
2234  toport = ppsc;
2235  ret = true;
2236  }
2237 
2238  return ret;
2239 }
2240 
2241 
2242 bool ServiceParser::parse_port_pos(std::string const &fromstring, uint8_t &toport, bool &formaterror)
2243 {
2244 // const char *t = fromstring.c_str();
2245  bool ret = false;
2246 
2247  // format of string is POS:hand_thumb or :hand_index or :hand_medium or :hand_pinky
2248  eObrd_portpos_t ppos = eobrd_portpos_unknown;
2249  bool result = parse_POS_port(fromstring, ppos, formaterror);
2250 
2251  if(false == result)
2252  {
2253  yWarning() << "ServiceParser::parse_port_pos():" << fromstring << "is not a legal string for a port pos";
2254  formaterror = true;
2255  ret = false;
2256  }
2257  else
2258  {
2259  toport = ppos;
2260  ret = true;
2261  }
2262 
2263  return ret;
2264 }
2265 
2266 
2267 
2268 
2269 //bool ServiceParser::parse_mais(std::string const &fromstring, eObrd_portmais_t &pmais, bool &formaterror)
2270 //{
2271 // // parses MAIS:eobrd_portmais_thumbproximal or MAIS:thumbproximal
2272 
2273 // const char *tt = fromstring.c_str();
2274 // char prefix[16] = {0};
2275 // sscanf(tt, "%5c", prefix);
2276 
2277 // if(0 != strcmp(prefix, "MAIS:"))
2278 // {
2279 // yWarning() << "ServiceParser::parse_mais():" << tt << "is not a legal string because it must begin with MAIS:";
2280 // formaterror = true;
2281 // return false;
2282 // }
2283 
2284 // // ok, now i remove the first 5 characters "MAIS:" and parse the second section .... it can be extended or compact
2285 // const char *t = &tt[5];
2286 
2287 // eObool_t usecompactstring = eobool_false;
2288 // pmais = eoboards_string2portmais(t, usecompactstring);
2289 
2290 // if(eobrd_portmais_unknown == pmais)
2291 // { // attempting to retrieve the compact form
2292 // usecompactstring = eobool_true;
2293 // pmais = eoboards_string2portmais(t, usecompactstring);
2294 // }
2295 
2296 // if(eobrd_portmais_unknown == pmais)
2297 // {
2298 // yWarning() << "ServiceParser::convert():" << t << "is not a legal string for eObrd_portmais_t";
2299 // formaterror = true;
2300 // return false;
2301 // }
2302 
2303 // return true;
2304 
2305 //}
2306 
2307 
2308 // we want to fill the des with relevant info:
2309 // we may have CAN1:1:0 if we have a act_foc or an act_mc4, or a CONN:P4 if we have a pwm.
2310 // hence, we need ... the string, the type of actuator, the ethboard (for transforming P4 into teh proper port value.
2311 bool ServiceParser::parse_actuator_port(std::string const &fromstring, eObrd_ethtype_t const ethboard, eOmc_actuator_t const type, eOmc_actuator_descriptor_t &todes, bool &formaterror)
2312 {
2313  const char *t = fromstring.c_str();
2314 
2315  bool ret = false;
2316  switch(type)
2317  {
2318  default:
2319  case eomc_act_unknown:
2320  {
2321  yWarning() << "ServiceParser::parse_actuator_port():" << t << "cannot be converted into a eObrd_location_t because argument type is" << eomc_actuator2string(type, eobool_false);
2322  todes.none.port = eobrd_port_none;
2323  ret = false;
2324  } break;
2325 
2326 
2327  case eomc_act_none:
2328  {
2329  //yWarning() << "ServiceParser::parse_actuator_port():" << t << "cannot be converted into a eObrd_location_t because argument type is" << eomc_actuator2string(type);
2330  todes.none.port = eobrd_port_none;
2331  ret = true;
2332  } break;
2333 
2334  case eomc_act_pwm:
2335  {
2336 
2337  uint8_t toport = eobrd_port_unknown;
2338  bool result = parse_port_conn(fromstring, static_cast<eObrd_type_t>(ethboard), toport, formaterror);
2339 
2340  if(false == result)
2341  {
2342  yWarning() << "ServiceParser::parse_actuator_port():" << t << "is not a legal string for a pwm connector port";
2343  formaterror = true;
2344  ret = false;
2345  }
2346  else
2347  {
2348  todes.pwm.port = toport;
2349  ret = true;
2350  }
2351 
2352  } break;
2353 
2354  case eomc_act_foc:
2355  case eomc_act_mc4:
2356  {
2357  // read it as a CAN address
2358  eObrd_location_t loc;
2359  bool result = convert(fromstring, loc, formaterror);
2360  ret = true;
2361  if(false == result)
2362  {
2363  yWarning() << "ServiceParser::parse_actuator_port():" << t << "is not a legal string for a eObrd_location_t";
2364  formaterror = true;
2365  ret = false;
2366  }
2367  else if((eomc_act_mc4 == type) && (eobrd_place_extcan != loc.any.place))
2368  {
2369  yWarning() << "ServiceParser::parse_actuator_port():" << t << "is not a legal string for a eomc_act_mc4 location because it is not a eobrd_place_extcan";
2370  formaterror = true;
2371  ret = false;
2372  }
2373  else if(eomc_act_foc == type)
2374  {
2375  if((eobrd_place_can != loc.any.place) && (eobrd_place_extcan != loc.any.place))
2376  {
2377  yWarning() << "ServiceParser::parse_actuator_port():" << t << "is not a legal string for a eomc_act_foc location because it is not a eobrd_place_extcan or eobrd_place_can";
2378  formaterror = true;
2379  ret = false;
2380  }
2381  }
2382 
2383  if(false == ret)
2384  {
2385  return ret;
2386  }
2387 
2388  if(eomc_act_foc == type)
2389  {
2390  // copy into todes.foc
2391  if(eobrd_place_can == loc.any.place)
2392  {
2393  todes.foc.canloc.port = loc.can.port;
2394  todes.foc.canloc.addr = loc.can.addr;
2395  todes.foc.canloc.insideindex = eobrd_caninsideindex_first;
2396 
2397  ret = true;
2398  }
2399  else
2400  {
2401  todes.foc.canloc.port = loc.extcan.port;
2402  todes.foc.canloc.addr = loc.extcan.addr;
2403  todes.foc.canloc.insideindex = loc.extcan.index;
2404  if(eobrd_caninsideindex_first != todes.foc.canloc.insideindex)
2405  {
2406  yWarning() << "ServiceParser::parse_actuator_port():" << "in eomc_act_foc the location has an index different from eobrd_caninsideindex_first. For now we force to it, but correct xml file.";
2407  todes.foc.canloc.insideindex = eobrd_caninsideindex_first;
2408  ret = true;
2409  }
2410  else
2411  {
2412  ret = true;
2413  }
2414  }
2415 
2416  }
2417  else if(eomc_act_mc4 == type)
2418  {
2419  // copy into todes.mc4
2420  todes.mc4.canloc.port = loc.extcan.port;
2421  todes.mc4.canloc.addr = loc.extcan.addr;
2422  todes.mc4.canloc.insideindex = loc.extcan.index;
2423 
2424  if(eobrd_caninsideindex_none == todes.foc.canloc.insideindex)
2425  {
2426  yWarning() << "ServiceParser::parse_actuator_port():" << "in eomc_act_mc4 the location has an eobrd_caninsideindex_none. Correct xml file.";
2427  formaterror = true;
2428  ret = false;
2429  }
2430  else
2431  {
2432  ret = true;
2433  }
2434  }
2435 
2436  } break;
2437 
2438  case eomc_act_advfoc:
2439  {
2440  // read it as a location
2441  eOlocation_t loc {eobus_none, 0, 0};
2442  bool result = convert(fromstring, loc, formaterror);
2443  ret = true;
2444  if(false == result)
2445  {
2446  yWarning() << "ServiceParser::parse_actuator_port():" << t << "is not a legal string for a eOlocation_t required by eomc_act_advfoc";
2447  formaterror = true;
2448  ret = false;
2449  }
2450 
2451  if(false == ret)
2452  {
2453  return ret;
2454  }
2455 
2456  // copy into todes.gen as it is uded by advfoc
2457  todes.gen.location = loc;
2458 
2459  } break;
2460 
2461 
2462  }
2463 
2464  return ret;
2465 }
2466 
2467 
2468 bool ServiceParser::convert(std::string const &fromstring, eOmc_actuator_t &toactuatortype, bool &formaterror)
2469 {
2470  const char *t = fromstring.c_str();
2471  eObool_t usecompactstring = eobool_false;
2472  toactuatortype = eomc_string2actuator(t, usecompactstring);
2473 
2474  if(eomc_act_unknown == toactuatortype)
2475  { // attempting to retrieve the compact form
2476  usecompactstring = eobool_true;
2477  toactuatortype = eomc_string2actuator(t, usecompactstring);
2478  }
2479 
2480  if(eomc_act_unknown == toactuatortype)
2481  {
2482  yWarning() << "ServiceParser::convert():" << t << "is not a legal string for eOmc_actuator_t";
2483  formaterror = true;
2484  return false;
2485  }
2486 
2487  return true;
2488 }
2489 
2490 
2491 bool ServiceParser::convert(std::string const &fromstring, eOmc_position_t &toposition, bool &formaterror)
2492 {
2493  const char *t = fromstring.c_str();
2494  eObool_t usecompactstring = eobool_false;
2495  toposition = eomc_string2position(t, usecompactstring);
2496 
2497  if(eomc_pos_unknown == toposition)
2498  { // attempting to retrieve the compact form
2499  usecompactstring = eobool_true;
2500  toposition = eomc_string2position(t, usecompactstring);
2501  }
2502 
2503  if(eomc_pos_unknown == toposition)
2504  {
2505  yWarning() << "ServiceParser::convert():" << t << "is not a legal string for eOmc_position_t";
2506  formaterror = true;
2507  return false;
2508  }
2509 
2510  return true;
2511 }
2512 
2513 bool ServiceParser::parse_connector(const std::string &fromstring, eObrd_connector_t &toconnector, bool &formaterror)
2514 {
2515  // parses CONN:P4 or CONN:eobrd_conn_P4
2516 
2517  const char *tt = fromstring.c_str();
2518  char prefix[16] = {0};
2519  sscanf(tt, "%5c", prefix);
2520 
2521  if(0 != strcmp(prefix, "CONN:"))
2522  {
2523  yWarning() << "ServiceParser::convert():" << tt << "is not a legal string for eObrd_connector_t because it must begin with CONN:";
2524  formaterror = true;
2525  return false;
2526  }
2527 
2528  // ok, now i remove the first 5 characters "CONN:" and parse the second section .... it can be extended or compact
2529  const char *t = &tt[5];
2530 
2531  eObool_t usecompactstring = eobool_false;
2532  toconnector = eoboards_string2connector(t, usecompactstring);
2533 
2534  if(eobrd_conn_unknown == toconnector)
2535  { // attempting to retrieve the compact form
2536  usecompactstring = eobool_true;
2537  toconnector = eoboards_string2connector(t, usecompactstring);
2538  }
2539 
2540  if(eobrd_conn_unknown == toconnector)
2541  {
2542  yWarning() << "ServiceParser::convert():" << t << "is not a legal string for eObrd_connector_t";
2543  formaterror = true;
2544  return false;
2545  }
2546 
2547  return true;
2548 }
2549 
2550 bool ServiceParser::parse_mais(const std::string &fromstring, eObrd_portmais_t &toportmais, bool &formaterror)
2551 {
2552  // parses MAIS:eobrd_portmais_thumbproximal or MAIS:thumbproximal
2553 
2554  const char *tt = fromstring.c_str();
2555  char prefix[16] = {0};
2556  sscanf(tt, "%5c", prefix);
2557 
2558  if(0 != strcmp(prefix, "MAIS:"))
2559  {
2560  yWarning() << "ServiceParser::parse_mais():" << tt << "is not a legal string for eObrd_portmais_t because it must begin with MAIS:";
2561  formaterror = true;
2562  return false;
2563  }
2564 
2565  // ok, now i remove the first 5 characters "MAIS:" and parse the second section .... it can be extended or compact
2566  const char *t = &tt[5];
2567 
2568  eObool_t usecompactstring = eobool_false;
2569  toportmais = eoboards_string2portmais(t, usecompactstring);
2570 
2571  if(eobrd_portmais_unknown == toportmais)
2572  { // attempting to retrieve the compact form
2573  usecompactstring = eobool_true;
2574  toportmais = eoboards_string2portmais(t, usecompactstring);
2575  }
2576 
2577  if(eobrd_portmais_unknown == toportmais)
2578  {
2579  yWarning() << "ServiceParser::parse_mais():" << t << "is not a legal string for eObrd_portmais_t";
2580  formaterror = true;
2581  return false;
2582  }
2583 
2584  return true;
2585 }
2586 
2587 
2588 bool ServiceParser::parse_psc(const std::string &fromstring, eObrd_portpsc_t &toportpsc, bool &formaterror)
2589 {
2590  // parses PSC:finger0 or finger0
2591 
2592  const char *tt = fromstring.c_str();
2593  char prefix[16] = {0};
2594  sscanf(tt, "%4c", prefix);
2595 
2596  const char *t=nullptr;
2597 
2598  if(0 != strcmp(prefix, "PSC:"))
2599  t = &tt[0]; // port of type finger0
2600  else
2601  t = &tt[4]; // port of type PSC:finger0
2602 
2603  eObool_t usecompactstring = eobool_false;
2604  toportpsc = eoboards_string2portpsc(t, usecompactstring);
2605 
2606  if(eobrd_portpsc_unknown == toportpsc)
2607  { // attempting to retrieve the compact form
2608  usecompactstring = eobool_true;
2609  toportpsc = eoboards_string2portpsc(t, usecompactstring);
2610  }
2611 
2612  if(eobrd_portpsc_unknown == toportpsc)
2613  {
2614  yWarning() << "ServiceParser::parse_psc(): " << t << " is not a legal string for eObrd_portpsc_t";
2615  formaterror = true;
2616  return false;
2617  }
2618 
2619  return true;
2620 }
2621 
2622 bool ServiceParser::parse_POS_port(const std::string &fromstring, eObrd_portpos_t &toportpos, bool &formaterror)
2623 {
2624  // parses POS:hand_thumb or :hand_index or :hand_medium or :hand_pinky
2625 
2626  const char *tt = fromstring.c_str();
2627  char prefix[16] = {0};
2628  sscanf(tt, "%4c", prefix);
2629 
2630  const char *t=nullptr;
2631 
2632  if(0 != strcmp(prefix, "POS:"))
2633  t = &tt[0]; // port of type hand_thumb
2634  else
2635  t = &tt[4]; // port of type POS:hand_thumb
2636 
2637  eObool_t usecompactstring = eobool_false;
2638  toportpos = eoboards_string2portpos(t, usecompactstring);
2639 
2640  if(eobrd_portpos_unknown == toportpos)
2641  { // attempting to retrieve the compact form
2642  usecompactstring = eobool_true;
2643  toportpos = eoboards_string2portpos(t, usecompactstring);
2644  }
2645 
2646  if(eobrd_portpos_unknown == toportpos)
2647  {
2648  yWarning() << "ServiceParser::parse_POS_port(): " << t << " is not a legal string for eObrd_portpos_t";
2649  formaterror = true;
2650  return false;
2651  }
2652 
2653  return true;
2654 }
2655 
2656 
2657 
2658 bool ServiceParser::parse_POS_CALIB_type(std::string const &fromstring, eoas_pos_TYPE_t &type, bool &formaterror)
2659 {
2660  const char *tt = fromstring.c_str();
2661  char prefix[16] = {0};
2662  sscanf(tt, "%5c", prefix);
2663 
2664  if(0 != strcmp(prefix, "TYPE:"))
2665  {
2666  yWarning() << "ServiceParser::convert():" << tt << "is not a legal string for eoas_pos_TYPE_t because it must begin with TYPE:";
2667  formaterror = true;
2668  return false;
2669  }
2670 
2671  // ok, now i remove the first 5 characters "TYPE:" and parse the second section .... it can be extended or compact
2672  const char *t = &tt[5];
2673 
2674  eObool_t usecompactstring = eobool_false;
2675  type = eoas_string2postype(t, usecompactstring);
2676 
2677  if(eoas_pos_TYPE_unknown == type)
2678  { // attempting to retrieve the compact form
2679  usecompactstring = eobool_true;
2680  type = eoas_string2postype(t, usecompactstring);
2681  }
2682 
2683  if(eoas_pos_TYPE_unknown == type)
2684  {
2685  yWarning() << "ServiceParser::convert():" << t << "is not a legal string for eoas_pos_TYPE_t";
2686  formaterror = true;
2687  return false;
2688  }
2689 
2690  return true;
2691 }
2692 
2693 bool ServiceParser::parse_POS_CALIB_rotation(std::string const &fromstring, eoas_pos_ROT_t &rot, bool &formaterror)
2694 {
2695  const char *tt = fromstring.c_str();
2696  char prefix[16] = {0};
2697  sscanf(tt, "%4c", prefix);
2698 
2699  if(0 != strcmp(prefix, "ROT:"))
2700  {
2701  yWarning() << "ServiceParser::convert():" << tt << "is not a legal string for eoas_pos_ROT_t because it must begin with ROT:";
2702  formaterror = true;
2703  return false;
2704  }
2705 
2706  // ok, now i remove the first 4 characters "ROT:" and parse the second section .... it can be extended or compact
2707  const char *t = &tt[4];
2708 
2709  eObool_t usecompactstring = eobool_false;
2710  rot = eoas_string2posrot(t, usecompactstring);
2711 
2712  yDebug() << t << " yyyyyyyyyyyyyyyyyyy " << rot;
2713 
2714 
2715  if(eoas_pos_ROT_unknown == rot)
2716  { // attempting to retrieve the compact form
2717  usecompactstring = eobool_true;
2718  rot = eoas_string2posrot(t, usecompactstring);
2719  yDebug() << t << " xxxxxxxxxxxxxxxxxxx " << rot;
2720  }
2721 
2722  if(eoas_pos_ROT_unknown == rot)
2723  {
2724  yWarning() << "ServiceParser::convert():" << t << "is not a legal string for eoas_pos_ROT_t";
2725  formaterror = true;
2726  return false;
2727  }
2728 
2729  return true;
2730 }
2731 
2732 bool ServiceParser::parse_POS_connector(std::string const &fromstring, const eObrd_type_t brd, eObrd_connector_t &conn, bool &formaterror)
2733 {
2734  uint8_t tmp {0};
2735  bool r = parse_port_conn(fromstring, brd, tmp, formaterror);
2736  conn = r ? static_cast<eObrd_connector_t>(tmp) : eobrd_conn_unknown;
2737  return r;
2738 }
2739 
2740 bool ServiceParser::convert(std::string const &fromstring, eOmc_encoder_t &toencodertype, bool &formaterror)
2741 {
2742  const char *t = fromstring.c_str();
2743  eObool_t usecompactstring = eobool_false;
2744  toencodertype = eomc_string2encoder(t, usecompactstring);
2745 
2746  if(eomc_enc_unknown == toencodertype)
2747  { // attempting to retrieve the compact form
2748  usecompactstring = eobool_true;
2749  toencodertype = eomc_string2encoder(t, usecompactstring);
2750  }
2751 
2752  if(eomc_enc_unknown == toencodertype)
2753  {
2754  yWarning() << "ServiceParser::convert():" << t << "is not a legal string for eOmc_encoder_t";
2755  formaterror = true;
2756  return false;
2757  }
2758 
2759  return true;
2760 }
2761 
2762 
2763 bool ServiceParser::check_motion(Searchable &config)
2764 {
2765  bool formaterror = false;
2766 
2767  // complete format is SERVICE{ type, PROPERTIES{ ETHBOARD, CANBOARDS, MC4, MAIS, CONTROLLER, JOINTMAPPING, JOINTSETS } }
2768  // so far, there is no SETTINGS{}.
2769  // then, some groups are not present for some kind of SERVICE.type
2770  // mc4: ETHBOARD, CANBOARDS, MC4, MAIS
2771  // foc: ETHBOARD, CANBOARDS, CONTROLLER, JOINTMAPPING, JOINTSETS
2772  // mc4plus: ETHBOARD, CONTROLLER, JOINTMAPPING, JOINTSETS
2773  // mc4plusmais: ETHBOARD, CANBOARDS, MAIS, CONTROLLER, JOINTMAPPING, JOINTSETS
2774 
2775 
2776 
2777  const bool itisOKifwedontfindtheXMLgroup = true;
2778 
2779  Bottle b_SERVICE(config.findGroup("SERVICE"));
2780  if(b_SERVICE.isNull())
2781  {
2782  if(false == itisOKifwedontfindtheXMLgroup)
2783  {
2784  yError() << "ServiceParser::check_motion() cannot find SERVICE group";
2785  return false;
2786  }
2787  else
2788  {
2789  yWarning() << "ServiceParser::check_motion() cannot find SERVICE group, but we are in permissive mode, hence we ask the ETH board to config itself according to its IP address";
2790  mc_service.type = eomn_serv_MC_generic;
2791  return true;
2792  }
2793  }
2794 
2795  // check whether we have the proper type
2796 
2797  if(false == b_SERVICE.check("type"))
2798  {
2799  if(false == itisOKifwedontfindtheXMLgroup)
2800  {
2801  yError() << "ServiceParser::check_motion() cannot find SERVICE.type";
2802  return false;
2803  }
2804  else
2805  {
2806  yWarning() << "ServiceParser::check_motion() cannot find SERVICE.type, but we are in permissive mode, hence we ask the ETH board to config itself according to its IP address";
2807  mc_service.type = eomn_serv_MC_generic;
2808  return true;
2809  }
2810  }
2811 
2812  Bottle b_type(b_SERVICE.find("type").asString());
2813  if(false == convert(b_type.toString(), mc_service.type, formaterror))
2814  {
2815  yError() << "ServiceParser::check_motion() has found unknown SERVICE.type = " << b_type.toString();
2816  return false;
2817  }
2818 
2819  if(eomn_serv_MC_generic == mc_service.type)
2820  {
2821  yWarning() << "ServiceParser::check_motion() detects SERVICE.type = eomn_serv_MC_generic.. hence we ask the ETH board to config itself according to its IP address";
2822  return true;
2823  }
2824 
2825  // check whether we have the proper groups at first level.
2826 
2827  Bottle b_PROPERTIES = Bottle(b_SERVICE.findGroup("PROPERTIES"));
2828  if(b_PROPERTIES.isNull())
2829  {
2830  yError() << "ServiceParser::check_motion() cannot find PROPERTIES";
2831  return false;
2832  }
2833 
2834 
2835  // now, inside PROPERTIES there are groups which depend on mc_service.type.
2836  // i prefer to check them all in here rather to go on and check them one after another.
2837  Bottle b_PROPERTIES_ETHBOARD = Bottle(b_PROPERTIES.findGroup("ETHBOARD"));
2838  bool has_PROPERTIES_ETHBOARD = !b_PROPERTIES_ETHBOARD.isNull();
2839 
2840  Bottle b_PROPERTIES_MAIS = Bottle(b_PROPERTIES.findGroup("MAIS"));
2841  bool has_PROPERTIES_MAIS = !b_PROPERTIES_MAIS.isNull();
2842 
2843  Bottle b_PROPERTIES_PSC = Bottle(b_PROPERTIES.findGroup("PSC"));
2844  bool has_PROPERTIES_PSC = !b_PROPERTIES_PSC.isNull();
2845 
2846  Bottle b_PROPERTIES_POS = Bottle(b_PROPERTIES.findGroup("POS"));
2847  bool has_PROPERTIES_POS = !b_PROPERTIES_POS.isNull();
2848 
2849  Bottle b_PROPERTIES_MC4 = Bottle(b_PROPERTIES.findGroup("MC4"));
2850  bool has_PROPERTIES_MC4 = !b_PROPERTIES_MC4.isNull();
2851 
2852  Bottle b_PROPERTIES_CANBOARDS = Bottle(b_PROPERTIES.findGroup("CANBOARDS"));
2853  bool has_PROPERTIES_CANBOARDS = !b_PROPERTIES_CANBOARDS.isNull();
2854 
2855  Bottle b_PROPERTIES_JOINTMAPPING = Bottle(b_PROPERTIES.findGroup("JOINTMAPPING"));
2856  bool has_PROPERTIES_JOINTMAPPING = !b_PROPERTIES_JOINTMAPPING.isNull();
2857 
2858  Bottle b_PROPERTIES_DIAGNOSTICS = Bottle(b_PROPERTIES.findGroup("DIAGNOSTICS"));
2859  bool has_PROPERTIES_DIAGNOSTICS = !b_PROPERTIES_DIAGNOSTICS.isNull();
2860 
2861 
2862 
2863 
2864 
2865  bool itisoksofar = false;
2866  switch(mc_service.type)
2867  {
2868  case eomn_serv_MC_foc:
2869  {
2870  // must have: ETHBOARD, CANBOARDS, JOINTMAPPING
2871  itisoksofar = true;
2872 
2873  if(false == has_PROPERTIES_ETHBOARD)
2874  {
2875  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.ETHBOARD for type" << eomn_servicetype2string(mc_service.type);
2876  itisoksofar = false;
2877  }
2878 
2879  if(false == has_PROPERTIES_CANBOARDS)
2880  {
2881  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.CANBOARDS for type" << eomn_servicetype2string(mc_service.type);
2882  itisoksofar = false;
2883  }
2884 
2885  if(false == has_PROPERTIES_JOINTMAPPING)
2886  {
2887  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING for type" << eomn_servicetype2string(mc_service.type);
2888  itisoksofar = false;
2889  }
2890 
2891  } break;
2892 
2893 
2894  case eomn_serv_MC_mc4plus:
2895  {
2896  // must have: ETHBOARD, JOINTMAPPING
2897 
2898  itisoksofar = true;
2899 
2900  if(false == has_PROPERTIES_ETHBOARD)
2901  {
2902  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.ETHBOARD for type" << eomn_servicetype2string(mc_service.type);
2903  itisoksofar = false;
2904  }
2905 
2906  if(false == has_PROPERTIES_JOINTMAPPING)
2907  {
2908  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING for type" << eomn_servicetype2string(mc_service.type);
2909  itisoksofar = false;
2910  }
2911 
2912  } break;
2913 
2914 
2915  case eomn_serv_MC_mc4plusmais:
2916  {
2917  // must have: ETHBOARD, CANBOARDS, MAIS, JOINTMAPPING
2918 
2919  itisoksofar = true;
2920 
2921  if(false == has_PROPERTIES_ETHBOARD)
2922  {
2923  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.ETHBOARD for type" << eomn_servicetype2string(mc_service.type);
2924  itisoksofar = false;
2925  }
2926 
2927  if(false == has_PROPERTIES_CANBOARDS)
2928  {
2929  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.CANBOARDS for type" << eomn_servicetype2string(mc_service.type);
2930  itisoksofar = false;
2931  }
2932 
2933  if(false == has_PROPERTIES_MAIS)
2934  {
2935  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.MAIS for type" << eomn_servicetype2string(mc_service.type);
2936  itisoksofar = false;
2937  }
2938 
2939  if(false == has_PROPERTIES_JOINTMAPPING)
2940  {
2941  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING for type" << eomn_servicetype2string(mc_service.type);
2942  itisoksofar = false;
2943  }
2944 
2945 
2946  } break;
2947 
2948  case eomn_serv_MC_mc4:
2949  {
2950  // must have: ETHBOARD, CANBOARDS, MC4, MAIS
2951 
2952  itisoksofar = true;
2953 
2954  if(false == has_PROPERTIES_ETHBOARD)
2955  {
2956  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.ETHBOARD for type" << eomn_servicetype2string(mc_service.type);
2957  itisoksofar = false;
2958  }
2959 
2960  if(false == has_PROPERTIES_CANBOARDS)
2961  {
2962  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.CANBOARDS for type" << eomn_servicetype2string(mc_service.type);
2963  itisoksofar = false;
2964  }
2965 
2966  if(false == has_PROPERTIES_MC4)
2967  {
2968  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.MC4 for type" << eomn_servicetype2string(mc_service.type);
2969  itisoksofar = false;
2970  }
2971 
2972  if(false == has_PROPERTIES_MAIS)
2973  {
2974  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.MAIS for type" << eomn_servicetype2string(mc_service.type);
2975  itisoksofar = false;
2976  }
2977 
2978  } break;
2979 
2980  case eomn_serv_MC_mc2pluspsc:
2981  {
2982  // must have: ETHBOARD, CANBOARDS, PSC, JOINTMAPPING
2983 
2984  itisoksofar = true;
2985 
2986  if(false == has_PROPERTIES_ETHBOARD)
2987  {
2988  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.ETHBOARD for type" << eomn_servicetype2string(mc_service.type);
2989  itisoksofar = false;
2990  }
2991 
2992  if(false == has_PROPERTIES_CANBOARDS)
2993  {
2994  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.CANBOARDS for type" << eomn_servicetype2string(mc_service.type);
2995  itisoksofar = false;
2996  }
2997 
2998  if(false == has_PROPERTIES_PSC)
2999  {
3000  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.PSC for type" << eomn_servicetype2string(mc_service.type);
3001  itisoksofar = false;
3002  }
3003 
3004  if(false == has_PROPERTIES_JOINTMAPPING)
3005  {
3006  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING for type" << eomn_servicetype2string(mc_service.type);
3007  itisoksofar = false;
3008  }
3009 
3010 
3011  } break;
3012 
3013 
3014  case eomn_serv_MC_mc4plusfaps:
3015  {
3016  // must have: ETHBOARD, CANBOARDS, POS, JOINTMAPPING
3017 
3018  itisoksofar = true;
3019 
3020  if(false == has_PROPERTIES_ETHBOARD)
3021  {
3022  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.ETHBOARD for type" << eomn_servicetype2string(mc_service.type);
3023  itisoksofar = false;
3024  }
3025 
3026  if(false == has_PROPERTIES_CANBOARDS)
3027  {
3028  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.CANBOARDS for type" << eomn_servicetype2string(mc_service.type);
3029  itisoksofar = false;
3030  }
3031 
3032  if(false == has_PROPERTIES_POS)
3033  {
3034  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.POS for type" << eomn_servicetype2string(mc_service.type);
3035  itisoksofar = false;
3036  }
3037 
3038  if(false == has_PROPERTIES_JOINTMAPPING)
3039  {
3040  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING for type" << eomn_servicetype2string(mc_service.type);
3041  itisoksofar = false;
3042  }
3043 
3044 
3045  } break;
3046 
3047  case eomn_serv_MC_advfoc:
3048  {
3049  // must have: ETHBOARD, CANBOARDS, JOINTMAPPING
3050 
3051  itisoksofar = true;
3052 
3053  if(false == has_PROPERTIES_ETHBOARD)
3054  {
3055  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.ETHBOARD for type" << eomn_servicetype2string(mc_service.type);
3056  itisoksofar = false;
3057  }
3058 
3059  if(false == has_PROPERTIES_CANBOARDS)
3060  {
3061  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.CANBOARDS for type" << eomn_servicetype2string(mc_service.type);
3062  itisoksofar = false;
3063  }
3064 
3065  if(false == has_PROPERTIES_JOINTMAPPING)
3066  {
3067  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING for type" << eomn_servicetype2string(mc_service.type);
3068  itisoksofar = false;
3069  }
3070 
3071  } break;
3072 
3073  default:
3074  {
3075  yError() << "ServiceParser::check_motion() has found an unknown type" << eomn_servicetype2string(mc_service.type);
3076  itisoksofar = false;
3077  } break;
3078  }
3079 
3080  if(false == itisoksofar)
3081  {
3082  yError() << "ServiceParser::check_motion() detected missing groups in PROPERTIES";
3083  return false;
3084  }
3085 
3086  // now i parse the groups
3087 
3088  if(true == has_PROPERTIES_ETHBOARD)
3089  {
3090  // i get type
3091 
3092  Bottle b_PROPERTIES_ETHBOARD_type = b_PROPERTIES_ETHBOARD.findGroup("type");
3093  if(b_PROPERTIES_ETHBOARD_type.isNull())
3094  {
3095  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.ETHBOARD.type";
3096  return false;
3097  }
3098 
3099  // we must have only one board
3100  int numofethboards = b_PROPERTIES_ETHBOARD_type.size() - 1;
3101  if(1 != numofethboards)
3102  {
3103  yError() << "ServiceParser::check_motion() PROPERTIES.ETHBOARD.type must have one board only";
3104  return false;
3105  }
3106  if(false == convert(b_PROPERTIES_ETHBOARD_type.get(1).asString(), mc_service.properties.ethboardtype, formaterror))
3107  {
3108  yError() << "ServiceParser::check_motion() has found unknown SERVICE.PROPERTIES.ETHBOARD.type = " << b_PROPERTIES_ETHBOARD_type.get(1).asString();
3109  return false;
3110  }
3111 
3112  } // has_PROPERTIES_ETHBOARD
3113 
3114 
3115  if(true == has_PROPERTIES_CANBOARDS)
3116  {
3117  // i get type, PROTOCOL.major/minor, FIRMWARE.major/minor/build and see their sizes. they must be all equal. i can have more than one board
3118 
3119  Bottle b_PROPERTIES_CANBOARDS_type = b_PROPERTIES_CANBOARDS.findGroup("type");
3120  if(b_PROPERTIES_CANBOARDS_type.isNull())
3121  {
3122  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.CANBOARDS.type";
3123  return false;
3124  }
3125  Bottle b_PROPERTIES_CANBOARDS_PROTOCOL = Bottle(b_PROPERTIES_CANBOARDS.findGroup("PROTOCOL"));
3126  if(b_PROPERTIES_CANBOARDS_PROTOCOL.isNull())
3127  {
3128  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.CANBOARDS.PROTOCOL";
3129  return false;
3130  }
3131  Bottle b_PROPERTIES_CANBOARDS_PROTOCOL_major = Bottle(b_PROPERTIES_CANBOARDS_PROTOCOL.findGroup("major"));
3132  if(b_PROPERTIES_CANBOARDS_PROTOCOL_major.isNull())
3133  {
3134  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.CANBOARDS.PROTOCOL.major";
3135  return false;
3136  }
3137  Bottle b_PROPERTIES_CANBOARDS_PROTOCOL_minor = Bottle(b_PROPERTIES_CANBOARDS_PROTOCOL.findGroup("minor"));
3138  if(b_PROPERTIES_CANBOARDS_PROTOCOL_minor.isNull())
3139  {
3140  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.CANBOARDS.PROTOCOL.minor";
3141  return false;
3142  }
3143  Bottle b_PROPERTIES_CANBOARDS_FIRMWARE = Bottle(b_PROPERTIES_CANBOARDS.findGroup("FIRMWARE"));
3144  if(b_PROPERTIES_CANBOARDS_FIRMWARE.isNull())
3145  {
3146  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.CANBOARDS.FIRMWARE";
3147  return false;
3148  }
3149  Bottle b_PROPERTIES_CANBOARDS_FIRMWARE_major = Bottle(b_PROPERTIES_CANBOARDS_FIRMWARE.findGroup("major"));
3150  if(b_PROPERTIES_CANBOARDS_FIRMWARE_major.isNull())
3151  {
3152  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.CANBOARDS.FIRMWARE.major";
3153  return false;
3154  }
3155  Bottle b_PROPERTIES_CANBOARDS_FIRMWARE_minor = Bottle(b_PROPERTIES_CANBOARDS_FIRMWARE.findGroup("minor"));
3156  if(b_PROPERTIES_CANBOARDS_FIRMWARE_minor.isNull())
3157  {
3158  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.CANBOARDS.FIRMWARE.minor";
3159  return false;
3160  }
3161  Bottle b_PROPERTIES_CANBOARDS_FIRMWARE_build = Bottle(b_PROPERTIES_CANBOARDS_FIRMWARE.findGroup("build"));
3162  if(b_PROPERTIES_CANBOARDS_FIRMWARE_build.isNull())
3163  {
3164  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.CANBOARDS.FIRMWARE.build";
3165  return false;
3166  }
3167 
3168  size_t tmp = b_PROPERTIES_CANBOARDS_type.size();
3169  size_t numboards = (0 == tmp) ? 0 : (tmp - 1); // first position of bottle contains the tag "type"
3170 
3171  // check if all other fields have the same size.
3172  if( (tmp != b_PROPERTIES_CANBOARDS_PROTOCOL_major.size()) ||
3173  (tmp != b_PROPERTIES_CANBOARDS_PROTOCOL_minor.size()) ||
3174  (tmp != b_PROPERTIES_CANBOARDS_FIRMWARE_major.size()) ||
3175  (tmp != b_PROPERTIES_CANBOARDS_FIRMWARE_minor.size()) ||
3176  (tmp != b_PROPERTIES_CANBOARDS_FIRMWARE_build.size())
3177  )
3178  {
3179  yError() << "ServiceParser::check_motion() in PROPERTIES.CANBOARDS some params have inconsistent lengths";
3180  return false;
3181  }
3182 
3183 
3184  mc_service.properties.canboards.resize(0);
3185 
3186  formaterror = false;
3187  for(size_t i=0; i<numboards; i++)
3188  {
3189  servCanBoard_t item;
3190 
3191  convert(b_PROPERTIES_CANBOARDS_type.get(i+1).asString(), item.type, formaterror);
3192  convert(b_PROPERTIES_CANBOARDS_PROTOCOL_major.get(i+1).asInt32(), item.protocol.major, formaterror);
3193  convert(b_PROPERTIES_CANBOARDS_PROTOCOL_minor.get(i+1).asInt32(), item.protocol.minor, formaterror);
3194 
3195  convert(b_PROPERTIES_CANBOARDS_FIRMWARE_major.get(i+1).asInt32(), item.firmware.major, formaterror);
3196  convert(b_PROPERTIES_CANBOARDS_FIRMWARE_minor.get(i+1).asInt32(), item.firmware.minor, formaterror);
3197  convert(b_PROPERTIES_CANBOARDS_FIRMWARE_build.get(i+1).asInt32(), item.firmware.build, formaterror);
3198 
3199  mc_service.properties.canboards.push_back(item);
3200  }
3201 
3202  // in here we could decide to return false if any previous conversion function has returned error
3203  // bool fromStringToBoolean(string str, bool &anyerror); // inside: if error then .... be sure to set error = true. dont set it to false.
3204 
3205  if(true == formaterror)
3206  {
3207  yError() << "ServiceParser::check_motion() has detected an illegal format for some of the params of PROPERTIES.CANBOARDS some param has inconsistent length";
3208  return false;
3209  }
3210 
3211  } // has_PROPERTIES_CANBOARDS
3212 
3213 
3214  if(true == has_PROPERTIES_MAIS)
3215  {
3216  // i get .location and nothing else
3217 
3218  Bottle b_PROPERTIES_MAIS_location = b_PROPERTIES_MAIS.findGroup("location");
3219  if(b_PROPERTIES_MAIS_location.isNull())
3220  {
3221  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.MAIS.location";
3222  return false;
3223  }
3224 
3225  int tmp = b_PROPERTIES_MAIS_location.size();
3226  int numboards = tmp - 1; // first position of bottle contains the tag "location"
3227 
3228  // check if numboards is 1.
3229  if(1 != numboards)
3230  {
3231  yError() << "ServiceParser::check_motion() in PROPERTIES.MAIS.location must contain one item only and it has:" << numboards;
3232  return false;
3233  }
3234 
3235  formaterror = false;
3236  eObrd_location_t loc;
3237  if(false == convert(b_PROPERTIES_MAIS_location.get(1).asString(), loc, formaterror))
3238  {
3239  yError() << "ServiceParser::check_motion() has detected an illegal format for SERVICE.PROPERTIES.MAIS.location";
3240  return false;
3241  }
3242 
3243  if(eobrd_place_can == loc.any.place)
3244  {
3245  mc_service.properties.maislocation.port = loc.can.port;
3246  mc_service.properties.maislocation.addr = loc.can.addr;
3247  mc_service.properties.maislocation.insideindex = eobrd_caninsideindex_none;
3248  }
3249  else if(eobrd_place_extcan == loc.any.place)
3250  {
3251  mc_service.properties.maislocation.port = loc.extcan.port;
3252  mc_service.properties.maislocation.addr = loc.extcan.addr;
3253  mc_service.properties.maislocation.insideindex = eobrd_caninsideindex_none;
3254  }
3255  else
3256  {
3257  yError() << "ServiceParser::check_motion() has detected an illegal format for SERVICE.PROPERTIES.MAIS.location. it must be either can or extcan";
3258  return false;
3259  }
3260 
3261  } // has_PROPERTIES_MAIS
3262 
3263 
3264  if(true == has_PROPERTIES_MC4)
3265  {
3266  // i get:
3267  // SHIFTS.velocity/estimJointVelocity/estimJointAcceleration/estimMotorVelocity/estimMotorAcceleration,
3268  // BROADCASTPOLICY, JOINT2BOARD)
3269 
3270  Bottle b_PROPERTIES_MC4_SHIFTS = Bottle(b_PROPERTIES_MC4.findGroup("SHIFTS"));
3271  if(b_PROPERTIES_MC4_SHIFTS.isNull())
3272  {
3273  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.MC4.SHIFTS";
3274  return false;
3275  }
3276 
3277  Bottle b_PROPERTIES_MC4_SHIFTS_velocity = Bottle(b_PROPERTIES_MC4_SHIFTS.findGroup("velocity"));
3278  if(b_PROPERTIES_MC4_SHIFTS_velocity.isNull())
3279  {
3280  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.MC4.SHIFTS.velocity";
3281  return false;
3282  }
3283  Bottle b_PROPERTIES_MC4_SHIFTS_estimJointVelocity = Bottle(b_PROPERTIES_MC4_SHIFTS.findGroup("estimJointVelocity"));
3284  if(b_PROPERTIES_MC4_SHIFTS_estimJointVelocity.isNull())
3285  {
3286  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.MC4.SHIFTS.estimJointVelocity";
3287  return false;
3288  }
3289  Bottle b_PROPERTIES_MC4_SHIFTS_estimJointAcceleration = Bottle(b_PROPERTIES_MC4_SHIFTS.findGroup("estimJointAcceleration"));
3290  if(b_PROPERTIES_MC4_SHIFTS_estimJointAcceleration.isNull())
3291  {
3292  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.MC4.SHIFTS.estimJointAcceleration";
3293  return false;
3294  }
3295  Bottle b_PROPERTIES_MC4_SHIFTS_estimMotorVelocity = Bottle(b_PROPERTIES_MC4_SHIFTS.findGroup("estimMotorVelocity"));
3296  if(b_PROPERTIES_MC4_SHIFTS_estimMotorVelocity.isNull())
3297  {
3298  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.MC4.SHIFTS.estimMotorVelocity";
3299  return false;
3300  }
3301  Bottle b_PROPERTIES_MC4_SHIFTS_estimMotorAcceleration = Bottle(b_PROPERTIES_MC4_SHIFTS.findGroup("estimMotorAcceleration"));
3302  if(b_PROPERTIES_MC4_SHIFTS_estimMotorAcceleration.isNull())
3303  {
3304  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.MC4.SHIFTS.estimMotorAcceleration";
3305  return false;
3306  }
3307 
3308  Bottle b_PROPERTIES_MC4_BROADCASTPOLICY = Bottle(b_PROPERTIES_MC4.findGroup("BROADCASTPOLICY"));
3309  if(b_PROPERTIES_MC4_BROADCASTPOLICY.isNull())
3310  {
3311  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.MC4.BROADCASTPOLICY";
3312  return false;
3313  }
3314 
3315  Bottle b_PROPERTIES_MC4_BROADCASTPOLICY_enable = Bottle(b_PROPERTIES_MC4_BROADCASTPOLICY.findGroup("enable"));
3316  if(b_PROPERTIES_MC4_BROADCASTPOLICY_enable.isNull())
3317  {
3318  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.MC4.BROADCASTPOLICY.enable";
3319  return false;
3320  }
3321 
3322 /* Bottle b_PROPERTIES_MC4_JOINT2BOARD = Bottle(b_PROPERTIES_MC4.findGroup("JOINT2BOARD"));
3323  if(b_PROPERTIES_MC4_JOINT2BOARD.isNull())
3324  {
3325  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.MC4.JOINT2BOARD";
3326  return false;
3327  }
3328 
3329  Bottle b_PROPERTIES_MC4_JOINT2BOARD_location = Bottle(b_PROPERTIES_MC4_JOINT2BOARD.findGroup("location"));
3330  if(b_PROPERTIES_MC4_JOINT2BOARD_location.isNull())
3331  {
3332  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.MC4.JOINT2BOARD.location";
3333  return false;
3334  }
3335 */
3336  // 1. get values for SHIFTS
3337 
3338  uint8_t value = 0;
3339  if(true == convert(b_PROPERTIES_MC4_SHIFTS_velocity.get(1).asInt32(), value, formaterror))
3340  {
3341  mc_service.properties.mc4shifts.velocity = value;
3342  }
3343  if(true == convert(b_PROPERTIES_MC4_SHIFTS_estimJointVelocity.get(1).asInt32(), value, formaterror))
3344  {
3345  if(value > 15)
3346  {
3347  yError() << "ServiceParser::check_motion() manages values of PROPERTIES.MC4.SHIFTS.estim* only in range [0, 15]. read value =" << value;
3348  return false;
3349  }
3350  mc_service.properties.mc4shifts.estimJointVelocity = value;
3351  }
3352  if(true == convert(b_PROPERTIES_MC4_SHIFTS_estimJointAcceleration.get(1).asInt32(), value, formaterror))
3353  {
3354  if(value > 15)
3355  {
3356  yError() << "ServiceParser::check_motion() manages values of PROPERTIES.MC4.SHIFTS.estim* only in range [0, 15]. read value =" << value;
3357  return false;
3358  }
3359  mc_service.properties.mc4shifts.estimJointAcceleration = value;
3360  }
3361  if(true == convert(b_PROPERTIES_MC4_SHIFTS_estimMotorVelocity.get(1).asInt32(), value, formaterror))
3362  {
3363  if(value > 15)
3364  {
3365  yError() << "ServiceParser::check_motion() manages values of PROPERTIES.MC4.SHIFTS.estim* only in range [0, 15]. read value =" << value;
3366  return false;
3367  }
3368  mc_service.properties.mc4shifts.estimMotorVelocity = value;
3369  }
3370  if(true == convert(b_PROPERTIES_MC4_SHIFTS_estimMotorAcceleration.get(1).asInt32(), value, formaterror))
3371  {
3372  if(value > 15)
3373  {
3374  yError() << "ServiceParser::check_motion() manages values of PROPERTIES.MC4.SHIFTS.estim* only in range [0, 15]. read value =" << value;
3375  return false;
3376  }
3377  mc_service.properties.mc4shifts.estimMotorAcceleration = value;
3378  }
3379 
3380  // 2. i get the values for b_PROPERTIES_MC4_BROADCASTPOLICY_enable
3381 
3382  int tmp = b_PROPERTIES_MC4_BROADCASTPOLICY_enable.size();
3383  int numofenables = tmp - 1; // first position of bottle contains the tag "enable"
3384 
3385  mc_service.properties.mc4broadcasts.resize(0);
3386  for(int i=0; i<numofenables; i++)
3387  {
3388  // transform the string into a value.
3389  eOmc_mc4broadcast_t item = eomc_mc4broadcast_unknown;
3390  const char *str = b_PROPERTIES_MC4_BROADCASTPOLICY_enable.get(i+1).asString().c_str();
3391 
3392  // check compact and then non-compact form
3393  if(eomc_mc4broadcast_unknown == (item = eomc_string2mc4broadcast(str, eobool_true)))
3394  {
3395  item = eomc_string2mc4broadcast(str, eobool_false);
3396  }
3397 
3398  if((eomc_mc4broadcast_unknown != item) && (eomc_mc4broadcast_none != item))
3399  { // if meaningful ...
3400  mc_service.properties.mc4broadcasts.push_back(item);
3401  }
3402  }
3403 
3404 
3405 
3406  // 3. i get the values for b_PROPERTIES_MC4_JOINT2BOARD_location.... there must be 12 values
3407 
3408 /* int tmp1 = b_PROPERTIES_MC4_JOINT2BOARD_location.size();
3409  int numoflocations = tmp1 - 1; // first position of bottle contains the tag "location"
3410 
3411  if(12 != numoflocations)
3412  {
3413  yError() << "ServiceParser::check_motion() detects that PROPERTIES.MC4.JOINT2BOARD.location has not 12 items but" << numoflocations;
3414  return false;
3415  }
3416 
3417  mc_service.properties.mc4joints.resize(0);
3418  for(int i=0; i<numoflocations; i++)
3419  {
3420  // transform the string into a location
3421 
3422  formaterror = false;
3423  eObrd_location_t loc;
3424  if(false == convert(b_PROPERTIES_MC4_JOINT2BOARD_location.get(i+1).asString(), loc, formaterror))
3425  {
3426  yError() << "ServiceParser::check_motion() has detected an illegal format for PROPERTIES.MC4.JOINT2BOARD.location";
3427  return false;
3428  }
3429 
3430  eObrd_canlocation_t item;
3431  if(eobrd_place_extcan == loc.any.place)
3432  {
3433  item.port = loc.extcan.port;
3434  item.addr = loc.extcan.addr;
3435  item.insideindex = loc.extcan.index;
3436  }
3437  else
3438  {
3439  yError() << "ServiceParser::check_motion() has detected an illegal format for PROPERTIES.MC4.JOINT2BOARD.location. it must be extcan";
3440  return false;
3441  }
3442 
3443  mc_service.properties.mc4joints.push_back(item);
3444  }
3445 */
3446 
3447  } // has_PROPERTIES_MC4
3448 
3449  if(true == has_PROPERTIES_PSC)
3450  {
3451  // i get .location and nothing else
3452 
3453  Bottle b_PROPERTIES_PSC_location = b_PROPERTIES_PSC.findGroup("location");
3454  if(b_PROPERTIES_PSC_location.isNull())
3455  {
3456  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.PSC.location";
3457  return false;
3458  }
3459 
3460  int tmp = b_PROPERTIES_PSC_location.size();
3461  int numboards = tmp - 1; // first position of bottle contains the tag "location"
3462 
3463  // check if numboards is 3.
3464  if(eOas_psc_boards_maxnumber != numboards)
3465  {
3466  yError() << "ServiceParser::check_motion() in PROPERTIES.PSC.location must contain three items and it has:" << numboards;
3467  return false;
3468  }
3469 
3470  mc_service.properties.psclocations.resize(3);
3471  for(int i=0; i<3; i++)
3472  {
3473  eObrd_location_t loc;
3474  formaterror = false;
3475  if(false == convert(b_PROPERTIES_PSC_location.get(1+i).asString(), loc, formaterror))
3476  {
3477  yError() << "ServiceParser::check_motion() has detected an illegal format for SERVICE.PROPERTIES.PSC.location";
3478  return false;
3479  }
3480 
3481  if(eobrd_place_can == loc.any.place)
3482  {
3483  mc_service.properties.psclocations[i].port = loc.can.port;
3484  mc_service.properties.psclocations[i].addr = loc.can.addr;
3485  mc_service.properties.psclocations[i].insideindex = eobrd_caninsideindex_none;
3486 
3487  }
3488  else if(eobrd_place_extcan == loc.any.place)
3489  {
3490  mc_service.properties.psclocations[i].port = loc.extcan.port;
3491  mc_service.properties.psclocations[i].addr = loc.extcan.addr;
3492  mc_service.properties.psclocations[i].insideindex = eobrd_caninsideindex_none;
3493  }
3494  else
3495  {
3496  yError() << "ServiceParser::check_motion() has detected an illegal format for SERVICE.PROPERTIES.PSC.location. it must be either can or extcan";
3497  return false;
3498  }
3499  }
3500 
3501  } // has_PROPERTIES_PSC
3502 
3503 
3504  if(true == has_PROPERTIES_POS)
3505  {
3506  // i get .location and nothing else
3507 
3508  Bottle b_PROPERTIES_POS_location = b_PROPERTIES_POS.findGroup("location");
3509  if(b_PROPERTIES_POS_location.isNull())
3510  {
3511  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.POS.location";
3512  return false;
3513  }
3514 
3515  int tmp = b_PROPERTIES_POS_location.size();
3516  int numboards = tmp - 1; // first position of bottle contains the tag "location"
3517 
3518  // check if numboards is 1.
3519  constexpr uint8_t wantedboards = 1;
3520  if(wantedboards != numboards)
3521  {
3522  yError() << "ServiceParser::check_motion() in PROPERTIES.POS.location must contain " << wantedboards << " items and it has:" << numboards;
3523  return false;
3524  }
3525 
3526  mc_service.properties.poslocations.resize(wantedboards);
3527  for(int i=0; i<wantedboards; i++)
3528  {
3529  eObrd_location_t loc;
3530  formaterror = false;
3531  if(false == convert(b_PROPERTIES_POS_location.get(1+i).asString(), loc, formaterror))
3532  {
3533  yError() << "ServiceParser::check_motion() has detected an illegal format for SERVICE.PROPERTIES.POS.location";
3534  return false;
3535  }
3536 
3537  if(eobrd_place_can == loc.any.place)
3538  {
3539  mc_service.properties.poslocations[i].port = loc.can.port;
3540  mc_service.properties.poslocations[i].addr = loc.can.addr;
3541  mc_service.properties.poslocations[i].insideindex = eobrd_caninsideindex_none;
3542 
3543  }
3544  else if(eobrd_place_extcan == loc.any.place)
3545  { // for pos service we should not have such a format
3546  yError() << "ServiceParser::check_motion() has detected an incorrect format for SERVICE.PROPERTIES.POS.location. it must be either can, not extcan";
3547  mc_service.properties.poslocations[i].port = loc.extcan.port;
3548  mc_service.properties.poslocations[i].addr = loc.extcan.addr;
3549  mc_service.properties.poslocations[i].insideindex = eobrd_caninsideindex_none;
3550  }
3551  else
3552  {
3553  yError() << "ServiceParser::check_motion() has detected an illegal format for SERVICE.PROPERTIES.POS.location. it must be can";
3554  return false;
3555  }
3556  }
3557 
3558  } // has_PROPERTIES_POS
3559 
3560  if(true == has_PROPERTIES_JOINTMAPPING)
3561  {
3562 
3563  // actuator, encoder1, encoder2 must all be present. the params contained inside must be all of equal length and equal to numberofjoints
3564 
3565  Bottle b_PROPERTIES_JOINTMAPPING_ACTUATOR = Bottle(b_PROPERTIES_JOINTMAPPING.findGroup("ACTUATOR"));
3566  if(b_PROPERTIES_JOINTMAPPING_ACTUATOR.isNull())
3567  {
3568  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ACTUATOR";
3569  return false;
3570  }
3571 
3572  Bottle b_PROPERTIES_JOINTMAPPING_ENCODER1 = Bottle(b_PROPERTIES_JOINTMAPPING.findGroup("ENCODER1"));
3573  if(b_PROPERTIES_JOINTMAPPING_ENCODER1.isNull())
3574  {
3575  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ENCODER1";
3576  return false;
3577  }
3578 
3579  Bottle b_PROPERTIES_JOINTMAPPING_ENCODER2 = Bottle(b_PROPERTIES_JOINTMAPPING.findGroup("ENCODER2"));
3580  if(b_PROPERTIES_JOINTMAPPING_ENCODER2.isNull())
3581  {
3582  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ENCODER2";
3583  return false;
3584  }
3585 
3586  // now the vectors the above three contain ...
3587 
3588  Bottle b_PROPERTIES_JOINTMAPPING_ACTUATOR_type = Bottle(b_PROPERTIES_JOINTMAPPING_ACTUATOR.findGroup("type"));
3589  if(b_PROPERTIES_JOINTMAPPING_ACTUATOR_type.isNull())
3590  {
3591  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ACTUATOR.type";
3592  return false;
3593  }
3594 
3595  Bottle b_PROPERTIES_JOINTMAPPING_ACTUATOR_onboard = Bottle(b_PROPERTIES_JOINTMAPPING_ACTUATOR.findGroup("onboard"));
3596  // mandatory only for advfoc
3597 
3598  Bottle b_PROPERTIES_JOINTMAPPING_ACTUATOR_port = Bottle(b_PROPERTIES_JOINTMAPPING_ACTUATOR.findGroup("port"));
3599  if(b_PROPERTIES_JOINTMAPPING_ACTUATOR_port.isNull())
3600  {
3601  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ACTUATOR.port";
3602  return false;
3603  }
3604 
3605  Bottle b_PROPERTIES_JOINTMAPPING_ENCODER1_type = Bottle(b_PROPERTIES_JOINTMAPPING_ENCODER1.findGroup("type"));
3606  if(b_PROPERTIES_JOINTMAPPING_ENCODER1_type.isNull())
3607  {
3608  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ENCODER1.type";
3609  return false;
3610  }
3611  Bottle b_PROPERTIES_JOINTMAPPING_ENCODER1_port = Bottle(b_PROPERTIES_JOINTMAPPING_ENCODER1.findGroup("port"));
3612  if(b_PROPERTIES_JOINTMAPPING_ENCODER1_port.isNull())
3613  {
3614  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ENCODER1.port";
3615  return false;
3616  }
3617  Bottle b_PROPERTIES_JOINTMAPPING_ENCODER1_position = Bottle(b_PROPERTIES_JOINTMAPPING_ENCODER1.findGroup("position"));
3618  if(b_PROPERTIES_JOINTMAPPING_ENCODER1_position.isNull())
3619  {
3620  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ENCODER1.position";
3621  return false;
3622  }
3623  Bottle b_PROPERTIES_JOINTMAPPING_ENCODER1_resolution = Bottle(b_PROPERTIES_JOINTMAPPING_ENCODER1.findGroup("resolution"));
3624  if(b_PROPERTIES_JOINTMAPPING_ENCODER1_resolution.isNull())
3625  {
3626  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ENCODER1.resolution";
3627  return false;
3628  }
3629  Bottle b_PROPERTIES_JOINTMAPPING_ENCODER1_tolerance = Bottle(b_PROPERTIES_JOINTMAPPING_ENCODER1.findGroup("tolerance"));
3630  if(b_PROPERTIES_JOINTMAPPING_ENCODER1_tolerance.isNull())
3631  {
3632  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ENCODER1.tolerance";
3633  return false;
3634  }
3635 
3636 
3637 
3638  Bottle b_PROPERTIES_JOINTMAPPING_ENCODER2_type = Bottle(b_PROPERTIES_JOINTMAPPING_ENCODER2.findGroup("type"));
3639  if(b_PROPERTIES_JOINTMAPPING_ENCODER2_type.isNull())
3640  {
3641  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ENCODER2.type";
3642  return false;
3643  }
3644  Bottle b_PROPERTIES_JOINTMAPPING_ENCODER2_port = Bottle(b_PROPERTIES_JOINTMAPPING_ENCODER2.findGroup("port"));
3645  if(b_PROPERTIES_JOINTMAPPING_ENCODER2_port.isNull())
3646  {
3647  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ENCODER2.port";
3648  return false;
3649  }
3650  Bottle b_PROPERTIES_JOINTMAPPING_ENCODER2_position = Bottle(b_PROPERTIES_JOINTMAPPING_ENCODER2.findGroup("position"));
3651  if(b_PROPERTIES_JOINTMAPPING_ENCODER2_position.isNull())
3652  {
3653  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ENCODER2.position";
3654  return false;
3655  }
3656  Bottle b_PROPERTIES_JOINTMAPPING_ENCODER2_resolution = Bottle(b_PROPERTIES_JOINTMAPPING_ENCODER2.findGroup("resolution"));
3657  if(b_PROPERTIES_JOINTMAPPING_ENCODER2_resolution.isNull())
3658  {
3659  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ENCODER2.resolution";
3660  return false;
3661  }
3662  Bottle b_PROPERTIES_JOINTMAPPING_ENCODER2_tolerance = Bottle(b_PROPERTIES_JOINTMAPPING_ENCODER2.findGroup("tolerance"));
3663  if(b_PROPERTIES_JOINTMAPPING_ENCODER2_tolerance.isNull())
3664  {
3665  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ENCODER2.tolerance";
3666  return false;
3667  }
3668  // now the size of the vectors must all be equal
3669 
3670  size_t tmp = b_PROPERTIES_JOINTMAPPING_ACTUATOR_type.size();
3671  if( (tmp != b_PROPERTIES_JOINTMAPPING_ACTUATOR_port.size()) ||
3672  (tmp != b_PROPERTIES_JOINTMAPPING_ENCODER1_type.size()) ||
3673  (tmp != b_PROPERTIES_JOINTMAPPING_ENCODER1_port.size()) ||
3674  (tmp != b_PROPERTIES_JOINTMAPPING_ENCODER1_position.size()) ||
3675  (tmp != b_PROPERTIES_JOINTMAPPING_ENCODER1_resolution.size())||
3676  (tmp != b_PROPERTIES_JOINTMAPPING_ENCODER1_tolerance.size()) ||
3677  (tmp != b_PROPERTIES_JOINTMAPPING_ENCODER2_type.size()) ||
3678  (tmp != b_PROPERTIES_JOINTMAPPING_ENCODER2_port.size()) ||
3679  (tmp != b_PROPERTIES_JOINTMAPPING_ENCODER2_position.size()) ||
3680  (tmp != b_PROPERTIES_JOINTMAPPING_ENCODER2_resolution.size()) ||
3681  (tmp != b_PROPERTIES_JOINTMAPPING_ENCODER2_tolerance.size())
3682  )
3683  {
3684  yError() << "ServiceParser::check_motion() detected wrong number of columns somewhere inside PROPERTIES.JOINTMAPPING";
3685  return false;
3686  }
3687 
3688  // ok, we have the number of joints .........
3689  mc_service.properties.numofjoints = (0 == tmp ) ? (0) : (tmp-1);
3690 
3691  // i attempt to parse the vectors inside actuators (type, port), encoder1 (type, port, position) and encoder2 (type, port, position).
3692 
3693  mc_service.properties.actuators.resize(0);
3694  mc_service.properties.encoder1s.resize(0);
3695  mc_service.properties.encoder2s.resize(0);
3696 
3697  if(eomn_serv_MC_mc4 == mc_service.type)
3698  {
3699  mc_service.properties.mc4joints.resize(0);
3700  }
3701 
3702 
3703  for(int i=0; i<mc_service.properties.numofjoints; i++)
3704  {
3705  servMC_actuator_t act;
3706  servMC_encoder_t enc1;
3707  servMC_encoder_t enc2;
3708  bool formaterror = false;
3709 
3710  eOmc_encoder_t enctype = eomc_enc_unknown;
3711  uint8_t encport = eobrd_port_unknown;
3712  eOmc_position_t encposition = eomc_pos_unknown;
3713 
3714  // actuators ..
3715  act.type = eomc_act_unknown;
3716  act.desc.pwm.port = eobrd_port_unknown;
3717 
3718  if(false == convert(b_PROPERTIES_JOINTMAPPING_ACTUATOR_type.get(i+1).asString(), act.type, formaterror))
3719  {
3720  yError() << "ServiceParser::check_motion() PROPERTIES.JOINTMAPPING.actuator.type not valid for item" << i;
3721  return false;
3722  }
3723 
3724  if((eomn_serv_MC_mc4 == mc_service.type) && (eomc_act_mc4 != act.type))
3725  {
3726  yError() << "ServiceParser::check_motion() PROPERTIES.JOINTMAPPING.actuator.type should be mc4 with mc service of type eomn_serv_MC_mc4. Error in item" << i;
3727  return false;
3728  }
3729 
3730  if(false == parse_actuator_port(b_PROPERTIES_JOINTMAPPING_ACTUATOR_port.get(i+1).asString(), mc_service.properties.ethboardtype, act.type, act.desc, formaterror))
3731  {
3732  yError() << "ServiceParser::check_motion() PROPERTIES.JOINTMAPPING.actuator.port not valid for item" << i;
3733  return false;
3734  }
3735 
3736  if(eomn_serv_MC_mc4 == mc_service.type)
3737  {
3738  eObrd_canlocation_t item;
3739  item.port = act.desc.mc4.canloc.port;
3740  item.addr = act.desc.mc4.canloc.addr;
3741  item.insideindex = act.desc.mc4.canloc.insideindex;
3742 
3743  mc_service.properties.mc4joints.push_back(item);
3744  }
3745 
3746  if(eomn_serv_MC_advfoc == mc_service.type)
3747  {
3748  if(b_PROPERTIES_JOINTMAPPING_ACTUATOR_onboard.isNull())
3749  {
3750  yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ACTUATOR.onboard for eomn_serv_MC_advfoc";
3751  return false;
3752  }
3753 
3754  if(act.type != eomc_act_advfoc)
3755  {
3756  yError() << "ServiceParser::check_motion() detectde that PROPERTIES.JOINTMAPPING.ACTUATOR.type for eomn_serv_MC_advfoc id not advfoc";
3757  return false;
3758  }
3759 
3760  act.advdescr.type = eomc_act_advfoc;
3761  act.advdescr.location = act.desc.gen.location;
3762  eObrd_cantype_t bb {};
3763  convert(b_PROPERTIES_JOINTMAPPING_ACTUATOR_onboard.get(i+1).asString(), bb, formaterror);
3764  act.advdescr.board.type = bb;
3765  }
3766 
3767 
3768  // encoder1s ...
3769 
3770  enc1.desc.type = eomc_enc_unknown;
3771  enc1.desc.port = eobrd_port_unknown;
3772  enc1.desc.pos = eomc_pos_unknown;
3773 
3774  enctype = eomc_enc_unknown;
3775  if(false == convert(b_PROPERTIES_JOINTMAPPING_ENCODER1_type.get(i+1).asString(), enctype, formaterror))
3776  {
3777  yError() << "ServiceParser::check_motion() PROPERTIES.JOINTMAPPING.encoder1.type not valid for item" << i;
3778  return false;
3779  }
3780  enc1.desc.type = enctype;
3781 
3782  // depending on type, we ....
3783 
3784 
3785 
3786  // dobbiamo fare un parser che riconosca CONN:P6 se aea, qenc etc, oppure MAIS:thumbproximal se mais
3787 
3788  encport = eobrd_port_unknown;
3789  if(false == parse_encoder_port(b_PROPERTIES_JOINTMAPPING_ENCODER1_port.get(i+1).asString(), mc_service.properties.ethboardtype, enctype, encport, formaterror))
3790  {
3791  yError() << "ServiceParser::check_motion() PROPERTIES.JOINTMAPPING.encoder1.port not valid for item" << i;
3792  return false;
3793  }
3794  enc1.desc.port = encport;
3795 
3796  encposition = eomc_pos_unknown;
3797  if(false == convert(b_PROPERTIES_JOINTMAPPING_ENCODER1_position.get(i+1).asString(), encposition, formaterror))
3798  {
3799  yError() << "ServiceParser::check_motion() PROPERTIES.JOINTMAPPING.encoder1.position not valid for item" << i;
3800  return false;
3801  }
3802  enc1.desc.pos = encposition;
3803 
3804  enc1.resolution = b_PROPERTIES_JOINTMAPPING_ENCODER1_resolution.get(i+1).asInt32();
3805 
3806  enc1.tolerance = b_PROPERTIES_JOINTMAPPING_ENCODER1_tolerance.get(i+1).asFloat64();
3807 
3808 
3809 
3810  // encoder2s ...
3811 
3812  enc2.desc.type = eomc_enc_unknown;
3813  enc2.desc.port = eobrd_port_unknown;
3814  enc2.desc.pos = eomc_pos_unknown;
3815 
3816  enctype = eomc_enc_unknown;
3817  if(false == convert(b_PROPERTIES_JOINTMAPPING_ENCODER2_type.get(i+1).asString(), enctype, formaterror))
3818  {
3819  yError() << "ServiceParser::check_motion() PROPERTIES.JOINTMAPPING.encoder2.type not valid for item" << i;
3820  return false;
3821  }
3822 
3823  enc2.desc.type = enctype;
3824 
3825 
3826  encport = eobrd_port_unknown;
3827  if(false == parse_encoder_port(b_PROPERTIES_JOINTMAPPING_ENCODER2_port.get(i+1).asString(), mc_service.properties.ethboardtype, enctype, encport, formaterror))
3828  {
3829  yError() << "ServiceParser::check_motion() PROPERTIES.JOINTMAPPING.encoder2.port not valid for item" << i;
3830  return false;
3831  }
3832  enc2.desc.port = encport;
3833 
3834  encposition = eomc_pos_unknown;
3835  if(false == convert(b_PROPERTIES_JOINTMAPPING_ENCODER2_position.get(i+1).asString(), encposition, formaterror))
3836  {
3837  yError() << "ServiceParser::check_motion() PROPERTIES.JOINTMAPPING.encoder2.position not valid for item" << i;
3838  return false;
3839  }
3840 
3841  enc2.desc.pos = encposition;
3842 
3843  enc2.resolution = b_PROPERTIES_JOINTMAPPING_ENCODER2_resolution.get(i+1).asInt32();
3844  enc2.tolerance = b_PROPERTIES_JOINTMAPPING_ENCODER2_tolerance.get(i+1).asFloat64();
3845 
3846 
3847  // ok, we push act, enc1, enc2
3848 
3849  mc_service.properties.actuators.push_back(act);
3850  mc_service.properties.encoder1s.push_back(enc1);
3851  mc_service.properties.encoder2s.push_back(enc2);
3852 
3853  }
3854 
3855  } // has_PROPERTIES_JOINTMAPPING
3856 
3857 
3858  // add default values. then we may change tem
3859  mc_service.diagconfig.mode = eomn_serv_diagn_mode_NONE;
3860  mc_service.diagconfig.par16 = 0;
3861 
3862  if(true == has_PROPERTIES_DIAGNOSTICS)
3863  {
3864  Bottle b_PROPERTIES_DIAGNOSTICS_mode = b_PROPERTIES_DIAGNOSTICS.findGroup("mode");
3865  Bottle b_PROPERTIES_DIAGNOSTICS_par16 = b_PROPERTIES_DIAGNOSTICS.findGroup("par16");
3866  if(!b_PROPERTIES_DIAGNOSTICS_mode.isNull() && !b_PROPERTIES_DIAGNOSTICS_par16.isNull())
3867  {
3868  // if we have both of them ... and they contain at least (only) one we get the values
3869  int n_type = b_PROPERTIES_DIAGNOSTICS_mode.size() - 1;
3870  int n_par16 = b_PROPERTIES_DIAGNOSTICS_par16.size() - 1;
3871  if((1 == n_type) && (1 == n_par16))
3872  {
3873  eOmn_serv_diagn_mode_t dm = eomn_serv_diagn_mode_NONE;
3874  int par16 = 0;
3875  if(false == convert(b_PROPERTIES_DIAGNOSTICS_mode.get(1).asString(), dm, formaterror))
3876  {
3877  yWarning() << "ServiceParser::check_motion() has detected an illegal format for SERVICE.PROPERTIES.DIAGNOSTICS.mode. Using {eOmn_serv_diagn_mode_NONE, 0}";
3878  }
3879  else if(!b_PROPERTIES_DIAGNOSTICS_par16.get(1).isInt32())
3880  {
3881  yWarning() << "ServiceParser::check_motion() has detected an illegal format for SERVICE.PROPERTIES.DIAGNOSTICS.par16. Using {eOmn_serv_diagn_mode_NONE, 0}";
3882  }
3883  else
3884  {
3885  par16 = b_PROPERTIES_DIAGNOSTICS_par16.get(1).asInt32();
3886  }
3887 
3888  mc_service.diagconfig.mode = dm;
3889  mc_service.diagconfig.par16 = static_cast<uint16_t>(par16);
3890 
3891  yWarning() << "ServiceParser::check_motion() has detected some DIAGNOSTICS config for this MC service: mode = " << eomn_servicediagnmode2string(dm) << ", par16 = " << mc_service.diagconfig.par16;
3892 
3893  }
3894 
3895  }
3896 
3897  } // has_PROPERTIES_DIAGNOSTICS
3898 
3899 
3900  return true;
3901 }
3902 
3903 // int ServiceParser::getnumofjointsets(void)
3904 // {
3905 //
3906 // int n=0;
3907 // int njointsinset[mc_service.properties.numofjoints]; //the max number of sets is equal to max number of joints.
3908 // for(int i=0; i<mc_service.properties.numofjoints;i++)
3909 // {
3910 // njointsinset[i] = 0;
3911 // }
3912 //
3913 // for(int i=0; i<mc_service.properties.numofjoints;i++)
3914 // {
3915 // int set = mc_service.properties.joint2set[i];
3916 //
3917 // if(set > mc_service.properties.numofjoints)
3918 // {
3919 // yError() << "ServiceParser::getnumofjointsets: error in joint2set param. The set number is too big. Remember: max number of set is equal to max num of joint.";
3920 // return false;
3921 // }
3922 //
3923 // njointsinset[set]++;
3924 // }
3925 // int count =0;
3926 // for(int i=0; i<mc_service.properties.numofjoints;i++)
3927 // {
3928 // if(njointsinset[i] != 0)
3929 // count++;
3930 // }
3931 //
3932 // return count;
3933 // }
3934 
3935 
3936 //bool ServiceParser::parseMCEncoderItem(Bottle &b_ENCODER, vector<servMC_encoder_t> &encoders, char *encString)
3937 //{
3938 //#warning -> correct warnings on
3939 //
3940 // Bottle b_ENCODER_TYPE(b_ENCODER.find("type").asString());
3941 // if(b_ENCODER_TYPE.isNull())
3942 // {
3943 // yError() << "ServiceParser::parseMCEncoderItem() cannot find JOINTMAPPING."<< encString<< ".type";
3944 // return false;
3945 // }
3946 //
3947 // Bottle b_ENCODER_PORT(b_ENCODER.find("port").asString());
3948 // if(b_ENCODER_PORT.isNull())
3949 // {
3950 // yError() << "ServiceParser::parseMCEncoderItem() cannot find JOINTMAPPING"<< encString<< ".type";
3951 // return false;
3952 // }
3953 //
3954 // encoders.resize(0);
3955 // int numofenc = b_ENCODER_TYPE.size() -1;
3956 //
3957 // //VALE: controlla che il numero di act sia uguale a quello di joint per embobjmotion control obj!!!
3958 // for(int i = 0; i< numofenc; i++)
3959 // {
3960 // servMC_encoder_t item;
3961 // bool formaterror = false;
3962 // if(false == convert(b_ENCODER_TYPE.get(i+1).asString(), item.type, formaterror))
3963 // {
3964 // yError() << "ServiceParser::parseMCEncoderItem() encoder type not valid in " << encString;
3965 // return false;
3966 // }
3967 // //VALE: commented in ordet to compile I have not enouth time to implement this function
3973 //
3974 // if(false == convert(b_ENCODER_TYPE.get(i+1).asString(), item.position, formaterror))
3975 // {
3976 // yError() << "ServiceParser::parseMCEncoderItem() encoder location not valid in " << encString;
3977 // return false;
3978 // }
3979 // encoders.push_back(item);
3980 //
3981 // }
3982 // return true;
3983 //}
3984 
3985 
3986 // bool ServiceParser::copyjomocouplingInfo( eOmc_4jomo_coupling_t *jc_dest)
3987 // {
3988 //
3989 // memset(jc_dest, 0, sizeof(eOmc_4jomo_coupling_t));
3990 //
3991 // // very important: so far, the fw in Controller.c must find eomc_jointSetNum_none in un-used entries, even if we have less than 4 joints.
3992 // memset(jc_dest->joint2set, eomc_jointSetNum_none, sizeof(jc_dest->joint2set));
3993 //
3994 // for(int i=0; i<mc_service.properties.numofjoints; i++)
3995 // {
3996 // jc_dest->joint2set[i] = mc_service.properties.joint2set[i];
3997 // }
3998 //
3999 // for(int i=0; i<4; i++)
4000 // {
4001 // for(int j=0; j<4; j++)
4002 // {
4003 // jc_dest->joint2motor[i][j] = eo_common_float_to_Q17_14(mc_service.properties.controller.matrixJ2M[4*i+j]);
4004 // jc_dest->motor2joint[i][j] = eo_common_float_to_Q17_14(mc_service.properties.controller.matrixM2J[4*i+j]);
4005 // }
4006 // }
4007 //
4008 //
4009 // for(int r=0; r<4; r++)
4010 // {
4011 // for(int c=0; c<6; c++)
4012 // {
4013 // jc_dest->encoder2joint[r][c] = eo_common_float_to_Q17_14(mc_service.properties.controller.matrixE2J[6*r+c]);
4014 // }
4015 // }
4016 //
4017 // for(int s=0; s< mc_service.properties.numofjointsets; s++)
4018 // {
4019 // memcpy(&jc_dest->jsetcfg[s] , &mc_service.properties.jointset_cfgs[s], sizeof(eOmc_jointset_configuration_t));
4020 // }
4021 //
4022 // return true;
4023 // }
4024 
4025 
4026 
4027 bool ServiceParser::parseService(Searchable &config, servConfigMC_t &mcconfig)
4028 {
4029  bool ret = false;
4030 
4031  if(false == check_motion(config))
4032  {
4033  yError() << "ServiceParser::parseService() gets same errors parsing SERVICE MC group";
4034  return ret;
4035  }
4036 
4037  // if we dont find the xml file ... we just return true but mc_service.type is eomn_serv_MC_generic.
4038  // in such a case we dont transmit the config and ask the eth board to config itself accoring to its ip address.
4039  // ...
4040 
4041  mcconfig.ethservice.configuration.type = mc_service.type;
4042  mcconfig.ethservice.configuration.diagnosticsmode = mc_service.diagconfig.mode;
4043  mcconfig.ethservice.configuration.diagnosticsparam = mc_service.diagconfig.par16;
4044 
4045  switch(mc_service.type)
4046  {
4047  case eomn_serv_MC_foc:
4048  {
4049  eOmn_serv_config_data_mc_foc_t *data_mc = &(mcconfig.ethservice.configuration.data.mc.foc_based);
4050 
4051  // 1. ->version (of foc board).
4052  data_mc->version.firmware.major = mc_service.properties.canboards.at(0).firmware.major;
4053  data_mc->version.firmware.minor = mc_service.properties.canboards.at(0).firmware.minor;
4054  data_mc->version.firmware.build = mc_service.properties.canboards.at(0).firmware.build;
4055  data_mc->version.protocol.major = mc_service.properties.canboards.at(0).protocol.major;
4056  data_mc->version.protocol.minor = mc_service.properties.canboards.at(0).protocol.minor;
4057 
4058  // we assume that all can boards have the same type for each joint
4059  data_mc->type = mc_service.properties.canboards.at(0).type;
4060 
4061  // 2. ->arrayofjomodescriptors
4062  EOarray *arrayofjomos = eo_array_New(4, sizeof(eOmc_jomo_descriptor_t), &data_mc->arrayofjomodescriptors);
4063  int numofjomos = mc_service.properties.numofjoints;
4064 
4065  for(int i=0; i<numofjomos; i++)
4066  {
4067  eOmc_jomo_descriptor_t jomodes = {};
4068 
4069  // 1. actuator is on foc: we need the address
4070  jomodes.actuator.foc.canloc.port = mc_service.properties.actuators[i].desc.foc.canloc.port;
4071  jomodes.actuator.foc.canloc.addr = mc_service.properties.actuators[i].desc.foc.canloc.addr;
4072  jomodes.actuator.foc.canloc.insideindex = eobrd_caninsideindex_first;
4073 
4074  // 2. encoder1 is ...
4075  jomodes.encoder1.type = mc_service.properties.encoder1s[i].desc.type;
4076  jomodes.encoder1.port = mc_service.properties.encoder1s[i].desc.port;
4077  jomodes.encoder1.pos = mc_service.properties.encoder1s[i].desc.pos;
4078 
4079  // 3. encoder2 is ...
4080  jomodes.encoder2.type = mc_service.properties.encoder2s[i].desc.type;
4081  jomodes.encoder2.port = mc_service.properties.encoder2s[i].desc.port;
4082  jomodes.encoder2.pos = mc_service.properties.encoder2s[i].desc.pos;
4083 
4084  eo_array_PushBack(arrayofjomos, &jomodes);
4085 
4086  }
4087 
4088 
4090  //eOmc_4jomo_coupling_t *jomocoupling = &data_mc->jomocoupling;
4091 
4092  //ret = copyjomocouplingInfo(jomocoupling);
4093 
4094  // ok, everything is done
4095  ret = true;
4096 
4097  } break;
4098 
4099  case eomn_serv_MC_mc4:
4100  {
4101  eOmn_serv_config_data_mc_mc4_t *data_mc = &(mcconfig.ethservice.configuration.data.mc.mc4_based);
4102 
4103  // 1. ->version (of mc4 board) + ->mais.version.
4104  bool mc4boardFound = false;
4105  bool maisboardFound = false;
4106  for(size_t i=0; i<mc_service.properties.canboards.size(); i++)
4107  {
4108  if(eobrd_cantype_mc4 == mc_service.properties.canboards[i].type)
4109  {
4110  data_mc->mc4version.protocol = mc_service.properties.canboards[i].protocol;
4111  data_mc->mc4version.firmware = mc_service.properties.canboards[i].firmware;
4112  mc4boardFound = true;
4113  }
4114  else if(eobrd_cantype_mais == mc_service.properties.canboards[i].type)
4115  {
4116  data_mc->mais.version.protocol = mc_service.properties.canboards[i].protocol;
4117  data_mc->mais.version.firmware = mc_service.properties.canboards[i].firmware;
4118  maisboardFound = true;
4119  }
4120  }
4121 
4122  if((false == maisboardFound) || (false == mc4boardFound))
4123  {
4124  yError() << "ServiceParser::parseService() gets same errors parsing SERVICE MC group for mc4: cannot find description of mc4 or mais board";
4125  }
4126 
4127 // data_mc->mc4version.firmware.major = mc_service.properties.canboards.at(0).firmware.major;
4128 // data_mc->mc4version.firmware.minor = mc_service.properties.canboards.at(0).firmware.minor;
4129 // data_mc->mc4version.firmware.build = mc_service.properties.canboards.at(0).firmware.build;
4130 // data_mc->mc4version.protocol.major = mc_service.properties.canboards.at(0).protocol.major;
4131 // data_mc->mc4version.protocol.minor = mc_service.properties.canboards.at(0).protocol.minor;
4132 
4133  // 2. ->mc4shifts
4134  data_mc->mc4shifts = mc_service.properties.mc4shifts;
4135 
4136  // 3. ->mc4joints
4137  for(int i=0; i<12; i++)
4138  {
4139  data_mc->mc4joints[i] = mc_service.properties.mc4joints[i];
4140  }
4141 
4142 
4143  // 4. ->mais.canloc
4144  data_mc->mais.canloc = mc_service.properties.maislocation;
4145 
4146  // 5. ->broadcastflags
4147  data_mc->broadcastflags = 0;
4148  for(size_t i=0; i<mc_service.properties.mc4broadcasts.size(); i++)
4149  {
4150  eOmc_mc4broadcast_t item = mc_service.properties.mc4broadcasts[i];
4151  if((eomc_mc4broadcast_none != item) && (eomc_mc4broadcast_unknown != item))
4152  {
4153  eo_common_hlfword_bitset(&data_mc->broadcastflags, item);
4154  }
4155  }
4156 
4157  // ok, everything is done
4158  ret = true;
4159 
4160  } break;
4161 
4162  case eomn_serv_MC_mc4plus:
4163  {
4164  eOmn_serv_config_data_mc_mc4plus_t *data_mc = &(mcconfig.ethservice.configuration.data.mc.mc4plus_based);
4165 
4166  // 3. ->arrayofjomodescriptors
4167  EOarray *arrayofjomos = eo_array_New(4, sizeof(eOmc_jomo_descriptor_t), &data_mc->arrayofjomodescriptors);
4168  int numofjomos = mc_service.properties.numofjoints;
4169 
4170  for(int i=0; i<numofjomos; i++)
4171  {
4172  eOmc_jomo_descriptor_t jomodes = {};
4173 
4174  // 1. actuator is on pwm: we need the port
4175  jomodes.actuator.pwm.port = mc_service.properties.actuators[i].desc.pwm.port;
4176 
4177  // 2. encoder1 is ...
4178  jomodes.encoder1.type = mc_service.properties.encoder1s[i].desc.type;
4179  jomodes.encoder1.port = mc_service.properties.encoder1s[i].desc.port;
4180  jomodes.encoder1.pos = mc_service.properties.encoder1s[i].desc.pos;
4181 
4182  // 3. encoder2 is ...
4183  jomodes.encoder2.type = mc_service.properties.encoder2s[i].desc.type;
4184  jomodes.encoder2.port = mc_service.properties.encoder2s[i].desc.port;
4185  jomodes.encoder2.pos = mc_service.properties.encoder2s[i].desc.pos;
4186 
4187  eo_array_PushBack(arrayofjomos, &jomodes);
4188 
4189  }
4190 
4191  // // 3. ->jomocoupling
4192  //eOmc_4jomo_coupling_t *jomocoupling = &data_mc->jomocoupling;
4193 
4194  //ret = copyjomocouplingInfo(jomocoupling);
4195 
4196  // ok, everything is done
4197  ret = true;
4198 
4199  } break;
4200 
4201  case eomn_serv_MC_mc4plusmais:
4202  {
4203  eOmn_serv_config_data_mc_mc4plusmais_t *data_mc = &(mcconfig.ethservice.configuration.data.mc.mc4plusmais_based);
4204 
4205  // 1. ->mais
4206  eOmn_serv_config_data_as_mais_t *mais = &data_mc->mais;
4207 
4208  mais->canloc.port = mc_service.properties.maislocation.port;
4209  mais->canloc.addr = mc_service.properties.maislocation.addr;
4210  mais->canloc.insideindex = mc_service.properties.maislocation.insideindex;
4211 
4212  mais->version.firmware.major = mc_service.properties.canboards.at(0).firmware.major;
4213  mais->version.firmware.minor = mc_service.properties.canboards.at(0).firmware.minor;
4214  mais->version.firmware.build = mc_service.properties.canboards.at(0).firmware.build;
4215  mais->version.protocol.major = mc_service.properties.canboards.at(0).protocol.major;
4216  mais->version.protocol.minor = mc_service.properties.canboards.at(0).protocol.minor;
4217 
4218  // 2. ->arrayofjomodescriptors
4219  EOarray *arrayofjomos = eo_array_New(4, sizeof(eOmc_jomo_descriptor_t), &data_mc->arrayofjomodescriptors);
4220  int numofjomos = mc_service.properties.numofjoints;
4221 
4222  for(int i=0; i<numofjomos; i++)
4223  {
4224  eOmc_jomo_descriptor_t jomodes = {};
4225 
4226  // 1. actuator is on pwm: we need the port
4227  jomodes.actuator.pwm.port = mc_service.properties.actuators[i].desc.pwm.port;
4228 
4229  // 2. encoder1 is ...
4230  jomodes.encoder1.type = mc_service.properties.encoder1s[i].desc.type;
4231  jomodes.encoder1.port = mc_service.properties.encoder1s[i].desc.port;
4232  jomodes.encoder1.pos = mc_service.properties.encoder1s[i].desc.pos;
4233 
4234  // 3. encoder2 is ...
4235  jomodes.encoder2.type = mc_service.properties.encoder2s[i].desc.type;
4236  jomodes.encoder2.port = mc_service.properties.encoder2s[i].desc.port;
4237  jomodes.encoder2.pos = mc_service.properties.encoder2s[i].desc.pos;
4238 
4239  eo_array_PushBack(arrayofjomos, &jomodes);
4240 
4241  }
4242 
4243 
4245  //eOmc_4jomo_coupling_t *jomocoupling = &data_mc->jomocoupling;
4246 
4247  //ret = copyjomocouplingInfo(jomocoupling);
4248 
4249  // ok, everything is done
4250  ret = true;
4251 
4252  } break;
4253 
4254  case eomn_serv_MC_mc2pluspsc:
4255  {
4256  eOmn_serv_config_data_mc_mc2pluspsc_t *data_mc = &(mcconfig.ethservice.configuration.data.mc.mc2pluspsc);
4257 
4258  // 1. ->psc
4259  eOmn_serv_config_data_as_psc_t *psc = &data_mc->psc;
4260 
4261 
4262  for(size_t i=0; i<mc_service.properties.psclocations.size(); i++)
4263  {
4264  psc->boardInfo.canloc[i].port=mc_service.properties.psclocations[i].port;
4265  psc->boardInfo.canloc[i].addr=mc_service.properties.psclocations[i].addr;
4266  psc->boardInfo.canloc[i].insideindex=mc_service.properties.psclocations[i].insideindex;
4267  }
4268 
4269 
4270  psc->version.firmware.major = mc_service.properties.canboards.at(0).firmware.major;
4271  psc->version.firmware.minor = mc_service.properties.canboards.at(0).firmware.minor;
4272  psc->version.firmware.build = mc_service.properties.canboards.at(0).firmware.build;
4273  psc->version.protocol.major = mc_service.properties.canboards.at(0).protocol.major;
4274  psc->version.protocol.minor = mc_service.properties.canboards.at(0).protocol.minor;
4275 
4276  // 2. ->arrayofjomodescriptors
4277  EOarray *arrayofjomos = eo_array_New(4, sizeof(eOmc_jomo_descriptor_t), &data_mc->arrayofjomodescriptors);
4278  int numofjomos = mc_service.properties.numofjoints;
4279 
4280  for(int i=0; i<numofjomos; i++)
4281  {
4282  eOmc_jomo_descriptor_t jomodes = {};
4283 
4284  // 1. actuator is on pwm: we need the port
4285  jomodes.actuator.pwm.port = mc_service.properties.actuators[i].desc.pwm.port;
4286 
4287  // 2. encoder1 is ...
4288  jomodes.encoder1.type = mc_service.properties.encoder1s[i].desc.type;
4289  jomodes.encoder1.port = mc_service.properties.encoder1s[i].desc.port;
4290  jomodes.encoder1.pos = mc_service.properties.encoder1s[i].desc.pos;
4291 
4292  // 3. encoder2 is ...
4293  jomodes.encoder2.type = mc_service.properties.encoder2s[i].desc.type;
4294  jomodes.encoder2.port = mc_service.properties.encoder2s[i].desc.port;
4295  jomodes.encoder2.pos = mc_service.properties.encoder2s[i].desc.pos;
4296 
4297  eo_array_PushBack(arrayofjomos, &jomodes);
4298 
4299  }
4300 
4301  // ok, everything is done
4302  ret = true;
4303 
4304  } break;
4305 
4306 
4307  case eomn_serv_MC_mc4plusfaps:
4308  {
4309  eOmn_serv_config_data_mc_mc4plusfaps_t *data_mc = &(mcconfig.ethservice.configuration.data.mc.mc4plusfaps);
4310 
4311  // 1. ->pos
4312  eOmn_serv_config_data_as_pos_t *pos = &data_mc->pos;
4313 
4314  // get firmware and protocol info
4315  for(size_t b=0; b<eOas_pos_boards_maxnumber; b++)
4316  {
4317  pos->config.boardconfig[b].boardinfo.type = mc_service.properties.canboards[b].type;
4318  pos->config.boardconfig[b].boardinfo.firmware.major = mc_service.properties.canboards[b].firmware.major;
4319  pos->config.boardconfig[b].boardinfo.firmware.minor = mc_service.properties.canboards[b].firmware.minor;
4320  pos->config.boardconfig[b].boardinfo.firmware.build = mc_service.properties.canboards[b].firmware.build;
4321  pos->config.boardconfig[b].boardinfo.protocol.major = mc_service.properties.canboards[b].protocol.major;
4322  pos->config.boardconfig[b].boardinfo.protocol.minor = mc_service.properties.canboards[b].protocol.minor;
4323 
4324  pos->config.boardconfig[b].canloc.addr = mc_service.properties.poslocations[b].addr;
4325  pos->config.boardconfig[b].canloc.port = mc_service.properties.poslocations[b].port;
4326 
4327  for(size_t s=0; s<eOas_pos_sensorsinboard_maxnumber; s++)
4328  {
4329  pos->config.boardconfig[b].sensors[s].connector = s;
4330  pos->config.boardconfig[b].sensors[s].type = eoas_pos_TYPE_decideg;
4331  pos->config.boardconfig[b].sensors[s].port = static_cast<eObrd_portpos_t>(s);
4332  pos->config.boardconfig[b].sensors[s].enabled = 1;
4333  pos->config.boardconfig[b].sensors[s].invertdirection = 0;
4334  pos->config.boardconfig[b].sensors[s].rotation = eoas_pos_ROT_zero;
4335  pos->config.boardconfig[b].sensors[s].offset = 0;
4336  }
4337  }
4338 
4339 #if 0
4340  for(size_t i=0; i<mc_service.properties.poslocations.size(); i++)
4341  {
4342  pos->config.boardconfig[0].canloc.port = mc_service.properties.poslocations[i].port;
4343  pos->config.boardconfig[0].canloc.addr = mc_service.properties.poslocations[i].addr;
4344  pos->config.boardconfig[0].canloc.insideindex = mc_service.properties.poslocations[i].insideindex;
4345  }
4346 
4347 
4348  pos->config.boardconfig[0].boardinfo.firmware.major = mc_service.properties.canboards.at(0).firmware.major;
4349  pos->config.boardconfig[0].boardinfo.firmware.minor = mc_service.properties.canboards.at(0).firmware.minor;
4350  pos->config.boardconfig[0].boardinfo.firmware.build = mc_service.properties.canboards.at(0).firmware.build;
4351  pos->config.boardconfig[0].boardinfo.protocol.major = mc_service.properties.canboards.at(0).protocol.major;
4352  pos->config.boardconfig[0].boardinfo.protocol.minor = mc_service.properties.canboards.at(0).protocol.minor;
4353 #endif
4354  // 2. ->arrayofjomodescriptors
4355  EOarray *arrayofjomos = eo_array_New(4, sizeof(eOmc_jomo_descriptor_t), &data_mc->arrayofjomodescriptors);
4356  size_t numofjomos = mc_service.properties.numofjoints;
4357 
4358  for(size_t i=0; i<numofjomos; i++)
4359  {
4360  eOmc_jomo_descriptor_t jomodes = {};
4361 
4362  // 1. actuator is on pwm: we need the port
4363  jomodes.actuator.pwm.port = mc_service.properties.actuators[i].desc.pwm.port;
4364 
4365  // 2. encoder1 is ...
4366  jomodes.encoder1.type = mc_service.properties.encoder1s[i].desc.type;
4367  jomodes.encoder1.port = mc_service.properties.encoder1s[i].desc.port;
4368  jomodes.encoder1.pos = mc_service.properties.encoder1s[i].desc.pos;
4369 
4370  // 3. encoder2 is ...
4371  jomodes.encoder2.type = mc_service.properties.encoder2s[i].desc.type;
4372  jomodes.encoder2.port = mc_service.properties.encoder2s[i].desc.port;
4373  jomodes.encoder2.pos = mc_service.properties.encoder2s[i].desc.pos;
4374 
4375  eo_array_PushBack(arrayofjomos, &jomodes);
4376  }
4377 
4378  // ok, everything is done
4379  ret = true;
4380 
4381  } break;
4382 
4383  case eomn_serv_MC_advfoc:
4384  {
4385  eOmn_serv_config_data_mc_advfoc_t *data_mc = &(mcconfig.ethservice.configuration.data.mc.advfoc);
4386 
4387  ret = true;
4388 
4389  // 1. ->eOmc_arrayof_4advjomodescriptors_t
4390  EOarray *arrayofjomos = eo_array_New(4, sizeof(eOmc_adv_jomo_descriptor_t), &data_mc->arrayof4advjomodescriptors);
4391  size_t numofjomos = mc_service.properties.numofjoints;
4392 
4393  for(size_t i=0; i<numofjomos; i++)
4394  {
4395  eOmc_adv_jomo_descriptor_t jomodes = {};
4396 
4397  // 1. actuator is on adv: we need the board, its location and its required versions of application and protocol
4398  if(mc_service.properties.actuators[i].type != eomc_act_advfoc)
4399  {
4400  yError() << "ServiceParser::parseService() unknown actuator value for eomn_serv_MC_advfoc mode. we need eomc_act_advfoc";
4401  ret = false;
4402  continue;
4403  }
4404 
4405  // find the relevant brd inside the vector mc_service.properties.canboards that matches mc_service.properties.actuators[i].board
4406  // so far i just use the first one
4407 
4408  // 1. actuator...
4409  jomodes.actuator.type = eomc_act_advfoc;
4410  jomodes.actuator.location = mc_service.properties.actuators[i].advdescr.location; //mc_service.properties.actuators[i].desc.gen.location;
4411  jomodes.actuator.board.type = mc_service.properties.actuators[i].advdescr.board.type;
4412  eObrd_firmwareversion_t fw {};
4413  eObrd_protocolversion_t pr {};
4414  // i must search for the fw and pr given the board inside ....
4415  bool ff {false};
4416  for(size_t i=0; i<mc_service.properties.canboards.size(); i++)
4417  {
4418  if(mc_service.properties.canboards[i].type == jomodes.actuator.board.type)
4419  {
4420  fw = mc_service.properties.canboards[i].firmware;
4421  pr = mc_service.properties.canboards[i].protocol;
4422  ff = true;
4423  break;
4424  }
4425  }
4426 
4427  if(false == ff)
4428  {
4429  yError() << "ServiceParser::parseService() could not find the actuator board inside the mc_service.properties.canboards[] vector";
4430  return false;
4431  }
4432 
4433  jomodes.actuator.board.firmware = fw;
4434  jomodes.actuator.board.protocol = pr;
4435 
4436  // 2. encoder1 is ...
4437  jomodes.encoder1.type = mc_service.properties.encoder1s[i].desc.type;
4438  jomodes.encoder1.port = mc_service.properties.encoder1s[i].desc.port;
4439  jomodes.encoder1.pos = mc_service.properties.encoder1s[i].desc.pos;
4440 
4441  // 3. encoder2 is ...
4442  jomodes.encoder2.type = mc_service.properties.encoder2s[i].desc.type;
4443  jomodes.encoder2.port = mc_service.properties.encoder2s[i].desc.port;
4444  jomodes.encoder2.pos = mc_service.properties.encoder2s[i].desc.pos;
4445 
4446  eo_array_PushBack(arrayofjomos, &jomodes);
4447  }
4448 
4449  // ok, everything is done
4450  ret = ret; // keep it as ret = ret ...
4451 
4452  } break;
4453 
4454  case eomn_serv_MC_generic:
4455  {
4456  yWarning() << "ServiceParser::parseService() eomn_serv_MC_generic detected. set type = eomn_serv_MC_generic to let the remote board configure itself according to its IP address";
4457  mcconfig.ethservice.configuration.type = eomn_serv_MC_generic;
4458  ret = true;
4459  } break;
4460 
4461  default:
4462  {
4463  yError() << "ServiceParser::parseService() unknown value in eOmn_serv_type_t field";
4464  ret = false;
4465  } break;
4466  }
4467 
4468 
4469  return ret;
4470 }
4471 
4472 
4474 {
4475  if(mc_service.properties.encoder1s[index].desc.pos == eomc_pos_atjoint)
4476  {
4477  return(&mc_service.properties.encoder1s[index]);
4478  }
4479  else if(mc_service.properties.encoder2s[index].desc.pos == eomc_pos_atjoint)
4480  {
4481  return(&mc_service.properties.encoder2s[index]);
4482  }
4483  else
4484  return NULL;
4485 }
4486 
4488 {
4489  if(mc_service.properties.encoder1s[index].desc.pos == eomc_pos_atmotor)
4490  {
4491  return(&mc_service.properties.encoder1s[index]);
4492  }
4493  else if(mc_service.properties.encoder2s[index].desc.pos == eomc_pos_atmotor)
4494  {
4495  return(&mc_service.properties.encoder2s[index]);
4496  }
4497  else
4498  return NULL;
4499 
4500 }
4501 
4502 //static eOmn_serv_configuration_t s_serv_config_mc_v3_0B0;
4503 /*static const eOmn_serv_configuration_t s_serv_config_mc_v3_0B0 =
4504 { // eb12 or 0B0
4505  .type = eomn_serv_MC_mc4plus,
4506  .filler = {0},
4507  .data.mc.mc4plus_based =
4508  {
4509  .boardtype4mccontroller = emscontroller_board_HEAD_neckpitch_neckroll,
4510  .filler = {0},
4511  .arrayofjomodescriptors =
4512  {
4513  .head =
4514  {
4515  .capacity = 4,
4516  .itemsize = sizeof(eOmn_serv_jomo_descriptor_t),
4517  .size = 2,
4518  .internalmem = 0
4519  },
4520  .data =
4521  {
4522  { // joint 0: neck-pitch
4523  .actuator.pwm =
4524  {
4525  .port = 0 // eomn_serv_mc_port_mc4plus_pwmP3 is hal_motor1=0 ?? verify!
4526  },
4527  .sensor =
4528  {
4529  .type = eomc_enc_aea,
4530  .port = 1, // eomn_serv_mc_port_mc4plus_spiP11 ?? verify!
4531  .pos = eomc_pos_atjoint
4532  },
4533  .encoder2 =
4534  {
4535  .type = eomc_enc_qenc,
4536  .port = 0, // eomn_serv_mc_port_mc4plus_qencP3 ?? verify!
4537  .pos = eomc_pos_atmotor
4538  }
4539  },
4540  { // joint 1: neck-roll
4541  .actuator.pwm =
4542  {
4543  .port = 2 // eomn_serv_mc_port_mc4plus_pwmP4 is hal_motor3=2 ?? verify!
4544  },
4545  .sensor =
4546  {
4547  .type = eomc_enc_aea,
4548  .port = 0, // eomn_serv_mc_port_mc4plus_spiP10 ?? verify!
4549  .pos = eomc_pos_atjoint
4550  },
4551  .encoder2 =
4552  {
4553  .type = eomc_enc_qenc,
4554  .port = 2, // eomn_serv_mc_port_mc4plus_qencP4 ?? verify!
4555  .pos = eomc_pos_atmotor
4556  }
4557  },
4558  { // joint 2
4559  .actuator.pwm =
4560  {
4561  .port = eomn_serv_mc_port_none
4562  },
4563  .sensor =
4564  {
4565  .type = eomn_serv_mc_sensor_none,
4566  .port = eomn_serv_mc_port_none,
4567  .pos = eomn_serv_mc_sensor_pos_none
4568  },
4569  .encoder2 =
4570  {
4571  .type = eomn_serv_mc_sensor_none,
4572  .port = eomn_serv_mc_port_none,
4573  .pos = eomn_serv_mc_sensor_pos_none
4574  }
4575  },
4576  { // joint 3
4577  .actuator.pwm =
4578  {
4579  .port = eomn_serv_mc_port_none
4580  },
4581  .sensor =
4582  {
4583  .type = eomn_serv_mc_sensor_none,
4584  .port = eomn_serv_mc_port_none,
4585  .pos = eomn_serv_mc_sensor_pos_none
4586  },
4587  .encoder2 =
4588  {
4589  .type = eomn_serv_mc_sensor_none,
4590  .port = eomn_serv_mc_port_none,
4591  .pos = eomn_serv_mc_sensor_pos_none
4592  }
4593  }
4594  }
4595  },
4596  .jomocoupling =
4597  {
4598  .joint2set =
4599  {
4600  eomc_jointSetNum_zero, eomc_jointSetNum_zero, eomc_jointSetNum_none, eomc_jointSetNum_none
4601  },
4602  .joint2motor =
4603  { // zero matrix: use matrix embedded in controller and seecetd by boardtype4mccontroller
4604  { EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
4605  { EO_COMMON_FLOAT_TO_Q17_14(-1.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
4606  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
4607  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f) }
4608  },
4609  .encoder2joint =
4610  { // identical matrix
4611  { EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
4612  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
4613  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
4614  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f) }
4615  }
4616  }
4617  }
4618 };
4619 */
4620 //static eOmn_serv_configuration_t s_serv_config_mc_v3_0B9;
4621 /*static const eOmn_serv_configuration_t s_serv_config_mc_v3_0B9=
4622 { // eb15 or 0B9
4623  .type = eomn_serv_MC_mc4plus,
4624  .filler = {0},
4625  .data.mc.mc4plus_based =
4626  {
4627  .boardtype4mccontroller = emscontroller_board_4jointsNotCoupled,
4628  .filler = {0},
4629  .arrayofjomodescriptors =
4630  {
4631  .head =
4632  {
4633  .capacity = 4,
4634  .itemsize = sizeof(eOmn_serv_jomo_descriptor_t),
4635  .size = 4,
4636  .internalmem = 0
4637  },
4638  .data =
4639  {
4640  { // joint 0: lip-left
4641  .actuator.pwm =
4642  {
4643  .port = 2 // eomn_serv_mc_port_mc4plus_pwmP4 is hal_motor2=1 ?? verify!
4644  },
4645  .sensor =
4646  {
4647  .type = eomc_enc_qenc,
4648  .port = 2, // eomn_serv_mc_port_mc4plus_qencP4 ?? verify!
4649  .pos = eomc_pos_atjoint
4650  },
4651  .encoder2 =
4652  {
4653  .type = eomc_enc_qenc,
4654  .port = 2, // eomn_serv_mc_port_mc4plus_qencP4 ?? verify!
4655  .pos = eomc_pos_atmotor
4656  }
4657  },
4658  { // joint 1: lip-high
4659  .actuator.pwm =
4660  {
4661  .port = 1 // eomn_serv_mc_port_mc4plus_pwmP2 is hal_motor2=1 ?? verify!
4662  },
4663  .sensor =
4664  {
4665  .type = eomc_enc_qenc,
4666  .port = 1, // eomn_serv_mc_port_mc4plus_qencP2 ?? verify!
4667  .pos = eomc_pos_atjoint
4668  },
4669  .encoder2 =
4670  {
4671  .type = eomc_enc_qenc,
4672  .port = 1, // eomn_serv_mc_port_mc4plus_qencP2 ?? verify!
4673  .pos = eomc_pos_atmotor
4674  }
4675  },
4676  { // joint 2: lip-right
4677  .actuator.pwm =
4678  {
4679  .port = 0 // eomn_serv_mc_port_mc4plus_pwmP3 is hal_motor4=3 ?? verify!
4680  },
4681  .sensor =
4682  {
4683  .type = eomc_enc_qenc,
4684  .port = 0, // eomn_serv_mc_port_mc4plus_qencP3 is hal_quad_enc1 = 0 ?? verify!
4685  .pos = eomc_pos_atjoint
4686  },
4687  .encoder2 =
4688  {
4689  .type = eomc_enc_qenc,
4690  .port = 0, // eomn_serv_mc_port_mc4plus_qencP3 is hal_quad_enc1 = 0 ?? verify!
4691  .pos = eomc_pos_atmotor
4692  }
4693  },
4694  { // joint 3: lip-bottom
4695  .actuator.pwm =
4696  {
4697  .port = 3 // eomn_serv_mc_port_mc4plus_pwmP5 is hal_motor3=2 ?? verify!
4698  },
4699  .sensor =
4700  {
4701  .type = eomc_enc_qenc,
4702  .port = 3, // eomn_serv_mc_port_mc4plus_qencP5 is hal_quad_enc4 = 3 ?? verify!
4703  .pos = eomc_pos_atjoint
4704  },
4705  .encoder2 =
4706  {
4707  .type = eomc_enc_qenc,
4708  .port = 3, // eomn_serv_mc_port_mc4plus_qencP5 is hal_quad_enc4 = 3 ?? verify!
4709  .pos = eomc_pos_atmotor
4710  }
4711  }
4712  }
4713  },
4714  .jomocoupling =
4715  {
4716  .joint2set =
4717  { // each joint is on a different set
4718  0, 1, 2, 3
4719  },
4720  .joint2motor =
4721  { // zero matrix: use matrix embedded in controller and seecetd by boardtype4mccontroller
4722  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
4723  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
4724  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
4725  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) }
4726  },
4727  .encoder2joint =
4728  { // identical matrix
4729  { EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
4730  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
4731  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
4732  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f) }
4733  }
4734  }
4735  }
4736 };*/
4737 
4738 
4739 
4740 
4741 // static eOmn_serv_configuration_t s_serv_config_mc_v3_0B1 = {};
4742 /*static const eOmn_serv_configuration_t s_serv_config_mc_v3_0B1 =
4743 { // eb13 or 0B1
4744  .type = eomn_serv_MC_mc4plus,
4745  .filler = {0},
4746  .data.mc.mc4plus_based =
4747  {
4748  .boardtype4mccontroller = emscontroller_board_HEAD_neckyaw_eyes,
4749  .filler = {0},
4750  .arrayofjomodescriptors =
4751  {
4752  .head =
4753  {
4754  .capacity = 4,
4755  .itemsize = sizeof(eOmn_serv_jomo_descriptor_t),
4756  .size = 4,
4757  .internalmem = 0
4758  },
4759  .data =
4760  {
4761  { // joint 0: neck-yaw
4762  .actuator.pwm =
4763  {
4764  .port = 0 // eomn_serv_mc_port_mc4plus_pwmP3 is hal_motor1=0 ?? verify!
4765  },
4766  .sensor =
4767  {
4768  .type = eomc_enc_aea,
4769  .port = 1, // eomn_serv_mc_port_mc4plus_spiP11 ?? verify!
4770  .pos = eomc_pos_atjoint
4771  },
4772  .encoder2 =
4773  {
4774  .type = eomc_enc_qenc,
4775  .port = 0, // eomn_serv_mc_port_mc4plus_qencP3 ?? verify!
4776  .pos = eomc_pos_atmotor
4777  }
4778  },
4779  { // joint 1: eyes-tilt
4780  .actuator.pwm =
4781  {
4782  .port = 1 // eomn_serv_mc_port_mc4plus_pwmP2 is hal_motor2=1 ?? verify!
4783  },
4784  .sensor =
4785  {
4786  .type = eomc_enc_aea,
4787  .port = 0, // eomn_serv_mc_port_mc4plus_spiP10 ?? verify!
4788  .pos = eomc_pos_atjoint
4789  },
4790  .encoder2 =
4791  {
4792  .type = eomc_enc_qenc,
4793  .port = 1, // eomn_serv_mc_port_mc4plus_qencP2 ?? verify!
4794  .pos = eomc_pos_atmotor
4795  }
4796  },
4797  { // joint 2: right-eye
4798  .actuator.pwm =
4799  {
4800  .port = 3 // eomn_serv_mc_port_mc4plus_pwmP5 is hal_motor4=3 ?? verify!
4801  },
4802  .sensor =
4803  {
4804  .type = eomc_enc_qenc,
4805  .port = 3, // eomn_serv_mc_port_mc4plus_qencP5 is hal_quad_enc4 = 3 ?? verify!
4806  .pos = eomc_pos_atjoint
4807  },
4808  .encoder2 =
4809  {
4810  .type = eomc_enc_qenc,
4811  .port = 3, // eomn_serv_mc_port_mc4plus_qencP5 is hal_quad_enc4 = 3 ?? verify!
4812  .pos = eomc_pos_atmotor
4813  }
4814  },
4815  { // joint 3: left-eye
4816  .actuator.pwm =
4817  {
4818  .port = 2 // eomn_serv_mc_port_mc4plus_pwmP4 is hal_motor3=2 ?? verify!
4819  },
4820  .sensor =
4821  {
4822  .type = eomc_enc_qenc,
4823  .port = 2, // eomn_serv_mc_port_mc4plus_qencP4 is hal_quad_enc3 = 2 ?? verify!
4824  .pos = eomc_pos_atjoint
4825  },
4826  .encoder2 =
4827  {
4828  .type = eomc_enc_qenc,
4829  .port = 2, // eomn_serv_mc_port_mc4plus_qencP4 is hal_quad_enc3 = 2 ?? verify!
4830  .pos = eomc_pos_atmotor
4831  }
4832  }
4833  }
4834  },
4835  .jomocoupling =
4836  {
4837  .joint2set =
4838  { //joint 2 and 3 are coupled
4839  eomc_jointSetNum_zero, eomc_jointSetNum_one, eomc_jointSetNum_two, eomc_jointSetNum_two
4840  },
4841 
4842  //inverted matrix: joint to motor
4843  // |m0| | 1 0 0 0 | |j0|
4844  // |m1| = | 0 1 0 0 | * |j1|
4845  // |m2| | 0 0 1 -1 | |j2|
4846  // |m3| | 0 0 1 1 | |j2|
4847 
4848 
4849  .joint2motor =
4850  { // zero matrix: use matrix embedded in controller and seecetd by boardtype4mccontroller
4851  { EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
4852  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
4853  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(-1.0f) },
4854  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f) }
4855  },
4856  .encoder2joint =
4857  { // identical matrix
4858  { EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
4859  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
4860  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
4861  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f) }
4862  }
4863  }
4864  }
4865 };
4866 */
4867 //static eOmn_serv_configuration_t s_serv_config_mc_v3_0B7;
4868 /*static const eOmn_serv_configuration_t s_serv_config_mc_v3_0B7 =
4869 { // eb14 or 0B7f
4870  .type = eomn_serv_MC_mc4plus,
4871  .filler = {0},
4872  .data.mc.mc4plus_based =
4873  {
4874  .boardtype4mccontroller = emscontroller_board_FACE_eyelids_jaw,
4875  .filler = {0},
4876  .arrayofjomodescriptors =
4877  {
4878  .head =
4879  {
4880  .capacity = 4,
4881  .itemsize = sizeof(eOmn_serv_jomo_descriptor_t),
4882  .size = 2,
4883  .internalmem = 0
4884  },
4885  .data =
4886  {
4887  { // joint 0: jaw
4888  .actuator.pwm =
4889  {
4890  ret = ret; .port = 0 // eomn_serv_mc_port_mc4plus_pwmP3 is hal_motor1=0 ?? verify!
4891  },
4892  .sensor =
4893  {
4894  .type = eomc_enc_aea,
4895  .port = 1, // eomn_serv_mc_port_mc4plus_spiP11 ?? verify!
4896  .pos = eomc_pos_atjoint
4897  },
4898  .encoder2 =
4899  {
4900  .type = eomn_serv_mc_sensor_none,
4901  .port = eomn_serv_mc_port_none,
4902  .pos = eomn_serv_mc_sensor_pos_none
4903  }
4904  },
4905  { // joint 1: eyelids
4906  .actuator.pwm =
4907  {
4908  .port = 1 // eomn_serv_mc_port_mc4plus_pwmP2 is hal_motor2=1 ?? verify!
4909  },
4910  .sensor =
4911  {
4912  .type = eomc_enc_aea,
4913  .port = 0, // eomn_serv_mc_port_mc4plus_spiP10 ?? verify!
4914  .pos = eomc_pos_atjoint
4915  },
4916  .encoder2 =
4917  {
4918  .type = eomc_enc_qenc,
4919  .port = 1, // eomn_serv_mc_port_mc4plus_qencP2 ?? verify!
4920  .pos = eomc_pos_atmotor
4921  }
4922  },
4923  { // joint 2
4924  .actuator.pwm =
4925  {
4926  .port = eomn_serv_mc_port_none
4927  },
4928  .sensor =
4929  {
4930  .type = eomn_serv_mc_sensor_none,
4931  .port = eomn_serv_mc_port_none,
4932  .pos = eomn_serv_mc_sensor_pos_none
4933  },
4934  .encoder2 =
4935  {
4936  .type = eomn_serv_mc_sensor_none,
4937  .port = eomn_serv_mc_port_none,
4938  .pos = eomn_serv_mc_sensor_pos_none
4939  }
4940  },
4941  { // joint 3
4942  .actuator.pwm =
4943  {
4944  .port = eomn_serv_mc_port_none
4945  },
4946  .sensor =
4947  {
4948  .type = eomn_serv_mc_sensor_none,
4949  .port = eomn_serv_mc_port_none,
4950  .pos = eomn_serv_mc_sensor_pos_none
4951  },
4952  .encoder2 =
4953  {
4954  .type = eomn_serv_mc_sensor_none,
4955  .port = eomn_serv_mc_port_none,
4956  .pos = eomn_serv_mc_sensor_pos_none
4957  }
4958  }
4959  }
4960  },
4961  .jomocoupling =
4962  {
4963  .joint2set =
4964  { // each joint is on a different set
4965  eomc_jointSetNum_zero, eomc_jointSetNum_one, eomc_jointSetNum_none, eomc_jointSetNum_none
4966  },
4967  .joint2motor =
4968  { // zero matrix: use matrix embedded in controller and seecetd by boardtype4mccontroller
4969  { EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
4970  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
4971  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
4972  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f) }
4973  },
4974  .encoder2joint =
4975  { // identical matrix
4976  { EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
4977  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
4978  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
4979  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f) }
4980  }
4981  }
4982  }
4983 };
4984 */
4985 
4986 /*eOmn_serv_configuration_t* arrayConf[4] =
4987 {
4988  &s_serv_config_mc_v3_0B9, // board ip.1, 0b9, face 4 lips
4989  &s_serv_config_mc_v3_0B7, // board ip.2, 0b7, face eyelids + jaw
4990  &s_serv_config_mc_v3_0B1, // board ip.3, 0b1, head neck yaw + 3 eyes
4991  &s_serv_config_mc_v3_0B0
4992 }*/
4993 
4994 static eOmn_serv_configuration_t s_serv_config_mc_v3_0B1 = {};
4995 
4996 bool ServiceParser::parseService2(Searchable &config, servConfigMC_t &mcconfig)
4997 {
4998  eOmc_arrayof_4jomodescriptors_t *ja = &s_serv_config_mc_v3_0B1.data.mc.mc4plus_based.arrayofjomodescriptors;
4999  eOmc_4jomo_coupling_t *jc = &s_serv_config_mc_v3_0B1.data.mc.mc4plus_based.jomocoupling;
5000 
5001 
5002  eOq17_14_t m1[][4] =
5003  { // zero matrix: use matrix embedded in controller and seecetd by boardtype4mccontroller
5004  { EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
5005  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
5006  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(-1.0f) },
5007  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f) }
5008  };
5009 
5010  eOq17_14_t m2[][4]=
5011  { // identical matrix
5012  { EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
5013  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
5014  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
5015  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f) }
5016  };
5017 
5018 
5019  //s_serv_config_mc_v3_0B1.type = eomn_serv_MC_mc4plus;
5020  //s_serv_config_mc_v3_0B1.filler = {0, 0, 0};
5021 
5022  //s_serv_config_mc_v3_0B1.data.mc.mc4plus_based.boardtype4mccontroller = 6; //emscontroller_board_HEAD_neckyaw_eyes;
5023  //s_serv_config_mc_v3_0B1.data.mc.mc4plus_based.filler = {0};
5024 
5025  ja->head.capacity = 4;
5026  ja->head.itemsize = sizeof(eOmc_jomo_descriptor_t);
5027  ja->head.size = 4;
5028  ja->head.internalmem = 0;
5029 
5030  ja->data[0].actuator.pwm.port = 0 ; // eomn_serv_mc_port_mc4plus_pwmP3 is hal_motor1=0 ?? verify!
5031  ja->data[0].encoder1.type = eomc_enc_aea;
5032  ja->data[0].encoder1.port = 1; // eomn_serv_mc_port_mc4plus_spiP11 ?? verify!
5033  ja->data[0].encoder1.pos = eomc_pos_atjoint;
5034 
5035  ja->data[0].encoder2.type = eomc_enc_qenc;
5036  ja->data[0].encoder2.port = 0; // eomn_serv_mc_port_mc4plus_qencP3 ?? verify!
5037  ja->data[0].encoder2.pos = eomc_pos_atmotor;
5038 
5039  ja->data[1].actuator.pwm.port = 1; // eomn_serv_mc_port_mc4plus_pwmP2 is hal_motor2=1 ?? verify!
5040  ja->data[1].encoder1.type = eomc_enc_aea;
5041  ja->data[1].encoder1.port = 0; // eomn_serv_mc_port_mc4plus_spiP10 ?? verify!
5042  ja->data[1].encoder1.pos = eomc_pos_atjoint;
5043  ja->data[1].encoder2.type = eomc_enc_qenc;
5044  ja->data[1].encoder2.port = 1; // eomn_serv_mc_port_mc4plus_qencP2 ?? verify!
5045  ja->data[1].encoder2.pos = eomc_pos_atmotor;
5046 
5047  ja->data[2].actuator.pwm.port = 3;
5048  ja->data[2].encoder1.type = eomc_enc_qenc;
5049  ja->data[2].encoder1.port = 3; // eomn_serv_mc_port_mc4plus_qencP5 is hal_quad_enc4 = 3 ?? verify!
5050  ja->data[2].encoder1.pos = eomc_pos_atjoint;
5051  ja->data[2].encoder2.type = eomc_enc_qenc,
5052  ja->data[2].encoder2.port = 3, // eomn_serv_mc_port_mc4plus_qencP5 is hal_quad_enc4 = 3 ?? verify!
5053  ja->data[2].encoder2.pos = eomc_pos_atmotor;
5054 
5055  ja->data[3].actuator.pwm.port = 2;
5056 
5057  ja->data[3].encoder1.type = eomc_enc_qenc;
5058  ja->data[3].encoder1.port = 2; // eomn_serv_mc_port_mc4plus_qencP4 is hal_quad_enc3 = 2 ?? verify!
5059  ja->data[3].encoder1.pos = eomc_pos_atjoint;
5060 
5061 
5062  ja->data[3].encoder2.type = eomc_enc_qenc;
5063  ja->data[3].encoder2.port = 2; // eomn_serv_mc_port_mc4plus_qencP4 is hal_quad_enc3 = 2 ?? verify!
5064  ja->data[3].encoder2.pos = eomc_pos_atmotor;
5065 
5066 
5067  jc->joint2set[0] = eomc_jointSetNum_zero;
5068  jc->joint2set[1] = eomc_jointSetNum_one;
5069  jc->joint2set[2] = eomc_jointSetNum_two;
5070  jc->joint2set[3] = eomc_jointSetNum_two;
5071 
5072 
5073 /*
5074  jc->joint2motor =
5075  { // zero matrix: use matrix embedded in controller and seecetd by boardtype4mccontroller
5076  { EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
5077  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
5078  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(-1.0f) },
5079  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f) }
5080  };
5081  jc->encoder2joint =
5082  { // identical matrix
5083  { EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
5084  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
5085  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f) },
5086  { EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(0.0f), EO_COMMON_FLOAT_TO_Q17_14(1.0f) }
5087  };
5088 
5089 
5090 
5091 */
5092 
5093  memcpy(&jc->joint2motor, &m1, sizeof(m1));
5094  memcpy(&jc->encoder2joint, &m2, sizeof(m2));
5095 
5096  yError() << "print first m ";
5097  for(int r=0; r<4; r++)
5098  {
5099  for(int c=0; c<4; c++)
5100  {
5101  yError() << "r=" <<r << "c=" << c << "val=" << m1[r][c];
5102  }
5103  }
5104 
5105  yError() << "print second m ";
5106  for(int r=0; r<4; r++)
5107  {
5108  for(int c=0; c<4; c++)
5109  {
5110  yError() << "r=" <<r << "c=" << c << "val=" << m2[r][c];
5111  }
5112  }
5113 
5114 
5115 
5116  if(mcconfig.id > 3)
5117  {
5118  yError() << " id scheda sbagliato " << mcconfig.id;
5119  return false;
5120  }
5121 
5122 
5123  memcpy(&mcconfig.ethservice, &s_serv_config_mc_v3_0B1, sizeof(eOmn_serv_configuration_t));
5124  return true;
5125 }
5126 
5127 #endif // #if defined(SERVICE_PARSER_USE_MC)
5128 
5129 // eof
bool parseService2(yarp::os::Searchable &config, servConfigMC_t &mcconfig)
bool parse_encoder_port(std::string const &fromstring, eObrd_ethtype_t const ethboard, eOmc_encoder_t type, uint8_t &toport, bool &formaterror)
bool parse_port_conn(std::string const &fromstring, eObrd_type_t const board, uint8_t &toport, bool &formaterror)
bool parse_actuator_port(std::string const &fromstring, eObrd_ethtype_t const ethboard, eOmc_actuator_t const type, eOmc_actuator_descriptor_t &todes, bool &formaterror)
bool parse_POS_CALIB_rotation(std::string const &fromstring, eoas_pos_ROT_t &rot, bool &formaterror)
bool convert(std::string const &fromstring, eOmc_actuator_t &toactuatortype, bool &formaterror)
bool parse_mais(std::string const &fromstring, eObrd_portmais_t &pmais, bool &formaterror)
bool parse_port_psc(std::string const &fromstring, uint8_t &toport, bool &formaterror)
bool parse_POS_CALIB_type(std::string const &fromstring, eoas_pos_TYPE_t &type, bool &formaterror)
bool parseService(yarp::os::Searchable &config, servConfigMais_t &maisconfig)
bool parse_port_pos(std::string const &fromstring, uint8_t &toport, bool &formaterror)
bool parse_POS_connector(std::string const &fromstring, const eObrd_type_t brd, eObrd_connector_t &conn, bool &formaterror)
bool parse_POS_port(std::string const &fromstring, eObrd_portpos_t &ppos, bool &formaterror)
servMC_encoder_t * getEncoderAtMotor(int index)
bool parse_connector(const std::string &fromstring, eObrd_connector_t &toconnector, bool &formaterror)
servMC_encoder_t * getEncoderAtJoint(int index)
bool parse_psc(std::string const &fromstring, eObrd_portpsc_t &ppsc, bool &formaterror)
bool parse_port_mais(std::string const &fromstring, uint8_t &toport, bool &formaterror)
uint8_t board
int n
Gain convert(const DiscreteGain dg)
Definition: strain.cpp:673
Q15 sub(Q15 &a, Q15 &b)
Definition: strain.cpp:1222
Copyright (C) 2008 RobotCub Consortium.
servAnalogPOScalibration_t calibration
eObrd_connector_t connector
eObrd_portpos_t port
servAnalogPOSspecific_t pos
std::string frameName
eObrd_type_t boardtype
std::string sensorName
eObrd_location_t location
eOas_sensor_t type
eObrd_cantype_t type
Definition: serviceParser.h:97
eObrd_protocolversion_t protocol
Definition: serviceParser.h:98
eObrd_firmwareversion_t firmware
Definition: serviceParser.h:99
std::string nameOfStrain
Definition: serviceParser.h:46
std::string frameName
Definition: serviceParser.h:49
eOmn_serv_parameter_t ethservice
Definition: serviceParser.h:43
eOmn_serv_parameter_t ethservice
Definition: serviceParser.h:62
std::vector< eOas_inertial3_descriptor_t > inertials
Definition: serviceParser.h:64
std::vector< std::string > id
Definition: serviceParser.h:65
std::vector< std::string > sensorName
Definition: serviceParser.h:66
eOmn_serv_parameter_t ethservice
Definition: serviceParser.h:90
eOmn_serv_parameter_t ethservice
Definition: serviceParser.h:26
std::string nameOfMais
Definition: serviceParser.h:28
eOmn_serv_parameter_t ethservice
Definition: serviceParser.h:81
eOmn_serv_parameter_t ethservice
Definition: serviceParser.h:73
servCanBoard_t canboard
eOmn_serv_parameter_t ethservice
Definition: serviceParser.h:34
std::string nameOfStrain
Definition: serviceParser.h:37
eOmc_adv_actuator_descriptor_t advdescr
eOmc_actuator_descriptor_t desc
eOmc_actuator_t type
eOmc_encoder_descriptor_t desc