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
43using namespace yarp::os;
45using namespace yarp::sig;
46using namespace yarp::math;
62 if (!
cmd.read(connection))
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);
609 for (
unsigned int i=0; i<
chainState->getN(); i++)
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++)
1128 chainPlan->setBlockingValue(chainCnt,tmp);
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++)
1252 if (_qdes.length()!=
ctrl->get_dim())
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");
1365 for (
unsigned int i=0; i<
chainState->getN(); i++)
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");
1413 for (
unsigned int i=0; i<
chainState->getN(); i++)
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");
1466 for (
unsigned int i=0; i<
chainState->getN(); i++)
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");
1505 for (
unsigned int i=0; i<
chainState->getN(); i++)
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");
1549 for (
unsigned int i=0; i<
chainState->getN(); i++)
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";
1688 bool inTarget=
ctrl->isInTarget();
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");
1995 Property DHTable;
limbState->toLinksProperties(DHTable);
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++)
2122 lDsc[i].minAbsVels[k]=tmp[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++)
2184 lVel[i]->setRefAcceleration(j,std::numeric_limits<double>::max());
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];
2626 for (
unsigned int i=0; i<
chainState->getN(); 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);
2768 for (
unsigned int i=0; i<
chainState->getN(); i++)
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());
2966 if (
connected && (min!=NULL) && (max!=NULL))
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);
3071 ctrl->setInTargetTol(tol);
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);
3135 Matrix J=
ctrl->get_J();
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;
3424 for (
unsigned int axis=0; axis<
chainState->getN(); axis++)
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"))
3811 ctrl->set_gamma(options.find(
"straightness").asFloat64());
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");
3839 straightness.addFloat64(
ctrl->get_gamma());
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
ServerCartesianController * server
void onRead(yarp::os::Bottle &command)
CartesianCtrlCommandPort(ServerCartesianController *server)
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
iCub::ctrl::Integrator * I
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.
A class for defining the iCub Arm.
A class for defining the iCub Leg.
yarp::sig::Vector EndEffPose(const bool axisRep=true)
Returns the coordinates of end-effector.
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.
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