icub-client
subSystem_KARMA.cpp
Go to the documentation of this file.
1 #include <yarp/os/all.h>
3 
4 using namespace yarp::dev;
5 using namespace yarp::os;
6 using namespace yarp::sig;
7 
8 void icubclient::SubSystem_KARMA::appendTarget(yarp::os::Bottle &b, const yarp::sig::VectorOf<double> &t)
9 {
10  yarp::os::Bottle &sub=b;
11  for (size_t i=0; i<t.length(); i++)
12  sub.addDouble(t[i]);
13 }
14 
15 void icubclient::SubSystem_KARMA::appendDouble(yarp::os::Bottle &b, const double &v)
16 {
17  yarp::os::Bottle &sub=b;
18  sub.addDouble(v);
19 }
20 
21 void icubclient::SubSystem_KARMA::selectHandCorrectTarget(yarp::os::Bottle &options, const std::string &targetName,
22  yarp::sig::VectorOf<double> &target, const std::string handToUse)
23 {
24  std::string hand="";
25  for (unsigned int i=0; i<options.size(); i++)
26  {
27  yarp::os::Value val=options.get(i);
28  if (val.isString())
29  {
30  std::string item=val.asString();
31  if ((item=="left") || (item=="right"))
32  {
33  hand=item;
34  break;
35  }
36  }
37  }
38 
39  // always choose hand
40  if (hand.empty())
41  {
42  if (handToUse.empty())
43  {
44  hand=(target[1]>0.0?"right":"left");
45  }
46  else
47  {
48  hand=handToUse;
49  }
50  }
51 
52  // apply 3D correction
53  if (portCalib.getOutputCount()>0 && targetName!="")
54  {
55  yarp::os::Bottle cmd,reply;
56  cmd.addString("get_location");
57  cmd.addString(hand);
58  cmd.addString(targetName);
59  cmd.addString("iol-"+hand);
60  portCalib.write(cmd,reply);
61  target[0]=reply.get(1).asDouble();
62  target[1]=reply.get(2).asDouble();
63  target[2]=reply.get(3).asDouble();
64 
65  Bottle opt;
66  opt.addString("fixate");
67  SubARE->look(target,opt);
68  }
69 }
70 
71 bool icubclient::SubSystem_KARMA::sendCmd(yarp::os::Bottle &cmd)
72 {
73  bool ret=false;
74 
75  yarp::os::Bottle bReply;
76  if (portRPC.write(cmd,bReply))
77  ret=(bReply.get(0).asVocab()==yarp::os::Vocab::encode("ack"));
78 
79  return ret;
80 }
81 
83 {
84  AREconnected=SubARE->Connect();
85  if (AREconnected)
86  yInfo()<<"KARMA connected to ARE";
87  else
88  yWarning()<<"KARMA didn't connect to ARE";
89 
90  bool ret=true;
91  if(!yarp::os::Network::isConnected(portStop.getName(),"/karmaMotor/stop:i")) {
92  ret&=yarp::os::Network::connect(portStop.getName(),"/karmaMotor/stop:i");
93  }
94  if(!yarp::os::Network::isConnected(portRPC.getName(),"/karmaMotor/rpc")) {
95  ret&=yarp::os::Network::connect(portRPC.getName(),"/karmaMotor/rpc");
96  }
97 
98  if(!yarp::os::Network::isConnected(portVision.getName(),"/karmaMotor/vision:i")) {
99  if (yarp::os::Network::connect(portVision.getName(),"/karmaMotor/vision:i"))
100  yInfo()<<"KARMA connected to tool tip vision";
101  else
102  yWarning()<<"KARMA didn't connect to tool tip vision";
103  }
104 
105  if(!yarp::os::Network::isConnected(portCalib.getName(),"/iolReachingCalibration/rpc")) {
106  if (yarp::os::Network::connect(portCalib.getName(),"/iolReachingCalibration/rpc"))
107  yInfo()<<"KARMA connected to calibrator";
108  else
109  yWarning()<<"KARMA didn't connect to calibrator";
110  }
111 
112  openCartesianClient();
113 
114  if (AREconnected)
115  {
116  hasTable = SubARE->getTableHeight(tableHeight);
117  if (hasTable)
118  yInfo("[SubSystem_KARMA] table height: %f",tableHeight);
119  else
120  yWarning("[SubSystem_KARMA] no table object");
121  }
122  else
123  {
124  hasTable = false;
125  tableHeight = 0.0;
126  yWarning("[SubSystem_KARMA] not connected to ARE");
127  }
128 
129  return ret;
130 }
131 
132 icubclient::SubSystem_KARMA::SubSystem_KARMA(const std::string &masterName, const std::string &robot) : SubSystem(masterName)
133 {
134  SubARE = new SubSystem_ARE(m_masterName+"/from_KARMA");
135 
136  this->robot = robot;
137 
138  portStop.open(("/" + masterName + "/" + SUBSYSTEM_KARMA + "/stop:i").c_str());
139  portRPC.open(("/" + masterName + "/" + SUBSYSTEM_KARMA + "/rpc").c_str());
140  portVision.open(("/" + masterName + "/" + SUBSYSTEM_KARMA + "/vision:i").c_str());
141  portFinder.open(("/" + masterName + "/" + SUBSYSTEM_KARMA + "/finder:rpc").c_str());
142  portCalib.open(("/" + masterName + "/" + SUBSYSTEM_KARMA + "/calib:io").c_str());
144 
145  hasTable = false;
146  AREconnected = false;
147  iCartCtrlL = nullptr;
148  iCartCtrlR = nullptr;
149  tableHeight = 0.0;
150 }
151 
153 {
154  portStop.interrupt();
155  portRPC.interrupt();
156  portVision.interrupt();
157  portCalib.interrupt();
158 
159  SubARE->Close();
160 
161  driverL.close();
162  driverR.close();
163  driverHL.close();
164  driverHR.close();
165 
166  portStop.close();
167  portRPC.close();
168  portVision.close();
169  portCalib.close();
170 }
171 
172 yarp::sig::VectorOf<double> icubclient::SubSystem_KARMA::applySafetyMargins(const yarp::sig::VectorOf<double> &in)
173 {
174  yarp::sig::VectorOf<double> out=in;
175  out[0]=std::min(out[0],-0.1);
176 
177  return out;
178 }
179 
181 {
182  Vector xL(3,0.0), xR(3,0.0), xdL(3,0.0), xdR(3,0.0), odL(3,0.0), odR(3,0.0);
183  double travelTime = 2.0;
184 
185  int contextL, contextR;
186  iCartCtrlL->storeContext(&contextL);
187  iCartCtrlR->storeContext(&contextR);
188 
189  iCartCtrlL->setTrajTime(travelTime);
190  iCartCtrlR->setTrajTime(travelTime);
191 
192  Bottle options;
193  Bottle &straightOpt=options.addList();
194  straightOpt.addString("straightness");
195  straightOpt.addDouble(10.0);
196  iCartCtrlL->tweakSet(options);
197  iCartCtrlR->tweakSet(options);
198 
199  iCartCtrlL->getPose(xL,odL);
200  iCartCtrlR->getPose(xR,odR);
201 
202  if (armType == "selectable")
203  {
204  if (xL[2]<xR[2])
205  armType = "left";
206  else
207  armType = "right";
208  }
209  yInfo("[SubSystem_KARMA] return %s arm before home",armType.c_str());
210  if (armType == "left")
211  {
212  xdL = xL;
213  xdL[2] = std::min(0.05,xL[2] + 0.1);
214  yInfo("[SubSystem_KARMA] xdL = %s",xdL.toString().c_str());
215  iCartCtrlL->goToPose(xdL,odL,1.0);
216  iCartCtrlL->waitMotionDone(0.1,4.0);
217  iCartCtrlL->stopControl();
218  iCartCtrlL->restoreContext(contextL);
219  iCartCtrlL->deleteContext(contextL);
220  }
221  else if (armType == "right")
222  {
223  xdR = xR;
224  xdR[2] = std::min(0.05,xR[2] + 0.1);
225  yInfo("[SubSystem_KARMA] xdR = %s",xdR.toString().c_str());
226  iCartCtrlR->goToPose(xdR,odR,1.0);
227  iCartCtrlR->waitMotionDone(0.1,4.0);
228  iCartCtrlR->stopControl();
229  iCartCtrlR->restoreContext(contextR);
230  iCartCtrlR->deleteContext(contextR);
231  }
232 
233  return true;
234 }
235 
236 bool icubclient::SubSystem_KARMA::chooseArm(const std::string &armType)
237 {
238  Vector dimTool(3,0.0);
239  yarp::os::Bottle bCmd;
240  bCmd.addVocab(yarp::os::Vocab::encode("tool"));
241  bCmd.addVocab(yarp::os::Vocab::encode("attach"));
242  bCmd.addString(armType);
243  appendTarget(bCmd,dimTool);
244 
245  return sendCmd(bCmd);
246 }
247 
249 {
250  yarp::os::Bottle bCmd;
251  bCmd.addVocab(yarp::os::Vocab::encode("tool"));
252  bCmd.addVocab(yarp::os::Vocab::encode("remove"));
253 
254 
255  if(!sendCmd(bCmd)) {
256  yError() << "Could not communicate with Karma";
257  }
258 }
259 
260 bool icubclient::SubSystem_KARMA::pushAside(const std::string &objName,
261  const yarp::sig::VectorOf<double> &objCenter, const double &targetPosY,
262  const double &theta,
263  const std::string &armType,
264  const yarp::os::Bottle &options)
265 {
266  // Calculate the pushing distance (radius) for push with Karma
267  Vector object = objCenter;
268  Bottle opt = options;
269  double zOffset = 0.05;
270  double actionOffset = 0.1; // add 10cm offset to deal with object dimension
271  yInfo ("[subSystem_KARMA] object center OPC : %s",object.toString().c_str());
272  selectHandCorrectTarget(opt,objName,object); // target is calibrated by this method
273  yInfo ("[subSystem_KARMA] object center calib: %s",object.toString().c_str());
274  double radius = fabs(object[1] - targetPosY);
275  yInfo ("objectY = %f",object[1]);
276  yInfo ("targetPosYRight = %f",targetPosY);
277  yInfo ("radius = %f",radius);
278  Vector targetCenter = object;
279  targetCenter[1] = targetPosY;
280 
281  if (hasTable)
282  targetCenter[2] = tableHeight+zOffset;
283 
284  yInfo ("object height = %f",targetCenter[2]);
285 
286  // Choose arm
287  bool armChoose = false;
288  if (armType =="right" || armType == "left")
289  armChoose = chooseArm(armType);
290 
291  // Call push (no calibration)
292  bool pushSucceed = push(targetCenter,theta,radius + actionOffset,options);
293 
294  //if (pushSucceed)
295  // returnArmSafely(armType);
296 
297  if (armChoose)
298  chooseArmAuto();
299 
300  return pushSucceed;
301 }
302 
303 bool icubclient::SubSystem_KARMA::pushFront(const std::string &objName,
304  const yarp::sig::VectorOf<double> &objCenter, const double &targetPosXFront,
305  const std::string &armType,
306  const yarp::os::Bottle &options)
307 {
308  // Calculate the pushing distance (radius) for push with Karma
309  Vector object = objCenter;
310  Bottle opt = options;
311  double zOffset = 0.1;
312  double actionOffset = 0.1; // add 10cm offset to deal with object dimension
313  yInfo ("[subSystem_KARMA] object center OPC : %s",object.toString().c_str());
314  selectHandCorrectTarget(opt,objName,object); // target is calibrated by this method
315  yInfo ("[subSystem_KARMA] object center calib: %s",object.toString().c_str());
316  double radius = fabs(object[0] - targetPosXFront);
317  yInfo ("objectX = %f",object[0]);
318  yInfo ("targetPosXFront = %f",targetPosXFront);
319  yInfo ("radius = %f",radius);
320  Vector targetCenter = object;
321  targetCenter[0] = targetPosXFront;
322 
323  if (hasTable)
324  targetCenter[2] = tableHeight+zOffset;
325 
326  yInfo ("object height = %f",targetCenter[2]);
327 
328  // Choose arm
329  bool armChoose = false;
330  if (armType =="right" || armType == "left")
331  armChoose = chooseArm(armType);
332 
333  // Call push (no calibration)
334  bool pushSucceed = push(targetCenter,-90,radius + actionOffset,options);
335 
336  //if (pushSucceed)
337  // returnArmSafely(armType);
338 
339  if (armChoose)
340  chooseArmAuto();
341 
342  return pushSucceed;
343 }
344 
345 bool icubclient::SubSystem_KARMA::push(const yarp::sig::VectorOf<double> &targetCenter,
346  const double theta, const double radius,
347  const yarp::os::Bottle &options)
348 {
349  yarp::os::Bottle bCmd;
350  bCmd.addVocab(yarp::os::Vocab::encode("push"));
351 
352  yarp::sig::VectorOf<double> target=targetCenter;
353  yarp::os::Bottle opt=options;
354 
355  target=applySafetyMargins(target);
356  appendTarget(bCmd,target);
357  appendDouble(bCmd,theta);
358  appendDouble(bCmd,radius);
359 
360  bCmd.append(opt);
361 
362  return sendCmd(bCmd);
363 }
364 
365 bool icubclient::SubSystem_KARMA::pullBack(const std::string &objName,
366  const yarp::sig::VectorOf<double> &objCenter, const double &targetPosXBack,
367  const std::string &armType,
368  const yarp::os::Bottle &options)
369 {
370  // Calculate the pulling distance (dist) for pull with Karma
371  Vector object = objCenter;
372  Bottle opt = options;
373  double zOffset = -0.04;
374  double actionOffset = 0.05; // add 5cm offset to deal with object dimension
375  yInfo ("[subSystem_KARMA] object center OPC : %s",object.toString().c_str());
376  selectHandCorrectTarget(opt,objName,object); // target is calibrated by this method
377  yInfo ("[subSystem_KARMA] object center calib: %s",object.toString().c_str());
378  double dist = fabs(object[0] - targetPosXBack); // dist in pulling ~ radius in pushing; radius in pulling ~ radius in pushing
379  yInfo ("objectX = %f",object[0]);
380  yInfo ("targetPosXBack = %f",targetPosXBack);
381  yInfo ("dist = %f",dist);
382  Vector targetCenter = object;
383 
384  if (hasTable)
385  targetCenter[2] = std::max(tableHeight,targetCenter[2]);
386  targetCenter[2] += zOffset;
387 
388  yInfo ("object height = %f",targetCenter[2]);
389 
390  // Choose arm
391  bool armChoose = false;
392  if (armType =="right" || armType == "left")
393  armChoose = chooseArm(armType);
394 
395  // Call draw (no calibration)
396  bool drawSucceed = draw(targetCenter,90,actionOffset,dist + actionOffset,options);
397 
398  //if (drawSucceed)
399  // returnArmSafely(armType);
400 
401  if (armChoose)
402  chooseArmAuto();
403 
404  return drawSucceed;
405 }
406 
407 bool icubclient::SubSystem_KARMA::draw(const yarp::sig::VectorOf<double> &targetCenter,
408  const double theta, const double radius,
409  const double dist, const yarp::os::Bottle &options)
410 {
411  yarp::os::Bottle bCmd;
412  bCmd.addVocab(yarp::os::Vocab::encode("draw"));
413 
414  yarp::sig::VectorOf<double> target=targetCenter;
415  yarp::os::Bottle opt=options;
416 
417  target=applySafetyMargins(target);
418  appendTarget(bCmd,target);
419  appendDouble(bCmd,theta);
420  appendDouble(bCmd,radius);
421  appendDouble(bCmd,dist);
422  bCmd.append(opt);
423 
424  return sendCmd(bCmd);
425 }
426 
427 bool icubclient::SubSystem_KARMA::vdraw(const std::string &objName,
428  const yarp::sig::VectorOf<double> &targetCenter,
429  const double theta, const double radius,
430  const double dist,
431  const yarp::os::Bottle &options)
432 {
433  yarp::os::Bottle bCmd;
434  bCmd.addVocab(yarp::os::Vocab::encode("vdraw"));
435 
436  yarp::sig::VectorOf<double> target=targetCenter;
437  yarp::os::Bottle opt=options;
438  selectHandCorrectTarget(opt,objName,target);
439  target=applySafetyMargins(target);
440  appendTarget(bCmd,target);
441  appendDouble(bCmd,theta);
442  appendDouble(bCmd,radius);
443  appendDouble(bCmd,dist);
444  bCmd.append(opt);
445 
446  return sendCmd(bCmd);
447 }
448 
450 {
451  std::string name = "KARMA";
452 
453  Property optionL("(device cartesiancontrollerclient)");
454  optionL.put("remote",("/"+robot+"/cartesianController/left_arm").c_str());
455  optionL.put("local",("/"+name+"/cart_ctrl/left_arm").c_str());
456 
457  Property optionR("(device cartesiancontrollerclient)");
458  optionR.put("remote",("/"+robot+"/cartesianController/right_arm").c_str());
459  optionR.put("local",("/"+name+"/cart_ctrl/right_arm").c_str());
460 
461  Property optionHL("(device remote_controlboard)");
462  optionHL.put("remote",("/"+robot+"/left_arm").c_str());
463  optionHL.put("local",("/"+name+"/hand_ctrl/left_arm").c_str());
464 
465  Property optionHR("(device remote_controlboard)");
466  optionHR.put("remote",("/"+robot+"/right_arm").c_str());
467  optionHR.put("local",("/"+name+"/hand_ctrl/right_arm").c_str());
468 
469 
470  if (!driverL.open(optionL))
471  {
472  return false;
473  }
474  if (!driverR.open(optionR))
475  {
476  driverL.close();
477  return false;
478  }
479 
480  if (!driverHL.open(optionHL))
481  {
482  driverL.close();
483  driverR.close();
484  return false;
485  }
486 
487  if (!driverHR.open(optionHR))
488  {
489  driverL.close();
490  driverR.close();
491  driverHL.close();
492  return false;
493  }
494 
495  driverL.view(iCartCtrlL);
496  driverR.view(iCartCtrlR);
497 
498  return true;
499 
500 }
501 
503 {
504  SubARE->Close();
505  delete SubARE;
506  driverL.close();
507  driverR.close();
508  driverHL.close();
509  driverHR.close();
510 }
bool chooseArm(const std::string &armType)
chooseArm (toolAttach in KARMA): wrapper for tool-attach of KARMA, can be used to choose the arm for ...
std::string m_type
Definition: subSystem.h:47
bool sendCmd(yarp::os::Bottle &cmd)
Sends a command to KARMA&#39;s RPC port.
bool pullBack(const std::string &objName, const yarp::sig::VectorOf< double > &objCenter, const double &targetPosXBack, const std::string &armType="selectable", const yarp::os::Bottle &options=yarp::os::Bottle())
pullBack (KARMA): pull an object to a certain location along x-axis of robot RoF
SubSystem to deal with the actionsRenderingEngine module (a.k.a.
Definition: subSystem_ARE.h:41
yarp::dev::PolyDriver driverHR
yarp::dev::PolyDriver driverR
yarp::os::RpcClient portRPC
Definition: subSystem.h:48
#define SUBSYSTEM_KARMA
bool vdraw(const std::string &objName, const yarp::sig::VectorOf< double > &targetCenter, const double theta, const double radius, const double dist, const yarp::os::Bottle &options=yarp::os::Bottle())
vdraw (KARMA): virtual draw action, along the positive direction of the x-axis (in robot FoR) ...
yarp::os::RpcClient portFinder
yarp::sig::VectorOf< double > applySafetyMargins(const yarp::sig::VectorOf< double > &in)
Applies safety margins, i.e.
void appendTarget(yarp::os::Bottle &b, const yarp::sig::VectorOf< double > &tCenter)
Appends a target vector t to the Bottle
bool draw(const yarp::sig::VectorOf< double > &targetCenter, const double theta, const double radius, const double dist, const yarp::os::Bottle &options=yarp::os::Bottle())
draw (KARMA): draw action, along the positive direction of the x-axis (in robot FoR) ...
yarp::dev::PolyDriver driverHL
Abstract class to handle sub-systems of the icub-client.
Definition: subSystem.h:43
void Close()
Clean up resources.
yarp::dev::PolyDriver driverL
SubSystem_KARMA(const std::string &masterName, const std::string &robot)
Default constructor.
bool returnArmSafely(std::string armType)
yarp::os::RpcClient portCalib
void selectHandCorrectTarget(yarp::os::Bottle &options, const std::string &targetName, yarp::sig::VectorOf< double > &target, const std::string handToUse="")
void chooseArmAuto()
chooseArmAuto (toolRemove in KARMA): wrapper for tool-remove of Karma, use to clear the arm choise ...
yarp::os::RpcClient portStop
void appendDouble(yarp::os::Bottle &b, const double &v)
Appends a double value v to the Bottle
bool pushFront(const std::string &objName, const yarp::sig::VectorOf< double > &objCenter, const double &targetPosXFront, const std::string &armType="selectable", const yarp::os::Bottle &options=yarp::os::Bottle())
pushFront (KARMA): push an object to a certain location along x-axis of robot RoF ...
bool push(const yarp::sig::VectorOf< double > &targetCenter, const double theta, const double radius, const yarp::os::Bottle &options=yarp::os::Bottle())
push (KARMA): push to certain position, along a defined direction
yarp::os::RpcClient portVision
bool pushAside(const std::string &objName, const yarp::sig::VectorOf< double > &objCenter, const double &targetPosY, const double &theta, const std::string &armType="selectable", const yarp::os::Bottle &options=yarp::os::Bottle())
pushAside (KARMA): push an object to a certain location along y-axis of robot RoF ...
void Close()
Clean up resources.
std::string m_masterName
Definition: subSystem.h:46
yarp::dev::ICartesianControl * iCartCtrlL
yarp::dev::ICartesianControl * iCartCtrlR