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