22 #include <gsl/gsl_math.h>
24 #include <yarp/math/Math.h>
26 #include <iCub/ctrl/math.h>
27 #include <iCub/d4c/d4c_server.h>
28 #include <iCub/d4c/private/d4c_helpers.h>
46 orientation.resize(4,0.0);
53 bool Item::fromProperty(
const Property &options)
55 if (options.check(
"name"))
56 name=options.find(
"name").asString().c_str();
58 if (options.check(
"active"))
59 active=options.find(
"active").asString()==
"on";
61 extractVector(options,
"center",center);
62 extractVector(options,
"orientation",orientation);
63 extractVector(options,
"radius",radius);
64 extractVector(options,
"color",color);
71 Property Item::toProperty()
const
73 Value vcenter; vcenter.fromString((
"("+
string(center.toString().c_str())+
")").c_str());
74 Value vorientation; vorientation.fromString((
"("+
string(orientation.toString().c_str())+
")").c_str());
75 Value vradius; vradius.fromString((
"("+
string(radius.toString().c_str())+
")").c_str());
76 Value vcolor; vcolor.fromString((
"("+
string(color.toString().c_str())+
")").c_str());
79 prop.put(
"name",name.c_str());
80 prop.put(
"type",type.c_str());
81 prop.put(
"active",active?
"on":
"off");
82 prop.put(
"center",vcenter);
83 prop.put(
"orientation",vorientation);
84 prop.put(
"radius",vradius);
85 prop.put(
"color",vcolor);
92 Target_MSD::Target_MSD() : K(0.0), D(0.0)
102 bool Target_MSD::fromProperty(
const Property &options)
105 Item::fromProperty(options);
107 if (options.check(
"K"))
108 K=options.find(
"K").asDouble();
110 if (options.check(
"D"))
111 D=options.find(
"D").asDouble();
118 Property Target_MSD::toProperty()
const
121 Property prop=Item::toProperty();
131 Vector Target_MSD::getField(
const Vector &x,
const Vector &xdot)
137 F=K*(center-getVectorPos(x))-D*getVectorPos(xdot);
144 F.resize(x.length(),0.0);
151 Obstacle_Gaussian::Obstacle_Gaussian() : G(0.0), cut_tails(false)
153 type=
"obstacle_gaussian";
161 bool Obstacle_Gaussian::fromProperty(
const Property &options)
164 Item::fromProperty(options);
166 if (options.check(
"G"))
167 G=options.find(
"G").asDouble();
169 if (options.check(
"cut_tails"))
170 cut_tails=options.find(
"cut_tails").asString()==
"on";
177 Property Obstacle_Gaussian::toProperty()
const
180 Property prop=Item::toProperty();
183 prop.put(
"cut_tails",cut_tails?
"on":
"off");
190 Vector Obstacle_Gaussian::getField(
const Vector &x,
const Vector &xdot)
192 Vector zeros(x.length(),0.0);
196 Matrix Hro=axis2dcm(orientation);
201 Vector xr=getVectorPos(x);
204 Vector xo=SE3inv(Hro)*xr;
209 Vector ell=(xo*xo)/(radius*radius);
210 double dist=ell[0]+ell[1]+ell[2];
212 if (cut_tails && (dist>1.0))
216 Vector F=(G*exp(-dist)/norm(dx))*dx;
227 GuiReporter::GuiReporter()
234 void GuiReporter::setServer(D4CServer *server)
241 void GuiReporter::report(
const PortInfo &info)
243 if ((server!=NULL) && info.created && !info.incoming)
244 server->scheduleInitGuiTrajectory();
249 D4CServer::D4CServer() : RateThread(20), If(0.0,Vector(7)), Iv(0.0,Vector(7))
253 controlEnabled=
false;
254 simulationEnabled=
false;
255 simulationFirstStep=
false;
256 doInitGuiTrajectory=
false;
258 initIntegration=
true;
271 toolFrame=invToolFrame=eye(4,4);
276 D4CServer::~D4CServer()
283 void D4CServer::printMessage(
const int logtype,
const int level,
284 const char *format, ...)
const
286 if (verbosity>=level)
289 str=
"*** "+name+
": ";
293 va_start(arg,format);
294 vsnprintf(buf,
sizeof(buf),format,arg);
304 yWarning(str.c_str());
310 printf(
"%s\n",str.c_str());
317 bool D4CServer::open(
const Property &options)
319 verbosity=options.check(
"verbosity",Value(0)).asInt();
320 device=options.check(
"device",Value(
"cartesiancontrollerclient")).asString().c_str();
321 name=options.check(
"name",Value(
"d4c_server")).asString().c_str();
322 robot=options.check(
"robot",Value(
"icub")).asString().c_str();
323 part=options.check(
"part",Value(
"both_arms")).asString().c_str();
324 offlineMode=options.check(
"offline");
326 if ((part!=
"right_arm") && (part!=
"left_arm") && (part!=
"both_arms"))
328 printMessage(log::error,1,
"server failed to open, unknown part specified");
332 period=options.check(
"period",Value(20)).asInt();
334 double Ts=(double)period/1000.0;
342 reporter.setServer(
this);
343 gui.setReporter(reporter);
345 data.open((
"/"+name+
"/data:o").c_str());
346 gui.open((
"/"+name+
"/gui:o").c_str());
347 rpc.open((
"/"+name+
"/rpc").c_str());
348 rpc.setReader(*
this);
352 if ((part==
"right_arm") || (part==
"both_arms"))
354 Property optCtrlRight;
355 optCtrlRight.put(
"device",device.c_str());
356 optCtrlRight.put(
"remote",(
"/"+robot+
"/cartesianController/right_arm").c_str());
357 optCtrlRight.put(
"local",(
"/"+name+
"_right/cartesian").c_str());
359 if (dCtrlRight.open(optCtrlRight))
360 dCtrlRight.view(iCtrlRight);
365 if ((part==
"left_arm") || (part==
"both_arms"))
367 Property optCtrlLeft;
368 optCtrlLeft.put(
"device",device.c_str());
369 optCtrlLeft.put(
"remote",(
"/"+robot+
"/cartesianController/left_arm").c_str());
370 optCtrlLeft.put(
"local",(
"/"+name+
"_left/cartesian").c_str());
372 if (dCtrlLeft.open(optCtrlLeft))
373 dCtrlLeft.view(iCtrlLeft);
379 if ((part==
"both_arms") || (part==
"right_arm"))
381 iCtrlActive=iCtrlRight;
386 iCtrlActive=iCtrlLeft;
391 iCtrlActive->getDOF(dof);
392 qhat.resize(dof.length(),0.0);
403 printMessage(log::info,1,
"server successfully open%s", offlineMode?
" (offline mode)":
"");
410 void D4CServer::close()
423 if ((part==
"right_arm") || (part==
"both_arms"))
425 if ((part==
"left_arm") || (part==
"both_arms"))
433 for (map<int,Item*>::iterator it=table.begin(); it!=table.end(); it++)
435 eraseGuiItem(GuiRequest(
"erase",it));
439 printMessage(log::no_info,1,
"erasing item %d",it->first);
446 eraseGuiTrajectory();
458 printMessage(log::info,1,
"server closed");
461 printMessage(log::warning,3,
"server is already closed");
466 Item* D4CServer::itemFactory(
const Property &options)
470 if (options.check(
"type"))
472 string name=options.check(
"name",Value(
"")).asString().c_str();
473 string type=options.find(
"type").asString().c_str();
475 printMessage(log::no_info,2,
"creating \"%s\" of type %s ...",name.c_str(),type.c_str());
477 if (type==
"target_msd")
479 else if (type==
"obstacle_gaussian")
480 item=
new Obstacle_Gaussian;
483 printMessage(log::warning,2,
"option \"type\" not found");
486 printMessage(log::no_info,2,
"successfully created");
488 printMessage(log::warning,2,
"unknown type");
495 bool D4CServer::addItem(
const Property &options,
int &item)
500 printMessage(log::no_info,2,
"received request for adding item: %s",
501 options.toString().c_str());
504 if (Item *pItem=itemFactory(options))
507 pItem->fromProperty(options);
508 table[item=itCnt++]=pItem;
509 map<int,Item*>::iterator it=table.find(item);
510 pushUpdateGuiItem(it);
512 printMessage(log::no_info,1,
"added item %s",
513 pItem->toProperty().toString().c_str());
517 printMessage(log::error,1,
"wrong request detected!");
524 printMessage(log::warning,1,
"server is not open");
531 bool D4CServer::eraseItem(
const int item)
536 printMessage(log::no_info,2,
"received request for erasing item %d",item);
539 map<int,Item*>::iterator it=table.find(item);
542 pushEraseGuiItem(it);
547 printMessage(log::no_info,1,
"item %d scheduled for erasing",item);
551 printMessage(log::warning,1,
"item %d not found!",item);
558 printMessage(log::warning,1,
"server is not open");
565 bool D4CServer::clearItems()
570 for (map<int,Item*>::iterator it=table.begin(); it!=table.end(); it++)
572 pushEraseGuiItem(it);
577 printMessage(log::no_info,1,
"all items have been scheduled for erasing");
584 printMessage(log::warning,1,
"server is not open");
591 bool D4CServer::getItems(Bottle &items)
597 for (map<int,Item*>::const_iterator it=table.begin(); it!=table.end(); it++)
598 items.addInt(it->first);
600 printMessage(log::no_info,1,
"list of items ids prepared for sending: (%s)",
601 items.toString().c_str());
608 printMessage(log::warning,1,
"server is not open");
615 bool D4CServer::setProperty(
const int item,
const Property &options)
620 printMessage(log::no_info,2,
"received request for setting item %d property: %s",
621 item,options.toString().c_str());
624 map<int,Item*>::iterator it=table.find(item);
627 it->second->fromProperty(options);
628 pushUpdateGuiItem(it);
630 printMessage(log::no_info,1,
"item %d property successfully updated: %s",
631 item,it->second->toProperty().toString().c_str());
635 printMessage(log::warning,1,
"item %d not found!",item);
642 printMessage(log::warning,1,
"server is not open");
649 bool D4CServer::getProperty(
const int item, Property &options)
654 printMessage(log::no_info,2,
"received request for getting item %d property",item);
657 map<int,Item*>::const_iterator it=table.find(item);
660 options=it->second->toProperty();
662 printMessage(log::no_info,1,
"item %d property successfully retrieved: %s",
663 item,options.toString().c_str());
667 printMessage(log::warning,1,
"item %d not found!",item);
674 printMessage(log::warning,1,
"server is not open");
681 bool D4CServer::enableField()
688 iCtrlActive->getPose(pos,orien);
690 copyVectorData(pos,this->x);
691 copyVectorData(orien,this->x);
693 initIntegration=
false;
697 printMessage(log::no_info,1,
"field enabled");
702 printMessage(log::warning,1,
"server is not open");
709 bool D4CServer::disableField()
715 iCtrlActive->stopControl();
718 printMessage(log::no_info,1,
"field disabled");
725 printMessage(log::warning,1,
"server is not open");
732 bool D4CServer::getFieldStatus(
bool &status)
737 printMessage(log::no_info,1,
"field status = %s",status?
"on":
"off");
742 printMessage(log::warning,1,
"server is not open");
749 bool D4CServer::enableControl()
757 printMessage(log::no_info,1,
"control enabled");
759 if (simulationEnabled)
761 simulationEnabled=
false;
762 printMessage(log::warning,2,
"simulation gets automatically disabled");
770 printMessage(log::warning,1,
"it is not possible to enable control in offline mode");
776 printMessage(log::warning,1,
"server is not open");
783 bool D4CServer::disableControl()
790 iCtrlActive->stopControl();
791 controlEnabled=
false;
792 printMessage(log::no_info,1,
"control disabled");
798 printMessage(log::warning,1,
"it is not possible to disable control in offline mode");
804 printMessage(log::warning,1,
"server is not open");
811 bool D4CServer::getControlStatus(
bool &status)
817 status=controlEnabled;
818 printMessage(log::no_info,1,
"control status = %s",status?
"on":
"off");
823 printMessage(log::warning,1,
"there is no possibility to enable or disable control in offline mode");
829 printMessage(log::warning,1,
"server is not open");
836 bool D4CServer::enableSimulation()
843 simulationEnabled=
true;
844 simulationFirstStep=
true;
845 printMessage(log::no_info,1,
"simulation enabled");
849 controlEnabled=
false;
850 printMessage(log::warning,2,
"control gets automatically disabled");
858 printMessage(log::warning,1,
"it is not possible to enable simulation in offline mode");
864 printMessage(log::warning,1,
"server is not open");
871 bool D4CServer::disableSimulation()
877 simulationEnabled=
false;
878 printMessage(log::no_info,1,
"simulation disabled");
883 printMessage(log::warning,1,
"it is not possible to disable simulation in offline mode");
889 printMessage(log::warning,1,
"server is not open");
896 bool D4CServer::getSimulationStatus(
bool &status)
902 status=simulationEnabled;
903 printMessage(log::no_info,1,
"simulation status = %s",status?
"on":
"off");
908 printMessage(log::warning,1,
"there is no possibility to enable or disable simulation in offline mode");
914 printMessage(log::warning,1,
"server is not open");
921 bool D4CServer::setPeriod(
const int period)
927 double Ts=(double)this->period/1000.0;
934 setRate(this->period);
935 printMessage(log::no_info,1,
"thread period changed to %d [ms]",period);
943 printMessage(log::warning,1,
"server is not open");
950 bool D4CServer::getPeriod(
int &period)
956 period=(int)const_cast<D4CServer*>(
this)->getRate();
957 printMessage(log::no_info,1,
"thread period is %d [ms]",period);
962 printMessage(log::no_info,1,
"integration time is %d [ms]",this->period);
969 printMessage(log::warning,1,
"server is not open");
976 bool D4CServer::setPointState(
const Vector &x,
const Vector &o,
977 const Vector &xdot,
const Vector &odot)
982 copyVectorData(x,this->x);
983 copyVectorData(o,this->x);
984 copyVectorData(xdot,this->xdot);
985 copyVectorData(odot,this->xdot);
987 If.reset(this->xdot);
990 initIntegration=
false;
992 printMessage(log::no_info,1,
"point state changed to x = %s; xdot = %s",
993 this->x.toString().c_str(),this->xdot.toString().c_str());
1000 printMessage(log::warning,1,
"server is not open");
1007 bool D4CServer::setPointOrientation(
const Vector &o,
const Vector &odot)
1012 copyVectorData(o,this->x);
1013 copyVectorData(odot,this->xdot);
1015 If.reset(this->xdot);
1018 printMessage(log::no_info,1,
"point state changed to x = %s; xdot = %s",
1019 this->x.toString().c_str(),this->xdot.toString().c_str());
1026 printMessage(log::warning,1,
"server is not open");
1033 bool D4CServer::setPointStateToTool()
1039 Vector x,o,xdot,odot;
1041 iCtrlActive->getTaskVelocities(xdot,odot);
1045 copyVectorData(x,this->x);
1046 copyVectorData(o,this->x);
1047 copyVectorData(xdot,this->xdot);
1048 copyVectorData(odot,this->xdot);
1050 If.reset(this->xdot);
1053 initIntegration=
false;
1055 printMessage(log::no_info,1,
"point state changed to x = %s; xdot = %s",
1056 this->x.toString().c_str(),this->xdot.toString().c_str());
1063 printMessage(log::warning,1,
"no connection with the robot in offline mode");
1069 printMessage(log::warning,1,
"server is not open");
1076 bool D4CServer::attachToolFrame(
const yarp::sig::Vector &x,
const yarp::sig::Vector &o)
1082 if ((x.length()<3) || (o.length()<4))
1084 printMessage(log::error,1,
"problem with vector lengths");
1090 toolFrame=axis2dcm(o);
1091 toolFrame(0,3)=x[0];
1092 toolFrame(1,3)=x[1];
1093 toolFrame(2,3)=x[2];
1095 invToolFrame=SE3inv(toolFrame);
1096 printMessage(log::no_info,1,
"attach tool frame = %s",toolFrame.toString().c_str());
1104 printMessage(log::warning,1,
"it is not possible to attach frame in offline mode");
1110 printMessage(log::warning,1,
"server is not open");
1117 bool D4CServer::getToolFrame(yarp::sig::Vector &x, yarp::sig::Vector &o)
1125 x[0]=toolFrame(0,3);
1126 x[1]=toolFrame(1,3);
1127 x[2]=toolFrame(2,3);
1128 o=dcm2axis(toolFrame);
1130 printMessage(log::no_info,1,
"tool frame currently attached is = %s",
1131 toolFrame.toString().c_str());
1138 printMessage(log::warning,1,
"there is no tool in offline mode");
1144 printMessage(log::warning,1,
"server is not open");
1151 bool D4CServer::removeToolFrame()
1158 toolFrame=invToolFrame=eye(4,4);
1159 printMessage(log::no_info,1,
"tool frame removed");
1165 printMessage(log::warning,1,
"there is no tool in offline mode");
1171 printMessage(log::warning,1,
"server is not open");
1178 bool D4CServer::getTool(yarp::sig::Vector &x, yarp::sig::Vector &o)
1185 iCtrlActive->getPose(pos,orien);
1187 Matrix frame1=axis2dcm(orien);
1192 Matrix frame2=frame1*toolFrame;
1199 printMessage(log::no_info,1,
"tool state is = %s",
1200 frame2.toString().c_str());
1205 printMessage(log::warning,1,
"there is no tool in offline mode");
1211 printMessage(log::warning,1,
"server is not open");
1218 bool D4CServer::getPointState(Vector &x, Vector &o, Vector &xdot, Vector &odot)
1222 x=getVectorPos(this->x);
1223 o=getVectorOrien(this->x);
1224 xdot=getVectorPos(this->xdot);
1225 odot=getVectorOrien(this->xdot);
1227 printMessage(log::no_info,1,
"point state is x = %s; xdot = %s",
1228 x.toString().c_str(),xdot.toString().c_str());
1233 printMessage(log::warning,1,
"server is not open");
1240 bool D4CServer::getField(Vector &field)
1244 field.resize(x.length(),0.0);
1245 for (map<int,Item*>::const_iterator it=table.begin(); it!=table.end(); it++)
1246 field=field+it->second->getField(x,xdot);
1248 printMessage(log::no_info,1,
"field = %s",field.toString().c_str());
1253 printMessage(log::warning,1,
"server is not open");
1260 bool D4CServer::getSimulation(Vector &xhat, Vector &ohat, Vector &qhat)
1266 xhat=getVectorPos(this->xhat);
1267 ohat=getVectorOrien(this->xhat);
1270 printMessage(log::no_info,1,
"simulated end-effector pose is xhat = %s; part configuration is qhat = %s",
1271 xhat.toString().c_str(),qhat.toString().c_str());
1276 printMessage(log::warning,1,
"there is no possibility to enable simulation in offline mode");
1282 printMessage(log::warning,1,
"server is not open");
1289 bool D4CServer::read(ConnectionReader &connection)
1292 cmd.read(connection);
1295 reply.addVocab(D4C_VOCAB_CMD_NACK);
1296 else switch(cmd.get(0).asVocab())
1299 case D4C_VOCAB_CMD_PING:
1301 reply.addVocab(D4C_VOCAB_CMD_ACK);
1306 case D4C_VOCAB_CMD_ADD:
1309 reply.addVocab(D4C_VOCAB_CMD_NACK);
1313 if (addItem(extractProperty(cmd.get(1)),item))
1315 reply.addVocab(D4C_VOCAB_CMD_ACK);
1319 reply.addVocab(D4C_VOCAB_CMD_NACK);
1326 case D4C_VOCAB_CMD_DEL:
1329 reply.addVocab(D4C_VOCAB_CMD_NACK);
1332 if (eraseItem(cmd.get(1).asInt()))
1333 reply.addVocab(D4C_VOCAB_CMD_ACK);
1335 reply.addVocab(D4C_VOCAB_CMD_NACK);
1342 case D4C_VOCAB_CMD_SET:
1345 reply.addVocab(D4C_VOCAB_CMD_NACK);
1346 else if (setProperty(cmd.get(1).asInt(),extractProperty(cmd.get(2))))
1347 reply.addVocab(D4C_VOCAB_CMD_ACK);
1349 reply.addVocab(D4C_VOCAB_CMD_NACK);
1355 case D4C_VOCAB_CMD_GET:
1358 reply.addVocab(D4C_VOCAB_CMD_NACK);
1362 if (getProperty(cmd.get(1).asInt(),options))
1365 val.fromString((
"("+
string(options.toString().c_str())+
")").c_str());
1367 reply.addVocab(D4C_VOCAB_CMD_ACK);
1371 reply.addVocab(D4C_VOCAB_CMD_NACK);
1378 case D4C_VOCAB_CMD_LIST:
1381 if (getItems(items))
1383 reply.addVocab(D4C_VOCAB_CMD_ACK);
1384 reply.addList().append(items);
1387 reply.addVocab(D4C_VOCAB_CMD_NACK);
1393 case D4C_VOCAB_CMD_CLEAR:
1396 reply.addVocab(D4C_VOCAB_CMD_ACK);
1398 reply.addVocab(D4C_VOCAB_CMD_NACK);
1404 case D4C_VOCAB_CMD_ENFIELD:
1407 reply.addVocab(D4C_VOCAB_CMD_ACK);
1409 reply.addVocab(D4C_VOCAB_CMD_NACK);
1415 case D4C_VOCAB_CMD_DISFIELD:
1418 reply.addVocab(D4C_VOCAB_CMD_ACK);
1420 reply.addVocab(D4C_VOCAB_CMD_NACK);
1426 case D4C_VOCAB_CMD_STATFIELD:
1429 if (getFieldStatus(status))
1431 reply.addVocab(D4C_VOCAB_CMD_ACK);
1432 reply.addString(status?
"on":
"off");
1435 reply.addVocab(D4C_VOCAB_CMD_NACK);
1441 case D4C_VOCAB_CMD_ENCTRL:
1443 if (enableControl())
1444 reply.addVocab(D4C_VOCAB_CMD_ACK);
1446 reply.addVocab(D4C_VOCAB_CMD_NACK);
1452 case D4C_VOCAB_CMD_DISCTRL:
1454 if (disableControl())
1455 reply.addVocab(D4C_VOCAB_CMD_ACK);
1457 reply.addVocab(D4C_VOCAB_CMD_NACK);
1463 case D4C_VOCAB_CMD_STATCTRL:
1466 if (getControlStatus(status))
1468 reply.addVocab(D4C_VOCAB_CMD_ACK);
1469 reply.addString(status?
"on":
"off");
1472 reply.addVocab(D4C_VOCAB_CMD_NACK);
1478 case D4C_VOCAB_CMD_ENSIM:
1480 if (enableSimulation())
1481 reply.addVocab(D4C_VOCAB_CMD_ACK);
1483 reply.addVocab(D4C_VOCAB_CMD_NACK);
1489 case D4C_VOCAB_CMD_DISSIM:
1491 if (disableSimulation())
1492 reply.addVocab(D4C_VOCAB_CMD_ACK);
1494 reply.addVocab(D4C_VOCAB_CMD_NACK);
1500 case D4C_VOCAB_CMD_STATSIM:
1503 if (getSimulationStatus(status))
1505 reply.addVocab(D4C_VOCAB_CMD_ACK);
1506 reply.addString(status?
"on":
"off");
1509 reply.addVocab(D4C_VOCAB_CMD_NACK);
1515 case D4C_VOCAB_CMD_SETPER:
1518 reply.addVocab(D4C_VOCAB_CMD_NACK);
1519 else if (setPeriod(cmd.get(1).asInt()))
1520 reply.addVocab(D4C_VOCAB_CMD_ACK);
1522 reply.addVocab(D4C_VOCAB_CMD_NACK);
1528 case D4C_VOCAB_CMD_GETPER:
1531 if (getPeriod(period))
1533 reply.addVocab(D4C_VOCAB_CMD_ACK);
1534 reply.addInt(period);
1537 reply.addVocab(D4C_VOCAB_CMD_NACK);
1543 case D4C_VOCAB_CMD_SETACTIF:
1546 reply.addVocab(D4C_VOCAB_CMD_NACK);
1547 else if (setActiveIF(cmd.get(1).asString().c_str()))
1548 reply.addVocab(D4C_VOCAB_CMD_ACK);
1550 reply.addVocab(D4C_VOCAB_CMD_NACK);
1556 case D4C_VOCAB_CMD_GETACTIF:
1559 if (getActiveIF(_activeIF))
1561 reply.addVocab(D4C_VOCAB_CMD_ACK);
1562 reply.addString(_activeIF.c_str());
1565 reply.addVocab(D4C_VOCAB_CMD_NACK);
1571 case D4C_VOCAB_CMD_GETTRAJ:
1573 Property options=extractProperty(cmd.get(1));
1574 if (options.isNull())
1575 reply.addVocab(D4C_VOCAB_CMD_NACK);
1578 int maxIterations=options.find(
"maxIterations").asInt();
1579 double Ts=options.find(
"Ts").asDouble();
1580 deque<Vector> trajPos;
1581 deque<Vector> trajOrien;
1582 if (getTrajectory(trajPos,trajOrien,maxIterations,Ts))
1584 reply.addVocab(D4C_VOCAB_CMD_ACK);
1586 Bottle &bPos=reply.addList();
1587 bPos.addString(
"trajPos");
1588 for (
unsigned int i=0; i<trajPos.size(); i++)
1590 Bottle &point=bPos.addList();
1591 for (
size_t j=0; j<trajPos[i].length(); j++)
1592 point.addDouble(trajPos[i][j]);
1595 Bottle &bOrien=reply.addList();
1596 bOrien.addString(
"trajOrien");
1597 for (
unsigned int i=0; i<trajOrien.size(); i++)
1599 Bottle &point=bOrien.addList();
1600 for (
size_t j=0; j<trajOrien[i].length(); j++)
1601 point.addDouble(trajOrien[i][j]);
1605 reply.addVocab(D4C_VOCAB_CMD_NACK);
1612 case D4C_VOCAB_CMD_EXECTRAJ:
1614 Bottle *options=cmd.get(1).asList();
1615 if (options->isNull())
1616 reply.addVocab(D4C_VOCAB_CMD_NACK);
1619 double trajTime=-1.0;
1620 deque<Vector> trajPos;
1621 deque<Vector> trajOrien;
1623 if (Bottle *BtrajTime=options->get(0).asList())
1624 if (BtrajTime->get(0).asString()==
"trajTime")
1625 trajTime=BtrajTime->get(1).asDouble();
1628 if (Bottle *BtrajPos=options->get(1).asList())
1630 if (BtrajPos->get(0).asString()==
"trajPos")
1632 for (
int i=1; i<BtrajPos->size(); i++)
1634 if (Bottle *point=BtrajPos->get(i).asList())
1636 Vector pos(point->size());
1637 for (
int j=0; j<point->size(); j++)
1638 pos[j]=point->get(j).asDouble();
1640 trajPos.push_back(pos);
1649 if (Bottle *BtrajOrien=reply.get(2).asList())
1651 if (BtrajOrien->get(0).asString()==
"trajOrien")
1653 for (
int i=1; i<BtrajOrien->size(); i++)
1655 if (Bottle *point=BtrajOrien->get(i).asList())
1657 Vector orien(point->size());
1658 for (
int j=0; j<point->size(); j++)
1659 orien[j]=point->get(j).asDouble();
1661 trajOrien.push_back(orien);
1669 if (!okPos || !okOrien)
1670 reply.addVocab(D4C_VOCAB_CMD_NACK);
1671 else if (executeTrajectory(trajPos,trajOrien,trajTime))
1672 reply.addVocab(D4C_VOCAB_CMD_ACK);
1674 reply.addVocab(D4C_VOCAB_CMD_NACK);
1681 case D4C_VOCAB_CMD_SETSTATETOTOOL:
1684 reply.addVocab(D4C_VOCAB_CMD_NACK);
1687 if (setPointStateToTool())
1688 reply.addVocab(D4C_VOCAB_CMD_ACK);
1690 reply.addVocab(D4C_VOCAB_CMD_NACK);
1697 case D4C_VOCAB_CMD_SETSTATE:
1700 reply.addVocab(D4C_VOCAB_CMD_NACK);
1703 Property options=extractProperty(cmd.get(1));
1704 if (options.isNull())
1705 reply.addVocab(D4C_VOCAB_CMD_NACK);
1709 if (extractVector(options,
"x",pos) && extractVector(options,
"xdot",vel))
1711 if (setPointState(getVectorPos(pos),getVectorOrien(pos),
1712 getVectorPos(vel),getVectorOrien(vel)))
1713 reply.addVocab(D4C_VOCAB_CMD_ACK);
1715 reply.addVocab(D4C_VOCAB_CMD_NACK);
1718 reply.addVocab(D4C_VOCAB_CMD_NACK);
1726 case D4C_VOCAB_CMD_SETORIEN:
1729 reply.addVocab(D4C_VOCAB_CMD_NACK);
1732 Property options=extractProperty(cmd.get(1));
1733 if (options.isNull())
1734 reply.addVocab(D4C_VOCAB_CMD_NACK);
1738 if (extractVector(options,
"o",o) && extractVector(options,
"odot",odot))
1740 if (setPointOrientation(o,odot))
1741 reply.addVocab(D4C_VOCAB_CMD_ACK);
1743 reply.addVocab(D4C_VOCAB_CMD_NACK);
1746 reply.addVocab(D4C_VOCAB_CMD_NACK);
1754 case D4C_VOCAB_CMD_GETSTATE:
1759 Property state=prepareData();
1763 val_state.fromString((
"("+
string(state.toString().c_str())+
")").c_str());
1765 reply.addVocab(D4C_VOCAB_CMD_ACK);
1766 reply.add(val_state);
1769 reply.addVocab(D4C_VOCAB_CMD_NACK);
1775 case D4C_VOCAB_CMD_ATTACHTOOLFRAME:
1778 reply.addVocab(D4C_VOCAB_CMD_NACK);
1782 Property options=extractProperty(cmd.get(1));
1783 extractVector(options,
"x",x);
1784 extractVector(options,
"o",o);
1786 if (attachToolFrame(x,o))
1787 reply.addVocab(D4C_VOCAB_CMD_ACK);
1789 reply.addVocab(D4C_VOCAB_CMD_NACK);
1796 case D4C_VOCAB_CMD_GETTOOLFRAME:
1799 if (getToolFrame(x,o))
1801 Value val_x; val_x.fromString((
"("+
string(x.toString().c_str())+
")").c_str());
1802 Value val_o; val_o.fromString((
"("+
string(o.toString().c_str())+
")").c_str());
1805 options.put(
"x",val_x);
1806 options.put(
"o",val_o);
1809 val.fromString((
"("+
string(options.toString().c_str())+
")").c_str());
1811 reply.addVocab(D4C_VOCAB_CMD_ACK);
1815 reply.addVocab(D4C_VOCAB_CMD_NACK);
1821 case D4C_VOCAB_CMD_REMOVETOOLFRAME:
1823 if (removeToolFrame())
1824 reply.addVocab(D4C_VOCAB_CMD_ACK);
1826 reply.addVocab(D4C_VOCAB_CMD_NACK);
1832 case D4C_VOCAB_CMD_GETTOOL:
1837 Value val_x; val_x.fromString((
"("+
string(x.toString().c_str())+
")").c_str());
1838 Value val_o; val_o.fromString((
"("+
string(o.toString().c_str())+
")").c_str());
1841 options.put(
"x",val_x);
1842 options.put(
"o",val_o);
1845 val.fromString((
"("+
string(options.toString().c_str())+
")").c_str());
1847 reply.addVocab(D4C_VOCAB_CMD_ACK);
1851 reply.addVocab(D4C_VOCAB_CMD_NACK);
1858 reply.addVocab(D4C_VOCAB_CMD_NACK);
1861 ConnectionWriter *returnToSender=connection.getWriter();
1862 if (returnToSender!=NULL)
1863 reply.write(*returnToSender);
1870 Property D4CServer::prepareData()
1875 Value val_field; val_field.fromString((
"("+
string(field.toString().c_str())+
")").c_str());
1876 Value val_xdot; val_xdot.fromString((
"("+
string(xdot.toString().c_str())+
")").c_str());
1877 Value val_x; val_x.fromString((
"("+
string(x.toString().c_str())+
")").c_str());
1878 Value val_xhat; val_xhat.fromString((
"("+
string(xhat.toString().c_str())+
")").c_str());
1879 Value val_qhat; val_qhat.fromString((
"("+
string(qhat.toString().c_str())+
")").c_str());
1882 out.put(
"field",val_field);
1883 out.put(
"xdot",val_xdot);
1885 out.put(
"xhat",val_xhat);
1886 out.put(
"qhat",val_qhat);
1893 void D4CServer::getTargetForCartesianIF(Vector &pos, Vector &orien)
1895 pos=getVectorPos(x);
1896 orien=getVectorOrien(x);
1898 Matrix frame1=axis2dcm(orien);
1903 Matrix frame2=frame1*invToolFrame;
1907 orien=dcm2axis(frame2);
1912 bool D4CServer::getActiveIF(
string &activeIF)
1918 activeIF=this->activeIF;
1919 printMessage(log::no_info,1,
"active interface: %s",activeIF.c_str());
1925 printMessage(log::warning,1,
"no connection with the robot in offline mode");
1931 printMessage(log::warning,1,
"server is not open");
1938 bool D4CServer::setActiveIF(
const string &activeIF)
1944 if (part==
"both_arms")
1946 if ((activeIF==
"right") || (activeIF==
"left"))
1949 iCtrlActive->stopControl();
1950 if (activeIF==
"right")
1951 iCtrlActive=iCtrlRight;
1953 iCtrlActive=iCtrlLeft;
1955 this->activeIF=activeIF;
1956 printMessage(log::no_info,1,
"active interface successfully set to %s",
1964 printMessage(log::error,1,
"wrong value specified, it should be \"right\" or \"left\"");
1970 printMessage(log::warning,1,
"cannot swap arm");
1976 printMessage(log::warning,1,
"no connection with the robot in offline mode");
1982 printMessage(log::warning,1,
"server is not open");
1989 void D4CServer::scheduleInitGuiTrajectory()
1991 doInitGuiTrajectory=
true;
1996 void D4CServer::initGuiTrajectory()
1998 if (gui.getOutputCount()>0)
2000 Bottle &obj=gui.prepare();
2003 obj.addString(
"trajectory");
2004 obj.addString(part.c_str());
2005 obj.addString(part.c_str());
2015 printMessage(log::no_info,4,
"initializing gui trajectory point");
2021 void D4CServer::updateGuiTrajectory()
2023 if (gui.getOutputCount()>0)
2025 Bottle &obj=gui.prepare();
2028 obj.addString(
"addpoint");
2029 obj.addString(part.c_str());
2030 obj.addDouble(1000.0*x[0]);
2031 obj.addDouble(1000.0*x[1]);
2032 obj.addDouble(1000.0*x[2]);
2035 printMessage(log::no_info,4,
"updating gui trajectory point");
2041 void D4CServer::eraseGuiTrajectory()
2043 if (gui.getOutputCount()>0)
2045 Bottle &obj=gui.prepare();
2048 obj.addString(
"delete");
2049 obj.addString(part.c_str());
2052 printMessage(log::no_info,4,
"erasing gui tracjectory point");
2058 void D4CServer::updateGuiItem(
const GuiRequest &req)
2060 if (gui.getOutputCount()>0)
2062 map<int,Item*>::iterator it=req.getIter();
2063 string name=req.getName();
2065 Item *pItem=it->second;
2067 Vector rpy=CTRL_RAD2DEG*dcm2rpy(axis2dcm(pItem->orientation));
2069 Bottle &obj=gui.prepare();
2072 obj.addString(
"object");
2073 obj.addString(name.c_str());
2074 obj.addDouble(1000.0*pItem->radius[0]);
2075 obj.addDouble(1000.0*pItem->radius[1]);
2076 obj.addDouble(1000.0*pItem->radius[2]);
2077 obj.addDouble(1000.0*pItem->center[0]);
2078 obj.addDouble(1000.0*pItem->center[1]);
2079 obj.addDouble(1000.0*pItem->center[2]);
2080 obj.addDouble(rpy[0]);
2081 obj.addDouble(rpy[1]);
2082 obj.addDouble(rpy[2]);
2083 obj.addInt((
int)pItem->color[0]);
2084 obj.addInt((
int)pItem->color[1]);
2085 obj.addInt((
int)pItem->color[2]);
2086 obj.addDouble(pItem->active?1.0:0.25);
2089 printMessage(log::no_info,4,
"updating gui item %s",name.c_str());
2095 void D4CServer::eraseGuiItem(
const GuiRequest &req)
2097 if (gui.getOutputCount()>0)
2099 Bottle &obj=gui.prepare();
2102 obj.addString(
"delete");
2103 obj.addString(req.getName().c_str());
2106 printMessage(log::no_info,1,
"erasing gui item %s",name.c_str());
2112 void D4CServer::pushUpdateGuiItem(map<int,Item*>::iterator &it)
2114 GuiRequest update(
"update",it);
2116 for (
unsigned int i=0; i<guiQueue.size(); i++)
2118 if (guiQueue[i]==update)
2120 printMessage(log::warning,5,
"gui item %d update is already scheduled",it->first);
2125 guiQueue.push_back(update);
2126 printMessage(log::no_info,5,
"scheduled request for gui item %d update",it->first);
2131 void D4CServer::pushEraseGuiItem(map<int,Item*>::iterator &it)
2134 GuiRequest update(
"update",it);
2136 for (
unsigned int i=0; i<guiQueue.size(); i++)
2138 if (guiQueue[i]==update)
2140 guiQueue.erase(guiQueue.begin()+i);
2141 printMessage(log::no_info,5,
"remove schedule for gui item %d update",item);
2146 guiQueue.push_back(GuiRequest(
"erase",it));
2147 printMessage(log::no_info,5,
"scheduled request for gui item %d erase",item);
2152 void D4CServer::handleGuiQueue()
2154 if (doInitGuiTrajectory)
2156 initGuiTrajectory();
2157 doInitGuiTrajectory=
false;
2161 else if (guiQueue.size() && (doTrajectoryCnt<3))
2163 GuiRequest guiReq=guiQueue.front();
2164 guiQueue.pop_front();
2166 if (guiReq.getType()==
"update")
2167 updateGuiItem(guiReq);
2168 else if (guiReq.getType()==
"erase")
2169 eraseGuiItem(guiReq);
2171 printMessage(log::warning,1,
"unknown gui request received!");
2177 updateGuiTrajectory();
2184 bool D4CServer::getTrajectory(deque<Vector> &trajPos, deque<Vector> &trajOrien,
2185 const unsigned int maxIterations,
const double Ts)
2190 printMessage(log::no_info,1,
"request for trajectory simulation");
2191 Vector xdotOffline=xdot;
2194 double _Ts=(Ts<=D4C_DEFAULT_TS_DISABLED)?(
double)period/1000.0:Ts;
2195 Integrator IfOffline(_Ts,xdotOffline);
2196 Integrator IvOffline(_Ts,xOffline);
2198 unsigned int iteration=0;
2199 while (iteration++<maxIterations)
2201 Vector field(x.length(),0.0);
2202 for (map<int,Item*>::const_iterator it=table.begin(); it!=table.end(); it++)
2203 field=field+it->second->getField(xOffline,xdotOffline);
2205 xdotOffline=IfOffline.integrate(field);
2206 xOffline=IvOffline.integrate(xdotOffline);
2208 trajPos.push_back(getVectorPos(xOffline));
2209 trajOrien.push_back(getVectorOrien(xOffline));
2217 printMessage(log::warning,1,
"server is not open");
2224 bool D4CServer::executeTrajectory(
const deque<Vector> &trajPos,
const deque<Vector> &trajOrien,
2225 const double trajTime)
2229 printMessage(log::no_info,1,
"request for trajectory execution");
2231 if (trajPos.size()!=trajOrien.size())
2233 printMessage(log::error,1,
"position and orientation data have different size!");
2236 else if (trajTime<0.0)
2238 printMessage(log::error,1,
"negative trajectory duration provided!");
2243 class TrackerThread :
public RateThread
2245 ICartesianControl *ctrl;
2246 const deque<Vector> *trajPos;
2247 const deque<Vector> *trajOrien;
2260 int i=std::min(N,(
int)((t*N)/trajTime));
2263 ctrl->goToPose(trajPos->at(i),trajOrien->at(i));
2267 void threadRelease()
2270 ctrl->goToPoseSync(trajPos->back(),trajOrien->back());
2271 ctrl->waitMotionDone();
2274 TrackerThread() : RateThread(20), pos(-1) { }
2275 void setInfo(ICartesianControl *ctrl,
const deque<Vector> *trajPos,
2276 const deque<Vector> *trajOrien,
const double trajTime)
2278 this->trajPos=trajPos;
2279 this->trajOrien=trajOrien;
2280 this->trajTime=trajTime;
2281 N=(int)(trajPos->size()-1);
2290 trackerThread.setRate((
int)getRate());
2291 trackerThread.setInfo(iCtrlActive,&trajPos,&trajOrien,trajTime);
2297 trackerThread.start();
2298 trackerThread.wait();
2299 trackerThread.stop();
2308 printMessage(log::warning,1,
"server is not open");
2315 void D4CServer::run()
2323 printMessage(log::no_info,4,
"processing %d items",table.size());
2328 xdot=If.integrate(field);
2329 x=Iv.integrate(xdot);
2334 getTargetForCartesianIF(pos,orien);
2335 iCtrlActive->goToPose(pos,orien);
2338 if (simulationEnabled)
2340 Vector pos,orien,xdhat,odhat;
2341 getTargetForCartesianIF(pos,orien);
2343 if (simulationFirstStep)
2345 iCtrlActive->askForPose(pos,orien,xdhat,odhat,qhat);
2346 simulationFirstStep=
false;
2351 iCtrlActive->getDOF(dof);
2354 for (
size_t i=0; i<dof.length(); i++)
2356 q0.push_back(qhat[i]);
2358 iCtrlActive->askForPose(q0,pos,orien,xdhat,odhat,qhat);
2361 copyVectorData(xdhat,xhat);
2362 copyVectorData(odhat,xhat);
2367 if (data.getOutputCount()>0)
2369 data.prepare()=prepareData();
2374 if (Time::now()-t0>0.03)