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
58 as_service.properties.canboards.resize(0);
59 as_service.properties.sensors.resize(0);
60
61 as_service.settings.acquisitionrate = 0;
62 as_service.settings.enabledsensors.resize(0);
63}
64
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
794 as_service.properties.canboards.resize(0);
795
796 formaterror = false;
797 for(int i=0; i<numboards; i++)
798 {
799 servCanBoard_t item;
800
801 convert(b_PROPERTIES_CANBOARDS_type.get(i+1).asString(), item.type, formaterror);
802 convert(b_PROPERTIES_CANBOARDS_PROTOCOL_major.get(i+1).asInt32(), item.protocol.major, formaterror);
803 convert(b_PROPERTIES_CANBOARDS_PROTOCOL_minor.get(i+1).asInt32(), item.protocol.minor, formaterror);
804
805 convert(b_PROPERTIES_CANBOARDS_FIRMWARE_major.get(i+1).asInt32(), item.firmware.major, formaterror);
806 convert(b_PROPERTIES_CANBOARDS_FIRMWARE_minor.get(i+1).asInt32(), item.firmware.minor, formaterror);
807 convert(b_PROPERTIES_CANBOARDS_FIRMWARE_build.get(i+1).asInt32(), item.firmware.build, formaterror);
808
809 as_service.properties.canboards.push_back(item);
810 }
811
812 // in here we could decide to return false if any previous conversion function has returned error
813 // bool fromStringToBoolean(string str, bool &anyerror); // inside: if error then .... be sure to set error = true. dont set it to false.
814
815 if(true == formaterror)
816 {
817 yError() << "ServiceParser::check_analog() has detected an illegal format for some of the params of PROPERTIES.CANBOARDS some param has inconsistent length";
818 return false;
819 }
820 }
821
822 Bottle b_PROPERTIES_SENSORS = Bottle(b_PROPERTIES.findGroup("SENSORS"));
823 if(b_PROPERTIES_SENSORS.isNull())
824 {
825 yError() << "ServiceParser::check_analog() cannot find PROPERTIES.SENSORS";
826 return false;
827 }
828 else
829 {
830
831 Bottle b_PROPERTIES_SENSORS_id = Bottle(b_PROPERTIES_SENSORS.findGroup("id"));
832 if(b_PROPERTIES_SENSORS_id.isNull())
833 {
834 yError() << "ServiceParser::check_analog() cannot find PROPERTIES.SENSORS.id";
835 return false;
836 }
837 Bottle b_PROPERTIES_SENSORS_type = Bottle(b_PROPERTIES_SENSORS.findGroup("type"));
838 if(b_PROPERTIES_SENSORS_type.isNull())
839 {
840 yError() << "ServiceParser::check_analog() cannot find PROPERTIES.SENSORS.type";
841 return false;
842 }
843 Bottle b_PROPERTIES_SENSORS_location = Bottle(b_PROPERTIES_SENSORS.findGroup("location"));
844 if(b_PROPERTIES_SENSORS_location.isNull())
845 {
846 yError() << "ServiceParser::check_analog() cannot find PROPERTIES.SENSORS.location";
847 return false;
848 }
849 Bottle b_PROPERTIES_SENSORS_frameName = Bottle(b_PROPERTIES_SENSORS.findGroup("framename"));
850 if(b_PROPERTIES_SENSORS_frameName.isNull() && eoas_string2sensor(b_PROPERTIES_SENSORS_type.get(1).asString().c_str())==eoas_strain)
851 {
852 yWarning() << "ServiceParser::check_analog() cannot find PROPERTIES.SENSORS.framename";
853 }
854 Bottle b_PROPERTIES_SENSORS_sensorName = Bottle(b_PROPERTIES_SENSORS.findGroup("sensorName"));
855 if(b_PROPERTIES_SENSORS_sensorName.isNull())
856 {
857 yWarning() << "ServiceParser::check_analog() cannot find PROPERTIES.SENSORS.sensorName";
858 }
859 Bottle b_PROPERTIES_SENSORS_boardType;
860 if((eomn_serv_AS_inertials3 == type) || (eomn_serv_AS_pos == type))
861 {
862
863 b_PROPERTIES_SENSORS_boardType = Bottle(b_PROPERTIES_SENSORS.findGroup("boardType"));
864 if(b_PROPERTIES_SENSORS_boardType.isNull())
865 {
866 yError() << "ServiceParser::check_analog() cannot find PROPERTIES.SENSORS.boardType";
867 return false;
868 }
869 }
870 else
871 {
872 b_PROPERTIES_SENSORS_boardType.clear();
873 }
874
875 Bottle b_PROPERTIES_SENSORS_pos_port;
876 Bottle b_PROPERTIES_SENSORS_pos_connector;
877 Bottle b_PROPERTIES_SENSORS_pos_CALIBRATION;
878 Bottle b_PROPERTIES_SENSORS_pos_CALIBRATION_type;
879 Bottle b_PROPERTIES_SENSORS_pos_CALIBRATION_rotation;
880 Bottle b_PROPERTIES_SENSORS_pos_CALIBRATION_offset;
881 Bottle b_PROPERTIES_SENSORS_pos_CALIBRATION_invertDirection;
882
883 // add params proper only of POS
884 if(type == eomn_serv_AS_pos)
885 {
886 b_PROPERTIES_SENSORS_pos_port = Bottle(b_PROPERTIES_SENSORS.findGroup("port"));
887 if(b_PROPERTIES_SENSORS_pos_port.isNull())
888 {
889 yError() << "ServiceParser::check_analog() cannot find PROPERTIES.SENSORS.port";
890 return false;
891 }
892
893 b_PROPERTIES_SENSORS_pos_connector = Bottle(b_PROPERTIES_SENSORS.findGroup("connector"));
894 if(b_PROPERTIES_SENSORS_pos_connector.isNull())
895 {
896 yError() << "ServiceParser::check_analog() cannot find PROPERTIES.SENSORS.connector";
897 return false;
898 }
899
900 b_PROPERTIES_SENSORS_pos_CALIBRATION = Bottle(b_PROPERTIES_SENSORS.findGroup("CALIBRATION"));
901 if(b_PROPERTIES_SENSORS_pos_CALIBRATION.isNull())
902 {
903 yWarning() << "ServiceParser::check_analog() cannot find PROPERTIES.SENSORS.CALIBRATION. Using neutral values (ROT:zero, 0.0, false)";
904 }
905 else
906 {
907 b_PROPERTIES_SENSORS_pos_CALIBRATION_type = Bottle(b_PROPERTIES_SENSORS_pos_CALIBRATION.findGroup("type"));
908 if(b_PROPERTIES_SENSORS_pos_CALIBRATION_type.isNull())
909 {
910 yWarning() << "ServiceParser::check_analog() cannot find PROPERTIES.SENSORS.CALIBRATION.type. Using value TYPE::decideg";
911 }
912
913 b_PROPERTIES_SENSORS_pos_CALIBRATION_rotation = Bottle(b_PROPERTIES_SENSORS_pos_CALIBRATION.findGroup("rotation"));
914 if(b_PROPERTIES_SENSORS_pos_CALIBRATION_rotation.isNull())
915 {
916 yWarning() << "ServiceParser::check_analog() cannot find PROPERTIES.SENSORS.CALIBRATION.rotation. Using value ROT::zero";
917 }
918 b_PROPERTIES_SENSORS_pos_CALIBRATION_offset = Bottle(b_PROPERTIES_SENSORS_pos_CALIBRATION.findGroup("offset"));
919 if(b_PROPERTIES_SENSORS_pos_CALIBRATION_offset.isNull())
920 {
921 yWarning() << "ServiceParser::check_analog() cannot find PROPERTIES.SENSORS.CALIBRATION.offset. Using value 0.0";
922 }
923 b_PROPERTIES_SENSORS_pos_CALIBRATION_invertDirection = Bottle(b_PROPERTIES_SENSORS_pos_CALIBRATION.findGroup("invertDirection"));
924 if(b_PROPERTIES_SENSORS_pos_CALIBRATION_invertDirection.isNull())
925 {
926 yWarning() << "ServiceParser::check_analog() cannot find PROPERTIES.SENSORS.CALIBRATION.invertDirection. Using value false";
927 }
928 }
929
930 }
931 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
1074 as_service.settings.enabledsensors.resize(0);
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 {
1091 servAnalogSensor_t item = as_service.properties.sensors.at(n);
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
1294 sk_service.properties.canboard.clear();
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);
1556 servAnalogSensor_t themais_sensor = as_service.settings.enabledsensors.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
1566 maisconfig.acquisitionrate = as_service.settings.acquisitionrate;
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
1610 strainconfig.acquisitionrate = as_service.settings.acquisitionrate;
1611 strainconfig.useCalibration = as_strain_settings.useCalibration;
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
1655 ftconfig.acquisitionrate = as_service.settings.acquisitionrate;
1656 ftconfig.useCalibration = as_strain_settings.useCalibration;
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
1728 imuconfig.acquisitionrate = as_service.settings.acquisitionrate;
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 {
1745 servAnalogSensor_t sensor = as_service.settings.enabledsensors.at(i);
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
1835 skinconfig.canboard.type = sk_service.properties.canboard.type;
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
1877 pscconfig.acquisitionrate = as_service.settings.acquisitionrate;
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 {
1891 servAnalogSensor_t sensor = as_service.settings.enabledsensors.at(i);
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 {
1967 board = &as_service.properties.canboards[0];
1968 }
1969 }
1970
1971 if(nullptr == board)
1972 {
1973 yError() << "ServiceParser::parseService(POS): cannot find the boardtype " << eoboards_type2string2(boardtype, eobool_true) << " of SENSORS::boardType inside CANBOARDS::type";
1974 return false;
1975 }
1976
1977 // reset configuration service
1978 memset(&posconfig.ethservice.configuration, 0, sizeof(posconfig.ethservice.configuration));
1979
1980 // set type of service
1981 posconfig.ethservice.configuration.type = eomn_serv_AS_pos;
1982
1983 //get acquisition rate
1984 posconfig.acquisitionrate = as_service.settings.acquisitionrate;
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 {
2012 servAnalogSensor_t snsr = as_service.settings.enabledsensors[s];
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 // complete format is SERVICE{ type, PROPERTIES{ ETHBOARD, CANBOARDS, MC4, MAIS, CONTROLLER, JOINTMAPPING, JOINTSETS } }
2775 // so far, there is no SETTINGS{}.
2776 // then, some groups are not present for some kind of SERVICE.type
2777 // mc4: ETHBOARD, CANBOARDS, MC4, MAIS
2778 // foc: ETHBOARD, CANBOARDS, CONTROLLER, JOINTMAPPING, JOINTSETS
2779 // mc4plus: ETHBOARD, CONTROLLER, JOINTMAPPING, JOINTSETS
2780 // mc4plusmais: ETHBOARD, CANBOARDS, MAIS, CONTROLLER, JOINTMAPPING, JOINTSETS
2781
2782
2783
2784 const bool itisOKifwedontfindtheXMLgroup = true;
2785
2786 Bottle b_SERVICE(config.findGroup("SERVICE"));
2787 if(b_SERVICE.isNull())
2788 {
2789 if(false == itisOKifwedontfindtheXMLgroup)
2790 {
2791 yError() << "ServiceParser::check_motion() cannot find SERVICE group";
2792 return false;
2793 }
2794 else
2795 {
2796 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";
2797 mc_service.type = eomn_serv_MC_generic;
2798 return true;
2799 }
2800 }
2801
2802 if(!b_SERVICE.findGroup("PROPERTIES").findGroup("POS").isNull())
2803 {
2804 yError() << "ServiceParser::check_motion() does not accept PROPERTIES.POS; configure POS through the standalone eomn_serv_AS_pos service";
2805 return false;
2806 }
2807
2808 // check whether we have the proper type
2809
2810 if(false == b_SERVICE.check("type"))
2811 {
2812 if(false == itisOKifwedontfindtheXMLgroup)
2813 {
2814 yError() << "ServiceParser::check_motion() cannot find SERVICE.type";
2815 return false;
2816 }
2817 else
2818 {
2819 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";
2820 mc_service.type = eomn_serv_MC_generic;
2821 return true;
2822 }
2823 }
2824
2825 Bottle b_type(b_SERVICE.find("type").asString());
2826 if(false == convert(b_type.toString(), mc_service.type, formaterror))
2827 {
2828 yError() << "ServiceParser::check_motion() has found unknown SERVICE.type = " << b_type.toString();
2829 return false;
2830 }
2831
2832 if(eomn_serv_MC_generic == mc_service.type)
2833 {
2834 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";
2835 return true;
2836 }
2837
2838 // check whether we have the proper groups at first level.
2839
2840 Bottle b_PROPERTIES = Bottle(b_SERVICE.findGroup("PROPERTIES"));
2841 if(b_PROPERTIES.isNull())
2842 {
2843 yError() << "ServiceParser::check_motion() cannot find PROPERTIES";
2844 return false;
2845 }
2846
2847
2848 // now, inside PROPERTIES there are groups which depend on mc_service.type.
2849 // i prefer to check them all in here rather to go on and check them one after another.
2850 Bottle b_PROPERTIES_ETHBOARD = Bottle(b_PROPERTIES.findGroup("ETHBOARD"));
2851 bool has_PROPERTIES_ETHBOARD = !b_PROPERTIES_ETHBOARD.isNull();
2852
2853 Bottle b_PROPERTIES_MAIS = Bottle(b_PROPERTIES.findGroup("MAIS"));
2854 bool has_PROPERTIES_MAIS = !b_PROPERTIES_MAIS.isNull();
2855
2856 Bottle b_PROPERTIES_PSC = Bottle(b_PROPERTIES.findGroup("PSC"));
2857 bool has_PROPERTIES_PSC = !b_PROPERTIES_PSC.isNull();
2858
2859 Bottle b_PROPERTIES_MC4 = Bottle(b_PROPERTIES.findGroup("MC4"));
2860 bool has_PROPERTIES_MC4 = !b_PROPERTIES_MC4.isNull();
2861
2862 Bottle b_PROPERTIES_CANBOARDS = Bottle(b_PROPERTIES.findGroup("CANBOARDS"));
2863 bool has_PROPERTIES_CANBOARDS = !b_PROPERTIES_CANBOARDS.isNull();
2864
2865 Bottle b_PROPERTIES_JOINTMAPPING = Bottle(b_PROPERTIES.findGroup("JOINTMAPPING"));
2866 bool has_PROPERTIES_JOINTMAPPING = !b_PROPERTIES_JOINTMAPPING.isNull();
2867
2868 Bottle b_PROPERTIES_DIAGNOSTICS = Bottle(b_PROPERTIES.findGroup("DIAGNOSTICS"));
2869 bool has_PROPERTIES_DIAGNOSTICS = !b_PROPERTIES_DIAGNOSTICS.isNull();
2870
2871
2872
2873
2874
2875 bool itisoksofar = false;
2876 switch(mc_service.type)
2877 {
2878 case eomn_serv_MC_foc:
2879 {
2880 // must have: ETHBOARD, CANBOARDS, JOINTMAPPING
2881 itisoksofar = true;
2882
2883 if(false == has_PROPERTIES_ETHBOARD)
2884 {
2885 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.ETHBOARD for type" << eomn_servicetype2string(mc_service.type);
2886 itisoksofar = false;
2887 }
2888
2889 if(false == has_PROPERTIES_CANBOARDS)
2890 {
2891 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.CANBOARDS for type" << eomn_servicetype2string(mc_service.type);
2892 itisoksofar = false;
2893 }
2894
2895 if(false == has_PROPERTIES_JOINTMAPPING)
2896 {
2897 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING for type" << eomn_servicetype2string(mc_service.type);
2898 itisoksofar = false;
2899 }
2900
2901 } break;
2902
2903
2904 case eomn_serv_MC_mc4plus:
2905 {
2906 // must have: ETHBOARD, JOINTMAPPING
2907
2908 itisoksofar = true;
2909
2910 if(false == has_PROPERTIES_ETHBOARD)
2911 {
2912 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.ETHBOARD for type" << eomn_servicetype2string(mc_service.type);
2913 itisoksofar = false;
2914 }
2915
2916 if(false == has_PROPERTIES_JOINTMAPPING)
2917 {
2918 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING for type" << eomn_servicetype2string(mc_service.type);
2919 itisoksofar = false;
2920 }
2921
2922 } break;
2923
2924
2925 case eomn_serv_MC_mc4plusmais:
2926 {
2927 // must have: ETHBOARD, CANBOARDS, MAIS, JOINTMAPPING
2928
2929 itisoksofar = true;
2930
2931 if(false == has_PROPERTIES_ETHBOARD)
2932 {
2933 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.ETHBOARD for type" << eomn_servicetype2string(mc_service.type);
2934 itisoksofar = false;
2935 }
2936
2937 if(false == has_PROPERTIES_CANBOARDS)
2938 {
2939 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.CANBOARDS for type" << eomn_servicetype2string(mc_service.type);
2940 itisoksofar = false;
2941 }
2942
2943 if(false == has_PROPERTIES_MAIS)
2944 {
2945 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.MAIS for type" << eomn_servicetype2string(mc_service.type);
2946 itisoksofar = false;
2947 }
2948
2949 if(false == has_PROPERTIES_JOINTMAPPING)
2950 {
2951 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING for type" << eomn_servicetype2string(mc_service.type);
2952 itisoksofar = false;
2953 }
2954
2955
2956 } break;
2957
2958 case eomn_serv_MC_mc4:
2959 {
2960 // must have: ETHBOARD, CANBOARDS, MC4, MAIS
2961
2962 itisoksofar = true;
2963
2964 if(false == has_PROPERTIES_ETHBOARD)
2965 {
2966 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.ETHBOARD for type" << eomn_servicetype2string(mc_service.type);
2967 itisoksofar = false;
2968 }
2969
2970 if(false == has_PROPERTIES_CANBOARDS)
2971 {
2972 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.CANBOARDS for type" << eomn_servicetype2string(mc_service.type);
2973 itisoksofar = false;
2974 }
2975
2976 if(false == has_PROPERTIES_MC4)
2977 {
2978 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.MC4 for type" << eomn_servicetype2string(mc_service.type);
2979 itisoksofar = false;
2980 }
2981
2982 if(false == has_PROPERTIES_MAIS)
2983 {
2984 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.MAIS for type" << eomn_servicetype2string(mc_service.type);
2985 itisoksofar = false;
2986 }
2987
2988 } break;
2989
2990 case eomn_serv_MC_mc2pluspsc:
2991 {
2992 // must have: ETHBOARD, CANBOARDS, PSC, JOINTMAPPING
2993
2994 itisoksofar = true;
2995
2996 if(false == has_PROPERTIES_ETHBOARD)
2997 {
2998 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.ETHBOARD for type" << eomn_servicetype2string(mc_service.type);
2999 itisoksofar = false;
3000 }
3001
3002 if(false == has_PROPERTIES_CANBOARDS)
3003 {
3004 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.CANBOARDS for type" << eomn_servicetype2string(mc_service.type);
3005 itisoksofar = false;
3006 }
3007
3008 if(false == has_PROPERTIES_PSC)
3009 {
3010 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.PSC for type" << eomn_servicetype2string(mc_service.type);
3011 itisoksofar = false;
3012 }
3013
3014 if(false == has_PROPERTIES_JOINTMAPPING)
3015 {
3016 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING for type" << eomn_servicetype2string(mc_service.type);
3017 itisoksofar = false;
3018 }
3019
3020
3021 } break;
3022
3023
3024 case eomn_serv_MC_mc4plusfaps:
3025 {
3026 // ETHBOARD, CANBOARDS and JOINTMAPPING are required. The Ethernet resource
3027 // supplies POS configuration from the activated standalone service.
3028
3029 itisoksofar = true;
3030
3031 if(false == has_PROPERTIES_ETHBOARD)
3032 {
3033 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.ETHBOARD for type" << eomn_servicetype2string(mc_service.type);
3034 itisoksofar = false;
3035 }
3036
3037 if(false == has_PROPERTIES_CANBOARDS)
3038 {
3039 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.CANBOARDS for type" << eomn_servicetype2string(mc_service.type);
3040 itisoksofar = false;
3041 }
3042
3043 if(false == has_PROPERTIES_JOINTMAPPING)
3044 {
3045 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING for type" << eomn_servicetype2string(mc_service.type);
3046 itisoksofar = false;
3047 }
3048
3049
3050 } break;
3051
3052 case eomn_serv_MC_advfoc:
3053 {
3054 // must have: ETHBOARD, CANBOARDS, JOINTMAPPING
3055
3056 itisoksofar = true;
3057
3058 if(false == has_PROPERTIES_ETHBOARD)
3059 {
3060 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.ETHBOARD for type" << eomn_servicetype2string(mc_service.type);
3061 itisoksofar = false;
3062 }
3063
3064 if(false == has_PROPERTIES_CANBOARDS)
3065 {
3066 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.CANBOARDS for type" << eomn_servicetype2string(mc_service.type);
3067 itisoksofar = false;
3068 }
3069
3070 if(false == has_PROPERTIES_JOINTMAPPING)
3071 {
3072 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING for type" << eomn_servicetype2string(mc_service.type);
3073 itisoksofar = false;
3074 }
3075
3076 } break;
3077
3078 default:
3079 {
3080 yError() << "ServiceParser::check_motion() has found an unknown type" << eomn_servicetype2string(mc_service.type);
3081 itisoksofar = false;
3082 } break;
3083 }
3084
3085 if(false == itisoksofar)
3086 {
3087 yError() << "ServiceParser::check_motion() detected missing groups in PROPERTIES";
3088 return false;
3089 }
3090
3091 // now i parse the groups
3092
3093 if(true == has_PROPERTIES_ETHBOARD)
3094 {
3095 // i get type
3096
3097 Bottle b_PROPERTIES_ETHBOARD_type = b_PROPERTIES_ETHBOARD.findGroup("type");
3098 if(b_PROPERTIES_ETHBOARD_type.isNull())
3099 {
3100 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.ETHBOARD.type";
3101 return false;
3102 }
3103
3104 // we must have only one board
3105 int numofethboards = b_PROPERTIES_ETHBOARD_type.size() - 1;
3106 if(1 != numofethboards)
3107 {
3108 yError() << "ServiceParser::check_motion() PROPERTIES.ETHBOARD.type must have one board only";
3109 return false;
3110 }
3111 if(false == convert(b_PROPERTIES_ETHBOARD_type.get(1).asString(), mc_service.properties.ethboardtype, formaterror))
3112 {
3113 yError() << "ServiceParser::check_motion() has found unknown SERVICE.PROPERTIES.ETHBOARD.type = " << b_PROPERTIES_ETHBOARD_type.get(1).asString();
3114 return false;
3115 }
3116
3117 } // has_PROPERTIES_ETHBOARD
3118
3119
3120 if(true == has_PROPERTIES_CANBOARDS)
3121 {
3122 // 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
3123
3124 Bottle b_PROPERTIES_CANBOARDS_type = b_PROPERTIES_CANBOARDS.findGroup("type");
3125 if(b_PROPERTIES_CANBOARDS_type.isNull())
3126 {
3127 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.CANBOARDS.type";
3128 return false;
3129 }
3130 Bottle b_PROPERTIES_CANBOARDS_PROTOCOL = Bottle(b_PROPERTIES_CANBOARDS.findGroup("PROTOCOL"));
3131 if(b_PROPERTIES_CANBOARDS_PROTOCOL.isNull())
3132 {
3133 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.CANBOARDS.PROTOCOL";
3134 return false;
3135 }
3136 Bottle b_PROPERTIES_CANBOARDS_PROTOCOL_major = Bottle(b_PROPERTIES_CANBOARDS_PROTOCOL.findGroup("major"));
3137 if(b_PROPERTIES_CANBOARDS_PROTOCOL_major.isNull())
3138 {
3139 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.CANBOARDS.PROTOCOL.major";
3140 return false;
3141 }
3142 Bottle b_PROPERTIES_CANBOARDS_PROTOCOL_minor = Bottle(b_PROPERTIES_CANBOARDS_PROTOCOL.findGroup("minor"));
3143 if(b_PROPERTIES_CANBOARDS_PROTOCOL_minor.isNull())
3144 {
3145 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.CANBOARDS.PROTOCOL.minor";
3146 return false;
3147 }
3148 Bottle b_PROPERTIES_CANBOARDS_FIRMWARE = Bottle(b_PROPERTIES_CANBOARDS.findGroup("FIRMWARE"));
3149 if(b_PROPERTIES_CANBOARDS_FIRMWARE.isNull())
3150 {
3151 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.CANBOARDS.FIRMWARE";
3152 return false;
3153 }
3154 Bottle b_PROPERTIES_CANBOARDS_FIRMWARE_major = Bottle(b_PROPERTIES_CANBOARDS_FIRMWARE.findGroup("major"));
3155 if(b_PROPERTIES_CANBOARDS_FIRMWARE_major.isNull())
3156 {
3157 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.CANBOARDS.FIRMWARE.major";
3158 return false;
3159 }
3160 Bottle b_PROPERTIES_CANBOARDS_FIRMWARE_minor = Bottle(b_PROPERTIES_CANBOARDS_FIRMWARE.findGroup("minor"));
3161 if(b_PROPERTIES_CANBOARDS_FIRMWARE_minor.isNull())
3162 {
3163 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.CANBOARDS.FIRMWARE.minor";
3164 return false;
3165 }
3166 Bottle b_PROPERTIES_CANBOARDS_FIRMWARE_build = Bottle(b_PROPERTIES_CANBOARDS_FIRMWARE.findGroup("build"));
3167 if(b_PROPERTIES_CANBOARDS_FIRMWARE_build.isNull())
3168 {
3169 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.CANBOARDS.FIRMWARE.build";
3170 return false;
3171 }
3172
3173 size_t tmp = b_PROPERTIES_CANBOARDS_type.size();
3174 size_t numboards = (0 == tmp) ? 0 : (tmp - 1); // first position of bottle contains the tag "type"
3175
3176 // check if all other fields have the same size.
3177 if( (tmp != b_PROPERTIES_CANBOARDS_PROTOCOL_major.size()) ||
3178 (tmp != b_PROPERTIES_CANBOARDS_PROTOCOL_minor.size()) ||
3179 (tmp != b_PROPERTIES_CANBOARDS_FIRMWARE_major.size()) ||
3180 (tmp != b_PROPERTIES_CANBOARDS_FIRMWARE_minor.size()) ||
3181 (tmp != b_PROPERTIES_CANBOARDS_FIRMWARE_build.size())
3182 )
3183 {
3184 yError() << "ServiceParser::check_motion() in PROPERTIES.CANBOARDS some params have inconsistent lengths";
3185 return false;
3186 }
3187
3188
3189 mc_service.properties.canboards.resize(0);
3190
3191 formaterror = false;
3192 for(size_t i=0; i<numboards; i++)
3193 {
3194 servCanBoard_t item;
3195
3196 convert(b_PROPERTIES_CANBOARDS_type.get(i+1).asString(), item.type, formaterror);
3197 convert(b_PROPERTIES_CANBOARDS_PROTOCOL_major.get(i+1).asInt32(), item.protocol.major, formaterror);
3198 convert(b_PROPERTIES_CANBOARDS_PROTOCOL_minor.get(i+1).asInt32(), item.protocol.minor, formaterror);
3199
3200 convert(b_PROPERTIES_CANBOARDS_FIRMWARE_major.get(i+1).asInt32(), item.firmware.major, formaterror);
3201 convert(b_PROPERTIES_CANBOARDS_FIRMWARE_minor.get(i+1).asInt32(), item.firmware.minor, formaterror);
3202 convert(b_PROPERTIES_CANBOARDS_FIRMWARE_build.get(i+1).asInt32(), item.firmware.build, formaterror);
3203
3204 mc_service.properties.canboards.push_back(item);
3205 }
3206
3207 // in here we could decide to return false if any previous conversion function has returned error
3208 // bool fromStringToBoolean(string str, bool &anyerror); // inside: if error then .... be sure to set error = true. dont set it to false.
3209
3210 if(true == formaterror)
3211 {
3212 yError() << "ServiceParser::check_motion() has detected an illegal format for some of the params of PROPERTIES.CANBOARDS some param has inconsistent length";
3213 return false;
3214 }
3215
3216 } // has_PROPERTIES_CANBOARDS
3217
3218
3219 if(true == has_PROPERTIES_MAIS && mc_service.type == eomn_serv_MC_mc4plusmais)
3220 {
3221 // i get .location and nothing else
3222
3223 Bottle b_PROPERTIES_MAIS_location = b_PROPERTIES_MAIS.findGroup("location");
3224 if(b_PROPERTIES_MAIS_location.isNull())
3225 {
3226 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.MAIS.location";
3227 return false;
3228 }
3229
3230 int tmp = b_PROPERTIES_MAIS_location.size();
3231 int numboards = tmp - 1; // first position of bottle contains the tag "location"
3232
3233 // check if numboards is 1.
3234 if(1 != numboards)
3235 {
3236 yError() << "ServiceParser::check_motion() in PROPERTIES.MAIS.location must contain one item only and it has:" << numboards;
3237 return false;
3238 }
3239
3240 formaterror = false;
3241 eObrd_location_t loc;
3242 if(false == convert(b_PROPERTIES_MAIS_location.get(1).asString(), loc, formaterror))
3243 {
3244 yError() << "ServiceParser::check_motion() has detected an illegal format for SERVICE.PROPERTIES.MAIS.location";
3245 return false;
3246 }
3247
3248 if(eobrd_place_can == loc.any.place)
3249 {
3250 mc_service.properties.maislocation.port = loc.can.port;
3251 mc_service.properties.maislocation.addr = loc.can.addr;
3252 mc_service.properties.maislocation.insideindex = eobrd_caninsideindex_none;
3253 }
3254 else if(eobrd_place_extcan == loc.any.place)
3255 {
3256 mc_service.properties.maislocation.port = loc.extcan.port;
3257 mc_service.properties.maislocation.addr = loc.extcan.addr;
3258 mc_service.properties.maislocation.insideindex = eobrd_caninsideindex_none;
3259 }
3260 else
3261 {
3262 yError() << "ServiceParser::check_motion() has detected an illegal format for SERVICE.PROPERTIES.MAIS.location. it must be either can or extcan";
3263 return false;
3264 }
3265
3266 } // has_PROPERTIES_MAIS
3267
3268
3269 if(true == has_PROPERTIES_MC4)
3270 {
3271 // i get:
3272 // SHIFTS.velocity/estimJointVelocity/estimJointAcceleration/estimMotorVelocity/estimMotorAcceleration,
3273 // BROADCASTPOLICY, JOINT2BOARD)
3274
3275 Bottle b_PROPERTIES_MC4_SHIFTS = Bottle(b_PROPERTIES_MC4.findGroup("SHIFTS"));
3276 if(b_PROPERTIES_MC4_SHIFTS.isNull())
3277 {
3278 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.MC4.SHIFTS";
3279 return false;
3280 }
3281
3282 Bottle b_PROPERTIES_MC4_SHIFTS_velocity = Bottle(b_PROPERTIES_MC4_SHIFTS.findGroup("velocity"));
3283 if(b_PROPERTIES_MC4_SHIFTS_velocity.isNull())
3284 {
3285 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.MC4.SHIFTS.velocity";
3286 return false;
3287 }
3288 Bottle b_PROPERTIES_MC4_SHIFTS_estimJointVelocity = Bottle(b_PROPERTIES_MC4_SHIFTS.findGroup("estimJointVelocity"));
3289 if(b_PROPERTIES_MC4_SHIFTS_estimJointVelocity.isNull())
3290 {
3291 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.MC4.SHIFTS.estimJointVelocity";
3292 return false;
3293 }
3294 Bottle b_PROPERTIES_MC4_SHIFTS_estimJointAcceleration = Bottle(b_PROPERTIES_MC4_SHIFTS.findGroup("estimJointAcceleration"));
3295 if(b_PROPERTIES_MC4_SHIFTS_estimJointAcceleration.isNull())
3296 {
3297 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.MC4.SHIFTS.estimJointAcceleration";
3298 return false;
3299 }
3300 Bottle b_PROPERTIES_MC4_SHIFTS_estimMotorVelocity = Bottle(b_PROPERTIES_MC4_SHIFTS.findGroup("estimMotorVelocity"));
3301 if(b_PROPERTIES_MC4_SHIFTS_estimMotorVelocity.isNull())
3302 {
3303 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.MC4.SHIFTS.estimMotorVelocity";
3304 return false;
3305 }
3306 Bottle b_PROPERTIES_MC4_SHIFTS_estimMotorAcceleration = Bottle(b_PROPERTIES_MC4_SHIFTS.findGroup("estimMotorAcceleration"));
3307 if(b_PROPERTIES_MC4_SHIFTS_estimMotorAcceleration.isNull())
3308 {
3309 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.MC4.SHIFTS.estimMotorAcceleration";
3310 return false;
3311 }
3312
3313 Bottle b_PROPERTIES_MC4_BROADCASTPOLICY = Bottle(b_PROPERTIES_MC4.findGroup("BROADCASTPOLICY"));
3314 if(b_PROPERTIES_MC4_BROADCASTPOLICY.isNull())
3315 {
3316 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.MC4.BROADCASTPOLICY";
3317 return false;
3318 }
3319
3320 Bottle b_PROPERTIES_MC4_BROADCASTPOLICY_enable = Bottle(b_PROPERTIES_MC4_BROADCASTPOLICY.findGroup("enable"));
3321 if(b_PROPERTIES_MC4_BROADCASTPOLICY_enable.isNull())
3322 {
3323 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.MC4.BROADCASTPOLICY.enable";
3324 return false;
3325 }
3326
3327/* Bottle b_PROPERTIES_MC4_JOINT2BOARD = Bottle(b_PROPERTIES_MC4.findGroup("JOINT2BOARD"));
3328 if(b_PROPERTIES_MC4_JOINT2BOARD.isNull())
3329 {
3330 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.MC4.JOINT2BOARD";
3331 return false;
3332 }
3333
3334 Bottle b_PROPERTIES_MC4_JOINT2BOARD_location = Bottle(b_PROPERTIES_MC4_JOINT2BOARD.findGroup("location"));
3335 if(b_PROPERTIES_MC4_JOINT2BOARD_location.isNull())
3336 {
3337 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.MC4.JOINT2BOARD.location";
3338 return false;
3339 }
3340*/
3341 // 1. get values for SHIFTS
3342
3343 uint8_t value = 0;
3344 if(true == convert(b_PROPERTIES_MC4_SHIFTS_velocity.get(1).asInt32(), value, formaterror))
3345 {
3346 mc_service.properties.mc4shifts.velocity = value;
3347 }
3348 if(true == convert(b_PROPERTIES_MC4_SHIFTS_estimJointVelocity.get(1).asInt32(), value, formaterror))
3349 {
3350 if(value > 15)
3351 {
3352 yError() << "ServiceParser::check_motion() manages values of PROPERTIES.MC4.SHIFTS.estim* only in range [0, 15]. read value =" << value;
3353 return false;
3354 }
3355 mc_service.properties.mc4shifts.estimJointVelocity = value;
3356 }
3357 if(true == convert(b_PROPERTIES_MC4_SHIFTS_estimJointAcceleration.get(1).asInt32(), value, formaterror))
3358 {
3359 if(value > 15)
3360 {
3361 yError() << "ServiceParser::check_motion() manages values of PROPERTIES.MC4.SHIFTS.estim* only in range [0, 15]. read value =" << value;
3362 return false;
3363 }
3364 mc_service.properties.mc4shifts.estimJointAcceleration = value;
3365 }
3366 if(true == convert(b_PROPERTIES_MC4_SHIFTS_estimMotorVelocity.get(1).asInt32(), value, formaterror))
3367 {
3368 if(value > 15)
3369 {
3370 yError() << "ServiceParser::check_motion() manages values of PROPERTIES.MC4.SHIFTS.estim* only in range [0, 15]. read value =" << value;
3371 return false;
3372 }
3373 mc_service.properties.mc4shifts.estimMotorVelocity = value;
3374 }
3375 if(true == convert(b_PROPERTIES_MC4_SHIFTS_estimMotorAcceleration.get(1).asInt32(), value, formaterror))
3376 {
3377 if(value > 15)
3378 {
3379 yError() << "ServiceParser::check_motion() manages values of PROPERTIES.MC4.SHIFTS.estim* only in range [0, 15]. read value =" << value;
3380 return false;
3381 }
3382 mc_service.properties.mc4shifts.estimMotorAcceleration = value;
3383 }
3384
3385 // 2. i get the values for b_PROPERTIES_MC4_BROADCASTPOLICY_enable
3386
3387 int tmp = b_PROPERTIES_MC4_BROADCASTPOLICY_enable.size();
3388 int numofenables = tmp - 1; // first position of bottle contains the tag "enable"
3389
3390 mc_service.properties.mc4broadcasts.resize(0);
3391 for(int i=0; i<numofenables; i++)
3392 {
3393 // transform the string into a value.
3394 eOmc_mc4broadcast_t item = eomc_mc4broadcast_unknown;
3395 const char *str = b_PROPERTIES_MC4_BROADCASTPOLICY_enable.get(i+1).asString().c_str();
3396
3397 // check compact and then non-compact form
3398 if(eomc_mc4broadcast_unknown == (item = eomc_string2mc4broadcast(str, eobool_true)))
3399 {
3400 item = eomc_string2mc4broadcast(str, eobool_false);
3401 }
3402
3403 if((eomc_mc4broadcast_unknown != item) && (eomc_mc4broadcast_none != item))
3404 { // if meaningful ...
3405 mc_service.properties.mc4broadcasts.push_back(item);
3406 }
3407 }
3408
3409
3410
3411 // 3. i get the values for b_PROPERTIES_MC4_JOINT2BOARD_location.... there must be 12 values
3412
3413/* int tmp1 = b_PROPERTIES_MC4_JOINT2BOARD_location.size();
3414 int numoflocations = tmp1 - 1; // first position of bottle contains the tag "location"
3415
3416 if(12 != numoflocations)
3417 {
3418 yError() << "ServiceParser::check_motion() detects that PROPERTIES.MC4.JOINT2BOARD.location has not 12 items but" << numoflocations;
3419 return false;
3420 }
3421
3422 mc_service.properties.mc4joints.resize(0);
3423 for(int i=0; i<numoflocations; i++)
3424 {
3425 // transform the string into a location
3426
3427 formaterror = false;
3428 eObrd_location_t loc;
3429 if(false == convert(b_PROPERTIES_MC4_JOINT2BOARD_location.get(i+1).asString(), loc, formaterror))
3430 {
3431 yError() << "ServiceParser::check_motion() has detected an illegal format for PROPERTIES.MC4.JOINT2BOARD.location";
3432 return false;
3433 }
3434
3435 eObrd_canlocation_t item;
3436 if(eobrd_place_extcan == loc.any.place)
3437 {
3438 item.port = loc.extcan.port;
3439 item.addr = loc.extcan.addr;
3440 item.insideindex = loc.extcan.index;
3441 }
3442 else
3443 {
3444 yError() << "ServiceParser::check_motion() has detected an illegal format for PROPERTIES.MC4.JOINT2BOARD.location. it must be extcan";
3445 return false;
3446 }
3447
3448 mc_service.properties.mc4joints.push_back(item);
3449 }
3450*/
3451
3452 } // has_PROPERTIES_MC4
3453
3454 if(true == has_PROPERTIES_PSC)
3455 {
3456 // i get .location and nothing else
3457
3458 Bottle b_PROPERTIES_PSC_location = b_PROPERTIES_PSC.findGroup("location");
3459 if(b_PROPERTIES_PSC_location.isNull())
3460 {
3461 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.PSC.location";
3462 return false;
3463 }
3464
3465 int tmp = b_PROPERTIES_PSC_location.size();
3466 int numboards = tmp - 1; // first position of bottle contains the tag "location"
3467
3468 // check if numboards is 3.
3469 if(eOas_psc_boards_maxnumber != numboards)
3470 {
3471 yError() << "ServiceParser::check_motion() in PROPERTIES.PSC.location must contain three items and it has:" << numboards;
3472 return false;
3473 }
3474
3475 mc_service.properties.psclocations.resize(3);
3476 for(int i=0; i<3; i++)
3477 {
3478 eObrd_location_t loc;
3479 formaterror = false;
3480 if(false == convert(b_PROPERTIES_PSC_location.get(1+i).asString(), loc, formaterror))
3481 {
3482 yError() << "ServiceParser::check_motion() has detected an illegal format for SERVICE.PROPERTIES.PSC.location";
3483 return false;
3484 }
3485
3486 if(eobrd_place_can == loc.any.place)
3487 {
3488 mc_service.properties.psclocations[i].port = loc.can.port;
3489 mc_service.properties.psclocations[i].addr = loc.can.addr;
3490 mc_service.properties.psclocations[i].insideindex = eobrd_caninsideindex_none;
3491
3492 }
3493 else if(eobrd_place_extcan == loc.any.place)
3494 {
3495 mc_service.properties.psclocations[i].port = loc.extcan.port;
3496 mc_service.properties.psclocations[i].addr = loc.extcan.addr;
3497 mc_service.properties.psclocations[i].insideindex = eobrd_caninsideindex_none;
3498 }
3499 else
3500 {
3501 yError() << "ServiceParser::check_motion() has detected an illegal format for SERVICE.PROPERTIES.PSC.location. it must be either can or extcan";
3502 return false;
3503 }
3504 }
3505
3506 } // has_PROPERTIES_PSC
3507
3508 if(true == has_PROPERTIES_JOINTMAPPING)
3509 {
3510
3511 // actuator, encoder1, encoder2 must all be present. the params contained inside must be all of equal length and equal to numberofjoints
3512
3513 Bottle b_PROPERTIES_JOINTMAPPING_ACTUATOR = Bottle(b_PROPERTIES_JOINTMAPPING.findGroup("ACTUATOR"));
3514 if(b_PROPERTIES_JOINTMAPPING_ACTUATOR.isNull())
3515 {
3516 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ACTUATOR";
3517 return false;
3518 }
3519
3520 Bottle b_PROPERTIES_JOINTMAPPING_ENCODER1 = Bottle(b_PROPERTIES_JOINTMAPPING.findGroup("ENCODER1"));
3521 if(b_PROPERTIES_JOINTMAPPING_ENCODER1.isNull())
3522 {
3523 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ENCODER1";
3524 return false;
3525 }
3526
3527 Bottle b_PROPERTIES_JOINTMAPPING_ENCODER2 = Bottle(b_PROPERTIES_JOINTMAPPING.findGroup("ENCODER2"));
3528 if(b_PROPERTIES_JOINTMAPPING_ENCODER2.isNull())
3529 {
3530 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ENCODER2";
3531 return false;
3532 }
3533
3534 // now the vectors the above three contain ...
3535
3536 Bottle b_PROPERTIES_JOINTMAPPING_ACTUATOR_type = Bottle(b_PROPERTIES_JOINTMAPPING_ACTUATOR.findGroup("type"));
3537 if(b_PROPERTIES_JOINTMAPPING_ACTUATOR_type.isNull())
3538 {
3539 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ACTUATOR.type";
3540 return false;
3541 }
3542
3543 Bottle b_PROPERTIES_JOINTMAPPING_ACTUATOR_onboard = Bottle(b_PROPERTIES_JOINTMAPPING_ACTUATOR.findGroup("onboard"));
3544 // mandatory only for advfoc
3545
3546 Bottle b_PROPERTIES_JOINTMAPPING_ACTUATOR_port = Bottle(b_PROPERTIES_JOINTMAPPING_ACTUATOR.findGroup("port"));
3547 if(b_PROPERTIES_JOINTMAPPING_ACTUATOR_port.isNull())
3548 {
3549 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ACTUATOR.port";
3550 return false;
3551 }
3552
3553 Bottle b_PROPERTIES_JOINTMAPPING_ENCODER1_type = Bottle(b_PROPERTIES_JOINTMAPPING_ENCODER1.findGroup("type"));
3554 if(b_PROPERTIES_JOINTMAPPING_ENCODER1_type.isNull())
3555 {
3556 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ENCODER1.type";
3557 return false;
3558 }
3559 Bottle b_PROPERTIES_JOINTMAPPING_ENCODER1_port = Bottle(b_PROPERTIES_JOINTMAPPING_ENCODER1.findGroup("port"));
3560 if(b_PROPERTIES_JOINTMAPPING_ENCODER1_port.isNull())
3561 {
3562 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ENCODER1.port";
3563 return false;
3564 }
3565 Bottle b_PROPERTIES_JOINTMAPPING_ENCODER1_position = Bottle(b_PROPERTIES_JOINTMAPPING_ENCODER1.findGroup("position"));
3566 if(b_PROPERTIES_JOINTMAPPING_ENCODER1_position.isNull())
3567 {
3568 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ENCODER1.position";
3569 return false;
3570 }
3571 Bottle b_PROPERTIES_JOINTMAPPING_ENCODER1_resolution = Bottle(b_PROPERTIES_JOINTMAPPING_ENCODER1.findGroup("resolution"));
3572 if(b_PROPERTIES_JOINTMAPPING_ENCODER1_resolution.isNull())
3573 {
3574 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ENCODER1.resolution";
3575 return false;
3576 }
3577 Bottle b_PROPERTIES_JOINTMAPPING_ENCODER1_tolerance = Bottle(b_PROPERTIES_JOINTMAPPING_ENCODER1.findGroup("tolerance"));
3578 if(b_PROPERTIES_JOINTMAPPING_ENCODER1_tolerance.isNull())
3579 {
3580 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ENCODER1.tolerance";
3581 return false;
3582 }
3583
3584
3585
3586 Bottle b_PROPERTIES_JOINTMAPPING_ENCODER2_type = Bottle(b_PROPERTIES_JOINTMAPPING_ENCODER2.findGroup("type"));
3587 if(b_PROPERTIES_JOINTMAPPING_ENCODER2_type.isNull())
3588 {
3589 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ENCODER2.type";
3590 return false;
3591 }
3592 Bottle b_PROPERTIES_JOINTMAPPING_ENCODER2_port = Bottle(b_PROPERTIES_JOINTMAPPING_ENCODER2.findGroup("port"));
3593 if(b_PROPERTIES_JOINTMAPPING_ENCODER2_port.isNull())
3594 {
3595 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ENCODER2.port";
3596 return false;
3597 }
3598 Bottle b_PROPERTIES_JOINTMAPPING_ENCODER2_position = Bottle(b_PROPERTIES_JOINTMAPPING_ENCODER2.findGroup("position"));
3599 if(b_PROPERTIES_JOINTMAPPING_ENCODER2_position.isNull())
3600 {
3601 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ENCODER2.position";
3602 return false;
3603 }
3604 Bottle b_PROPERTIES_JOINTMAPPING_ENCODER2_resolution = Bottle(b_PROPERTIES_JOINTMAPPING_ENCODER2.findGroup("resolution"));
3605 if(b_PROPERTIES_JOINTMAPPING_ENCODER2_resolution.isNull())
3606 {
3607 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ENCODER2.resolution";
3608 return false;
3609 }
3610 Bottle b_PROPERTIES_JOINTMAPPING_ENCODER2_tolerance = Bottle(b_PROPERTIES_JOINTMAPPING_ENCODER2.findGroup("tolerance"));
3611 if(b_PROPERTIES_JOINTMAPPING_ENCODER2_tolerance.isNull())
3612 {
3613 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ENCODER2.tolerance";
3614 return false;
3615 }
3616 // now the size of the vectors must all be equal
3617
3618 size_t tmp = b_PROPERTIES_JOINTMAPPING_ACTUATOR_type.size();
3619 if( (tmp != b_PROPERTIES_JOINTMAPPING_ACTUATOR_port.size()) ||
3620 (tmp != b_PROPERTIES_JOINTMAPPING_ENCODER1_type.size()) ||
3621 (tmp != b_PROPERTIES_JOINTMAPPING_ENCODER1_port.size()) ||
3622 (tmp != b_PROPERTIES_JOINTMAPPING_ENCODER1_position.size()) ||
3623 (tmp != b_PROPERTIES_JOINTMAPPING_ENCODER1_resolution.size())||
3624 (tmp != b_PROPERTIES_JOINTMAPPING_ENCODER1_tolerance.size()) ||
3625 (tmp != b_PROPERTIES_JOINTMAPPING_ENCODER2_type.size()) ||
3626 (tmp != b_PROPERTIES_JOINTMAPPING_ENCODER2_port.size()) ||
3627 (tmp != b_PROPERTIES_JOINTMAPPING_ENCODER2_position.size()) ||
3628 (tmp != b_PROPERTIES_JOINTMAPPING_ENCODER2_resolution.size()) ||
3629 (tmp != b_PROPERTIES_JOINTMAPPING_ENCODER2_tolerance.size())
3630 )
3631 {
3632 yError() << "ServiceParser::check_motion() detected wrong number of columns somewhere inside PROPERTIES.JOINTMAPPING";
3633 return false;
3634 }
3635
3636 // ok, we have the number of joints .........
3637 mc_service.properties.numofjoints = (0 == tmp ) ? (0) : (tmp-1);
3638
3639 // i attempt to parse the vectors inside actuators (type, port), encoder1 (type, port, position) and encoder2 (type, port, position).
3640
3641 mc_service.properties.actuators.resize(0);
3642 mc_service.properties.encoder1s.resize(0);
3643 mc_service.properties.encoder2s.resize(0);
3644
3645 if(eomn_serv_MC_mc4 == mc_service.type)
3646 {
3647 mc_service.properties.mc4joints.resize(0);
3648 }
3649
3650
3651 for(int i=0; i<mc_service.properties.numofjoints; i++)
3652 {
3653 servMC_actuator_t act;
3654 servMC_encoder_t enc1;
3655 servMC_encoder_t enc2;
3656 bool formaterror = false;
3657
3658 eOmc_encoder_t enctype = eomc_enc_unknown;
3659 uint8_t encport = eobrd_port_unknown;
3660 eOmc_position_t encposition = eomc_pos_unknown;
3661
3662 // actuators ..
3663 act.type = eomc_act_unknown;
3664 act.desc.pwm.port = eobrd_port_unknown;
3665
3666 if(false == convert(b_PROPERTIES_JOINTMAPPING_ACTUATOR_type.get(i+1).asString(), act.type, formaterror))
3667 {
3668 yError() << "ServiceParser::check_motion() PROPERTIES.JOINTMAPPING.actuator.type not valid for item" << i;
3669 return false;
3670 }
3671
3672 if((eomn_serv_MC_mc4 == mc_service.type) && (eomc_act_mc4 != act.type))
3673 {
3674 yError() << "ServiceParser::check_motion() PROPERTIES.JOINTMAPPING.actuator.type should be mc4 with mc service of type eomn_serv_MC_mc4. Error in item" << i;
3675 return false;
3676 }
3677
3678 if(false == parse_actuator_port(b_PROPERTIES_JOINTMAPPING_ACTUATOR_port.get(i+1).asString(), mc_service.properties.ethboardtype, act.type, act.desc, formaterror))
3679 {
3680 yError() << "ServiceParser::check_motion() PROPERTIES.JOINTMAPPING.actuator.port not valid for item" << i;
3681 return false;
3682 }
3683
3684 if(eomn_serv_MC_mc4 == mc_service.type)
3685 {
3686 eObrd_canlocation_t item;
3687 item.port = act.desc.mc4.canloc.port;
3688 item.addr = act.desc.mc4.canloc.addr;
3689 item.insideindex = act.desc.mc4.canloc.insideindex;
3690
3691 mc_service.properties.mc4joints.push_back(item);
3692 }
3693
3694 if(eomn_serv_MC_advfoc == mc_service.type)
3695 {
3696 if(b_PROPERTIES_JOINTMAPPING_ACTUATOR_onboard.isNull())
3697 {
3698 yError() << "ServiceParser::check_motion() cannot find PROPERTIES.JOINTMAPPING.ACTUATOR.onboard for eomn_serv_MC_advfoc";
3699 return false;
3700 }
3701
3702 if(act.type != eomc_act_advfoc)
3703 {
3704 yError() << "ServiceParser::check_motion() detectde that PROPERTIES.JOINTMAPPING.ACTUATOR.type for eomn_serv_MC_advfoc id not advfoc";
3705 return false;
3706 }
3707
3708 act.advdescr.type = eomc_act_advfoc;
3709 act.advdescr.location = act.desc.gen.location;
3710 eObrd_cantype_t bb {};
3711 convert(b_PROPERTIES_JOINTMAPPING_ACTUATOR_onboard.get(i+1).asString(), bb, formaterror);
3712 act.advdescr.board.type = bb;
3713 }
3714
3715
3716 // encoder1s ...
3717
3718 enc1.desc.type = eomc_enc_unknown;
3719 enc1.desc.port = eobrd_port_unknown;
3720 enc1.desc.pos = eomc_pos_unknown;
3721
3722 enctype = eomc_enc_unknown;
3723 if(false == convert(b_PROPERTIES_JOINTMAPPING_ENCODER1_type.get(i+1).asString(), enctype, formaterror))
3724 {
3725 yError() << "ServiceParser::check_motion() PROPERTIES.JOINTMAPPING.encoder1.type not valid for item" << i;
3726 return false;
3727 }
3728 enc1.desc.type = enctype;
3729
3730 // depending on type, we ....
3731
3732
3733
3734 // dobbiamo fare un parser che riconosca CONN:P6 se aea, qenc etc, oppure MAIS:thumbproximal se mais
3735
3736 encport = eobrd_port_unknown;
3737 if(false == parse_encoder_port(b_PROPERTIES_JOINTMAPPING_ENCODER1_port.get(i+1).asString(), mc_service.properties.ethboardtype, enctype, encport, formaterror))
3738 {
3739 yError() << "ServiceParser::check_motion() PROPERTIES.JOINTMAPPING.encoder1.port not valid for item" << i;
3740 return false;
3741 }
3742 enc1.desc.port = encport;
3743
3744 encposition = eomc_pos_unknown;
3745 if(false == convert(b_PROPERTIES_JOINTMAPPING_ENCODER1_position.get(i+1).asString(), encposition, formaterror))
3746 {
3747 yError() << "ServiceParser::check_motion() PROPERTIES.JOINTMAPPING.encoder1.position not valid for item" << i;
3748 return false;
3749 }
3750 enc1.desc.pos = encposition;
3751
3752 enc1.resolution = b_PROPERTIES_JOINTMAPPING_ENCODER1_resolution.get(i+1).asInt32();
3753
3754 enc1.tolerance = b_PROPERTIES_JOINTMAPPING_ENCODER1_tolerance.get(i+1).asFloat64();
3755
3756
3757
3758 // encoder2s ...
3759
3760 enc2.desc.type = eomc_enc_unknown;
3761 enc2.desc.port = eobrd_port_unknown;
3762 enc2.desc.pos = eomc_pos_unknown;
3763
3764 enctype = eomc_enc_unknown;
3765 if(false == convert(b_PROPERTIES_JOINTMAPPING_ENCODER2_type.get(i+1).asString(), enctype, formaterror))
3766 {
3767 yError() << "ServiceParser::check_motion() PROPERTIES.JOINTMAPPING.encoder2.type not valid for item" << i;
3768 return false;
3769 }
3770
3771 enc2.desc.type = enctype;
3772
3773
3774 encport = eobrd_port_unknown;
3775 if(false == parse_encoder_port(b_PROPERTIES_JOINTMAPPING_ENCODER2_port.get(i+1).asString(), mc_service.properties.ethboardtype, enctype, encport, formaterror))
3776 {
3777 yError() << "ServiceParser::check_motion() PROPERTIES.JOINTMAPPING.encoder2.port not valid for item" << i;
3778 return false;
3779 }
3780 enc2.desc.port = encport;
3781
3782 encposition = eomc_pos_unknown;
3783 if(false == convert(b_PROPERTIES_JOINTMAPPING_ENCODER2_position.get(i+1).asString(), encposition, formaterror))
3784 {
3785 yError() << "ServiceParser::check_motion() PROPERTIES.JOINTMAPPING.encoder2.position not valid for item" << i;
3786 return false;
3787 }
3788
3789 enc2.desc.pos = encposition;
3790
3791 enc2.resolution = b_PROPERTIES_JOINTMAPPING_ENCODER2_resolution.get(i+1).asInt32();
3792 enc2.tolerance = b_PROPERTIES_JOINTMAPPING_ENCODER2_tolerance.get(i+1).asFloat64();
3793
3794
3795 // ok, we push act, enc1, enc2
3796
3797 mc_service.properties.actuators.push_back(act);
3798 mc_service.properties.encoder1s.push_back(enc1);
3799 mc_service.properties.encoder2s.push_back(enc2);
3800
3801 }
3802
3803 } // has_PROPERTIES_JOINTMAPPING
3804
3805
3806 // add default values. then we may change tem
3807 mc_service.diagconfig.mode = eomn_serv_diagn_mode_NONE;
3808 mc_service.diagconfig.par16 = 0;
3809
3810 if(true == has_PROPERTIES_DIAGNOSTICS)
3811 {
3812 Bottle b_PROPERTIES_DIAGNOSTICS_mode = b_PROPERTIES_DIAGNOSTICS.findGroup("mode");
3813 Bottle b_PROPERTIES_DIAGNOSTICS_par16 = b_PROPERTIES_DIAGNOSTICS.findGroup("par16");
3814 if(!b_PROPERTIES_DIAGNOSTICS_mode.isNull() && !b_PROPERTIES_DIAGNOSTICS_par16.isNull())
3815 {
3816 // if we have both of them ... and they contain at least (only) one we get the values
3817 int n_type = b_PROPERTIES_DIAGNOSTICS_mode.size() - 1;
3818 int n_par16 = b_PROPERTIES_DIAGNOSTICS_par16.size() - 1;
3819 if((1 == n_type) && (1 == n_par16))
3820 {
3821 eOmn_serv_diagn_mode_t dm = eomn_serv_diagn_mode_NONE;
3822 int par16 = 0;
3823 if(false == convert(b_PROPERTIES_DIAGNOSTICS_mode.get(1).asString(), dm, formaterror))
3824 {
3825 yWarning() << "ServiceParser::check_motion() has detected an illegal format for SERVICE.PROPERTIES.DIAGNOSTICS.mode. Using {eOmn_serv_diagn_mode_NONE, 0}";
3826 }
3827 else if(!b_PROPERTIES_DIAGNOSTICS_par16.get(1).isInt32())
3828 {
3829 yWarning() << "ServiceParser::check_motion() has detected an illegal format for SERVICE.PROPERTIES.DIAGNOSTICS.par16. Using {eOmn_serv_diagn_mode_NONE, 0}";
3830 }
3831 else
3832 {
3833 par16 = b_PROPERTIES_DIAGNOSTICS_par16.get(1).asInt32();
3834 }
3835
3836 mc_service.diagconfig.mode = dm;
3837 mc_service.diagconfig.par16 = static_cast<uint16_t>(par16);
3838
3839 yWarning() << "ServiceParser::check_motion() has detected some DIAGNOSTICS config for this MC service: mode = " << eomn_servicediagnmode2string(dm) << ", par16 = " << mc_service.diagconfig.par16;
3840
3841 }
3842
3843 }
3844
3845 } // has_PROPERTIES_DIAGNOSTICS
3846
3847
3848 return true;
3849}
3850
3851// int ServiceParser::getnumofjointsets(void)
3852// {
3853//
3854// int n=0;
3855// int njointsinset[mc_service.properties.numofjoints]; //the max number of sets is equal to max number of joints.
3856// for(int i=0; i<mc_service.properties.numofjoints;i++)
3857// {
3858// njointsinset[i] = 0;
3859// }
3860//
3861// for(int i=0; i<mc_service.properties.numofjoints;i++)
3862// {
3863// int set = mc_service.properties.joint2set[i];
3864//
3865// if(set > mc_service.properties.numofjoints)
3866// {
3867// 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.";
3868// return false;
3869// }
3870//
3871// njointsinset[set]++;
3872// }
3873// int count =0;
3874// for(int i=0; i<mc_service.properties.numofjoints;i++)
3875// {
3876// if(njointsinset[i] != 0)
3877// count++;
3878// }
3879//
3880// return count;
3881// }
3882
3883
3884//bool ServiceParser::parseMCEncoderItem(Bottle &b_ENCODER, vector<servMC_encoder_t> &encoders, char *encString)
3885//{
3886//#warning -> correct warnings on
3887//
3888// Bottle b_ENCODER_TYPE(b_ENCODER.find("type").asString());
3889// if(b_ENCODER_TYPE.isNull())
3890// {
3891// yError() << "ServiceParser::parseMCEncoderItem() cannot find JOINTMAPPING."<< encString<< ".type";
3892// return false;
3893// }
3894//
3895// Bottle b_ENCODER_PORT(b_ENCODER.find("port").asString());
3896// if(b_ENCODER_PORT.isNull())
3897// {
3898// yError() << "ServiceParser::parseMCEncoderItem() cannot find JOINTMAPPING"<< encString<< ".type";
3899// return false;
3900// }
3901//
3902// encoders.resize(0);
3903// int numofenc = b_ENCODER_TYPE.size() -1;
3904//
3905// //VALE: controlla che il numero di act sia uguale a quello di joint per embobjmotion control obj!!!
3906// for(int i = 0; i< numofenc; i++)
3907// {
3908// servMC_encoder_t item;
3909// bool formaterror = false;
3910// if(false == convert(b_ENCODER_TYPE.get(i+1).asString(), item.type, formaterror))
3911// {
3912// yError() << "ServiceParser::parseMCEncoderItem() encoder type not valid in " << encString;
3913// return false;
3914// }
3915// //VALE: commented in ordet to compile I have not enouth time to implement this function
3921//
3922// if(false == convert(b_ENCODER_TYPE.get(i+1).asString(), item.position, formaterror))
3923// {
3924// yError() << "ServiceParser::parseMCEncoderItem() encoder location not valid in " << encString;
3925// return false;
3926// }
3927// encoders.push_back(item);
3928//
3929// }
3930// return true;
3931//}
3932
3933
3934// bool ServiceParser::copyjomocouplingInfo( eOmc_4jomo_coupling_t *jc_dest)
3935// {
3936//
3937// memset(jc_dest, 0, sizeof(eOmc_4jomo_coupling_t));
3938//
3939// // 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.
3940// memset(jc_dest->joint2set, eomc_jointSetNum_none, sizeof(jc_dest->joint2set));
3941//
3942// for(int i=0; i<mc_service.properties.numofjoints; i++)
3943// {
3944// jc_dest->joint2set[i] = mc_service.properties.joint2set[i];
3945// }
3946//
3947// for(int i=0; i<4; i++)
3948// {
3949// for(int j=0; j<4; j++)
3950// {
3951// jc_dest->joint2motor[i][j] = eo_common_float_to_Q17_14(mc_service.properties.controller.matrixJ2M[4*i+j]);
3952// jc_dest->motor2joint[i][j] = eo_common_float_to_Q17_14(mc_service.properties.controller.matrixM2J[4*i+j]);
3953// }
3954// }
3955//
3956//
3957// for(int r=0; r<4; r++)
3958// {
3959// for(int c=0; c<6; c++)
3960// {
3961// jc_dest->encoder2joint[r][c] = eo_common_float_to_Q17_14(mc_service.properties.controller.matrixE2J[6*r+c]);
3962// }
3963// }
3964//
3965// for(int s=0; s< mc_service.properties.numofjointsets; s++)
3966// {
3967// memcpy(&jc_dest->jsetcfg[s] , &mc_service.properties.jointset_cfgs[s], sizeof(eOmc_jointset_configuration_t));
3968// }
3969//
3970// return true;
3971// }
3972
3973
3974
3975bool ServiceParser::parseService(Searchable &config, servConfigMC_t &mcconfig)
3976{
3977 bool ret = false;
3978
3979 if(false == check_motion(config))
3980 {
3981 yError() << "ServiceParser::parseService() gets same errors parsing SERVICE MC group";
3982 return ret;
3983 }
3984
3985 // if we dont find the xml file ... we just return true but mc_service.type is eomn_serv_MC_generic.
3986 // in such a case we dont transmit the config and ask the eth board to config itself accoring to its ip address.
3987 // ...
3988
3989 mcconfig.ethservice.configuration.type = mc_service.type;
3990 mcconfig.ethservice.configuration.diagnosticsmode = mc_service.diagconfig.mode;
3991 mcconfig.ethservice.configuration.diagnosticsparam = mc_service.diagconfig.par16;
3992
3993 switch(mc_service.type)
3994 {
3995 case eomn_serv_MC_foc:
3996 {
3997 eOmn_serv_config_data_mc_foc_t *data_mc = &(mcconfig.ethservice.configuration.data.mc.foc_based);
3998
3999 // 1. ->version (of foc board).
4000 data_mc->version.firmware.major = mc_service.properties.canboards.at(0).firmware.major;
4001 data_mc->version.firmware.minor = mc_service.properties.canboards.at(0).firmware.minor;
4002 data_mc->version.firmware.build = mc_service.properties.canboards.at(0).firmware.build;
4003 data_mc->version.protocol.major = mc_service.properties.canboards.at(0).protocol.major;
4004 data_mc->version.protocol.minor = mc_service.properties.canboards.at(0).protocol.minor;
4005
4006 // we assume that all can boards have the same type for each joint
4007 data_mc->type = mc_service.properties.canboards.at(0).type;
4008
4009 // 2. ->arrayofjomodescriptors
4010 EOarray *arrayofjomos = eo_array_New(4, sizeof(eOmc_jomo_descriptor_t), &data_mc->arrayofjomodescriptors);
4011 int numofjomos = mc_service.properties.numofjoints;
4012
4013 for(int i=0; i<numofjomos; i++)
4014 {
4015 eOmc_jomo_descriptor_t jomodes = {};
4016
4017 // 1. actuator is on foc: we need the address
4018 jomodes.actuator.foc.canloc.port = mc_service.properties.actuators[i].desc.foc.canloc.port;
4019 jomodes.actuator.foc.canloc.addr = mc_service.properties.actuators[i].desc.foc.canloc.addr;
4020 jomodes.actuator.foc.canloc.insideindex = eobrd_caninsideindex_first;
4021
4022 // 2. encoder1 is ...
4023 jomodes.encoder1.type = mc_service.properties.encoder1s[i].desc.type;
4024 jomodes.encoder1.port = mc_service.properties.encoder1s[i].desc.port;
4025 jomodes.encoder1.pos = mc_service.properties.encoder1s[i].desc.pos;
4026
4027 // 3. encoder2 is ...
4028 jomodes.encoder2.type = mc_service.properties.encoder2s[i].desc.type;
4029 jomodes.encoder2.port = mc_service.properties.encoder2s[i].desc.port;
4030 jomodes.encoder2.pos = mc_service.properties.encoder2s[i].desc.pos;
4031
4032 eo_array_PushBack(arrayofjomos, &jomodes);
4033
4034 }
4035
4036
4038 //eOmc_4jomo_coupling_t *jomocoupling = &data_mc->jomocoupling;
4039
4040 //ret = copyjomocouplingInfo(jomocoupling);
4041
4042 // ok, everything is done
4043 ret = true;
4044
4045 } break;
4046
4047 case eomn_serv_MC_mc4:
4048 {
4049 eOmn_serv_config_data_mc_mc4_t *data_mc = &(mcconfig.ethservice.configuration.data.mc.mc4_based);
4050
4051 // 1. ->version (of mc4 board) + ->mais.version.
4052 bool mc4boardFound = false;
4053 bool maisboardFound = false;
4054 for(size_t i=0; i<mc_service.properties.canboards.size(); i++)
4055 {
4056 if(eobrd_cantype_mc4 == mc_service.properties.canboards[i].type)
4057 {
4058 data_mc->mc4version.protocol = mc_service.properties.canboards[i].protocol;
4059 data_mc->mc4version.firmware = mc_service.properties.canboards[i].firmware;
4060 mc4boardFound = true;
4061 }
4062 else if(eobrd_cantype_mais == mc_service.properties.canboards[i].type)
4063 {
4064 data_mc->mais.version.protocol = mc_service.properties.canboards[i].protocol;
4065 data_mc->mais.version.firmware = mc_service.properties.canboards[i].firmware;
4066 maisboardFound = true;
4067 }
4068 }
4069
4070 if((false == maisboardFound) || (false == mc4boardFound))
4071 {
4072 yError() << "ServiceParser::parseService() gets same errors parsing SERVICE MC group for mc4: cannot find description of mc4 or mais board";
4073 }
4074
4075// data_mc->mc4version.firmware.major = mc_service.properties.canboards.at(0).firmware.major;
4076// data_mc->mc4version.firmware.minor = mc_service.properties.canboards.at(0).firmware.minor;
4077// data_mc->mc4version.firmware.build = mc_service.properties.canboards.at(0).firmware.build;
4078// data_mc->mc4version.protocol.major = mc_service.properties.canboards.at(0).protocol.major;
4079// data_mc->mc4version.protocol.minor = mc_service.properties.canboards.at(0).protocol.minor;
4080
4081 // 2. ->mc4shifts
4082 data_mc->mc4shifts = mc_service.properties.mc4shifts;
4083
4084 // 3. ->mc4joints
4085 for(int i=0; i<12; i++)
4086 {
4087 data_mc->mc4joints[i] = mc_service.properties.mc4joints[i];
4088 }
4089
4090
4091 // 4. ->mais.canloc
4092 data_mc->mais.canloc = mc_service.properties.maislocation;
4093
4094 // 5. ->broadcastflags
4095 data_mc->broadcastflags = 0;
4096 for(size_t i=0; i<mc_service.properties.mc4broadcasts.size(); i++)
4097 {
4098 eOmc_mc4broadcast_t item = mc_service.properties.mc4broadcasts[i];
4099 if((eomc_mc4broadcast_none != item) && (eomc_mc4broadcast_unknown != item))
4100 {
4101 eo_common_hlfword_bitset(&data_mc->broadcastflags, item);
4102 }
4103 }
4104
4105 // ok, everything is done
4106 ret = true;
4107
4108 } break;
4109
4110 case eomn_serv_MC_mc4plus:
4111 {
4112 eOmn_serv_config_data_mc_mc4plus_t *data_mc = &(mcconfig.ethservice.configuration.data.mc.mc4plus_based);
4113
4114 // 3. ->arrayofjomodescriptors
4115 EOarray *arrayofjomos = eo_array_New(4, sizeof(eOmc_jomo_descriptor_t), &data_mc->arrayofjomodescriptors);
4116 int numofjomos = mc_service.properties.numofjoints;
4117
4118 for(int i=0; i<numofjomos; i++)
4119 {
4120 eOmc_jomo_descriptor_t jomodes = {};
4121
4122 // 1. actuator is on pwm: we need the port
4123 jomodes.actuator.pwm.port = mc_service.properties.actuators[i].desc.pwm.port;
4124
4125 // 2. encoder1 is ...
4126 jomodes.encoder1.type = mc_service.properties.encoder1s[i].desc.type;
4127 jomodes.encoder1.port = mc_service.properties.encoder1s[i].desc.port;
4128 jomodes.encoder1.pos = mc_service.properties.encoder1s[i].desc.pos;
4129
4130 // 3. encoder2 is ...
4131 jomodes.encoder2.type = mc_service.properties.encoder2s[i].desc.type;
4132 jomodes.encoder2.port = mc_service.properties.encoder2s[i].desc.port;
4133 jomodes.encoder2.pos = mc_service.properties.encoder2s[i].desc.pos;
4134
4135 eo_array_PushBack(arrayofjomos, &jomodes);
4136
4137 }
4138
4139 // // 3. ->jomocoupling
4140 //eOmc_4jomo_coupling_t *jomocoupling = &data_mc->jomocoupling;
4141
4142 //ret = copyjomocouplingInfo(jomocoupling);
4143
4144 // ok, everything is done
4145 ret = true;
4146
4147 } break;
4148
4149 case eomn_serv_MC_mc4plusmais:
4150 {
4151 eOmn_serv_config_data_mc_mc4plusmais_t *data_mc = &(mcconfig.ethservice.configuration.data.mc.mc4plusmais_based);
4152
4153 // 1. ->mais
4154 eOmn_serv_config_data_as_mais_t *mais = &data_mc->mais;
4155
4156 mais->canloc.port = mc_service.properties.maislocation.port;
4157 mais->canloc.addr = mc_service.properties.maislocation.addr;
4158 mais->canloc.insideindex = mc_service.properties.maislocation.insideindex;
4159
4160 mais->version.firmware.major = mc_service.properties.canboards.at(0).firmware.major;
4161 mais->version.firmware.minor = mc_service.properties.canboards.at(0).firmware.minor;
4162 mais->version.firmware.build = mc_service.properties.canboards.at(0).firmware.build;
4163 mais->version.protocol.major = mc_service.properties.canboards.at(0).protocol.major;
4164 mais->version.protocol.minor = mc_service.properties.canboards.at(0).protocol.minor;
4165
4166 // 2. ->arrayofjomodescriptors
4167 EOarray *arrayofjomos = eo_array_New(4, sizeof(eOmc_jomo_descriptor_t), &data_mc->arrayofjomodescriptors);
4168 int numofjomos = mc_service.properties.numofjoints;
4169
4170 for(int i=0; i<numofjomos; i++)
4171 {
4172 eOmc_jomo_descriptor_t jomodes = {};
4173
4174 // 1. actuator is on pwm: we need the port
4175 jomodes.actuator.pwm.port = mc_service.properties.actuators[i].desc.pwm.port;
4176
4177 // 2. encoder1 is ...
4178 jomodes.encoder1.type = mc_service.properties.encoder1s[i].desc.type;
4179 jomodes.encoder1.port = mc_service.properties.encoder1s[i].desc.port;
4180 jomodes.encoder1.pos = mc_service.properties.encoder1s[i].desc.pos;
4181
4182 // 3. encoder2 is ...
4183 jomodes.encoder2.type = mc_service.properties.encoder2s[i].desc.type;
4184 jomodes.encoder2.port = mc_service.properties.encoder2s[i].desc.port;
4185 jomodes.encoder2.pos = mc_service.properties.encoder2s[i].desc.pos;
4186
4187 eo_array_PushBack(arrayofjomos, &jomodes);
4188
4189 }
4190
4191
4193 //eOmc_4jomo_coupling_t *jomocoupling = &data_mc->jomocoupling;
4194
4195 //ret = copyjomocouplingInfo(jomocoupling);
4196
4197 // ok, everything is done
4198 ret = true;
4199
4200 } break;
4201
4202 case eomn_serv_MC_mc2pluspsc:
4203 {
4204 eOmn_serv_config_data_mc_mc2pluspsc_t *data_mc = &(mcconfig.ethservice.configuration.data.mc.mc2pluspsc);
4205
4206 // 1. ->psc
4207 eOmn_serv_config_data_as_psc_t *psc = &data_mc->psc;
4208
4209
4210 for(size_t i=0; i<mc_service.properties.psclocations.size(); i++)
4211 {
4212 psc->boardInfo.canloc[i].port=mc_service.properties.psclocations[i].port;
4213 psc->boardInfo.canloc[i].addr=mc_service.properties.psclocations[i].addr;
4214 psc->boardInfo.canloc[i].insideindex=mc_service.properties.psclocations[i].insideindex;
4215 }
4216
4217
4218 psc->version.firmware.major = mc_service.properties.canboards.at(0).firmware.major;
4219 psc->version.firmware.minor = mc_service.properties.canboards.at(0).firmware.minor;
4220 psc->version.firmware.build = mc_service.properties.canboards.at(0).firmware.build;
4221 psc->version.protocol.major = mc_service.properties.canboards.at(0).protocol.major;
4222 psc->version.protocol.minor = mc_service.properties.canboards.at(0).protocol.minor;
4223
4224 // 2. ->arrayofjomodescriptors
4225 EOarray *arrayofjomos = eo_array_New(4, sizeof(eOmc_jomo_descriptor_t), &data_mc->arrayofjomodescriptors);
4226 int numofjomos = mc_service.properties.numofjoints;
4227
4228 for(int i=0; i<numofjomos; i++)
4229 {
4230 eOmc_jomo_descriptor_t jomodes = {};
4231
4232 // 1. actuator is on pwm: we need the port
4233 jomodes.actuator.pwm.port = mc_service.properties.actuators[i].desc.pwm.port;
4234
4235 // 2. encoder1 is ...
4236 jomodes.encoder1.type = mc_service.properties.encoder1s[i].desc.type;
4237 jomodes.encoder1.port = mc_service.properties.encoder1s[i].desc.port;
4238 jomodes.encoder1.pos = mc_service.properties.encoder1s[i].desc.pos;
4239
4240 // 3. encoder2 is ...
4241 jomodes.encoder2.type = mc_service.properties.encoder2s[i].desc.type;
4242 jomodes.encoder2.port = mc_service.properties.encoder2s[i].desc.port;
4243 jomodes.encoder2.pos = mc_service.properties.encoder2s[i].desc.pos;
4244
4245 eo_array_PushBack(arrayofjomos, &jomodes);
4246
4247 }
4248
4249 // ok, everything is done
4250 ret = true;
4251
4252 } break;
4253
4254
4255 case eomn_serv_MC_mc4plusfaps:
4256 {
4257 eOmn_serv_config_data_mc_mc4plusfaps_t *data_mc = &(mcconfig.ethservice.configuration.data.mc.mc4plusfaps);
4258
4259 // The firmware still requires an embedded POS dependency. Initialize
4260 // it explicitly so the Ethernet resource can supply
4261 // the standalone POS configuration before sending the MC request.
4262 eOmn_serv_config_data_as_pos_t *pos = &data_mc->pos;
4263 *pos = {};
4264 for(auto &board : pos->config.boardconfig)
4265 {
4266 board.boardinfo.type = eobrd_cantype_none;
4267 }
4268
4269 // 2. ->arrayofjomodescriptors
4270 EOarray *arrayofjomos = eo_array_New(4, sizeof(eOmc_jomo_descriptor_t), &data_mc->arrayofjomodescriptors);
4271 size_t numofjomos = mc_service.properties.numofjoints;
4272
4273 for(size_t i=0; i<numofjomos; i++)
4274 {
4275 eOmc_jomo_descriptor_t jomodes = {};
4276
4277 // 1. actuator is on pwm: we need the port
4278 jomodes.actuator.pwm.port = mc_service.properties.actuators[i].desc.pwm.port;
4279
4280 // 2. encoder1 is ...
4281 jomodes.encoder1.type = mc_service.properties.encoder1s[i].desc.type;
4282 jomodes.encoder1.port = mc_service.properties.encoder1s[i].desc.port;
4283 jomodes.encoder1.pos = mc_service.properties.encoder1s[i].desc.pos;
4284
4285 // 3. encoder2 is ...
4286 jomodes.encoder2.type = mc_service.properties.encoder2s[i].desc.type;
4287 jomodes.encoder2.port = mc_service.properties.encoder2s[i].desc.port;
4288 jomodes.encoder2.pos = mc_service.properties.encoder2s[i].desc.pos;
4289
4290 eo_array_PushBack(arrayofjomos, &jomodes);
4291 }
4292
4293 // ok, everything is done
4294 ret = true;
4295
4296 } break;
4297
4298 case eomn_serv_MC_advfoc:
4299 {
4300 eOmn_serv_config_data_mc_advfoc_t *data_mc = &(mcconfig.ethservice.configuration.data.mc.advfoc);
4301
4302 ret = true;
4303
4304 // 1. ->eOmc_arrayof_4advjomodescriptors_t
4305 EOarray *arrayofjomos = eo_array_New(4, sizeof(eOmc_adv_jomo_descriptor_t), &data_mc->arrayof4advjomodescriptors);
4306 size_t numofjomos = mc_service.properties.numofjoints;
4307
4308 for(size_t i=0; i<numofjomos; i++)
4309 {
4310 eOmc_adv_jomo_descriptor_t jomodes = {};
4311
4312 // 1. actuator is on adv: we need the board, its location and its required versions of application and protocol
4313 if(mc_service.properties.actuators[i].type != eomc_act_advfoc)
4314 {
4315 yError() << "ServiceParser::parseService() unknown actuator value for eomn_serv_MC_advfoc mode. we need eomc_act_advfoc";
4316 ret = false;
4317 continue;
4318 }
4319
4320 // find the relevant brd inside the vector mc_service.properties.canboards that matches mc_service.properties.actuators[i].board
4321 // so far i just use the first one
4322
4323 // 1. actuator...
4324 jomodes.actuator.type = eomc_act_advfoc;
4325 jomodes.actuator.location = mc_service.properties.actuators[i].advdescr.location; //mc_service.properties.actuators[i].desc.gen.location;
4326 jomodes.actuator.board.type = mc_service.properties.actuators[i].advdescr.board.type;
4327 eObrd_firmwareversion_t fw {};
4328 eObrd_protocolversion_t pr {};
4329 // i must search for the fw and pr given the board inside ....
4330 bool ff {false};
4331 for(size_t i=0; i<mc_service.properties.canboards.size(); i++)
4332 {
4333 if(mc_service.properties.canboards[i].type == jomodes.actuator.board.type)
4334 {
4335 fw = mc_service.properties.canboards[i].firmware;
4336 pr = mc_service.properties.canboards[i].protocol;
4337 ff = true;
4338 break;
4339 }
4340 }
4341
4342 if(false == ff)
4343 {
4344 yError() << "ServiceParser::parseService() could not find the actuator board inside the mc_service.properties.canboards[] vector";
4345 return false;
4346 }
4347
4348 jomodes.actuator.board.firmware = fw;
4349 jomodes.actuator.board.protocol = pr;
4350
4351 // 2. encoder1 is ...
4352 jomodes.encoder1.type = mc_service.properties.encoder1s[i].desc.type;
4353 jomodes.encoder1.port = mc_service.properties.encoder1s[i].desc.port;
4354 jomodes.encoder1.pos = mc_service.properties.encoder1s[i].desc.pos;
4355
4356 // 3. encoder2 is ...
4357 jomodes.encoder2.type = mc_service.properties.encoder2s[i].desc.type;
4358 jomodes.encoder2.port = mc_service.properties.encoder2s[i].desc.port;
4359 jomodes.encoder2.pos = mc_service.properties.encoder2s[i].desc.pos;
4360
4361 eo_array_PushBack(arrayofjomos, &jomodes);
4362 }
4363
4364 // ok, everything is done
4365 ret = ret; // keep it as ret = ret ...
4366
4367 } break;
4368
4369 case eomn_serv_MC_generic:
4370 {
4371 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";
4372 mcconfig.ethservice.configuration.type = eomn_serv_MC_generic;
4373 ret = true;
4374 } break;
4375
4376 default:
4377 {
4378 yError() << "ServiceParser::parseService() unknown value in eOmn_serv_type_t field";
4379 ret = false;
4380 } break;
4381 }
4382
4383
4384 return ret;
4385}
4386
4387
4389{
4390 if(mc_service.properties.encoder1s[index].desc.pos == eomc_pos_atjoint)
4391 {
4392 return(&mc_service.properties.encoder1s[index]);
4393 }
4394 else if(mc_service.properties.encoder2s[index].desc.pos == eomc_pos_atjoint)
4395 {
4396 return(&mc_service.properties.encoder2s[index]);
4397 }
4398 else
4399 return NULL;
4400}
4401
4403{
4404 if(mc_service.properties.encoder1s[index].desc.pos == eomc_pos_atmotor)
4405 {
4406 return(&mc_service.properties.encoder1s[index]);
4407 }
4408 else if(mc_service.properties.encoder2s[index].desc.pos == eomc_pos_atmotor)
4409 {
4410 return(&mc_service.properties.encoder2s[index]);
4411 }
4412 else
4413 return NULL;
4414
4415}
4416
4417//static eOmn_serv_configuration_t s_serv_config_mc_v3_0B0;
4418/*static const eOmn_serv_configuration_t s_serv_config_mc_v3_0B0 =
4419{ // eb12 or 0B0
4420 .type = eomn_serv_MC_mc4plus,
4421 .filler = {0},
4422 .data.mc.mc4plus_based =
4423 {
4424 .boardtype4mccontroller = emscontroller_board_HEAD_neckpitch_neckroll,
4425 .filler = {0},
4426 .arrayofjomodescriptors =
4427 {
4428 .head =
4429 {
4430 .capacity = 4,
4431 .itemsize = sizeof(eOmn_serv_jomo_descriptor_t),
4432 .size = 2,
4433 .internalmem = 0
4434 },
4435 .data =
4436 {
4437 { // joint 0: neck-pitch
4438 .actuator.pwm =
4439 {
4440 .port = 0 // eomn_serv_mc_port_mc4plus_pwmP3 is hal_motor1=0 ?? verify!
4441 },
4442 .sensor =
4443 {
4444 .type = eomc_enc_aea,
4445 .port = 1, // eomn_serv_mc_port_mc4plus_spiP11 ?? verify!
4446 .pos = eomc_pos_atjoint
4447 },
4448 .encoder2 =
4449 {
4450 .type = eomc_enc_qenc,
4451 .port = 0, // eomn_serv_mc_port_mc4plus_qencP3 ?? verify!
4452 .pos = eomc_pos_atmotor
4453 }
4454 },
4455 { // joint 1: neck-roll
4456 .actuator.pwm =
4457 {
4458 .port = 2 // eomn_serv_mc_port_mc4plus_pwmP4 is hal_motor3=2 ?? verify!
4459 },
4460 .sensor =
4461 {
4462 .type = eomc_enc_aea,
4463 .port = 0, // eomn_serv_mc_port_mc4plus_spiP10 ?? verify!
4464 .pos = eomc_pos_atjoint
4465 },
4466 .encoder2 =
4467 {
4468 .type = eomc_enc_qenc,
4469 .port = 2, // eomn_serv_mc_port_mc4plus_qencP4 ?? verify!
4470 .pos = eomc_pos_atmotor
4471 }
4472 },
4473 { // joint 2
4474 .actuator.pwm =
4475 {
4476 .port = eomn_serv_mc_port_none
4477 },
4478 .sensor =
4479 {
4480 .type = eomn_serv_mc_sensor_none,
4481 .port = eomn_serv_mc_port_none,
4482 .pos = eomn_serv_mc_sensor_pos_none
4483 },
4484 .encoder2 =
4485 {
4486 .type = eomn_serv_mc_sensor_none,
4487 .port = eomn_serv_mc_port_none,
4488 .pos = eomn_serv_mc_sensor_pos_none
4489 }
4490 },
4491 { // joint 3
4492 .actuator.pwm =
4493 {
4494 .port = eomn_serv_mc_port_none
4495 },
4496 .sensor =
4497 {
4498 .type = eomn_serv_mc_sensor_none,
4499 .port = eomn_serv_mc_port_none,
4500 .pos = eomn_serv_mc_sensor_pos_none
4501 },
4502 .encoder2 =
4503 {
4504 .type = eomn_serv_mc_sensor_none,
4505 .port = eomn_serv_mc_port_none,
4506 .pos = eomn_serv_mc_sensor_pos_none
4507 }
4508 }
4509 }
4510 },
4511 .jomocoupling =
4512 {
4513 .joint2set =
4514 {
4515 eomc_jointSetNum_zero, eomc_jointSetNum_zero, eomc_jointSetNum_none, eomc_jointSetNum_none
4516 },
4517 .joint2motor =
4518 { // zero matrix: use matrix embedded in controller and seecetd by boardtype4mccontroller
4519 { 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) },
4520 { 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) },
4521 { 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) },
4522 { 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) }
4523 },
4524 .encoder2joint =
4525 { // identical matrix
4526 { 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) },
4527 { 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) },
4528 { 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) },
4529 { 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) }
4530 }
4531 }
4532 }
4533};
4534*/
4535//static eOmn_serv_configuration_t s_serv_config_mc_v3_0B9;
4536/*static const eOmn_serv_configuration_t s_serv_config_mc_v3_0B9=
4537{ // eb15 or 0B9
4538 .type = eomn_serv_MC_mc4plus,
4539 .filler = {0},
4540 .data.mc.mc4plus_based =
4541 {
4542 .boardtype4mccontroller = emscontroller_board_4jointsNotCoupled,
4543 .filler = {0},
4544 .arrayofjomodescriptors =
4545 {
4546 .head =
4547 {
4548 .capacity = 4,
4549 .itemsize = sizeof(eOmn_serv_jomo_descriptor_t),
4550 .size = 4,
4551 .internalmem = 0
4552 },
4553 .data =
4554 {
4555 { // joint 0: lip-left
4556 .actuator.pwm =
4557 {
4558 .port = 2 // eomn_serv_mc_port_mc4plus_pwmP4 is hal_motor2=1 ?? verify!
4559 },
4560 .sensor =
4561 {
4562 .type = eomc_enc_qenc,
4563 .port = 2, // eomn_serv_mc_port_mc4plus_qencP4 ?? verify!
4564 .pos = eomc_pos_atjoint
4565 },
4566 .encoder2 =
4567 {
4568 .type = eomc_enc_qenc,
4569 .port = 2, // eomn_serv_mc_port_mc4plus_qencP4 ?? verify!
4570 .pos = eomc_pos_atmotor
4571 }
4572 },
4573 { // joint 1: lip-high
4574 .actuator.pwm =
4575 {
4576 .port = 1 // eomn_serv_mc_port_mc4plus_pwmP2 is hal_motor2=1 ?? verify!
4577 },
4578 .sensor =
4579 {
4580 .type = eomc_enc_qenc,
4581 .port = 1, // eomn_serv_mc_port_mc4plus_qencP2 ?? verify!
4582 .pos = eomc_pos_atjoint
4583 },
4584 .encoder2 =
4585 {
4586 .type = eomc_enc_qenc,
4587 .port = 1, // eomn_serv_mc_port_mc4plus_qencP2 ?? verify!
4588 .pos = eomc_pos_atmotor
4589 }
4590 },
4591 { // joint 2: lip-right
4592 .actuator.pwm =
4593 {
4594 .port = 0 // eomn_serv_mc_port_mc4plus_pwmP3 is hal_motor4=3 ?? verify!
4595 },
4596 .sensor =
4597 {
4598 .type = eomc_enc_qenc,
4599 .port = 0, // eomn_serv_mc_port_mc4plus_qencP3 is hal_quad_enc1 = 0 ?? verify!
4600 .pos = eomc_pos_atjoint
4601 },
4602 .encoder2 =
4603 {
4604 .type = eomc_enc_qenc,
4605 .port = 0, // eomn_serv_mc_port_mc4plus_qencP3 is hal_quad_enc1 = 0 ?? verify!
4606 .pos = eomc_pos_atmotor
4607 }
4608 },
4609 { // joint 3: lip-bottom
4610 .actuator.pwm =
4611 {
4612 .port = 3 // eomn_serv_mc_port_mc4plus_pwmP5 is hal_motor3=2 ?? verify!
4613 },
4614 .sensor =
4615 {
4616 .type = eomc_enc_qenc,
4617 .port = 3, // eomn_serv_mc_port_mc4plus_qencP5 is hal_quad_enc4 = 3 ?? verify!
4618 .pos = eomc_pos_atjoint
4619 },
4620 .encoder2 =
4621 {
4622 .type = eomc_enc_qenc,
4623 .port = 3, // eomn_serv_mc_port_mc4plus_qencP5 is hal_quad_enc4 = 3 ?? verify!
4624 .pos = eomc_pos_atmotor
4625 }
4626 }
4627 }
4628 },
4629 .jomocoupling =
4630 {
4631 .joint2set =
4632 { // each joint is on a different set
4633 0, 1, 2, 3
4634 },
4635 .joint2motor =
4636 { // zero matrix: use matrix embedded in controller and seecetd by boardtype4mccontroller
4637 { 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) },
4638 { 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) },
4639 { 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) },
4640 { 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) }
4641 },
4642 .encoder2joint =
4643 { // identical matrix
4644 { 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) },
4645 { 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) },
4646 { 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) },
4647 { 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) }
4648 }
4649 }
4650 }
4651};*/
4652
4653
4654
4655
4656// static eOmn_serv_configuration_t s_serv_config_mc_v3_0B1 = {};
4657/*static const eOmn_serv_configuration_t s_serv_config_mc_v3_0B1 =
4658{ // eb13 or 0B1
4659 .type = eomn_serv_MC_mc4plus,
4660 .filler = {0},
4661 .data.mc.mc4plus_based =
4662 {
4663 .boardtype4mccontroller = emscontroller_board_HEAD_neckyaw_eyes,
4664 .filler = {0},
4665 .arrayofjomodescriptors =
4666 {
4667 .head =
4668 {
4669 .capacity = 4,
4670 .itemsize = sizeof(eOmn_serv_jomo_descriptor_t),
4671 .size = 4,
4672 .internalmem = 0
4673 },
4674 .data =
4675 {
4676 { // joint 0: neck-yaw
4677 .actuator.pwm =
4678 {
4679 .port = 0 // eomn_serv_mc_port_mc4plus_pwmP3 is hal_motor1=0 ?? verify!
4680 },
4681 .sensor =
4682 {
4683 .type = eomc_enc_aea,
4684 .port = 1, // eomn_serv_mc_port_mc4plus_spiP11 ?? verify!
4685 .pos = eomc_pos_atjoint
4686 },
4687 .encoder2 =
4688 {
4689 .type = eomc_enc_qenc,
4690 .port = 0, // eomn_serv_mc_port_mc4plus_qencP3 ?? verify!
4691 .pos = eomc_pos_atmotor
4692 }
4693 },
4694 { // joint 1: eyes-tilt
4695 .actuator.pwm =
4696 {
4697 .port = 1 // eomn_serv_mc_port_mc4plus_pwmP2 is hal_motor2=1 ?? verify!
4698 },
4699 .sensor =
4700 {
4701 .type = eomc_enc_aea,
4702 .port = 0, // eomn_serv_mc_port_mc4plus_spiP10 ?? verify!
4703 .pos = eomc_pos_atjoint
4704 },
4705 .encoder2 =
4706 {
4707 .type = eomc_enc_qenc,
4708 .port = 1, // eomn_serv_mc_port_mc4plus_qencP2 ?? verify!
4709 .pos = eomc_pos_atmotor
4710 }
4711 },
4712 { // joint 2: right-eye
4713 .actuator.pwm =
4714 {
4715 .port = 3 // eomn_serv_mc_port_mc4plus_pwmP5 is hal_motor4=3 ?? verify!
4716 },
4717 .sensor =
4718 {
4719 .type = eomc_enc_qenc,
4720 .port = 3, // eomn_serv_mc_port_mc4plus_qencP5 is hal_quad_enc4 = 3 ?? verify!
4721 .pos = eomc_pos_atjoint
4722 },
4723 .encoder2 =
4724 {
4725 .type = eomc_enc_qenc,
4726 .port = 3, // eomn_serv_mc_port_mc4plus_qencP5 is hal_quad_enc4 = 3 ?? verify!
4727 .pos = eomc_pos_atmotor
4728 }
4729 },
4730 { // joint 3: left-eye
4731 .actuator.pwm =
4732 {
4733 .port = 2 // eomn_serv_mc_port_mc4plus_pwmP4 is hal_motor3=2 ?? verify!
4734 },
4735 .sensor =
4736 {
4737 .type = eomc_enc_qenc,
4738 .port = 2, // eomn_serv_mc_port_mc4plus_qencP4 is hal_quad_enc3 = 2 ?? verify!
4739 .pos = eomc_pos_atjoint
4740 },
4741 .encoder2 =
4742 {
4743 .type = eomc_enc_qenc,
4744 .port = 2, // eomn_serv_mc_port_mc4plus_qencP4 is hal_quad_enc3 = 2 ?? verify!
4745 .pos = eomc_pos_atmotor
4746 }
4747 }
4748 }
4749 },
4750 .jomocoupling =
4751 {
4752 .joint2set =
4753 { //joint 2 and 3 are coupled
4754 eomc_jointSetNum_zero, eomc_jointSetNum_one, eomc_jointSetNum_two, eomc_jointSetNum_two
4755 },
4756
4757 //inverted matrix: joint to motor
4758 // |m0| | 1 0 0 0 | |j0|
4759 // |m1| = | 0 1 0 0 | * |j1|
4760 // |m2| | 0 0 1 -1 | |j2|
4761 // |m3| | 0 0 1 1 | |j2|
4762
4763
4764 .joint2motor =
4765 { // zero matrix: use matrix embedded in controller and seecetd by boardtype4mccontroller
4766 { 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) },
4767 { 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) },
4768 { 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) },
4769 { 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) }
4770 },
4771 .encoder2joint =
4772 { // identical matrix
4773 { 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) },
4774 { 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) },
4775 { 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) },
4776 { 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) }
4777 }
4778 }
4779 }
4780};
4781*/
4782//static eOmn_serv_configuration_t s_serv_config_mc_v3_0B7;
4783/*static const eOmn_serv_configuration_t s_serv_config_mc_v3_0B7 =
4784{ // eb14 or 0B7f
4785 .type = eomn_serv_MC_mc4plus,
4786 .filler = {0},
4787 .data.mc.mc4plus_based =
4788 {
4789 .boardtype4mccontroller = emscontroller_board_FACE_eyelids_jaw,
4790 .filler = {0},
4791 .arrayofjomodescriptors =
4792 {
4793 .head =
4794 {
4795 .capacity = 4,
4796 .itemsize = sizeof(eOmn_serv_jomo_descriptor_t),
4797 .size = 2,
4798 .internalmem = 0
4799 },
4800 .data =
4801 {
4802 { // joint 0: jaw
4803 .actuator.pwm =
4804 {
4805 ret = ret; .port = 0 // eomn_serv_mc_port_mc4plus_pwmP3 is hal_motor1=0 ?? verify!
4806 },
4807 .sensor =
4808 {
4809 .type = eomc_enc_aea,
4810 .port = 1, // eomn_serv_mc_port_mc4plus_spiP11 ?? verify!
4811 .pos = eomc_pos_atjoint
4812 },
4813 .encoder2 =
4814 {
4815 .type = eomn_serv_mc_sensor_none,
4816 .port = eomn_serv_mc_port_none,
4817 .pos = eomn_serv_mc_sensor_pos_none
4818 }
4819 },
4820 { // joint 1: eyelids
4821 .actuator.pwm =
4822 {
4823 .port = 1 // eomn_serv_mc_port_mc4plus_pwmP2 is hal_motor2=1 ?? verify!
4824 },
4825 .sensor =
4826 {
4827 .type = eomc_enc_aea,
4828 .port = 0, // eomn_serv_mc_port_mc4plus_spiP10 ?? verify!
4829 .pos = eomc_pos_atjoint
4830 },
4831 .encoder2 =
4832 {
4833 .type = eomc_enc_qenc,
4834 .port = 1, // eomn_serv_mc_port_mc4plus_qencP2 ?? verify!
4835 .pos = eomc_pos_atmotor
4836 }
4837 },
4838 { // joint 2
4839 .actuator.pwm =
4840 {
4841 .port = eomn_serv_mc_port_none
4842 },
4843 .sensor =
4844 {
4845 .type = eomn_serv_mc_sensor_none,
4846 .port = eomn_serv_mc_port_none,
4847 .pos = eomn_serv_mc_sensor_pos_none
4848 },
4849 .encoder2 =
4850 {
4851 .type = eomn_serv_mc_sensor_none,
4852 .port = eomn_serv_mc_port_none,
4853 .pos = eomn_serv_mc_sensor_pos_none
4854 }
4855 },
4856 { // joint 3
4857 .actuator.pwm =
4858 {
4859 .port = eomn_serv_mc_port_none
4860 },
4861 .sensor =
4862 {
4863 .type = eomn_serv_mc_sensor_none,
4864 .port = eomn_serv_mc_port_none,
4865 .pos = eomn_serv_mc_sensor_pos_none
4866 },
4867 .encoder2 =
4868 {
4869 .type = eomn_serv_mc_sensor_none,
4870 .port = eomn_serv_mc_port_none,
4871 .pos = eomn_serv_mc_sensor_pos_none
4872 }
4873 }
4874 }
4875 },
4876 .jomocoupling =
4877 {
4878 .joint2set =
4879 { // each joint is on a different set
4880 eomc_jointSetNum_zero, eomc_jointSetNum_one, eomc_jointSetNum_none, eomc_jointSetNum_none
4881 },
4882 .joint2motor =
4883 { // zero matrix: use matrix embedded in controller and seecetd by boardtype4mccontroller
4884 { 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) },
4885 { 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) },
4886 { 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) },
4887 { 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) }
4888 },
4889 .encoder2joint =
4890 { // identical matrix
4891 { 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) },
4892 { 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) },
4893 { 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) },
4894 { 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) }
4895 }
4896 }
4897 }
4898};
4899*/
4900
4901/*eOmn_serv_configuration_t* arrayConf[4] =
4902{
4903 &s_serv_config_mc_v3_0B9, // board ip.1, 0b9, face 4 lips
4904 &s_serv_config_mc_v3_0B7, // board ip.2, 0b7, face eyelids + jaw
4905 &s_serv_config_mc_v3_0B1, // board ip.3, 0b1, head neck yaw + 3 eyes
4906 &s_serv_config_mc_v3_0B0
4907}*/
4908
4909static eOmn_serv_configuration_t s_serv_config_mc_v3_0B1 = {};
4910
4911bool ServiceParser::parseService2(Searchable &config, servConfigMC_t &mcconfig)
4912{
4913 eOmc_arrayof_4jomodescriptors_t *ja = &s_serv_config_mc_v3_0B1.data.mc.mc4plus_based.arrayofjomodescriptors;
4914 eOmc_4jomo_coupling_t *jc = &s_serv_config_mc_v3_0B1.data.mc.mc4plus_based.jomocoupling;
4915
4916
4917 eOq17_14_t m1[][4] =
4918 { // zero matrix: use matrix embedded in controller and seecetd by boardtype4mccontroller
4919 { 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) },
4920 { 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) },
4921 { 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) },
4922 { 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) }
4923 };
4924
4925 eOq17_14_t m2[][4]=
4926 { // identical matrix
4927 { 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) },
4928 { 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) },
4929 { 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) },
4930 { 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) }
4931 };
4932
4933
4934 //s_serv_config_mc_v3_0B1.type = eomn_serv_MC_mc4plus;
4935 //s_serv_config_mc_v3_0B1.filler = {0, 0, 0};
4936
4937 //s_serv_config_mc_v3_0B1.data.mc.mc4plus_based.boardtype4mccontroller = 6; //emscontroller_board_HEAD_neckyaw_eyes;
4938 //s_serv_config_mc_v3_0B1.data.mc.mc4plus_based.filler = {0};
4939
4940 ja->head.capacity = 4;
4941 ja->head.itemsize = sizeof(eOmc_jomo_descriptor_t);
4942 ja->head.size = 4;
4943 ja->head.internalmem = 0;
4944
4945 ja->data[0].actuator.pwm.port = 0 ; // eomn_serv_mc_port_mc4plus_pwmP3 is hal_motor1=0 ?? verify!
4946 ja->data[0].encoder1.type = eomc_enc_aea;
4947 ja->data[0].encoder1.port = 1; // eomn_serv_mc_port_mc4plus_spiP11 ?? verify!
4948 ja->data[0].encoder1.pos = eomc_pos_atjoint;
4949
4950 ja->data[0].encoder2.type = eomc_enc_qenc;
4951 ja->data[0].encoder2.port = 0; // eomn_serv_mc_port_mc4plus_qencP3 ?? verify!
4952 ja->data[0].encoder2.pos = eomc_pos_atmotor;
4953
4954 ja->data[1].actuator.pwm.port = 1; // eomn_serv_mc_port_mc4plus_pwmP2 is hal_motor2=1 ?? verify!
4955 ja->data[1].encoder1.type = eomc_enc_aea;
4956 ja->data[1].encoder1.port = 0; // eomn_serv_mc_port_mc4plus_spiP10 ?? verify!
4957 ja->data[1].encoder1.pos = eomc_pos_atjoint;
4958 ja->data[1].encoder2.type = eomc_enc_qenc;
4959 ja->data[1].encoder2.port = 1; // eomn_serv_mc_port_mc4plus_qencP2 ?? verify!
4960 ja->data[1].encoder2.pos = eomc_pos_atmotor;
4961
4962 ja->data[2].actuator.pwm.port = 3;
4963 ja->data[2].encoder1.type = eomc_enc_qenc;
4964 ja->data[2].encoder1.port = 3; // eomn_serv_mc_port_mc4plus_qencP5 is hal_quad_enc4 = 3 ?? verify!
4965 ja->data[2].encoder1.pos = eomc_pos_atjoint;
4966 ja->data[2].encoder2.type = eomc_enc_qenc,
4967 ja->data[2].encoder2.port = 3, // eomn_serv_mc_port_mc4plus_qencP5 is hal_quad_enc4 = 3 ?? verify!
4968 ja->data[2].encoder2.pos = eomc_pos_atmotor;
4969
4970 ja->data[3].actuator.pwm.port = 2;
4971
4972 ja->data[3].encoder1.type = eomc_enc_qenc;
4973 ja->data[3].encoder1.port = 2; // eomn_serv_mc_port_mc4plus_qencP4 is hal_quad_enc3 = 2 ?? verify!
4974 ja->data[3].encoder1.pos = eomc_pos_atjoint;
4975
4976
4977 ja->data[3].encoder2.type = eomc_enc_qenc;
4978 ja->data[3].encoder2.port = 2; // eomn_serv_mc_port_mc4plus_qencP4 is hal_quad_enc3 = 2 ?? verify!
4979 ja->data[3].encoder2.pos = eomc_pos_atmotor;
4980
4981
4982 jc->joint2set[0] = eomc_jointSetNum_zero;
4983 jc->joint2set[1] = eomc_jointSetNum_one;
4984 jc->joint2set[2] = eomc_jointSetNum_two;
4985 jc->joint2set[3] = eomc_jointSetNum_two;
4986
4987
4988/*
4989 jc->joint2motor =
4990 { // zero matrix: use matrix embedded in controller and seecetd by boardtype4mccontroller
4991 { 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) },
4992 { 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) },
4993 { 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) },
4994 { 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) }
4995 };
4996 jc->encoder2joint =
4997 { // identical matrix
4998 { 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) },
4999 { 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) },
5000 { 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) },
5001 { 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) }
5002 };
5003
5004
5005
5006*/
5007
5008 memcpy(&jc->joint2motor, &m1, sizeof(m1));
5009 memcpy(&jc->encoder2joint, &m2, sizeof(m2));
5010
5011 yError() << "print first m ";
5012 for(int r=0; r<4; r++)
5013 {
5014 for(int c=0; c<4; c++)
5015 {
5016 yError() << "r=" <<r << "c=" << c << "val=" << m1[r][c];
5017 }
5018 }
5019
5020 yError() << "print second m ";
5021 for(int r=0; r<4; r++)
5022 {
5023 for(int c=0; c<4; c++)
5024 {
5025 yError() << "r=" <<r << "c=" << c << "val=" << m2[r][c];
5026 }
5027 }
5028
5029
5030
5031 if(mcconfig.id > 3)
5032 {
5033 yError() << " id scheda sbagliato " << mcconfig.id;
5034 return false;
5035 }
5036
5037
5038 memcpy(&mcconfig.ethservice, &s_serv_config_mc_v3_0B1, sizeof(eOmn_serv_configuration_t));
5039 return true;
5040}
5041
5042#endif // #if defined(SERVICE_PARSER_USE_MC)
5043
5044// 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.
static eOmn_serv_configuration_t s_serv_config_mc_v3_0B1
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