29 #include <yarp/math/Math.h>
33 #define CARTCTRL_SERVER_VER "2.0"
34 #define CARTCTRL_DEFAULT_PER 0.01
35 #define CARTCTRL_DEFAULT_TASKVEL_PERFACTOR 4
36 #define CARTCTRL_DEFAULT_TOL 1e-2
37 #define CARTCTRL_DEFAULT_TRAJTIME 2.0
38 #define CARTCTRL_DEFAULT_POSCTRL "on"
39 #define CARTCTRL_DEFAULT_MULJNTCTRL "on"
40 #define CARTCTRL_CONNECT_SOLVER_PING 1.0
43 using namespace yarp::os;
45 using namespace yarp::sig;
46 using namespace yarp::math;
62 if (!
cmd.read(connection))
65 if (server->respond(
cmd,reply))
66 if (ConnectionWriter *writer=connection.getWriter())
88 int pose=command.get(1).asVocab32();
89 double t=command.get(2).asFloat64();
90 Bottle *v=command.get(3).asList();
95 Vector od(v->size()-xd.length());
97 for (
size_t i=0; i<xd.length(); i++)
98 xd[i]=v->get(i).asFloat64();
100 for (
size_t i=0; i<od.length(); i++)
101 od[i]=v->get(xd.length()+i).asFloat64();
103 server->goToPose(xd,od,t);
107 Vector xd(v->size());
109 for (
int i=0; i<v->size(); i++)
110 xd[i]=v->get(i).asFloat64();
112 server->goToPosition(xd,t);
117 Bottle *v=command.get(1).asList();
120 Vector odot(v->size()-xdot.length());
122 for (
size_t i=0; i<xdot.length(); i++)
123 xdot[i]=v->get(i).asFloat64();
125 for (
size_t i=0; i<odot.length(); i++)
126 odot[i]=v->get(xdot.length()+i).asFloat64();
128 server->setTaskVelocities(xdot,odot);
138 yAssert(x0.length()>=7);
140 R=axis2dcm(x0.subVector(3,6));
147 yAssert(x0.length()>=7);
148 I->reset(x0.subVector(0,2));
149 R=axis2dcm(x0.subVector(3,6));
156 yAssert(vel.length()>=7);
157 Vector w=vel.subVector(3,6);
160 return cat(I->integrate(vel.subVector(0,2)),dcm2axis(R));
235 string prefixName=
"/";
241 portCmd->open(prefixName+
"/command:i");
244 portRpc.open(prefixName+
"/rpc:i");
293 switch (command.get(0).asVocab32())
306 if (command.size()>3)
308 int pose=command.get(1).asVocab32();
309 double t=command.get(2).asFloat64();
310 Bottle *v=command.get(3).asList();
311 Vector xd(v->size());
313 for (
int i=0; i<v->size(); i++)
314 xd[i]=v->get(i).asFloat64();
320 lock_guard<mutex> lck(
mtx);
326 lock_guard<mutex> lck(
mtx);
353 Bottle slvCommand=command;
357 yError(
"%s: unable to get reply from solver!",
ctrlName.c_str());
382 if (command.size()>1)
384 int id=command.get(1).asInt32();
397 if (command.size()>1)
399 Bottle *ids=command.get(1).asList();
412 if (command.size()>1)
413 switch (command.get(1).asVocab32())
460 reply.addString(priority);
475 reply.addFloat64(
time);
490 reply.addFloat64(tol);
533 if (command.size()>2)
535 int axis=command.get(2).asInt32();
541 reply.addFloat64(
min);
542 reply.addFloat64(
max);
560 Bottle &dofPart=reply.addList();
562 for (
size_t i=0; i<curDof.length(); i++)
563 dofPart.addInt32((
int)curDof[i]);
578 reply.addList().read(curRestPos);
589 Vector curRestWeights;
593 reply.addList().read(curRestWeights);
630 reply.addList().read(qdot);
645 Bottle &xdotPart=reply.addList();
647 for (
size_t i=0; i<xdot.length(); i++)
648 xdotPart.addFloat64(xdot[i]);
650 for (
size_t i=0; i<odot.length(); i++)
651 xdotPart.addFloat64(odot[i]);
662 if (command.size()>2)
664 int axis=command.get(2).asInt32();
671 Bottle &posePart=reply.addList();
673 for (
size_t i=0; i<
x.length(); i++)
674 posePart.addFloat64(
x[i]);
676 for (
size_t i=0; i<o.length(); i++)
677 posePart.addFloat64(o[i]);
679 Bottle &stampPart=reply.addList();
680 stampPart.addInt32(stamp.getCount());
681 stampPart.addFloat64(stamp.getTime());
699 Bottle &tipPart=reply.addList();
701 for (
size_t i=0; i<
x.length(); i++)
702 tipPart.addFloat64(
x[i]);
704 for (
size_t i=0; i<o.length(); i++)
705 tipPart.addFloat64(o[i]);
720 reply.addList()=
info;
735 reply.addList()=options;
756 if (command.size()>2)
757 switch (command.get(1).asVocab32())
762 int mode=command.get(2).asVocab32();
781 int mode=command.get(2).asVocab32();
800 string priority=command.get(2).asString();
834 if (command.size()>4)
836 int axis=command.get(2).asInt32();
837 double min=command.get(3).asFloat64();
838 double max=command.get(4).asFloat64();
854 if (Bottle *b=command.get(2).asList())
856 Vector newDof(b->size());
859 for (
int i=0; i<b->size(); i++)
860 newDof[i]=b->get(i).asFloat64();
862 if (
setDOF(newDof,curDof))
865 Bottle &dofPart=reply.addList();
867 for (
size_t i=0; i<curDof.length(); i++)
868 dofPart.addInt32((
int)curDof[i]);
882 if (Bottle *b=command.get(2).asList())
884 Vector newRestPos(b->size());
887 for (
int i=0; i<b->size(); i++)
888 newRestPos[i]=b->get(i).asFloat64();
893 reply.addList().read(curRestPos);
907 if (Bottle *b=command.get(2).asList())
909 Vector newRestWeights(b->size());
910 Vector curRestWeights;
912 for (
int i=0; i<b->size(); i++)
913 newRestWeights[i]=b->get(i).asFloat64();
918 reply.addList().read(curRestWeights);
932 if (Bottle *b=command.get(2).asList())
937 Vector o(b->size()-
x.length());
939 for (
size_t i=0; i<
x.length(); i++)
940 x[i]=b->get(i).asFloat64();
942 for (
size_t i=0; i<o.length(); i++)
943 o[i]=b->get(i+
x.length()).asFloat64();
962 if (Bottle *options=command.get(2).asList())
988 if (command.size()>2)
989 switch (command.get(1).asVocab32())
994 int mode=command.get(2).asVocab32();
998 double checkPoint=command.get(3).asFloat64();
1013 int mode=command.get(2).asVocab32();
1017 double checkPoint=command.get(3).asFloat64();
1032 int mode=command.get(2).asVocab32();
1071 yInfo(
"%s: aligning joints bounds ...",
ctrlName.c_str());
1072 for (
size_t i=0; i<
lDsc.size(); i++)
1074 yInfo(
"part #%lu: %s",(
unsigned long)i,
lDsc[i].key.c_str());
1075 for (
int j=0; j<
lJnt[i]; j++)
1079 yError(
"joint #%d: failed getting limits!",cnt);
1083 yInfo(
"joint #%d: [%g, %g] deg",cnt,
min,
max);
1103 double timeStamp=-1.0;
1105 for (
int i=0; i<
numDrv; i++)
1110 ok=
lPid[i]->getPidReferences(VOCAB_PIDTYPE_POSITION,fbTmp.data());
1113 ok=
lEnt[i]->getEncodersTimed(fbTmp.data(),stamps.data());
1114 timeStamp=
std::max(timeStamp,findMax(stamps.subVector(0,
lJnt[i]-1)));
1117 ok=
lEnc[i]->getEncoders(fbTmp.data());
1121 for (
int j=0; j<
lJnt[i]; j++)
1136 else for (
int j=0; j<
lJnt[i]; j++)
1202 yWarning(
"%s: skipped message from solver due to invalid token (rx=%g)>(thr=%g)",
1214 yWarning(
"%s: skipped message from solver since controller has been stopped (rx=%g)<=(thr=%g)",
1224 Vector _xdes, _qdes;
1229 int l1=(int)b2->size();
1231 int len=l1<l2 ? l1 : l2;
1234 for (
int i=0; i<len; i++)
1235 _xdes[i]=b2->get(i).asFloat64();
1244 int l1=(int)b2->size();
1246 int len=l1<l2 ? l1 : l2;
1249 for (
int i=0; i<len; i++)
1254 yWarning(
"%s: skipped message from solver since does not match the controller dimension (qdes=%d)!=(ctrl=%d)",
1259 else if (!(_qdes==
qdes))
1290 jointsToSet.clear();
1293 lMod[i]->getControlModes(modes.data());
1294 for (
int j=0; j<
lJnt[i]; j++)
1298 int mode=modes[
lRmp[i][j]];
1299 if ((mode==VOCAB_CM_HW_FAULT) || (mode==VOCAB_CM_IDLE))
1303 if (mode!=VOCAB_CM_POSITION_DIRECT)
1304 jointsToSet.push_back(chainCnt);
1306 else if (mode!=VOCAB_CM_VELOCITY)
1307 jointsToSet.push_back(chainCnt);
1321 if (jointsToSet.size()==0)
1327 for (
int i=0; i<
numDrv; i++)
1331 for (
int j=0; j<
lJnt[i]; j++)
1333 if (chainCnt==jointsToSet[k])
1335 joints.push_back(
lRmp[i][j]);
1344 if (joints.size()>0)
1345 lMod[i]->setControlModes((
int)joints.size(),joints.data(),modes.data());
1360 info.addString(
"position");
1361 info.addString(
"multiple");
1369 int joint=
lRmp[j][k];
1372 joints.push_back(joint);
1373 refs.push_back(ref);
1376 ss<<
lDsc[j].key<<
"_"<<joint;
1377 info.addString(ss.str());
1378 info.addFloat64(ref);
1385 if (joints.size()>0)
1386 lPos[j]->setPositions((
int)joints.size(),joints.data(),refs.data());
1409 info.addString(
"velocity");
1410 info.addString(
"multiple");
1417 int joint=
lRmp[j][k];
1419 double thres=
lDsc[j].minAbsVels[k];
1422 if ((vel!=0.0) && (fabs(vel)<thres))
1423 vel=yarp::math::sign(
qdes[cnt]-
fb[cnt])*thres;
1425 joints.push_back(joint);
1426 vels.push_back(vel);
1429 ss<<
lDsc[j].key<<
"_"<<joint;
1430 info.addString(ss.str());
1431 info.addFloat64(vel);
1439 if (joints.size()>0)
1440 lVel[j]->velocityMove((
int)joints.size(),joints.data(),vels.data());
1461 info.addString(
"position");
1462 info.addString(
"single");
1470 int joint=
lRmp[j][k];
1472 lPos[j]->setPosition(joint,ref);
1475 ss<<
lDsc[j].key<<
"_"<<joint;
1476 info.addString(ss.str());
1477 info.addFloat64(ref);
1501 info.addString(
"velocity");
1502 info.addString(
"single");
1509 int joint=
lRmp[j][k];
1511 double thres=
lDsc[j].minAbsVels[k];
1514 if ((vel!=0.0) && (fabs(vel)<thres))
1515 vel=yarp::math::sign(
qdes[cnt]-
fb[cnt])*thres;
1517 lVel[j]->velocityMove(joint,vel);
1520 ss<<
lDsc[j].key<<
"_"<<joint;
1521 info.addString(ss.str());
1522 info.addFloat64(vel);
1546 info.addString(
"single");
1553 int joint=
lRmp[j][k];
1555 ss<<
lDsc[j].key<<
"_"<<joint;
1556 info.addString(ss.str());
1560 lStp[j]->stop(joint);
1561 info.addString(
"stop");
1566 lVel[j]->velocityMove(joint,0.0);
1567 info.addFloat64(0.0);
1595 yInfo(
"Starting %s at %d ms",
ctrlName.c_str(),(
int)(1000.0*getPeriod()));
1604 yInfo(
"%s started successfully",
ctrlName.c_str());
1606 yError(
"%s did not start!",
ctrlName.c_str());
1615 lock_guard<mutex> lck(
mtx);
1626 vector<int> jointsToSet;
1631 string event=
"none";
1664 event=
"motion-onset";
1698 event=
"motion-done";
1728 if (event==
"motion-onset")
1733 if (event==
"motion-done")
1758 yInfo(
"Stopping %s",
ctrlName.c_str());
1770 yInfo(
"***** Configuring cartesian controller *****");
1774 Bottle &optGeneral=config.findGroup(
"GENERAL");
1775 if (optGeneral.isNull())
1777 yError(
"GENERAL group is missing");
1782 yInfo(
"Acquiring options for group GENERAL...");
1785 if (optGeneral.check(
"SolverNameToConnect"))
1786 slvName=optGeneral.find(
"SolverNameToConnect").asString();
1789 yError(
"SolverNameToConnect option is missing");
1794 if (optGeneral.check(
"KinematicPart"))
1796 kinPart=optGeneral.find(
"KinematicPart").asString();
1799 yError(
"Attempt to instantiate an unknown kinematic part");
1800 yError(
"Available parts are: arm, leg, custom");
1807 yError(
"KinematicPart option is missing");
1812 string _partKinType;
1813 if (optGeneral.check(
"KinematicType"))
1815 kinType=optGeneral.find(
"KinematicType").asString();
1817 _partKinType=_kinType.substr(0,_kinType.find(
"_"));
1819 if ((_partKinType!=
"left") && (_partKinType!=
"right"))
1821 yError(
"Attempt to instantiate unknown kinematic type");
1822 yError(
"Available types are: left, right, left_v*, right_v*");
1829 yError(
"KinematicType option is missing");
1834 if (optGeneral.check(
"NumberOfDrivers"))
1836 numDrv=optGeneral.find(
"NumberOfDrivers").asInt32();
1839 yError(
"NumberOfDrivers shall be positive");
1846 yError(
"NumberOfDrivers option is missing");
1852 if (optGeneral.check(
"ControllerName"))
1853 ctrlName=optGeneral.find(
"ControllerName").asString();
1857 yWarning(
"default ControllerName assumed: %s",
ctrlName.c_str());
1860 if (optGeneral.check(
"ControllerPeriod"))
1861 setPeriod((
double)optGeneral.find(
"ControllerPeriod").asInt32()/1000.0);
1872 debugInfoEnabled=optGeneral.check(
"DebugInfo",Value(
"off")).asString()==
"on";
1874 yDebug(
"Commands to robot will be also streamed out on debug port");
1877 for (
int i=0; i<
numDrv; i++)
1879 ostringstream entry;
1880 entry<<
"DRIVER_"<<i;
1881 string entry_str(entry.str());
1883 Bottle &optDrv=config.findGroup(entry_str);
1884 if (optDrv.isNull())
1886 yError(
"%s group is missing",entry_str.c_str());
1891 yInfo(
"Acquiring options for group %s...",entry_str.c_str());
1895 if (optDrv.check(
"Key"))
1896 desc.
key=optDrv.find(
"Key").asString();
1899 yError(
"Key option is missing");
1904 if (optDrv.check(
"JointsOrder"))
1906 string jointsOrderType=optDrv.find(
"JointsOrder").asString();
1908 if (jointsOrderType==
"direct")
1910 else if (jointsOrderType==
"reversed")
1914 yError(
"Attempt to select an unknown mapping order");
1915 yError(
"Available orders are: direct, reversed");
1922 yError(
"JointsOrder option is missing");
1927 if (Bottle *pMinAbsVelsBottle=optDrv.find(
"MinAbsVels").asList())
1930 desc.
minAbsVels.resize(pMinAbsVelsBottle->size());
1932 for (
int j=0; j<pMinAbsVelsBottle->size(); j++)
1934 desc.
minAbsVels[j]=pMinAbsVelsBottle->get(j).asFloat64();
1942 yWarning(
"MinAbsVels option is missing ... using default values");
1946 lDsc.push_back(desc);
1950 Bottle &optPlantModel=config.findGroup(
"PLANT_MODEL");
1951 if (!optPlantModel.isNull())
1953 yInfo(
"PLANT_MODEL group detected");
1969 else if (optGeneral.check(
"CustomKinFile"))
1971 ResourceFinder rf_kin;
1972 if (optGeneral.check(
"CustomKinContext"))
1973 rf_kin.setDefaultContext(optGeneral.find(
"CustomKinContext").asString());
1974 rf_kin.configure(0,NULL);
1975 string pathToCustomKinFile=rf_kin.findFileByName(optGeneral.find(
"CustomKinFile").asString());
1977 Property linksOptions;
1983 yError(
"Invalid links parameters");
1990 yError(
"CustomKinFile option is missing");
1996 yInfo()<<
"DH Table: "<<DHTable.toString();
2038 yInfo(
"***** Attaching drivers to cartesian controller %s *****",
ctrlName.c_str());
2039 yInfo(
"Received list of %d driver(s)",nd);
2043 yError(
"Expected list of %d driver(s)",
numDrv);
2054 for (
int i=0; i<
numDrv; i++)
2056 yInfo(
"Acquiring info on driver %s...",
lDsc[i].key.c_str());
2060 for (j=0; j<
drivers.size(); j++)
2066 yError(
"None of provided drivers is of type %s",
lDsc[i].key.c_str());
2071 if (
drivers[j]->poly->isValid())
2073 yInfo(
"driver %s successfully open",
lDsc[i].key.c_str());
2077 IEncodersTimed *ent;
2079 IControlLimits *lim;
2080 IVelocityControl *vel;
2081 IPositionDirect *pos;
2082 IPositionControl *stp;
2096 enc->getAxes(&joints);
2104 if (joints>remainingJoints)
2105 joints=remainingJoints;
2107 remainingJoints-=joints;
2109 int *rmpTmp=
new int[joints];
2110 for (
int k=0; k<joints; k++)
2111 rmpTmp[k]=
lDsc[i].jointsDirectOrder ? k : (joints-k-1);
2114 if (
lDsc[i].useDefaultMinAbsVel)
2115 lDsc[i].minAbsVels.resize(joints,0.0);
2116 else if (
lDsc[i].minAbsVels.length()<(
size_t)joints)
2118 Vector
tmp=
lDsc[i].minAbsVels;
2119 lDsc[i].minAbsVels.resize(joints,0.0);
2121 for (
size_t k=0; k<
tmp.length(); k++)
2125 lMod.push_back(mod);
2126 lEnc.push_back(enc);
2127 lEnt.push_back(ent);
2128 lPid.push_back(pid);
2129 lLim.push_back(lim);
2130 lPos.push_back(pos);
2131 lStp.push_back(stp);
2132 lJnt.push_back(joints);
2133 lRmp.push_back(rmpTmp);
2134 lVel.push_back(vel);
2138 yError(
"unable to open driver %s",
lDsc[i].key.c_str());
2143 yInfo(
"%s: IControlMode %s",
ctrlName.c_str(),
2146 yInfo(
"%s: %s interface will be used",
ctrlName.c_str(),
2149 yInfo(
"%s: IPidControl %s",
ctrlName.c_str(),
2152 yInfo(
"%s: IPositionDirect %s",
ctrlName.c_str(),
2156 yInfo(
"%s: %s interface will be used",
ctrlName.c_str(),
2159 yInfo(
"%s: %s control will be used",
ctrlName.c_str(),
2176 yError(
"unable to retrieve joints limits");
2182 for (
int i=0; i<
numDrv; i++)
2183 for (
int j=0; j<
lJnt[i]; j++)
2222 for (
unsigned int i=0; i<
lRmp.size(); i++)
2251 string portSlvName=
"/";
2252 portSlvName=portSlvName+
slvName+
"/in";
2254 bool ok=Network::exists(portSlvName,
true);
2255 yInfo(
"%s: Checking if cartesian solver %s is alive... %s",
2267 yInfo(
"%s: Connecting to cartesian solver %s...",
ctrlName.c_str(),
slvName.c_str());
2269 string portSlvName=
"/";
2270 portSlvName=portSlvName+
slvName;
2274 ok&=Network::connect(portSlvName+
"/out",
portSlvIn.getName(),
"udp");
2275 ok&=Network::connect(
portSlvOut.getName(),portSlvName+
"/in",
"udp");
2276 ok&=Network::connect(
portSlvRpc.getName(),portSlvName+
"/rpc");
2279 yInfo(
"%s: Connections established with %s",
ctrlName.c_str(),
slvName.c_str());
2282 yError(
"%s: Problems detected while connecting to %s",
ctrlName.c_str(),
slvName.c_str());
2291 Bottle command, reply;
2298 yError(
"%s: unable to get reply from solver!",
ctrlName.c_str());
2304 Bottle *rxDofPart=reply.get(1).asList();
2305 for (
int i=0; i<rxDofPart->size(); i++)
2307 if (rxDofPart->get(i).asInt32()!=0)
2329 const double t,
const bool latchToken)
2375 Bottle command, reply;
2383 yError(
"%s: unable to get reply from solver!",
ctrlName.c_str());
2400 lock_guard<mutex> lck(
mtx);
2448 if (
connected && ((
p==
"position") || (
p==
"orientation")))
2450 lock_guard<mutex> lck(
mtx);
2452 Bottle command, reply;
2461 yError(
"%s: unable to get reply from solver!",
ctrlName.c_str());
2474 Bottle command, reply;
2483 "position":
"orientation";
2486 yError(
"%s: unable to get reply from solver!",
ctrlName.c_str());
2498 lock_guard<mutex> lck(
mtx);
2502 o.resize(pose.length()-
x.length());
2504 for (
size_t i=0; i<
x.length(); i++)
2507 for (
size_t i=0; i<o.length(); i++)
2508 o[i]=pose[
x.length()+i];
2522 Vector &o, Stamp *stamp)
2526 lock_guard<mutex> lck(
mtx);
2534 for (
size_t i=0; i<
x.length(); i++)
2559 lock_guard<mutex> lck(
mtx);
2561 Vector _xd(xd.length()+od.length());
2562 for (
size_t i=0; i<xd.length(); i++)
2565 for (
size_t i=0; i<od.length(); i++)
2566 _xd[xd.length()+i]=od[i];
2581 lock_guard<mutex> lck(
mtx);
2612 lock_guard<mutex> lck(
mtx);
2615 odhat.resize(
xdes.length()-3);
2617 for (
size_t i=0; i<xdhat.length(); i++)
2620 for (
size_t i=0; i<odhat.length(); i++)
2621 odhat[i]=
xdes[xdhat.length()+i];
2643 Vector &xdhat, Vector &odhat,
2649 lock_guard<mutex> lck(
mtx);
2651 Bottle command, reply;
2652 Vector tg(xd.length()+od.length());
2653 for (
size_t i=0; i<xd.length(); i++)
2656 for (
size_t i=0; i<od.length(); i++)
2657 tg[xd.length()+i]=od[i];
2668 yError(
"%s: unable to get reply from solver!",
ctrlName.c_str());
2676 const Vector &od, Vector &xdhat,
2677 Vector &odhat, Vector &qdhat)
2682 lock_guard<mutex> lck(
mtx);
2684 Bottle command, reply;
2685 Vector tg(xd.length()+od.length());
2686 for (
size_t i=0; i<xd.length(); i++)
2689 for (
size_t i=0; i<od.length(); i++)
2690 tg[xd.length()+i]=od[i];
2702 yError(
"%s: unable to get reply from solver!",
ctrlName.c_str());
2710 Vector &odhat, Vector &qdhat)
2715 lock_guard<mutex> lck(
mtx);
2717 Bottle command, reply;
2727 yError(
"%s: unable to get reply from solver!",
ctrlName.c_str());
2735 Vector &xdhat, Vector &odhat,
2741 lock_guard<mutex> lck(
mtx);
2743 Bottle command, reply;
2754 yError(
"%s: unable to get reply from solver!",
ctrlName.c_str());
2765 lock_guard<mutex> lck(
mtx);
2783 lock_guard<mutex> lck(
mtx);
2785 Bottle command, reply;
2788 Bottle &txDofPart=command.addList();
2789 for (
size_t i=0; i<newDof.length(); i++)
2790 txDofPart.addInt32((
int)newDof[i]);
2798 Bottle *rxDofPart=reply.get(1).asList();
2799 curDof.resize((
size_t)rxDofPart->size());
2800 for (
int i=0; i<rxDofPart->size(); i++)
2802 curDof[i]=rxDofPart->get(i).asInt32();
2820 yError(
"%s: unable to get reply from solver!",
ctrlName.c_str());
2834 lock_guard<mutex> lck(
mtx);
2836 Bottle command, reply;
2844 Bottle *rxRestPart=reply.get(1).asList();
2845 curRestPos.resize(rxRestPart->size());
2846 for (
int i=0; i<rxRestPart->size(); i++)
2847 curRestPos[i]=rxRestPart->get(i).asFloat64();
2852 yError(
"%s: unable to get reply from solver!",
ctrlName.c_str());
2867 lock_guard<mutex> lck(
mtx);
2869 Bottle command, reply;
2872 command.addList().read(newRestPos);
2878 Bottle *rxRestPart=reply.get(1).asList();
2879 curRestPos.resize(rxRestPart->size());
2880 for (
int i=0; i<rxRestPart->size(); i++)
2881 curRestPos[i]=rxRestPart->get(i).asFloat64();
2886 yError(
"%s: unable to get reply from solver!",
ctrlName.c_str());
2900 lock_guard<mutex> lck(
mtx);
2902 Bottle command, reply;
2910 Bottle *rxRestPart=reply.get(1).asList();
2911 curRestWeights.resize(rxRestPart->size());
2912 for (
int i=0; i<rxRestPart->size(); i++)
2913 curRestWeights[i]=rxRestPart->get(i).asFloat64();
2918 yError(
"%s: unable to get reply from solver!",
ctrlName.c_str());
2929 Vector &curRestWeights)
2933 lock_guard<mutex> lck(
mtx);
2935 Bottle command, reply;
2938 command.addList().read(newRestWeights);
2944 Bottle *rxRestPart=reply.get(1).asList();
2945 curRestWeights.resize(rxRestPart->size());
2946 for (
int i=0; i<rxRestPart->size(); i++)
2947 curRestWeights[i]=rxRestPart->get(i).asFloat64();
2952 yError(
"%s: unable to get reply from solver!",
ctrlName.c_str());
2968 lock_guard<mutex> lck(
mtx);
2971 Bottle command, reply;
2974 command.addInt32(axis);
2978 yError(
"%s: unable to get reply from solver!",
ctrlName.c_str());
2981 *
min=reply.get(1).asFloat64();
2982 *
max=reply.get(2).asFloat64();
2999 lock_guard<mutex> lck(
mtx);
3001 Bottle command, reply;
3004 command.addInt32(axis);
3005 command.addFloat64(
min);
3006 command.addFloat64(
max);
3012 yError(
"%s: unable to get reply from solver!",
ctrlName.c_str());
3048 lock_guard<mutex> lck(
mtx);
3095 Matrix Des=axis2dcm(
xdes.subVector(3,6));
3096 Vector ax=dcm2axis(Des*SE3inv(
H));
3109 lock_guard<mutex> lck(
mtx);
3119 lock_guard<mutex> lck(
mtx);
3133 lock_guard<mutex> lck(
mtx);
3136 Vector taskVel(7,0.0);
3138 if ((J.rows()>0) && (J.cols()==
velCmd.length()))
3142 Vector _odot=taskVel.subVector(3,(
unsigned int)taskVel.length()-1);
3143 double thetadot=
norm(_odot);
3147 taskVel[3]=_odot[0];
3148 taskVel[4]=_odot[1];
3149 taskVel[5]=_odot[2];
3150 taskVel.push_back(thetadot);
3154 odot.resize(taskVel.length()-xdot.length());
3156 for (
size_t i=0; i<xdot.length(); i++)
3159 for (
size_t i=0; i<odot.length(); i++)
3160 odot[i]=taskVel[xdot.length()+i];
3175 lock_guard<mutex> lck(
mtx);
3177 for (
int i=0; i<3; i++)
3180 for (
size_t i=3; i<
xdot_set.length(); i++)
3206 if (
connected && (
x.length()>=3) || (o.length()>=4))
3208 lock_guard<mutex> lck(
mtx);
3210 Bottle command, reply;
3213 Bottle &txTipPart=command.addList();
3215 for (
int i=0; i<3; i++)
3216 txTipPart.addFloat64(
x[i]);
3218 for (
int i=0; i<4; i++)
3219 txTipPart.addFloat64(o[i]);
3227 Matrix HN=axis2dcm(o);
3236 yError(
"%s: unable to get reply from solver!",
ctrlName.c_str());
3250 lock_guard<mutex> lck(
mtx);
3286 const double timeout)
3289 double t0=Time::now();
3293 Time::delay(period);
3337 lock_guard<mutex> lck(
mtx);
3351 Vector _dof,_restPos,_restWeights;
3352 Vector _tip_x,_tip_o;
3359 Matrix _limits(N,2);
3360 for (
unsigned int axis=0; axis<N; axis++)
3364 _limits(axis,0)=
min;
3365 _limits(axis,1)=
max;
3368 double _trajTime,_tol;
3369 bool _mode,_useReference;
3376 lock_guard<mutex> lck(
mtx);
3383 context.
tip_x=_tip_x;
3384 context.
tip_o=_tip_o;
3409 map<int,Context>::iterator itr=
contextMap.find(
id);
3413 context=itr->second;
3449 map<int,Context>::iterator itr=
contextMap.find(
id);
3463 if (contextIdList!=NULL)
3465 lock_guard<mutex> lck(
mtx);
3467 for (
int i=0; i<contextIdList->size(); i++)
3469 int id=contextIdList->get(i).asInt32();
3470 map<int,Context>::iterator itr=
contextMap.find(
id);
3489 Bottle &serverVer=
info.addList();
3490 serverVer.addString(
"server_version");
3496 size_t pos=type.find(
"_v");
3498 if (pos!=string::npos)
3501 Bottle &partVer=
info.addList();
3502 partVer.addString(kinPartStr+
"_version");
3505 Bottle &partType=
info.addList();
3506 partType.addString(kinPartStr+
"_type");
3507 partType.addString(type);
3509 Bottle &events=
info.addList();
3510 events.addString(
"events");
3511 Bottle &eventsList=events.addList();
3512 eventsList.addString(
"motion-onset");
3513 eventsList.addString(
"motion-done");
3514 eventsList.addString(
"motion-ongoing");
3515 eventsList.addString(
"closing");
3516 eventsList.addString(
"*");
3527 const double checkPoint)
3530 map<string,CartesianEvent*>::iterator itr;
3537 ev.addString(event);
3538 ev.addFloat64(
time);
3539 if (checkPoint>=0.0)
3540 ev.addFloat64(checkPoint);
3551 if (itr->second!=NULL)
3553 CartesianEvent &Event=*itr->second;
3554 Event.cartesianEventVariables.type=event;
3555 Event.cartesianEventVariables.time=
time;
3557 if (checkPoint>=0.0)
3558 Event.cartesianEventVariables.motionOngoingCheckPoint=checkPoint;
3560 Event.cartesianEventCallback();
3564 string typeExtended=event;
3565 if (checkPoint>=0.0)
3568 ss<<
event<<
"-"<<checkPoint;
3569 typeExtended=ss.str();
3576 if (itr->second!=NULL)
3578 CartesianEvent &Event=*itr->second;
3579 Event.cartesianEventVariables.type=event;
3580 Event.cartesianEventVariables.time=
time;
3582 if (checkPoint>=0.0)
3583 Event.cartesianEventVariables.motionOngoingCheckPoint=checkPoint;
3585 Event.cartesianEventCallback();
3597 string type=
event.cartesianEventParameters.type;
3598 if (type==
"motion-ongoing")
3600 double checkPoint=
event.cartesianEventParameters.motionOngoingCheckPoint;
3604 ss<<type<<
"-"<<checkPoint;
3619 string type=
event.cartesianEventParameters.type;
3620 if (type==
"motion-ongoing")
3622 double checkPoint=
event.cartesianEventParameters.motionOngoingCheckPoint;
3626 ss<<type<<
"-"<<
event.cartesianEventParameters.motionOngoingCheckPoint;
3665 if ((checkPoint>=0.0) && (checkPoint<=1.0))
3667 lock_guard<mutex> lck(
mtx);
3680 if ((checkPoint>=0.0) && (checkPoint<=1.0))
3682 lock_guard<mutex> lck(
mtx);
3700 lock_guard<mutex> lck(
mtx);
3702 events.addFloat64(*itr);
3714 Bottle command, reply;
3725 yError(
"%s: unable to get reply from solver!",
ctrlName.c_str());
3738 lock_guard<mutex> lck(
mtx);
3740 Bottle command, reply;
3749 yError(
"%s: unable to get reply from solver!",
ctrlName.c_str());
3762 Bottle command, reply;
3770 options=*reply.get(1).asList();
3773 yError(
"%s: unable to get reply from solver!",
ctrlName.c_str());
3786 lock_guard<mutex> lck(
mtx);
3788 Bottle command, reply;
3791 command.addList()=options;
3797 yError(
"%s: unable to get reply from solver!",
ctrlName.c_str());
3810 if (options.check(
"straightness"))
3814 if (options.check(
"task_2"))
3818 if (options.check(
"tol") || options.check(
"constr_tol") ||
3819 options.check(
"max_iter"))
3831 lock_guard<mutex> lck(
mtx);
3837 Bottle &straightness=options.addList();
3838 straightness.addString(
"straightness");
3846 Bottle &task2=options.addList();
3847 task2.addString(
"task_2");
#define IKINCARTCTRL_VOCAB_OPT_Q
#define IKINCARTCTRL_VOCAB_OPT_INFO
#define IKINCARTCTRL_VOCAB_VAL_POSE_XYZ
#define IKINCARTCTRL_VOCAB_OPT_PRIO
#define IKINCARTCTRL_VOCAB_OPT_UNREGISTER
#define IKINCARTCTRL_VOCAB_VAL_TRUE
#define IKINCARTCTRL_VOCAB_CMD_GO
#define IKINCARTCTRL_VOCAB_OPT_REST_POS
#define IKINCARTCTRL_VOCAB_OPT_REFERENCE
#define IKINCARTCTRL_VOCAB_OPT_DES
#define IKINCARTCTRL_VOCAB_OPT_LIM
#define IKINCARTCTRL_VOCAB_OPT_QDOT
#define IKINCARTCTRL_VOCAB_OPT_LIST
#define IKINCARTCTRL_VOCAB_OPT_X
#define IKINCARTCTRL_VOCAB_REP_ACK
#define IKINCARTCTRL_VOCAB_VAL_FALSE
#define IKINCARTCTRL_VOCAB_CMD_STORE
#define IKINCARTCTRL_VOCAB_OPT_TIME
#define IKINCARTCTRL_VOCAB_CMD_DELETE
#define IKINCARTCTRL_VOCAB_OPT_MODE
#define IKINCARTCTRL_VOCAB_CMD_TASKVEL
#define IKINCARTCTRL_VOCAB_VAL_POSE_FULL
#define IKINCARTCTRL_VOCAB_VAL_MODE_TRACK
#define IKINCARTCTRL_VOCAB_OPT_DOF
#define IKINCARTCTRL_VOCAB_OPT_TOL
#define IKINCARTCTRL_VOCAB_VAL_MODE_SINGLE
#define IKINCARTCTRL_VOCAB_CMD_ASK
#define IKINCARTCTRL_VOCAB_CMD_SET
#define IKINCARTCTRL_VOCAB_OPT_REST_WEIGHTS
#define IKINCARTCTRL_VOCAB_CMD_RESTORE
#define IKINCARTCTRL_VOCAB_OPT_ISSOLVERON
#define IKINCARTCTRL_VOCAB_OPT_TIP_FRAME
#define IKINCARTCTRL_VOCAB_CMD_EVENT
#define IKINCARTCTRL_VOCAB_OPT_XDOT
#define IKINCARTCTRL_VOCAB_OPT_TWEAK
#define IKINCARTCTRL_VOCAB_OPT_POSE
#define IKINCARTCTRL_VOCAB_CMD_STOP
#define IKINCARTCTRL_VOCAB_OPT_REGISTER
#define IKINCARTCTRL_VOCAB_VAL_EVENT_ONGOING
#define IKINCARTCTRL_VOCAB_REP_NACK
#define IKINCARTCTRL_VOCAB_OPT_MOTIONDONE
#define CARTCTRL_DEFAULT_TRAJTIME
#define CARTCTRL_DEFAULT_POSCTRL
#define CARTCTRL_CONNECT_SOLVER_PING
#define CARTCTRL_DEFAULT_TASKVEL_PERFACTOR
#define CARTCTRL_SERVER_VER
#define CARTCTRL_DEFAULT_PER
#define CARTCTRL_DEFAULT_MULJNTCTRL
#define CARTCTRL_DEFAULT_TOL
void onRead(yarp::os::Bottle &command)
CartesianCtrlCommandPort(ServerCartesianController *server)
CartesianCtrlRpcProcessor(ServerCartesianController *server)
bool read(yarp::os::ConnectionReader &connection)
servercartesiancontroller : implements the server part of the Cartesian Interface.
bool tweakSet(const yarp::os::Bottle &options)
yarp::os::BufferedPort< yarp::os::Bottle > portEvent
bool setTrackingMode(const bool f)
iCub::iKin::MultiRefMinJerkCtrl * ctrl
iCub::iKin::iKinLimb * limbState
double txTokenLatchedStopControl
bool deleteContexts(yarp::os::Bottle *contextIdList)
yarp::os::Property plantModelProperties
std::deque< yarp::dev::IVelocityControl * > lVel
yarp::os::Bottle sendCtrlCmdSingleJointPosition()
yarp::os::Bottle listMotionOngoingEvents()
virtual ~ServerCartesianController()
yarp::os::BufferedPort< yarp::sig::Vector > portState
void notifyEvent(const std::string &event, const double checkPoint=-1.0)
friend class CartesianCtrlRpcProcessor
std::deque< yarp::dev::IPositionControl * > lStp
yarp::os::Bottle sendCtrlCmdMultipleJointsVelocity()
bool askForPosition(const yarp::sig::Vector &xd, yarp::sig::Vector &xdhat, yarp::sig::Vector &odhat, yarp::sig::Vector &qdhat)
std::map< int, Context > contextMap
bool getDOF(yarp::sig::Vector &curDof)
yarp::os::Bottle sendCtrlCmdMultipleJointsPosition()
yarp::os::RpcClient portSlvRpc
std::deque< DriverDescriptor > lDsc
bool getRestWeights(yarp::sig::Vector &curRestWeights)
bool setTrajTimeHelper(const double t)
yarp::os::Stamp debugInfo
double txTokenLatchedGoToRpc
yarp::os::BufferedPort< yarp::os::Bottle > portDebugInfo
yarp::sig::Vector xdot_set
CartesianCtrlRpcProcessor * rpcProcessor
bool getTipFrame(yarp::sig::Vector &x, yarp::sig::Vector &o)
friend class CartesianCtrlCommandPort
bool getTrajTime(double *t)
bool goToPosition(const yarp::sig::Vector &xd, const double t=0.0)
bool attachAll(const yarp::dev::PolyDriverList &p)
void motionOngoingEventsHandling()
std::deque< yarp::dev::IEncodersTimed * > lEnt
iCub::iKin::iKinChain * chainState
bool setLimits(const int axis, const double min, const double max)
double getFeedback(yarp::sig::Vector &_fb)
bool multipleJointsControlEnabled
bool checkMotionDone(bool *f)
bool open(yarp::os::Searchable &config)
bool setTrackingModeHelper(const bool f)
yarp::os::Bottle sendCtrlCmdSingleJointVelocity()
bool getReferenceMode(bool *f)
bool getPosePriority(std::string &p)
bool getInTargetTol(double *tol)
bool setRestWeights(const yarp::sig::Vector &newRestWeights, yarp::sig::Vector &curRestWeights)
yarp::os::Bottle(ServerCartesianController::* sendCtrlCmd)()
std::multiset< double > motionOngoingEventsCurrent
bool attachTipFrame(const yarp::sig::Vector &x, const yarp::sig::Vector &o)
yarp::os::BufferedPort< yarp::os::Bottle > portSlvOut
bool setTrajTime(const double t)
bool getTask2ndOptions(yarp::os::Value &v)
std::deque< yarp::dev::IControlMode * > lMod
bool registerEvent(yarp::dev::CartesianEvent &event)
bool getLimits(const int axis, double *min, double *max)
bool unregisterMotionOngoingEvent(const double checkPoint)
yarp::os::RpcServer portRpc
std::deque< yarp::dev::IControlLimits * > lLim
void setJointsCtrlMode(const std::vector< int > &jointsToSet)
bool tweakGet(yarp::os::Bottle &options)
bool waitMotionDone(const double period=0.1, const double timeout=0.0)
bool setTask2ndOptions(const yarp::os::Value &v)
bool setInTargetTolHelper(const double tol)
bool respond(const yarp::os::Bottle &command, yarp::os::Bottle &reply)
bool getSolverConvergenceOptions(yarp::os::Bottle &options)
bool setPosePriority(const std::string &p)
bool askForPose(const yarp::sig::Vector &xd, const yarp::sig::Vector &od, yarp::sig::Vector &xdhat, yarp::sig::Vector &odhat, yarp::sig::Vector &qdhat)
bool getTaskVelocities(yarp::sig::Vector &xdot, yarp::sig::Vector &odot)
int taskRefVelPeriodFactor
bool goToPoseSync(const yarp::sig::Vector &xd, const yarp::sig::Vector &od, const double t=0.0)
bool getInfo(yarp::os::Bottle &info)
bool setSolverConvergenceOptions(const yarp::os::Bottle &options)
iCub::iKin::iKinLimb * limbPlan
TaskRefVelTargetGenerator * taskRefVelTargetGen
bool goToPose(const yarp::sig::Vector &xd, const yarp::sig::Vector &od, const double t=0.0)
std::map< std::string, yarp::dev::CartesianEvent * > eventsMap
bool unregisterEvent(yarp::dev::CartesianEvent &event)
bool goTo(unsigned int _ctrlPose, const yarp::sig::Vector &xd, const double t, const bool latchToken=false)
bool areJointsHealthyAndSet(std::vector< int > &jointsToSet)
void motionOngoingEventsFlush()
yarp::os::BufferedPort< yarp::os::Bottle > portSlvIn
bool setTaskVelocities(const yarp::sig::Vector &xdot, const yarp::sig::Vector &odot)
std::multiset< double > motionOngoingEvents
bool goToPositionSync(const yarp::sig::Vector &xd, const double t=0.0)
CartesianCtrlCommandPort * portCmd
bool setRestPos(const yarp::sig::Vector &newRestPos, yarp::sig::Vector &curRestPos)
iCub::iKin::iKinChain * chainPlan
bool storeContext(int *id)
ServerCartesianController()
bool restoreContext(const int id)
bool getTrackingMode(bool *f)
std::deque< yarp::dev::IPositionDirect * > lPos
bool setReferenceMode(const bool f)
std::deque< yarp::dev::IEncoders * > lEnc
yarp::os::Stamp eventInfo
void stopLimb(const bool execStopPosition=true)
yarp::dev::PolyDriverList drivers
std::condition_variable cv_syncEvent
bool setInTargetTol(const double tol)
bool deleteContext(const int id)
bool setDOF(const yarp::sig::Vector &newDof, yarp::sig::Vector &curDof)
bool getRestPos(yarp::sig::Vector &curRestPos)
bool getPose(yarp::sig::Vector &x, yarp::sig::Vector &o, yarp::os::Stamp *stamp=NULL)
bool getDesired(yarp::sig::Vector &xdhat, yarp::sig::Vector &odhat, yarp::sig::Vector &qdhat)
bool getJointsVelocities(yarp::sig::Vector &qdot)
SmithPredictor smithPredictor
bool registerMotionOngoingEvent(const double checkPoint)
std::deque< yarp::dev::IPidControl * > lPid
void configure(const yarp::os::Property &options, iCub::iKin::iKinChain &chain)
yarp::sig::Vector computeCmd(const yarp::sig::Vector &u)
void restart(const yarp::sig::Vector &y0)
void reset(const yarp::sig::Vector &x0)
yarp::sig::Vector integrate(const yarp::sig::Vector &vel)
virtual ~TaskRefVelTargetGenerator()
TaskRefVelTargetGenerator(const double Ts, const yarp::sig::Vector &x0)
A class for defining a saturated integrator based on Tustin formula: .
static yarp::os::Bottle * getEndEffectorPoseOption(const yarp::os::Bottle &b)
Retrieves the end-effector pose data.
static void addVectorOption(yarp::os::Bottle &b, const int vcb, const yarp::sig::Vector &v)
static yarp::os::Bottle * getJointsOption(const yarp::os::Bottle &b)
Retrieves the joints configuration data.
static void addModeOption(yarp::os::Bottle &b, const bool tracking)
Appends to a bottle all data needed to change the tracking mode.
static void addTargetOption(yarp::os::Bottle &b, const yarp::sig::Vector &xd)
Appends to a bottle all data needed to command a target.
static bool getDesiredOption(const yarp::os::Bottle &reply, yarp::sig::Vector &xdhat, yarp::sig::Vector &odhat, yarp::sig::Vector &qdhat)
static bool getTokenOption(const yarp::os::Bottle &b, double *token)
Retrieves the token from the bottle.
static void addTokenOption(yarp::os::Bottle &b, const double token)
Appends to a bottle a token to be exchanged with the solver.
static void addPoseOption(yarp::os::Bottle &b, const unsigned int pose)
Appends to a bottle all data needed to change the pose mode.
A class derived from iKinCtrl implementing the multi-referential approach.
void setPlantParameters(const yarp::os::Property ¶meters, const std::string &entryTag="dimension")
Allows user to assign values to the parameters of plant under control (for the configuration space on...
virtual yarp::sig::Vector iterate(yarp::sig::Vector &xd, yarp::sig::Vector &qd, yarp::sig::Vector *xdot_set, const unsigned int verbose)
void add_compensation(const yarp::sig::Vector &comp)
Adds to the controller input a further compensation term.
double set_execTime(const double _execTime, const bool warn=false)
Sets the task execution time in seconds.
yarp::sig::Vector get_qdot() const
Returns the actual derivative of joint angles.
virtual void set_q(const yarp::sig::Vector &q0)
Sets the joint angles values.
double get_gamma() const
Returns the parameter gamma which is used to blend the contribute of the task controller versus the c...
void set_gamma(double _gamma)
Sets the parameter gamma which is used to blend the contribute of the task controller versus the cont...
virtual void restart(const yarp::sig::Vector &q0)
Reinitializes the algorithm's internal state and resets the starting point.
A class for defining the iCub Arm.
A class for defining the iCub Leg.
yarp::sig::Matrix getH(const unsigned int i, const bool allLink=false)
Returns the rigid roto-translation matrix from the root reference frame to the ith frame in Denavit-H...
yarp::sig::Matrix getHN() const
Returns HN, the rigid roto-translation matrix from the Nth frame to the end-effector.
bool setHN(const yarp::sig::Matrix &_HN)
Sets HN, the rigid roto-translation matrix from the Nth frame to the end-effector.
bool releaseLink(const unsigned int i)
Releases the ith Link.
bool setBlockingValue(const unsigned int i, double Ang)
Changes the value of the ith blocked Link.
yarp::sig::Vector EndEffPose(const bool axisRep=true)
Returns the coordinates of end-effector.
yarp::sig::Vector getAng()
Returns the current free joint angles values.
yarp::sig::Vector setAng(const yarp::sig::Vector &q)
Sets the free joint angles to values of q[i].
unsigned int getN() const
Returns the number of Links belonging to the Chain.
unsigned int getDOF() const
Returns the current number of Chain's DOF.
bool blockLink(const unsigned int i, double Ang)
Blocks the ith Link at the a certain value of its joint angle.
virtual bool isInTarget()
Checks if the End-Effector is in target.
virtual yarp::sig::Matrix get_J() const
Returns the actual Jacobian used in computation.
virtual yarp::sig::Vector get_q() const
Returns the actual joint angles values.
virtual void setInTargetTol(double tol_x)
Sets tolerance for in-target check (5e-3 by default).
unsigned int get_dim() const
Returns the number of Chain DOF.
void set_ctrlPose(unsigned int _ctrlPose)
Sets the state of Pose control settings.
virtual yarp::sig::Vector get_x() const
Returns the actual cartesian position of the End-Effector.
virtual double getInTargetTol() const
Returns tolerance for in-target check.
A class for defining the versions of the iCub limbs.
std::string get_version() const
Return the version string.
A class for defining generic Limb.
iKinChain * asChain()
Returns a pointer to the Limb seen as Chain object.
std::string getType() const
Returns the Limb type as a string.
bool toLinksProperties(yarp::os::Property &options)
Provides the links attributes listed in a property object.
bool isValid() const
Checks if the limb has been properly configured.
double norm(const yarp::sig::Matrix &M, int col)
Returns the norm of the vector given in the form: matrix(:,col).
#define IKINCTRL_POSE_FULL
#define IKINCTRL_POSE_XYZ
#define IKINCTRL_POSE_ANG
#define IKINSLV_VOCAB_OPT_DOF
#define IKINSLV_VOCAB_OPT_PRIO
#define IKINSLV_VOCAB_VAL_PRIO_XYZ
#define IKINSLV_VOCAB_VAL_MODE_TRACK
#define IKINSLV_VOCAB_VAL_MODE_SINGLE
#define IKINSLV_VOCAB_OPT_Q
#define IKINSLV_VOCAB_OPT_CONVERGENCE
#define IKINSLV_VOCAB_OPT_MODE
#define IKINSLV_VOCAB_CMD_SET
#define IKINSLV_VOCAB_CMD_ASK
#define IKINSLV_VOCAB_REP_ACK
#define IKINSLV_VOCAB_OPT_REST_POS
#define IKINSLV_VOCAB_OPT_TIP_FRAME
#define IKINSLV_VOCAB_CMD_GET
#define IKINSLV_VOCAB_OPT_LIM
#define IKINSLV_VOCAB_OPT_TASK2
#define IKINSLV_VOCAB_OPT_REST_WEIGHTS
#define IKINSLV_VOCAB_REP_NACK
#define IKINSLV_VOCAB_OPT_X
#define IKINSLV_VOCAB_VAL_PRIO_ANG
#define IKINSLV_VOCAB_OPT_XD
static string pathToCustomKinFile
yarp::sig::Vector minAbsVels
yarp::os::Bottle solverConvergence
yarp::sig::Vector restPos
yarp::sig::Vector restWeights