11#include <yarp/os/Bottle.h>
19#include <yarp/os/LogStream.h>
23#include "EoProtocol.h"
24#include "EoProtocolMN.h"
25#include "EoProtocolMC.h"
26#include "EoProtocolAS.h"
32using namespace yarp::os;
40 _njoints = numofjoints;
41 _boardname = boardname;
43 _positionControlLaw.resize(0);
44 _velocityControlLaw.resize(0);
45 _mixedControlLaw.resize(0);
48 _torqueControlLaw.resize(0);
49 _currentControlLaw.resize(0);
50 _speedControlLaw.resize(0);
52 _kbemf=allocAndCheck<double>(_njoints);
53 _ktau=allocAndCheck<double>(_njoints);
54 _filterType=allocAndCheck<int>(_njoints);
55 _viscousPos=allocAndCheck<double>(_njoints);
56 _viscousNeg=allocAndCheck<double>(_njoints);
57 _coulombPos=allocAndCheck<double>(_njoints);
58 _coulombNeg=allocAndCheck<double>(_njoints);
59 _velocityThres=allocAndCheck<double>(_njoints);
61 minjerkAlgoMap.clear();
63 torqueAlgoMap.clear();
68 checkAndDestroy(_kbemf);
69 checkAndDestroy(_ktau);
70 checkAndDestroy(_filterType);
71 checkAndDestroy(_viscousPos);
72 checkAndDestroy(_viscousNeg);
73 checkAndDestroy(_coulombPos);
74 checkAndDestroy(_coulombNeg);
75 checkAndDestroy(_velocityThres);
91 if(!parseControlsGroup(config))
96 if(!parseSelectedCurrentPid(config, lowLevPidisMandatory, cpids))
101 if(!parseSelectedSpeedPid(config, lowLevPidisMandatory, spids))
106 if(!parseSelectedPositionControl(config))
111 if(!parseSelectedVelocityControl(config))
116 if(!parseSelectedMixedControl(config))
131 if(!parseSelectedTorqueControl(config))
136 if(!getCorrectPidForEachJoint(ppids, tpids))
143#define LOAD_STRINGS(dest, source) for (unsigned int i=1; i<source.size(); ++i) dest.push_back(source.get(i).asString())
145bool Parser::parseControlsGroup(yarp::os::Searchable &config)
149 Bottle controlsGroup = config.findGroup(
"CONTROLS",
"Configuration of used control laws ");
150 if(controlsGroup.isNull())
152 yError() <<
"embObjMC BOARD " << _boardname <<
" no CONTROLS group found in config file, returning";
156 if (!extractGroup(controlsGroup, xtmp,
"positionControl",
"Position Control ", _njoints))
160 if (!extractGroup(controlsGroup, xtmp,
"velocityControl",
"Velocity Control ", _njoints))
164 if (!extractGroup(controlsGroup, xtmp,
"mixedControl",
"Mixed Control ", _njoints))
176 if (!extractGroup(controlsGroup, xtmp,
"torqueControl",
"Torque Control ", _njoints))
180 if (!extractGroup(controlsGroup, xtmp,
"currentPid",
"Current Pid ", _njoints))
184 if (!extractGroup(controlsGroup, xtmp,
"speedPid",
"Speed Pid ", _njoints))
193bool Parser::parseSelectedCurrentPid(yarp::os::Searchable &config,
bool pidisMandatory,
PidInfo *pids)
196 for (
int i = 0; i<_njoints; i++)
198 if (_currentControlLaw[i] ==
"none")
202 yError() <<
"embObjMC BOARD " << _boardname <<
"CurrentPid is mandatory. It should be different from none ";
209 Bottle botControlLaw = config.findGroup(_currentControlLaw[i]);
210 if (botControlLaw.isNull())
212 yError() <<
"embObjMC BOARD " << _boardname <<
"Missing " << i <<
" current control law " << _currentControlLaw[i].c_str();
217 Value &valControlLaw = botControlLaw.find(
"controlLaw");
218 if ((valControlLaw.isNull()) || (!valControlLaw.isString()))
220 yError() <<
"embObjMC BOARD " << _boardname <<
"Unable read " << i <<
" control law parameter for " << _currentControlLaw[i].c_str() <<
". Quitting.";
224 string strControlLaw = valControlLaw.toString();
225 if (strControlLaw !=
string(
"low_lev_current"))
227 yError() <<
"embObjMC BOARD " << _boardname <<
"Unable to use " << i <<
" control law " << strControlLaw <<
" for current pid. Quitting.";
231 yarp::dev::PidFeedbackUnitsEnum fbk_unitstype;
232 yarp::dev::PidOutputUnitsEnum out_unitstype;
233 if (!parsePidUnitsType(botControlLaw, fbk_unitstype, out_unitstype))
236 yarp::dev::Pid *mycpids =
new yarp::dev::Pid[_njoints];
238 if (!parsePidsGroup2FOC(botControlLaw, mycpids))
246 pids[i].
out_type = eomc_ctrl_out_type_cur;
250 pids[i].
pid = mycpids[i];
256 return checkJointTypes(pids,
"CURRENT");
259bool Parser::parseSelectedSpeedPid(yarp::os::Searchable &config,
bool pidisMandatory,
PidInfo *pids)
262 for (
int i = 0; i<_njoints; i++)
264 if (_speedControlLaw[i] ==
"none")
268 yError() <<
"embObjMC BOARD " << _boardname <<
"SpeedPid is mandatory. It should be different from none ";
275 Bottle botControlLaw = config.findGroup(_speedControlLaw[i]);
276 if (botControlLaw.isNull())
278 yError() <<
"embObjMC BOARD " << _boardname <<
"Missing " << i <<
" control law " << _speedControlLaw[i].c_str();
283 Value &valControlLaw = botControlLaw.find(
"controlLaw");
284 if ((valControlLaw.isNull()) || (!valControlLaw.isString()))
286 yError() <<
"embObjMC BOARD " << _boardname <<
"Unable read " << i <<
" control law parameter for " << _speedControlLaw[i].c_str() <<
". Quitting.";
290 string strControlLaw= valControlLaw.toString();
291 if (strControlLaw !=
string(
"low_lev_speed"))
293 yError() <<
"embObjMC BOARD " << _boardname <<
"Unable to use " << i <<
" control law " << strControlLaw <<
" for speed pid. Quitting.";
297 yarp::dev::PidFeedbackUnitsEnum fbk_unitstype;
298 yarp::dev::PidOutputUnitsEnum out_unitstype;
299 if (!parsePidUnitsType(botControlLaw, fbk_unitstype, out_unitstype))
302 yarp::dev::Pid *mycpids =
new yarp::dev::Pid[_njoints];
304 if (!parsePidsGroup2FOC(botControlLaw, mycpids))
315 pids[i].
pid = mycpids[i];
321 return checkJointTypes(pids,
"SPEED");
324bool Parser::parseSelectedPositionControl(yarp::os::Searchable &config)
326 for(
int i=0; i<_njoints; i++)
329 Bottle botControlLaw = config.findGroup(_positionControlLaw[i]);
330 if (botControlLaw.isNull())
332 yError() <<
"embObjMC BOARD " << _boardname <<
"Missing " << _positionControlLaw[i].c_str();
337 Value &valControlLaw= botControlLaw.find(
"controlLaw");
339 if ((valControlLaw.isNull()) || (!valControlLaw.isString()))
341 yError() <<
"embObjMC BOARD " << _boardname <<
"Unable read controlLaw parameter for " << _positionControlLaw[i].c_str() <<
". Quitting.";
346 string strControlLaw = valControlLaw.toString();
347 if (strControlLaw !=
"minjerk")
349 yError() <<
"embObjMC BOARD " << _boardname <<
"Unknown control law for " << _positionControlLaw[i].c_str() <<
". Quitting.";
353 Value &valOutputType= botControlLaw.find(
"outputType");
354 if( (valOutputType.isNull()) || (!valOutputType.isString()) )
356 yError() <<
"embObjMC BOARD " << _boardname <<
"Unable read outputType parameter for " << _positionControlLaw[i].c_str() <<
". Quitting.";
360 string strOutputType= valOutputType.toString();
361 if (strOutputType ==
string(
"pwm"))
363 if (!parsePid_minJerk_outPwm(botControlLaw, _positionControlLaw[i]))
365 yError() <<
"embObjMC BOARD " << _boardname <<
"format error in " << _positionControlLaw[i];
369 else if (strOutputType ==
string(
"velocity"))
371 if (!parsePid_minJerk_outVel(botControlLaw, _positionControlLaw[i]))
373 yError() <<
"embObjMC BOARD " << _boardname <<
"format error in " << _positionControlLaw[i];
377 else if (strOutputType ==
string(
"current"))
379 if (!parsePid_minJerk_outCur(botControlLaw, _positionControlLaw[i]))
381 yError() <<
"embObjMC BOARD " << _boardname <<
"format error in " << _positionControlLaw[i];
387 yError() <<
"embObjMC BOARD " << _boardname <<
"Unable to use output type " << strOutputType <<
" for position control. Quitting.";
396bool Parser::parseSelectedVelocityControl(yarp::os::Searchable &config)
398 for(
int i=0; i<_njoints; i++)
400 if(_velocityControlLaw[i] ==
"none")
406 Bottle botControlLaw = config.findGroup(_velocityControlLaw[i]);
407 if (botControlLaw.isNull())
409 yError() <<
"embObjMC BOARD " << _boardname <<
"Missing " << _velocityControlLaw[i].c_str();
414 Value &valControlLaw=botControlLaw.find(
"controlLaw");
416 if ((valControlLaw.isNull()) || (!valControlLaw.isString()))
418 yError() <<
"embObjMC BOARD " << _boardname <<
"Unable read controlLaw parameter for " << _velocityControlLaw[i].c_str() <<
". Quitting.";
423 string strControlLaw = valControlLaw.toString();
424 if (strControlLaw !=
"minjerk")
426 yError() <<
"embObjMC BOARD " << _boardname <<
"Unknown control law for " << _velocityControlLaw[i].c_str() <<
". Quitting.";
430 Value &valOutputType = botControlLaw.find(
"outputType");
431 if ((valOutputType.isNull()) || (!valOutputType.isString()))
433 yError() <<
"embObjMC BOARD " << _boardname <<
"Unable read control law parameter for " << _velocityControlLaw[i].c_str() <<
". Quitting.";
437 string strOutputType = valOutputType.toString();
438 if (strOutputType ==
string(
"pwm"))
440 if (!parsePid_minJerk_outPwm(botControlLaw, _velocityControlLaw[i]))
442 yError() <<
"embObjMC BOARD " << _boardname <<
"format error in "<< _velocityControlLaw[i];
446 else if (strOutputType ==
string(
"velocity"))
448 if (!parsePid_minJerk_outVel(botControlLaw, _velocityControlLaw[i]))
450 yError() <<
"embObjMC BOARD " << _boardname <<
"format error in " << _velocityControlLaw[i];
454 else if (strOutputType ==
string(
"current"))
456 if (!parsePid_minJerk_outCur(botControlLaw, _velocityControlLaw[i]))
458 yError() <<
"embObjMC BOARD " << _boardname <<
"format error in " << _velocityControlLaw[i];
464 yError() <<
"embObjMC BOARD " << _boardname <<
"Unable to use output type " << strOutputType <<
" for velocity control. Quitting.";
473bool Parser::parseSelectedMixedControl(yarp::os::Searchable &config)
475 for (
int i = 0; i<_njoints; i++)
477 if(_mixedControlLaw[i] ==
"none")
483 Bottle botControlLaw = config.findGroup(_mixedControlLaw[i]);
484 if (botControlLaw.isNull())
486 yError() <<
"embObjMC BOARD " << _boardname <<
"Missing " << _mixedControlLaw[i].c_str();
491 Value &valControlLaw = botControlLaw.find(
"controlLaw");
493 if ((valControlLaw.isNull()) || (!valControlLaw.isString()))
495 yError() <<
"embObjMC BOARD " << _boardname <<
"Unable read controlLaw parameter for " << _mixedControlLaw[i].c_str() <<
". Quitting.";
500 string strControlLaw = valControlLaw.toString();
501 if (strControlLaw !=
"minjerk")
503 yError() <<
"embObjMC BOARD " << _boardname <<
"Unknown control law for " << _mixedControlLaw[i].c_str() <<
". Quitting.";
508 Value &valOutputType = botControlLaw.find(
"outputType");
509 if ((valOutputType.isNull()) || (!valOutputType.isString()))
511 yError() <<
"embObjMC BOARD " << _boardname <<
"Unable read control law parameter for " << _mixedControlLaw[i].c_str() <<
". Quitting.";
515 string strOutputType = valOutputType.toString();
516 if (strOutputType ==
string(
"pwm"))
518 if (!parsePid_minJerk_outPwm(botControlLaw, _mixedControlLaw[i]))
520 yError() <<
"embObjMC BOARD " << _boardname <<
"format error in " << _velocityControlLaw[i];
524 else if (strOutputType ==
string(
"velocity"))
526 if (!parsePid_minJerk_outVel(botControlLaw, _mixedControlLaw[i]))
528 yError() <<
"embObjMC BOARD " << _boardname <<
"format error in " << _velocityControlLaw[i];
532 else if (strOutputType ==
string(
"current"))
534 if (!parsePid_minJerk_outCur(botControlLaw, _mixedControlLaw[i]))
536 yError() <<
"embObjMC BOARD " << _boardname <<
"format error in " << _velocityControlLaw[i];
542 yError() <<
"embObjMC BOARD " << _boardname <<
"Unable to use output type " << strOutputType <<
" for mixed control. Quitting.";
551bool Parser::parseSelectedPosDirectControl(yarp::os::Searchable &config)
553 for (
int i = 0; i<_njoints; i++)
556 Bottle botControlLaw = config.findGroup(_posDirectControlLaw[i]);
557 if (botControlLaw.isNull())
559 yError() <<
"embObjMC BOARD " << _boardname <<
"Missing " << _posDirectControlLaw[i].c_str();
564 Value &valControlLaw= botControlLaw.find(
"controlLaw");
566 if ((valControlLaw.isNull()) || (!valControlLaw.isString()))
568 yError() <<
"embObjMC BOARD " << _boardname <<
"Unable read controlLaw parameter for " << _posDirectControlLaw[i].c_str() <<
". Quitting.";
573 string strControlLaw = valControlLaw.toString();
574 if (strControlLaw !=
"direct")
576 yError() <<
"embObjMC BOARD " << _boardname <<
"Unknown control law for " << _posDirectControlLaw[i].c_str() <<
". Quitting.";
580 Value &valOutputType = botControlLaw.find(
"outputType");
581 if ((valOutputType.isNull()) || (!valOutputType.isString()))
583 yError() <<
"embObjMC BOARD " << _boardname <<
"Unable read outputType parameter for " << _posDirectControlLaw[i].c_str() <<
". Quitting.";
587 string strOutputType = valOutputType.toString();
588 if (strOutputType ==
string(
"pwm"))
590 if (!parsePid_direct_outPwm(botControlLaw, _posDirectControlLaw[i]))
592 yError() <<
"embObjMC BOARD " << _boardname <<
"format error in " << _posDirectControlLaw[i];
596 else if (strOutputType ==
string(
"velocity"))
598 if (!parsePid_direct_outVel(botControlLaw, _posDirectControlLaw[i]))
600 yError() <<
"embObjMC BOARD " << _boardname <<
"format error in " << _posDirectControlLaw[i];
604 else if (strOutputType ==
string(
"current"))
606 if (!parsePid_direct_outCur(botControlLaw, _posDirectControlLaw[i]))
608 yError() <<
"embObjMC BOARD " << _boardname <<
"format error in " << _posDirectControlLaw[i];
614 yError() <<
"embObjMC BOARD " << _boardname <<
"Unable to use output type " << strOutputType <<
" for direct position control. Quitting.";
623bool Parser::parseSelectedVelDirectControl(yarp::os::Searchable &config)
625 for (
int i = 0; i<_njoints; i++)
628 Bottle botControlLaw = config.findGroup(_velDirectControlLaw[i]);
629 if (botControlLaw.isNull())
631 yError() <<
"embObjMC BOARD " << _boardname <<
"Missing " << _velDirectControlLaw[i].c_str();
636 Value &valControlLaw = botControlLaw.find(
"controlLaw");
638 if ((valControlLaw.isNull()) || (!valControlLaw.isString()))
640 yError() <<
"embObjMC BOARD " << _boardname <<
"Unable read controlLaw parameter for " << _velDirectControlLaw[i].c_str() <<
". Quitting.";
645 string strControlLaw = valControlLaw.toString();
646 if (strControlLaw !=
"direct")
648 yError() <<
"embObjMC BOARD " << _boardname <<
"Unknown control law for " << _velDirectControlLaw[i].c_str() <<
". Quitting.";
652 Value &valOutputType = botControlLaw.find(
"outputType");
653 if ((valOutputType.isNull()) || (!valOutputType.isString()))
655 yError() <<
"embObjMC BOARD " << _boardname <<
"Unable read outputType parameter for " << _velDirectControlLaw[i].c_str() <<
". Quitting.";
659 string strOutputType = valOutputType.toString();
660 if (strOutputType ==
string(
"pwm"))
662 if (!parsePid_direct_outPwm(botControlLaw, _velDirectControlLaw[i]))
664 yError() <<
"embObjMC BOARD " << _boardname <<
"format error in " << _velDirectControlLaw[i];
668 else if (strOutputType ==
string(
"velocity"))
670 if (!parsePid_direct_outVel(botControlLaw, _velDirectControlLaw[i]))
672 yError() <<
"embObjMC BOARD " << _boardname <<
"format error in " << _velDirectControlLaw[i];
676 else if (strOutputType ==
string(
"current"))
678 if (!parsePid_direct_outCur(botControlLaw, _velDirectControlLaw[i]))
680 yError() <<
"embObjMC BOARD " << _boardname <<
"format error in " << _velDirectControlLaw[i];
686 yError() <<
"embObjMC BOARD " << _boardname <<
"Unable to use output type " << strOutputType <<
" for direct velocity control. Quitting.";
696bool Parser::parseSelectedTorqueControl(yarp::os::Searchable &config)
698 for(
int i=0; i<_njoints; i++)
700 if(_torqueControlLaw[i] ==
"none")
705 Bottle botControlLaw = config.findGroup(_torqueControlLaw[i]);
706 if (botControlLaw.isNull())
708 yError() <<
"embObjMC BOARD " << _boardname <<
"Missing " << _torqueControlLaw[i].c_str();
713 Value &valControlLaw= botControlLaw.find(
"controlLaw");
714 if( (valControlLaw.isNull()) || (!valControlLaw.isString()) )
716 yError() <<
"embObjMC BOARD " << _boardname <<
"Unable read control law parameter for " << _torqueControlLaw[i].c_str() <<
". Quitting.";
720 string strControlLaw = valControlLaw.toString();
721 if (strControlLaw !=
"torque")
723 yError() <<
"embObjMC BOARD " << _boardname <<
"Unknown control law for " << _torqueControlLaw[i].c_str() <<
". Quitting.";
727 Value &valOutputType = botControlLaw.find(
"outputType");
728 if ((valOutputType.isNull()) || (!valOutputType.isString()))
730 yError() <<
"embObjMC BOARD " << _boardname <<
"Unable read outputType parameter for " << _torqueControlLaw[i].c_str() <<
". Quitting.";
734 string strOutputType = valOutputType.toString();
735 if (strOutputType ==
string(
"pwm"))
737 if (!parsePid_torque_outPwm(botControlLaw, _torqueControlLaw[i]))
739 yError() <<
"embObjMC BOARD " << _boardname <<
"format error in " << _torqueControlLaw[i];
743 else if (strOutputType ==
string(
"velocity"))
745 if (!parsePid_torque_outVel(botControlLaw, _torqueControlLaw[i]))
747 yError() <<
"embObjMC BOARD " << _boardname <<
"format error in " << _torqueControlLaw[i];
751 else if (strOutputType ==
string(
"current"))
753 if (!parsePid_torque_outCur(botControlLaw, _torqueControlLaw[i]))
755 yError() <<
"embObjMC BOARD " << _boardname <<
"format error in " << _torqueControlLaw[i];
761 yError() <<
"embObjMC BOARD " << _boardname <<
"Unable to use output type " << strOutputType <<
" for torque control. Quitting.";
798bool Parser::parsePidsGroup2FOC(Bottle& pidsGroup, Pid myPid[])
803 if (!extractGroup(pidsGroup, xtmp,
"kff",
"kff parameter", _njoints))
return false;
804 for (
int j = 0; j<_njoints; j++) myPid[j].kff = xtmp.get(j + 1).asFloat64();
806 if (!extractGroup(pidsGroup, xtmp,
"kp",
"kp parameter", _njoints))
return false;
807 for (
int j = 0; j<_njoints; j++) myPid[j].kp = xtmp.get(j + 1).asFloat64();
809 if (!extractGroup(pidsGroup, xtmp,
"kd",
"kd parameter", _njoints))
return false;
810 for (
int j = 0; j<_njoints; j++) myPid[j].kd = xtmp.get(j + 1).asFloat64();
812 if (!extractGroup(pidsGroup, xtmp,
"maxOutput",
"maxOutput parameter", _njoints))
return false;
813 for (
int j = 0; j<_njoints; j++) myPid[j].max_output = xtmp.get(j + 1).asFloat64();
815 if (!extractGroup(pidsGroup, xtmp,
"ki",
"ki parameter", _njoints))
return false;
816 for (
int j = 0; j<_njoints; j++) myPid[j].ki = xtmp.get(j + 1).asFloat64();
818 if (!extractGroup(pidsGroup, xtmp,
"maxInt",
"maxInt parameter", _njoints))
return false;
819 for (
int j = 0; j<_njoints; j++) myPid[j].max_int = xtmp.get(j + 1).asFloat64();
821 if (!extractGroup(pidsGroup, xtmp,
"shift",
"shift parameter", _njoints))
return false;
822 for (
int j = 0; j<_njoints; j++) myPid[j].scale = xtmp.get(j + 1).asFloat64();
828bool Parser::parsePidsGroupSimple(Bottle& pidsGroup, Pid myPid[])
839 if (!extractGroup(pidsGroup, xtmp,
"kff",
"kff parameter", _njoints))
return false;
840 for (
int j = 0; j<_njoints; j++) myPid[j].kff = xtmp.get(j + 1).asFloat64();
842 if (!extractGroup(pidsGroup, xtmp,
"kp",
"kp parameter", _njoints))
return false;
843 for (
int j = 0; j<_njoints; j++) myPid[j].kp = xtmp.get(j + 1).asFloat64();
845 if (!extractGroup(pidsGroup, xtmp,
"kd",
"kd parameter", _njoints))
return false;
846 for (
int j = 0; j<_njoints; j++) myPid[j].kd = xtmp.get(j + 1).asFloat64();
848 if (!extractGroup(pidsGroup, xtmp,
"maxOutput",
"maxOutput parameter", _njoints))
return false;
849 for (
int j = 0; j<_njoints; j++) myPid[j].max_output = xtmp.get(j + 1).asFloat64();
854bool Parser::parsePidsGroupExtended(Bottle& pidsGroup, Pid myPid[])
863 if (!parsePidsGroupSimple(pidsGroup, myPid))
return false;
874 if (!extractGroup(pidsGroup, xtmp,
"ki",
"ki parameter", _njoints))
return false;
875 for (
int j = 0; j<_njoints; j++) myPid[j].ki = xtmp.get(j + 1).asFloat64();
877 if (!extractGroup(pidsGroup, xtmp,
"maxInt",
"maxInt parameter", _njoints))
return false;
878 for (
int j = 0; j<_njoints; j++) myPid[j].max_int = xtmp.get(j + 1).asFloat64();
880 if (!extractGroup(pidsGroup, xtmp,
"stictionUp",
"stictionUp parameter", _njoints))
return false;
881 for (
int j = 0; j<_njoints; j++) myPid[j].stiction_up_val = xtmp.get(j + 1).asFloat64();
883 if (!extractGroup(pidsGroup, xtmp,
"stictionDown",
"stictionDown parameter", _njoints))
return false;
884 for (
int j = 0; j<_njoints; j++) myPid[j].stiction_down_val = xtmp.get(j + 1).asFloat64();
889bool Parser::parsePidsGroupDeluxe(Bottle& pidsGroup, Pid myPid[])
902 if (!parsePidsGroupExtended(pidsGroup, myPid))
return false;
906 if (!extractGroup(pidsGroup, xtmp,
"kbemf",
"kbemf parameter", _njoints,
false))
908 yWarning() <<
"kbemf not found. Using fallback where kbemf is set to 0.";
909 for (
int j = 0; j<_njoints; j++) _kbemf[j] = 0;
913 for (
int j = 0; j<_njoints; j++) _kbemf[j] = xtmp.get(j + 1).asFloat64();
916 if (!extractGroup(pidsGroup, xtmp,
"ktau",
"ktau parameter", _njoints))
return false;
917 for (
int j = 0; j<_njoints; j++) _ktau[j] = xtmp.get(j + 1).asFloat64();
919 if (!extractGroup(pidsGroup, xtmp,
"filterType",
"filterType param", _njoints))
return false;
920 for (
int j = 0; j<_njoints; j++) _filterType[j] = xtmp.get(j + 1).asInt32();
923 if (!extractGroup(pidsGroup, xtmp,
"viscousPos",
"viscousPos parameter", _njoints,
false))
925 for (
int j = 0; j<_njoints; j++) _viscousPos[j] = 0;
929 for (
int j = 0; j<_njoints; j++) _viscousPos[j] = xtmp.get(j + 1).asFloat64();
932 if (!extractGroup(pidsGroup, xtmp,
"viscousNeg",
"viscousNeg parameter", _njoints,
false))
934 for (
int j = 0; j<_njoints; j++) _viscousNeg[j] = 0;
938 for (
int j = 0; j<_njoints; j++) _viscousNeg[j] = xtmp.get(j + 1).asFloat64();
941 if (!extractGroup(pidsGroup, xtmp,
"coulombPos",
"coulombPos parameter", _njoints,
false))
943 for (
int j = 0; j<_njoints; j++) _coulombPos[j] = 0;
947 for (
int j = 0; j<_njoints; j++) _coulombPos[j] = xtmp.get(j + 1).asFloat64();
950 if (!extractGroup(pidsGroup, xtmp,
"coulombNeg",
"coulombNeg parameter", _njoints,
false))
952 for (
int j = 0; j<_njoints; j++) _coulombNeg[j] = 0;
956 for (
int j = 0; j<_njoints; j++) _coulombNeg[j] = xtmp.get(j + 1).asFloat64();
959 if (!extractGroup(pidsGroup, xtmp,
"velocityThres",
"velocity threshold parameter for torque control", _njoints,
false))
961 for (
int j = 0; j<_njoints; j++) _velocityThres[j] = 0;
965 for (
int j = 0; j<_njoints; j++) _velocityThres[j] = xtmp.get(j + 1).asFloat64();
1013bool Parser::extractGroup(Bottle &input, Bottle &
out,
const std::string &key1,
const std::string &txt,
int size,
bool mandatory)
1016 Bottle &
tmp=input.findGroup(key1.c_str(), txt.c_str());
1019 std::string message = key1 +
" parameter not found for board " + _boardname +
" in bottle " + input.toString();
1021 yError () << message.c_str();
1023 yWarning() << message.c_str();
1027 if(
tmp.size()!=size)
1029 yError () << key1.c_str() <<
" incorrect number of entries in BOARD " << _boardname;
1037bool Parser::parsePid_minJerk_outPwm(Bottle &b_pid,
string controlLaw)
1039 if (minjerkAlgoMap.find(controlLaw) != minjerkAlgoMap.end())
return true;
1043 yarp::dev::PidFeedbackUnitsEnum fbk_PidUnits;
1044 yarp::dev::PidOutputUnitsEnum out_PidUnits;
1045 if (!parsePidUnitsType(b_pid, fbk_PidUnits, out_PidUnits))
return false;
1046 pidAlgo_ptr->
setUnits(fbk_PidUnits, out_PidUnits);
1048 parsePidsGroupExtended(b_pid, pidAlgo_ptr->
pid);
1050 minjerkAlgoMap.insert(std::pair<std::string, Pid_Algorithm*>(controlLaw, pidAlgo_ptr));
1055bool Parser::parsePid_minJerk_outCur(Bottle &b_pid,
string controlLaw)
1057 if (minjerkAlgoMap.find(controlLaw) != minjerkAlgoMap.end())
return true;
1061 yarp::dev::PidFeedbackUnitsEnum fbk_PidUnits;
1062 yarp::dev::PidOutputUnitsEnum out_PidUnits;
1063 if (!parsePidUnitsType(b_pid, fbk_PidUnits, out_PidUnits))
return false;
1064 pidAlgo_ptr->
setUnits(fbk_PidUnits, out_PidUnits);
1066 parsePidsGroupExtended(b_pid, pidAlgo_ptr->
pid);
1068 minjerkAlgoMap.insert(std::pair<std::string, Pid_Algorithm*>(controlLaw, pidAlgo_ptr));
1073bool Parser::parsePid_minJerk_outVel(Bottle &b_pid,
string controlLaw)
1075 if (minjerkAlgoMap.find(controlLaw) != minjerkAlgoMap.end())
return true;
1079 yarp::dev::PidFeedbackUnitsEnum fbk_PidUnits;
1080 yarp::dev::PidOutputUnitsEnum out_PidUnits;
1081 if (!parsePidUnitsType(b_pid, fbk_PidUnits, out_PidUnits))
return false;
1082 pidAlgo_ptr->
setUnits(fbk_PidUnits, out_PidUnits);
1084 parsePidsGroupSimple(b_pid, pidAlgo_ptr->
pid);
1086 minjerkAlgoMap.insert(std::pair<std::string, Pid_Algorithm*>(controlLaw, pidAlgo_ptr));
1147bool Parser::parsePid_torque_outPwm(Bottle &b_pid,
string controlLaw)
1149 if (torqueAlgoMap.find(controlLaw) != torqueAlgoMap.end())
return true;
1153 yarp::dev::PidFeedbackUnitsEnum fbk_PidUnits;
1154 yarp::dev::PidOutputUnitsEnum out_PidUnits;
1155 if(!parsePidUnitsType(b_pid, fbk_PidUnits, out_PidUnits))
return false;
1156 pidAlgo_ptr->
setUnits(fbk_PidUnits, out_PidUnits);
1158 parsePidsGroupDeluxe(b_pid, pidAlgo_ptr->
pid);
1160 torqueAlgoMap.insert( std::pair<std::string, Pid_Algorithm*>(controlLaw, pidAlgo_ptr));
1165bool Parser::parsePid_torque_outCur(Bottle &b_pid,
string controlLaw)
1167 if (torqueAlgoMap.find(controlLaw) != torqueAlgoMap.end())
return true;
1171 yarp::dev::PidFeedbackUnitsEnum fbk_PidUnits;
1172 yarp::dev::PidOutputUnitsEnum out_PidUnits;
1173 if (!parsePidUnitsType(b_pid, fbk_PidUnits, out_PidUnits))
return false;
1174 pidAlgo_ptr->
setUnits(fbk_PidUnits, out_PidUnits);
1176 parsePidsGroupDeluxe(b_pid, pidAlgo_ptr->
pid);
1178 torqueAlgoMap.insert(std::pair<std::string, Pid_Algorithm*>(controlLaw, pidAlgo_ptr));
1183bool Parser::parsePid_torque_outVel(Bottle &b_pid,
string controlLaw)
1185 if (torqueAlgoMap.find(controlLaw) != torqueAlgoMap.end())
return true;
1189 yarp::dev::PidFeedbackUnitsEnum fbk_PidUnits;
1190 yarp::dev::PidOutputUnitsEnum out_PidUnits;
1191 if(!parsePidUnitsType(b_pid, fbk_PidUnits, out_PidUnits))
return false;
1192 pidAlgo_ptr->
setUnits(fbk_PidUnits, out_PidUnits);
1194 parsePidsGroupExtended(b_pid, pidAlgo_ptr->
pid);
1196 torqueAlgoMap.insert ( std::pair<std::string, Pid_Algorithm*>(controlLaw, pidAlgo_ptr) );
1208 memset(ppids, 0,
sizeof(
PidInfo)*_njoints);
1210 memset(tpids, 0,
sizeof(
TrqPidInfo)*_njoints);
1212 map<string, Pid_Algorithm*>::iterator it;
1214 for (
int i = 0; i < _njoints; i++)
1217 it = minjerkAlgoMap.find(_positionControlLaw[i]);
1218 if (it == minjerkAlgoMap.end())
1220 yError() <<
"embObjMC BOARD " << _boardname <<
"Cannot find " << _positionControlLaw[i].c_str() <<
"in parsed pos pid";
1224 minjerkAlgo_ptr = minjerkAlgoMap[_positionControlLaw[i]];
1226 ppids[i].
pid = minjerkAlgo_ptr->
getPID(i);
1270 if (_torqueControlLaw[i] ==
"none")
1272 torqueAlgo_ptr = NULL;
1276 it = torqueAlgoMap.find(_torqueControlLaw[i]);
1277 if (it == torqueAlgoMap.end())
1279 yError() <<
"embObjMC BOARD " << _boardname <<
"Cannot find " << _torqueControlLaw[i].c_str() <<
"in parsed trq pid";
1283 torqueAlgo_ptr = torqueAlgoMap[_torqueControlLaw[i]];
1288 tpids[i].
pid = torqueAlgo_ptr->
getPID(i);
1295 tpids[i].
kbemf = _kbemf[i];
1296 tpids[i].
ktau = _ktau[i];
1316 return checkJointTypes(tpids,
"TORQUE") && checkJointTypes(ppids,
"POSITION");
1319bool Parser::parsePidUnitsType(Bottle &bPid, yarp::dev::PidFeedbackUnitsEnum &fbk_pidunits, yarp::dev::PidOutputUnitsEnum& out_pidunits)
1322 Value &fbkControlUnits=bPid.find(
"fbkControlUnits");
1323 Value &outControlUnits = bPid.find(
"outputControlUnits");
1324 if(fbkControlUnits.isNull())
1326 yError() <<
"embObjMC BOARD " << _boardname <<
" missing fbkControlUnits parameter";
1329 if(!fbkControlUnits.isString())
1331 yError() <<
"embObjMC BOARD " << _boardname <<
" fbkControlUnits parameter is not a string";
1334 if (outControlUnits.isNull())
1336 yError() <<
"embObjMC BOARD " << _boardname <<
" missing outputControlUnits parameter";
1339 if (!outControlUnits.isString())
1341 yError() <<
"embObjMC BOARD " << _boardname <<
" outputControlUnits parameter is not a string";
1345 if(fbkControlUnits.toString()==
string(
"metric_units"))
1347 fbk_pidunits = yarp::dev::PidFeedbackUnitsEnum::METRIC;
1349 else if(fbkControlUnits.toString()==
string(
"machine_units"))
1351 fbk_pidunits = yarp::dev::PidFeedbackUnitsEnum::RAW_MACHINE_UNITS;
1355 yError() <<
"embObjMC BOARD " << _boardname <<
"invalid fbkControlUnits value: " << fbkControlUnits.toString().c_str();
1359 if (outControlUnits.toString() ==
string(
"dutycycle_percent"))
1361 out_pidunits = yarp::dev::PidOutputUnitsEnum::DUTYCYCLE_PWM_PERCENT;
1363 else if (outControlUnits.toString() ==
string(
"machine_units"))
1365 out_pidunits = yarp::dev::PidOutputUnitsEnum::RAW_MACHINE_UNITS;
1369 yError() <<
"embObjMC BOARD " << _boardname <<
"invalid outputControlUnits value: " << outControlUnits.toString().c_str();
1377 Bottle &focGroup=config.findGroup(groupName);
1378 if (focGroup.isNull() )
1380 yError() <<
"embObjMC BOARD " << _boardname <<
" detected that Group " << groupName <<
" is not found in configuration file";
1387 if (!extractGroup(focGroup, xtmp,
"HasHallSensor",
"HasHallSensor 0/1 ", _njoints))
1393 for (i = 1; i < xtmp.size(); i++)
1394 foc_based_info[i - 1].hasHallSensor = xtmp.get(i).asInt32() != 0;
1397 if (!extractGroup(focGroup, xtmp,
"TemperatureSensorType",
"TemperatureSensorType PT100/PT1000/NONE ", _njoints,
false))
1400 if (extractGroup(focGroup, xtmp,
"HasTempSensor",
"HasTempSensor 0/1 ", _njoints,
false))
1402 for (i = 1; i < xtmp.size(); i++)
1404 if (xtmp.get(i).asInt32() != 0)
1406 yError() <<
"In " << _boardname <<
"entry" << i <<
": inconsistent configuration. HasTempSensor cannot be used alone. Will be soon deprecated. Use TemperatureSensorType in 2FOC group and set Temperature limits in LIMITS group." ;
1413 for (i = 0; i < _njoints; i++)
1416 temperatureSensorsVector.at(i) = std::make_unique<eomc::TemperatureSensorNONE>();
1417 yWarning()<< _boardname <<
"ATTENTION HasTempSensor will be soon DEPRECATED in favour of TemperatureSensorType (PT100, PT1000, NONE(=default)). Currently kept for backward compatibility but update your configuration files if using a Temperature Sensor";
1423 for (i = 1; i < xtmp.size(); i++)
1425 std::string s = xtmp.get(i).asString();
1429 temperatureSensorsVector.at(i-1) = std::make_unique<eomc::TemperatureSensorPT100>();
1432 else if (s ==
"PT1000")
1436 temperatureSensorsVector.at(i-1) = std::make_unique<eomc::TemperatureSensorPT1000>();
1441 yWarning(
"Not available or Not supported TemperatureSensorType: %s. Setting NONE as default", s.c_str());
1443 temperatureSensorsVector.at(i-1) = std::make_unique<eomc::TemperatureSensorNONE>();
1447 if (!extractGroup(focGroup, xtmp,
"HasRotorEncoder",
"HasRotorEncoder 0/1 ", _njoints))
1454 for (i = 1; i < xtmp.size(); i++)
1455 foc_based_info[i - 1].hasRotorEncoder = xtmp.get(i).asInt32() != 0;
1457 if (!extractGroup(focGroup, xtmp,
"HasRotorEncoderIndex",
"HasRotorEncoderIndex 0/1 ", _njoints))
1463 for (i = 1; i < xtmp.size(); i++)
1464 foc_based_info[i - 1].hasRotorEncoderIndex = xtmp.get(i).asInt32() != 0;
1467 if (!extractGroup(focGroup, xtmp,
"Verbose",
"Verbose 0/1 ", _njoints,
false))
1470 yWarning() <<
"In " << _boardname <<
" there isn't " << groupName <<
". Verbose failed. By default it is disabled" ;
1471 for (i = 0; i < (unsigned)_njoints; i++)
1472 foc_based_info[i].verbose = 0;
1476 for (i = 1; i < xtmp.size(); i++)
1477 foc_based_info[i - 1].verbose = xtmp.get(i).asInt32() != 0;
1480 std::vector<int> AutoCalibration (_njoints);
1481 if (!extractGroup(focGroup, xtmp,
"AutoCalibration",
"AutoCalibration 0/1 ", _njoints,
false))
1484 yWarning() <<
"In " << _boardname <<
" there isn't " << groupName <<
". AutoCalibration failed. By default it is disabled" ;
1485 for (i = 0; i < (unsigned)_njoints; i++)
1486 AutoCalibration[i] = 0;
1490 for (i = 1; i < xtmp.size(); i++)
1491 AutoCalibration[i - 1] = xtmp.get(i).asInt32();
1495 if (!extractGroup(focGroup, xtmp,
"RotorIndexOffset",
"RotorIndexOffset", _njoints))
1501 for (i = 1; i < xtmp.size(); i++)
1503 if(AutoCalibration[i-1] == 0)
1506 if (foc_based_info[i - 1].rotorIndexOffset <0 || foc_based_info[i - 1].rotorIndexOffset >359)
1508 yError() <<
"In " << _boardname <<
"joint " << i-1 <<
": rotorIndexOffset should be in [0,359] range." ;
1514 yWarning() <<
"In " << _boardname <<
"joint " << i-1 <<
": motor autocalibration is enabled!!! ATTENTION!!!" ;
1522 for (i = 0; i < (unsigned)_njoints; i++)
1524 if((0 == foc_based_info[i].hasRotorEncoderIndex) && (0 != foc_based_info[i].
rotorIndexOffset))
1526 yError() <<
"In " << _boardname <<
"joint " << i <<
": inconsistent configuration: if rotor encoder hasn't index then its offset should be 0." ;
1532 if (!extractGroup(focGroup, xtmp,
"MotorPoles",
"MotorPoles", _njoints))
1538 for (i = 1; i < xtmp.size(); i++)
1539 foc_based_info[i - 1].motorPoles = xtmp.get(i).asInt32();
1542 if (!extractGroup(focGroup, xtmp,
"HasSpeedEncoder",
"HasSpeedEncoder 0/1 ", _njoints))
1544 yWarning () <<
"missing param HasSpeedEncoder";
1550 for (i = 1; i < xtmp.size(); i++)
1551 foc_based_info[i - 1].hasSpeedEncoder = xtmp.get(i).asInt32() != 0;
1560 Bottle jointsetcfg = config.findGroup(
"JOINTSET_CFG");
1561 if (jointsetcfg.isNull())
1563 yError() <<
"embObjMC BOARD " << _boardname <<
"Missing JOINTSET_CFG group";
1571 if(!extractGroup(jointsetcfg, xtmp,
"numberofsets",
"number of sets ", 1))
1576 numofsets = xtmp.get(1).asInt32();
1578 if((0 == numofsets) || (numofsets > _njoints))
1580 yError() <<
"embObjMC BOARD " << _boardname <<
"Number of jointsets is not correct. it should belong to (1, " << _njoints <<
")";
1586 if(!checkAndSetVectorSize(jsets, numofsets,
"parseJointsetCfgGroup"))
1589 if(!checkAndSetVectorSize(joint2set, _njoints,
"parseJointsetCfgGroup"))
1592 for(
unsigned int s=0;s<(unsigned)numofsets;s++)
1594 char jointset_string[80];
1595 sprintf(jointset_string,
"JOINTSET_%d", s);
1596 bool formaterror =
false;
1599 Bottle &js_cfg = jointsetcfg.findGroup(jointset_string);
1602 yError() <<
"embObjMC BOARD " << _boardname <<
"cannot find " << jointset_string;
1611 Bottle &b_listofjoints=js_cfg.findGroup(
"listofjoints",
"list of joints");
1612 if (b_listofjoints.isNull())
1614 yError() <<
"embObjMC BOARD " << _boardname <<
"listofjoints parameter not found";
1618 int numOfJointsInSet = b_listofjoints.size()-1;
1619 if((numOfJointsInSet < 1) || (numOfJointsInSet>_njoints))
1621 yError() <<
"embObjMC BOARD " << _boardname <<
"numof joints of set " << s <<
" is not correct";
1626 for (
int j = 0; j <numOfJointsInSet; j++)
1628 int jointofthisset = b_listofjoints.get(j+1).asInt32();
1630 if((jointofthisset< 0) || (jointofthisset>_njoints))
1632 yError() <<
"embObjMC BOARD " << _boardname <<
"invalid joint number for set " << s;
1636 jsets.at(s).joints.push_back(jointofthisset);
1639 joint2set.at(jointofthisset) = s;
1643 if(!extractGroup(js_cfg, xtmp,
"constraint",
"type of jointset constraint ", 1))
1648 eOmc_jsetconstraint_t constraint;
1649 if(!convert(xtmp.get(1).asString(), constraint, formaterror))
1653 jsets.at(s).cfg.constraints.type = constraint;
1656 if(!extractGroup(js_cfg, xtmp,
"param1",
"param1 of jointset constraint ", 1))
1660 jsets.at(s).cfg.constraints.param1 = (float)xtmp.get(1).asFloat64();
1663 if(!extractGroup(js_cfg, xtmp,
"param2",
"param2 of jointset constraint ", 1))
1667 jsets.at(s).cfg.constraints.param2 = (float)xtmp.get(1).asFloat64();
1676 if(!checkAndSetVectorSize(timeouts, _njoints,
"parseTimeoutsGroup"))
1681 Bottle timeoutsGroup =config.findGroup(
"TIMEOUTS");
1682 if(timeoutsGroup.isNull())
1684 yError() <<
"embObjMC BOARD " << _boardname <<
" no TIMEOUTS group found in config file.";
1690 if (!extractGroup(timeoutsGroup, xtmp,
"velocity",
"a list of timeout to be used in the vmo control", _njoints))
1692 yError() <<
"embObjMC BOARD " << _boardname <<
" no velocity parameter found in TIMEOUTS group in motion control config file.";
1697 for(i=1; i<xtmp.size(); i++)
1698 timeouts[i-1].velocity = xtmp.get(i).asInt32();
1708 Bottle &limits=config.findGroup(
"LIMITS");
1709 if (limits.isNull())
1711 yError() <<
"embObjMC BOARD " << _boardname <<
" detected that Group LIMITS is not found in configuration file";
1715 currLimits.resize(_njoints);
1720 if (!extractGroup(limits, xtmp,
"motorOverloadCurrents",
"a list of current limits", _njoints))
1723 for(i=1; i<xtmp.size(); i++) currLimits[i-1].overloadCurrent=xtmp.get(i).asFloat64();
1726 if (!extractGroup(limits, xtmp,
"motorNominalCurrents",
"a list of nominal current limits", _njoints))
1729 for(i=1; i<xtmp.size(); i++) currLimits[i-1].nominalCurrent =xtmp.get(i).asFloat64();
1732 if (!extractGroup(limits, xtmp,
"motorPeakCurrents",
"a list of peak current limits", _njoints))
1735 for(i=1; i<xtmp.size(); i++) currLimits[i-1].peakCurrent=xtmp.get(i).asFloat64();
1743 Bottle &limits = config.findGroup(
"LIMITS");
1744 if (limits.isNull())
1746 yError() <<
"embObjMC BOARD " << _boardname <<
" detected that Group LIMITS is not found in configuration file";
1750 temperatureLimits.resize(_njoints);
1755 if(!extractGroup(limits, xtmp,
"hardwareTemperatureLimits",
"a list of temperature limits", _njoints,
false))
1757 yWarning(
"hardwareTemperatureLimits param not found in config file for board %s. Please update robot configuration files or contact https://github.com/robotology/icub-support if needed. Using default values.", _boardname.c_str());
1758 for (i = 0; i < (unsigned)_njoints; i++)
1760 temperatureLimits[i].hardwareTemperatureLimit = 0;
1761 temperatureLimits[i].warningTemperatureLimit = 0;
1766 for (i = 1; i < xtmp.size(); i++) temperatureLimits[i - 1].hardwareTemperatureLimit = xtmp.get(i).asFloat64();
1767 if (!extractGroup(limits, xtmp,
"warningTemperatureLimits",
"a list of warning temperature limits", _njoints,
false))
1770 yWarning(
"warningTemperatureLimits param not found in config file for board %s. Please update robot configuration files or contact https://github.com/robotology/icub-support if needed. Using default values.", _boardname.c_str());
1772 for (i = 0; i < (unsigned)_njoints; i++) temperatureLimits[i].warningTemperatureLimit = 0;
1776 for (i = 1; i < xtmp.size(); i++) temperatureLimits[i - 1].warningTemperatureLimit = xtmp.get(i).asFloat64();
1781 for (i = 0; i < (unsigned)_njoints; i++)
1783 if(temperatureLimits[i].warningTemperatureLimit > (0.85 * temperatureLimits[i].hardwareTemperatureLimit))
1785 yError() <<
"In " << _boardname <<
"joint " << i <<
": inconsistent temperature limits. warningTemperatureLimit must be smaller than 85% of hardwareTemperatureLimit" ;
1794 Bottle &limits=config.findGroup(
"LIMITS");
1795 if (limits.isNull())
1797 yError() <<
"embObjMC BOARD " << _boardname <<
" detected that Group LIMITS is not found in configuration file";
1801 jointsLimits.resize(_njoints);
1806 if (!extractGroup(limits, xtmp,
"jntPosMax",
"a list of user maximum angles (in degrees)", _njoints))
1809 for(i=1; i<xtmp.size(); i++) jointsLimits[i-1].posMax = xtmp.get(i).asFloat64();
1812 if (!extractGroup(limits, xtmp,
"jntPosMin",
"a list of user minimum angles (in degrees)", _njoints))
1815 for(i=1; i<xtmp.size(); i++) jointsLimits[i-1].posMin = xtmp.get(i).asFloat64();
1818 if (!extractGroup(limits, xtmp,
"hardwareJntPosMax",
"a list of hardware maximum angles (in degrees)", _njoints))
1822 for(i=1; i<xtmp.size(); i++) jointsLimits[i-1].posHwMax = xtmp.get(i).asFloat64();
1825 for(i=0; i<(unsigned)_njoints; i++)
1827 if(jointsLimits[i].posMax > jointsLimits[i].posHwMax)
1829 yError() <<
"embObjMotionControl: user has set a limit bigger then hardware limit!. Please check jntPosMax.";
1836 if (!extractGroup(limits, xtmp,
"hardwareJntPosMin",
"a list of hardware minimum angles (in degrees)", _njoints))
1842 for(i=1; i<xtmp.size(); i++) jointsLimits[i-1].posHwMin = xtmp.get(i).asFloat64();
1845 for(i=0; i<(unsigned)_njoints; i++)
1847 if(jointsLimits[i].posMin < jointsLimits[i].posHwMin)
1849 yError() <<
"embObjMotionControl: user has set a limit bigger then hardware limit!. Please check jntPosMin.";
1857 if (!extractGroup(limits, xtmp,
"jntVelMax",
"a list of maximum velocities for the joints (in degrees/s)", _njoints))
1860 for (i = 1; i<xtmp.size(); i++) jointsLimits[i - 1].velMax = xtmp.get(i).asFloat64();
1867 Bottle &limits=config.findGroup(
"LIMITS");
1868 if (limits.isNull())
1870 yError() <<
"embObjMC BOARD " << _boardname <<
" detected that Group LIMITS is not found in configuration file";
1874 if(!checkAndSetVectorSize(rotorsLimits, _njoints,
"parseRotorsLimits"))
1881 if (!extractGroup(limits, xtmp,
"rotorPosMax",
"a list of maximum rotor angles (in degrees)", _njoints))
1884 for(i=1; i<xtmp.size(); i++) rotorsLimits[i-1].posMax = xtmp.get(i).asFloat64();
1889 if (!extractGroup(limits, xtmp,
"rotorPosMin",
"a list of minimum roto angles (in degrees)", _njoints))
1892 for(i=1; i<xtmp.size(); i++) rotorsLimits[i-1].posMin = xtmp.get(i).asFloat64();
1895 if (!extractGroup(limits, xtmp,
"motorPwmLimit",
"a list of motor PWM limits", _njoints))
1898 for(i=1; i<xtmp.size(); i++)
1900 rotorsLimits[i-1].pwmMax = xtmp.get(i).asFloat64();
1901 if(rotorsLimits[i-1].pwmMax<0)
1903 yError() <<
"motorPwmLimit should be a positive value";
1914 Bottle coupling_bottle = config.findGroup(
"COUPLINGS");
1915 if (coupling_bottle.isNull())
1917 yError() <<
"embObjMC BOARD " << _boardname <<
"Missing Coupling group";
1921 int fixedMatrix4X4Size = 16;
1922 int fixedMatrix4X6Size = 24;
1923 bool formaterror =
false;
1926 if (!extractGroup(coupling_bottle, xtmp,
"matrixJ2M",
"matrixJ2M ", fixedMatrix4X4Size))
1931 if(
false == convert(xtmp, couplingInfo.
matrixJ2M, formaterror, fixedMatrix4X4Size))
1933 yError() <<
"embObjMC BOARD " << _boardname <<
" has detected an illegal format for some of the values of CONTROLLER.matrixJ2M";
1939 if (!extractGroup(coupling_bottle, xtmp,
"matrixE2J",
"matrixE2J ", fixedMatrix4X6Size))
1944 formaterror =
false;
1945 if(
false == convert(xtmp, couplingInfo.
matrixE2J, formaterror, fixedMatrix4X6Size))
1947 yError() <<
"embObjMC BOARD " << _boardname <<
" has detected an illegal format for some of the values of CONTROLLER.matrixE2J";
1953 if (!extractGroup(coupling_bottle, xtmp,
"matrixM2J",
"matrixM2J ", fixedMatrix4X4Size))
1958 formaterror =
false;
1959 if(
false == convert(xtmp, couplingInfo.
matrixM2J, formaterror, fixedMatrix4X4Size))
1961 yError() <<
"embObjMC BOARD " << _boardname <<
" has detected an illegal format for some of the values of CONTROLLER.matrixM2J";
1970 if (!config.findGroup(
"GENERAL").find(
"MotioncontrolVersion").isInt32())
1972 yError() <<
"Missing MotioncontrolVersion parameter. RobotInterface cannot start. Please contact icub-support@iit.it";
1976 version = config.findGroup(
"GENERAL").find(
"MotioncontrolVersion").asInt32();
1984 if(!config.findGroup(
"GENERAL").find(
"verbose").isBool())
1986 yError() <<
"embObjMotionControl::open() detects that general->verbose bool param is different from accepted values (true / false). Assuming false";
1991 ret = config.findGroup(
"GENERAL").find(
"verbose").asBool();
1993 _verbosewhenok = ret;
2001 Value use_raw = config.findGroup(
"GENERAL").find(
"useRawEncoderData");
2003 if(use_raw.isNull())
2005 useRawEncoderData =
false;
2009 if(!use_raw.isBool())
2011 yWarning() <<
"embObjMotionControl::open() detected that useRawEncoderData bool param is different from accepted values (true / false). Assuming false";
2012 useRawEncoderData =
false;
2016 useRawEncoderData = use_raw.asBool();
2017 if(useRawEncoderData)
2019 yWarning() <<
"embObjMotionControl::open() detected that it is using raw data from encoders! Be careful See 'useRawEncoderData' param in config file";
2020 yWarning() <<
"DO NOT USE OR CALIBRATE THE ROBOT IN THIS CONFIGURATION!";
2021 yWarning() <<
"CHECK IF THE FAULT BUTTON IS PRESSED and press ENTER to continue";
2028 Value use_limitedPWM = config.findGroup(
"GENERAL").find(
"useLimitedPWM");
2029 if(use_limitedPWM.isNull())
2031 pwmIsLimited =
false;
2035 if(!use_limitedPWM.isBool())
2037 pwmIsLimited =
false;
2041 pwmIsLimited = use_limitedPWM.asBool();
2053 axisInfo.resize(_njoints);
2055 Bottle general = config.findGroup(
"GENERAL");
2056 if (general.isNull())
2058 yError() <<
"embObjMC BOARD " << _boardname <<
"Missing General group" ;
2063 if (!extractGroup(general, xtmp,
"AxisMap",
"a list of reordered indices for the axes", _njoints))
2066 for (i = 1; i < xtmp.size(); i++)
2068 int user_joint = xtmp.get(i).asInt32();
2069 if(user_joint>= _njoints)
2071 yError() <<
"embObjMC BOARD " << _boardname <<
"In AxisMap param: joint " << i-1 <<
"has been mapped to not-existing joint ("<< user_joint <<
"). Here there are only "<< _njoints <<
"joints";
2074 axisMap[i-1] = user_joint;
2078 if (!extractGroup(general, xtmp,
"AxisName",
"a list of strings representing the axes names", _njoints))
2082 for (i = 1; i < xtmp.size(); i++)
2084 int mappedto = axisInfo[i-1].mappedto;
2085 axisInfo[axisMap[i - 1]].name = xtmp.get(i).asString();
2088 if (!extractGroup(general, xtmp,
"AxisType",
"a list of strings representing the axes type (revolute/prismatic)", _njoints))
2092 for (i = 1; i < xtmp.size(); i++)
2094 string s = xtmp.get(i).asString();
2095 int mappedto = axisInfo[i-1].mappedto;
2096 if (s ==
"revolute") axisInfo[axisMap[i - 1]].type = VOCAB_JOINTTYPE_REVOLUTE;
2097 else if (s ==
"prismatic") axisInfo[axisMap[i - 1]].type = VOCAB_JOINTTYPE_PRISMATIC;
2100 yError(
"Unknown AxisType value %s!", s.c_str());
2101 axisInfo[axisMap[i - 1]].type = VOCAB_JOINTTYPE_UNKNOWN;
2111 Bottle general = config.findGroup(
"GENERAL");
2112 if (general.isNull())
2114 yError() <<
"embObjMC BOARD " << _boardname <<
"Missing General group" ;
2122 if (!extractGroup(general, xtmp,
"Encoder",
"a list of scales for the encoders", _njoints))
2127 for (i = 1; i < xtmp.size(); i++)
2129 tmp_A2E = xtmp.get(i).asFloat64();
2132 yWarning() <<
"embObjMC BOARD " << _boardname <<
"Encoder parameter should be positive!";
2134 encoderFactor[i - 1] = tmp_A2E;
2142 Bottle general = config.findGroup(
"GENERAL");
2143 if (general.isNull())
2145 yError() <<
"embObjMC BOARD " << _boardname <<
"Missing General group";
2153 if (!extractGroup(general, xtmp,
"fullscalePWM",
"a list of scales for the fullscalePWM conversion factor", _njoints))
2155 yError(
"fullscalePWM param not found in config file. Please update robot configuration files or contact https://github.com/robotology/icub-support");
2159 for (i = 1; i < xtmp.size(); i++)
2161 tmpval = xtmp.get(i).asFloat64();
2164 yError() <<
"embObjMC BOARD " << _boardname <<
"fullscalePWM parameter should be positive!";
2167 dutycycleToPWM[i - 1] = tmpval / 100.0;
2175 Bottle general = config.findGroup(
"GENERAL");
2176 if (general.isNull())
2178 yError() <<
"embObjMC BOARD " << _boardname <<
"Missing General group";
2186 if (!extractGroup(general, xtmp,
"ampsToSensor",
"a list of scales for the ampsToSensor conversion factor", _njoints))
2188 yError(
"ampsToSensor param not found in config file. Please update robot configuration files or contact https://github.com/robotology/icub-support");
2192 for (i = 1; i < xtmp.size(); i++)
2194 tmpval = xtmp.get(i).asFloat64();
2197 yError() <<
"embObjMC BOARD " << _boardname <<
"ampsToSensor parameter should be positive!";
2200 ampsToSensor[i - 1] = tmpval;
2208 Bottle general = config.findGroup(
"GENERAL");
2209 if (general.isNull())
2211 yError() <<
"embObjMC BOARD " << _boardname <<
"Missing General group" ;
2219 if (!extractGroup(general, xtmp,
"Gearbox_M2J",
"The gearbox reduction ratio", _njoints))
2224 for (i = 1; i < xtmp.size(); i++)
2226 gearbox_M2J[i-1] = xtmp.get(i).asFloat64();
2227 if (gearbox_M2J[i-1]==0)
2229 yError() <<
"embObjMC BOARD " << _boardname <<
"Using a gearbox value = 0 may cause problems! Check your configuration files";
2236 if (!extractGroup(general, xtmp,
"Gearbox_E2J",
"The gearbox reduction ratio between encoder and joint", _njoints))
2241 int test = xtmp.size();
2242 for (i = 1; i < xtmp.size(); i++)
2244 gearbox_E2J[i-1] = xtmp.get(i).asFloat64();
2245 if (gearbox_E2J[i-1]==0)
2247 yError() <<
"embObjMC BOARD " << _boardname <<
"Using a gearbox value = 0 may cause problems! Check your configuration files";
2265 Bottle general = config.findGroup(
"OTHER_CONTROL_PARAMETERS");
2266 if (general.isNull())
2268 yWarning() <<
"embObjMC BOARD " << _boardname <<
"Missing OTHER_CONTROL_PARAMETERS.DeadZone parameter. I'll use default value. (see documentation for more datails)";
2276 if (!extractGroup(general, xtmp,
"deadZone",
"The deadzone of joint", _njoints,
false))
2278 yWarning() <<
"embObjMC BOARD " << _boardname <<
"Missing OTHER_CONTROL_PARAMETERS group.DeadZone parameter. I'll use default value. (see documentation for more datails)";
2284 for (i = 1; i < xtmp.size(); i++)
2286 deadzone[i-1] = xtmp.get(i).asFloat64();
2294 Bottle general = config.findGroup(
"KALMAN_FILTER");
2295 if (general.isNull())
2297 yWarning() <<
"embObjMC BOARD " << _boardname <<
"Missing KALMAN_FILTER group. Kalman Filter will be disabled by default.";
2300 for(
int j=0; j<_njoints; j++)
2302 kalmanFilterParams[j].enabled =
false;
2303 kalmanFilterParams[j].x0.fill(0.0);
2304 kalmanFilterParams[j].Q.fill(0.0);
2305 kalmanFilterParams[j].R = 0.0;
2306 kalmanFilterParams[j].P0 = 0.0;
2315 if (!extractGroup(general, xtmp,
"kalmanFilterEnabled",
"kalman filter of joint: ", _njoints,
true))
2317 yWarning() <<
"embObjMC BOARD " << _boardname <<
"Missing kalmanFilterEnabled parameter. It will be disabled by default.";
2320 for (
int j = 0; j<_njoints; j++) kalmanFilterParams[j].enabled = xtmp.get(j + 1).asBool();
2323 if (!extractGroup(general, xtmp,
"x0",
"Initial state x0 of kalman filter of joint: ", _njoints,
true))
2325 yWarning() <<
"embObjMC BOARD " << _boardname <<
"Missing initial state x0 parameter. Kalman Filter will be disabled by default.";
2328 for (
int j = 0; j<_njoints; j++) kalmanFilterParams[j].x0.at(0) = xtmp.get(j + 1).asFloat32();
2331 if (!extractGroup(general, xtmp,
"x1",
"Initial state x1 of kalman filter of joint: ", _njoints,
true))
2333 yWarning() <<
"embObjMC BOARD " << _boardname <<
"Missing initial state x1 parameter. Kalman Filter will be disabled by default.";
2336 for (
int j = 0; j<_njoints; j++) kalmanFilterParams[j].x0.at(1) = xtmp.get(j + 1).asFloat32();
2339 if (!extractGroup(general, xtmp,
"x2",
"Initial state x2 of kalman filter of joint: ", _njoints,
true))
2341 yWarning() <<
"embObjMC BOARD " << _boardname <<
"Missing initial state x2 parameter. Kalman Filter will be disabled by default.";
2344 for (
int j = 0; j<_njoints; j++) kalmanFilterParams[j].x0.at(2) = xtmp.get(j + 1).asFloat32();
2347 if (!extractGroup(general, xtmp,
"Q0",
"Process Q0 noise covariance matrix of kalman filter of joint: ", _njoints,
true))
2349 yWarning() <<
"embObjMC BOARD " << _boardname <<
"Missing Q0 parameter. Kalman Filter will be disabled by default.";
2352 for (
int j = 0; j<_njoints; j++) kalmanFilterParams[j].Q.at(0) = xtmp.get(j + 1).asFloat32();
2355 if (!extractGroup(general, xtmp,
"Q1",
"Process Q1 noise covariance matrix of kalman filter of joint: ", _njoints,
true))
2357 yWarning() <<
"embObjMC BOARD " << _boardname <<
"Missing Q1 parameter. Kalman Filter will be disabled by default.";
2360 for (
int j = 0; j<_njoints; j++) kalmanFilterParams[j].Q.at(1) = xtmp.get(j + 1).asFloat32();
2363 if (!extractGroup(general, xtmp,
"Q2",
"Process Q2 noise covariance matrix of kalman filter of joint: ", _njoints,
true))
2365 yWarning() <<
"embObjMC BOARD " << _boardname <<
"Missing Q2 parameter. Kalman Filter will be disabled by default.";
2368 for (
int j = 0; j<_njoints; j++) kalmanFilterParams[j].Q.at(2) = xtmp.get(j + 1).asFloat32();
2371 if (!extractGroup(general, xtmp,
"R",
"Measurement noise covariance matrix of kalman filter for joint: ", _njoints,
true))
2373 yWarning() <<
"embObjMC BOARD " << _boardname <<
"Missing R scalar parameter. Kalman Filter will be disabled by default.";
2376 for (
int j = 0; j<_njoints; j++) kalmanFilterParams[j].R = xtmp.get(j + 1).asFloat32();
2379 if (!extractGroup(general, xtmp,
"P0",
"Initial state estimation error covariance matrix of kalman filter of joint: ", _njoints,
true))
2381 yWarning() <<
"embObjMC BOARD " << _boardname <<
"Missing P0 scalar parameter. Kalman Filter will be disabled by default.";
2384 for (
int j = 0; j<_njoints; j++) kalmanFilterParams[j].P0 = xtmp.get(j + 1).asFloat32();
2393 Bottle general = config.findGroup(
"GENERAL");
2394 if (general.isNull())
2396 yError() <<
"embObjMC BOARD " << _boardname <<
"Missing General group" ;
2402 if(!extractGroup(general, xtmp,
"useMotorSpeedFbk",
"Use motor speed feedback", _njoints))
2407 for (i = 1; i < xtmp.size(); i++)
2409 useMotorSpeedFbk[i-1] = xtmp.get(i).asInt32();
2418 Bottle impedanceGroup;
2419 impedanceGroup=config.findGroup(
"IMPEDANCE",
"IMPEDANCE parameters");
2421 if(impedanceGroup.isNull())
2423 yError() <<
"embObjMC BOARD " << _boardname <<
"fromConfig(): Error: no IMPEDANCE group found in config file, returning";
2431 yDebug() <<
"embObjMC BOARD " << _boardname <<
":fromConfig() detected that IMPEDANCE parameters section is found";
2434 if(!checkAndSetVectorSize(impedance, _njoints,
"parseImpedanceGroup"))
2440 if (!extractGroup(impedanceGroup, xtmp,
"stiffness",
"stiffness parameter", _njoints))
2443 for (j=0; j<_njoints; j++)
2444 impedance[j].stiffness = xtmp.get(j+1).asFloat64();
2446 if (!extractGroup(impedanceGroup, xtmp,
"damping",
"damping parameter", _njoints))
2449 for (j=0; j<_njoints; j++)
2450 impedance[j].damping = xtmp.get(j+1).asFloat64();
2454 yInfo() <<
"embObjMC BOARD " << _boardname <<
"IMPEDANCE section: parameters successfully loaded";
2460bool Parser::convert(std::string
const &fromstring, eOmc_jsetconstraint_t &jsetconstraint,
bool& formaterror)
2462 const char *t = fromstring.c_str();
2464 eObool_t usecompactstring = eobool_false;
2465 jsetconstraint = eomc_string2jsetconstraint(t, usecompactstring);
2467 if(eomc_jsetconstraint_unknown == jsetconstraint)
2469 usecompactstring = eobool_true;
2470 jsetconstraint = eomc_string2jsetconstraint(t, usecompactstring);
2473 if(eomc_jsetconstraint_unknown == jsetconstraint)
2475 yError() <<
"embObjMC BOARD " << _boardname <<
"String" << t <<
"cannot be converted into a proper eOmc_jsetconstraint_t";
2483bool Parser::convert(Bottle &bottle, vector<double> &matrix,
bool &formaterror,
int targetsize)
2487 int tmp = bottle.size();
2488 int sizeofmatrix = tmp - 1;
2491 if(targetsize != sizeofmatrix)
2493 yError() <<
"embObjMC BOARD " << _boardname <<
" in converting string do matrix.In the matrix there are not" << targetsize <<
"elements";
2497 formaterror =
false;
2498 for(
int i=0; i<sizeofmatrix; i++)
2503 item = bottle.get(i+1).asFloat64();
2504 matrix.push_back(item);
2515void Parser::debugUtil_printControlLaws(
void)
2518 yError() <<
"position control law: ";
2519 for(
int x=0;
x<_njoints;
x++)
2521 yError() <<
" - j " <<
x << _positionControlLaw[
x].c_str();
2524 yError() <<
"velocity control law: ";
2525 for(
int x=0;
x<_njoints;
x++)
2527 yError() <<
"- j " <<
x << _velocityControlLaw[
x].c_str();
2531 yError() <<
"torque control law: ";
2532 for(
int x=0;
x<_njoints;
x++)
2534 yError() <<
" - j " <<
x << _torqueControlLaw[
x].c_str();
2573 switch(
cfg.constraints.type)
2575 case eomc_jsetconstraint_none:
2576 cout <<
"constraint is " <<
"eomc_jsetconstraint_none";
2578 case eomc_jsetconstraint_cerhand:
2579 cout <<
"constraint is " <<
"eomc_jsetconstraint_cerhand";
2581 case eomc_jsetconstraint_trifid:
2582 cout <<
"constraint is " <<
"eomc_jsetconstraint_trifid";
2585 cout <<
". constraint is " <<
"unknown";
2588 cout <<
" param1="<<
cfg.constraints.param1 <<
" param2=" <<
cfg.constraints.param2 << endl;
2592bool Parser::checkJointTypes(
PidInfo *pids,
const std::string &pid_type)
2596 int firstjoint = -1;
2599 if(pid_type ==
"TORQUE")
2605 for(
int i=0; i<_njoints; i++)
2608 if(firstjoint != -1 && !checkSinglePid(trq_pids[firstjoint], trq_pids[i], firstjoint, i, pid_type))
2613 if(firstjoint == -1 && trq_pids[i].enabled)
2621 for(
int i=0; i<_njoints; i++)
2624 if(firstjoint != -1 && !checkSinglePid(pids[firstjoint], pids[i], firstjoint, i, pid_type))
2629 if(firstjoint == -1 && pids[i].enabled)
2639bool Parser::checkSinglePid(
PidInfo &firstPid,
PidInfo ¤tPid,
const int &firstjoint,
const int ¤tjoint,
const std::string &pid_type)
2648 yError() <<
"embObjMC BOARD " << _boardname <<
"all joints with " << pid_type <<
" enabled should have same controlunits type. Joint " << firstjoint <<
" differs from joint " << currentjoint;
eOmc_jointset_configuration_t cfg
bool parseJointsetCfgGroup(yarp::os::Searchable &config, std::vector< JointsSet > &jsets, std::vector< int > &jointtoset)
bool parseJointsLimits(yarp::os::Searchable &config, std::vector< jointLimits_t > &jointsLimits)
bool parseAmpsToSensor(yarp::os::Searchable &config, double ampsToSensor[])
Parser(int numofjoints, std::string boardname)
bool parseMechanicalsFlags(yarp::os::Searchable &config, int useMotorSpeedFbk[])
bool parseMotioncontrolVersion(yarp::os::Searchable &config, int &version)
bool parseAxisInfo(yarp::os::Searchable &config, int axisMap[], std::vector< axisInfo_t > &axisInfo)
bool parseFocGroup(yarp::os::Searchable &config, focBasedSpecificInfo_t *foc_based_info, std::string groupName, std::vector< std::unique_ptr< eomc::ITemperatureSensor > > &temperatureSensorsVector)
bool parseCouplingInfo(yarp::os::Searchable &config, couplingInfo_t &couplingInfo)
bool parsePids(yarp::os::Searchable &config, PidInfo *ppids, TrqPidInfo *tpids, PidInfo *cpids, PidInfo *spids, bool lowLevPidisMandatory)
bool parseTemperatureLimits(yarp::os::Searchable &config, std::vector< temperatureLimits_t > &temperatureLimits)
bool parseDeadzoneValue(yarp::os::Searchable &config, double deadzone[], bool *found)
bool isVerboseEnabled(yarp::os::Searchable &config)
bool parseTimeoutsGroup(yarp::os::Searchable &config, std::vector< timeouts_t > &timeouts, int defaultVelocityTimeout)
bool parseCurrentLimits(yarp::os::Searchable &config, std::vector< motorCurrentLimits_t > &currLimits)
bool parseEncoderFactor(yarp::os::Searchable &config, double encoderFactor[])
bool parsefullscalePWM(yarp::os::Searchable &config, double dutycycleToPWM[])
bool parseRotorsLimits(yarp::os::Searchable &config, std::vector< rotorLimits_t > &rotorsLimits)
bool parseImpedanceGroup(yarp::os::Searchable &config, std::vector< impedanceParameters_t > &impedance)
bool parseKalmanFilterParams(yarp::os::Searchable &config, std::vector< kalmanFilterParams_t > &kalmanFilterParams)
bool parseGearboxValues(yarp::os::Searchable &config, double gearbox_M2J[], double gearbox_E2J[])
bool parseBehaviourFalgs(yarp::os::Searchable &config, bool &useRawEncoderData, bool &pwmIsLimited)
std::string usernamePidSelected
yarp::dev::PidFeedbackUnitsEnum fbk_PidUnits
eOmc_ctrl_out_type_t out_type
yarp::dev::PidOutputUnitsEnum out_PidUnits
yarp::dev::PidFeedbackUnitsEnum fbk_PidUnits
void setUnits(yarp::dev::PidFeedbackUnitsEnum fu, yarp::dev::PidOutputUnitsEnum ou)
eOmc_ctrl_out_type_t out_type
yarp::dev::PidOutputUnitsEnum out_PidUnits
virtual yarp::dev::Pid getPID(int joint)=0
double viscousPos
motor torque constant
double ktau
back-emf compensation parameter
#define LOAD_STRINGS(dest, source)
std::vector< double > matrixM2J
std::vector< double > matrixE2J
std::vector< double > matrixJ2M