visual-tracking-control
main.cpp
Go to the documentation of this file.
1 #include <cmath>
2 #include <iostream>
3 
4 #include <iCub/ctrl/minJerkCtrl.h>
5 #include <iCub/iKin/iKinFwd.h>
6 #include <opencv2/core/core.hpp>
7 #include <opencv2/imgproc/imgproc.hpp>
8 #include <SuperimposeMesh/SISkeleton.h>
9 #include <yarp/dev/CartesianControl.h>
10 #include <yarp/dev/GazeControl.h>
11 #include <yarp/dev/PolyDriver.h>
12 #include <yarp/math/Math.h>
13 #include <yarp/math/SVD.h>
14 #include <yarp/os/BufferedPort.h>
15 #include <yarp/os/LogStream.h>
16 #include <yarp/os/Network.h>
17 #include <yarp/os/Property.h>
18 #include <yarp/os/RFModule.h>
19 #include <yarp/os/RpcClient.h>
20 #include <yarp/os/Time.h>
21 #include <yarp/sig/Image.h>
22 #include <yarp/sig/Matrix.h>
23 #include <yarp/sig/Vector.h>
24 
25 using namespace yarp::dev;
26 using namespace yarp::math;
27 using namespace yarp::os;
28 using namespace yarp::sig;
29 using namespace iCub::ctrl;
30 using namespace iCub::iKin;
31 
32 
33 class RFMReaching : public RFModule
34 {
35 public:
36  bool configure(ResourceFinder &rf)
37  {
38  if (!port_estimates_in_.open("/reaching/estimates:i"))
39  {
40  yError() << "Could not open /reaching/estimates:i port! Closing.";
41  return false;
42  }
43 
44  if (!port_image_left_in_.open("/reaching/cam_left/img:i"))
45  {
46  yError() << "Could not open /reaching/cam_left/img:i port! Closing.";
47  return false;
48  }
49 
50  if (!port_image_left_out_.open("/reaching/cam_left/img:o"))
51  {
52  yError() << "Could not open /reaching/cam_left/img:o port! Closing.";
53  return false;
54  }
55 
56  if (!port_click_left_.open("/reaching/cam_left/click:i"))
57  {
58  yError() << "Could not open /reaching/cam_left/click:in port! Closing.";
59  return false;
60  }
61 
62  if (!port_image_right_in_.open("/reaching/cam_right/img:i"))
63  {
64  yError() << "Could not open /reaching/cam_right/img:i port! Closing.";
65  return false;
66  }
67 
68  if (!port_image_right_out_.open("/reaching/cam_right/img:o"))
69  {
70  yError() << "Could not open /reaching/cam_right/img:o port! Closing.";
71  return false;
72  }
73 
74  if (!port_click_right_.open("/reaching/cam_right/click:i"))
75  {
76  yError() << "Could not open /reaching/cam_right/click:i port! Closing.";
77  return false;
78  }
79 
80  if (!port_px_left_endeffector.open("/reaching/cam_left/x:o"))
81  {
82  yError() << "Could not open /reaching/cam_left/x:o port! Closing.";
83  return false;
84  }
85 
86  if (!port_px_right_endeffector.open("/reaching/cam_right/x:o"))
87  {
88  yError() << "Could not open /reaching/cam_right/x:o port! Closing.";
89  return false;
90  }
91 
92  if (!setGazeController()) return false;
93 
94  if (!setTorsoRemoteControlboard()) return false;
95 
96  if (!setRightArmRemoteControlboard()) return false;
97 
98  if (!setRightArmCartesianController()) return false;
99 
100  Bottle btl_cam_info;
101  itf_gaze_->getInfo(btl_cam_info);
102  yInfo() << "[CAM INFO]" << btl_cam_info.toString();
103  Bottle* cam_left_info = btl_cam_info.findGroup("camera_intrinsics_left").get(1).asList();
104  Bottle* cam_right_info = btl_cam_info.findGroup("camera_intrinsics_right").get(1).asList();
105 
106  float left_fx = static_cast<float>(cam_left_info->get(0).asDouble());
107  float left_cx = static_cast<float>(cam_left_info->get(2).asDouble());
108  float left_fy = static_cast<float>(cam_left_info->get(5).asDouble());
109  float left_cy = static_cast<float>(cam_left_info->get(6).asDouble());
110 
111  left_proj_ = zeros(3, 4);
112  left_proj_(0, 0) = left_fx;
113  left_proj_(0, 2) = left_cx;
114  left_proj_(1, 1) = left_fy;
115  left_proj_(1, 2) = left_cy;
116  left_proj_(2, 2) = 1.0;
117 
118  yInfo() << "left_proj_ =\n" << left_proj_.toString();
119 
120  float right_fx = static_cast<float>(cam_right_info->get(0).asDouble());
121  float right_cx = static_cast<float>(cam_right_info->get(2).asDouble());
122  float right_fy = static_cast<float>(cam_right_info->get(5).asDouble());
123  float right_cy = static_cast<float>(cam_right_info->get(6).asDouble());
124 
125  right_proj_ = zeros(3, 4);
126  right_proj_(0, 0) = right_fx;
127  right_proj_(0, 2) = right_cx;
128  right_proj_(1, 1) = right_fy;
129  right_proj_(1, 2) = right_cy;
130  right_proj_(2, 2) = 1.0;
131 
132  yInfo() << "right_proj_ =\n" << right_proj_.toString();
133 
134 
135  Vector left_eye_x;
136  Vector left_eye_o;
137  itf_gaze_->getLeftEyePose(left_eye_x, left_eye_o);
138 
139  Vector right_eye_x;
140  Vector right_eye_o;
141  itf_gaze_->getRightEyePose(right_eye_x, right_eye_o);
142 
143  yInfo() << "left_eye_o =" << left_eye_o.toString();
144  yInfo() << "right_eye_o =" << right_eye_o.toString();
145 
146 
147  Matrix l_H_eye = axis2dcm(left_eye_o);
148  left_eye_x.push_back(1.0);
149  l_H_eye.setCol(3, left_eye_x);
150  Matrix l_H_r_to_eye = SE3inv(l_H_eye);
151 
152  Matrix r_H_eye = axis2dcm(right_eye_o);
153  right_eye_x.push_back(1.0);
154  r_H_eye.setCol(3, right_eye_x);
155  Matrix r_H_r_to_eye = SE3inv(r_H_eye);
156 
157  yInfo() << "l_H_r_to_eye =\n" << l_H_r_to_eye.toString();
158  yInfo() << "r_H_r_to_eye =\n" << r_H_r_to_eye.toString();
159 
160  l_H_r_to_cam_ = left_proj_ * l_H_r_to_eye;
161  r_H_r_to_cam_ = right_proj_ * r_H_r_to_eye;
162 
163  yInfo() << "l_H_r_to_cam_ =\n" << l_H_r_to_cam_.toString();
164  yInfo() << "r_H_r_to_cam_ =\n" << r_H_r_to_cam_.toString();
165 
166 
167  l_si_skel_ = new SISkeleton(left_fx, left_fy, left_cx, left_cy);
168  r_si_skel_ = new SISkeleton(right_fx, right_fy, right_cx, right_cy);
169 
170  icub_index_ = iCubFinger("right_index");
171  std::deque<IControlLimits*> temp_lim;
172  temp_lim.push_front(itf_fingers_lim_);
173  if (!icub_index_.alignJointsBounds(temp_lim))
174  {
175  yError() << "Cannot set joint bound for index finger.";
176  return false;
177  }
178 
179  handler_port_.open("/reaching/cmd:i");
180  attach(handler_port_);
181 
182  return true;
183  }
184 
185 
186  double getPeriod() { return 0; }
187 
188 
190  {
191  while (!take_estimates_);
192 
193  /* Get the initial end-effector pose from hand-tracking */
194  Vector* estimates = port_estimates_in_.read(true);
195 
196  /* Get the initial end-effector pose from the cartesian controller */
197 // Vector pose(12);
198 // Vector pose_x;
199 // Vector pose_o;
200 // itf_rightarm_cart_->getPose(pose_x, pose_o);
201 // pose_x.push_back(1.0);
202 // Matrix Ha = axis2dcm(pose_o);
203 // Ha.setCol(3, pose_x);
204 //
205 // Vector init_chain_joints;
206 // icub_index_.getChainJoints(readRootToFingers().subVector(3, 18), init_chain_joints);
207 // Vector init_tip_pose_index = (Ha * icub_index_.getH((M_PI/180.0) * init_chain_joints).getCol(3)).subVector(0, 2);
208 //
209 // pose.setSubvector(0, init_tip_pose_index);
210 // pose.setSubvector(3, zeros(3));
211 // pose.setSubvector(6, init_tip_pose_index);
212 // pose.setSubvector(9, zeros(3));
213 //
214 // Vector* estimates = &pose;
215  /* **************************************************** */
216 
217  if (should_stop_) return false;
218 
219 
220  yInfo() << "estimates = [" << estimates->toString() << "]";
221 
222  Vector px_img_left;
223  px_img_left.push_back(l_px_goal_[0]);
224  px_img_left.push_back(l_px_goal_[1]);
225  yInfo() << "px_img_left = [" << px_img_left.toString() << "]";
226 
227  Vector px_img_right;
228  px_img_right.push_back(r_px_goal_[0]);
229  px_img_right.push_back(r_px_goal_[1]);
230  yInfo() << "px_img_right = [" << px_img_right.toString() << "]";
231 
232  Vector px_des;
233  px_des.push_back(px_img_left[0]); /* u_l */
234  px_des.push_back(px_img_right[0]); /* u_r */
235  px_des.push_back(px_img_left[1]); /* v_l */
236  yInfo() << "px_des = [" << px_des.toString() << "]";
237 
238 
239  // FIXME: solo per controllo con l/r_px?
240  Vector px_ee_left; /* u_ee_l, v_ee_l */
241  itf_gaze_->get2DPixel(LEFT, estimates->subVector(0, 2), px_ee_left);
242  yInfo() << "estimates(0, 2) = [" << estimates->subVector(0, 2).toString() << "]";
243  yInfo() << "px_ee_left = [" << px_ee_left.toString() << "]";
244 
245 
246  Vector px_ee_right; /* u_ee_r, v_ee_r */
247  itf_gaze_->get2DPixel(RIGHT, estimates->subVector(6, 8), px_ee_right);
248  yInfo() << "estimates(6, 8) = [" << estimates->subVector(6, 8).toString() << "]";
249  yInfo() << "px_ee_right = [" << px_ee_right.toString() << "]";
250  /* ********************************** */
251 
252 
253  Vector left_eye_x;
254  Vector left_eye_o;
255  itf_gaze_->getLeftEyePose(left_eye_x, left_eye_o);
256 
257  Vector l_px = (l_H_r_to_cam_.submatrix(0, 2, 0, 2) * (estimates->subVector(0, 2) - left_eye_x));
258  yInfo() << "Proj left ee = [" << (l_px.subVector(0, 1) / l_px[2]).toString() << "]";
259 
260 
261  Vector right_eye_x;
262  Vector right_eye_o;
263  itf_gaze_->getRightEyePose(right_eye_x, right_eye_o);
264 
265  Vector r_px = (r_H_r_to_cam_.submatrix(0, 2, 0, 2) * (estimates->subVector(6, 8) - right_eye_x));
266  yInfo() << "Proj right ee = [" << (r_px.subVector(0, 1) / r_px[2]).toString() << "]";
267 
268 
269  Vector px_ee_now;
270  px_ee_now.push_back(l_px [0] / l_px[2]); /* u_ee_l */
271  px_ee_now.push_back(r_px[0] / r_px[2]); /* u_ee_r */
272  px_ee_now.push_back(l_px [1] / l_px[2]); /* v_ee_l */
273  yInfo() << "px_ee_now = [" << px_ee_now.toString() << "]";
274 
275 
276  /* Jacobian */
277  Matrix jacobian(3, 3);
278 
279  Vector l_ee_x = estimates->subVector(0, 2);
280  l_ee_x.push_back(1.0);
281 
282  double l_num_u = dot(l_H_r_to_cam_.subrow(0, 0, 4), l_ee_x);
283  double l_num_v = dot(l_H_r_to_cam_.subrow(1, 0, 4), l_ee_x);
284  double l_lambda = dot(l_H_r_to_cam_.subrow(2, 0, 4), l_ee_x);
285  double l_lambda_sq = pow(l_lambda, 2.0);
286 
287  jacobian(0, 0) = (l_H_r_to_cam_(0, 0) * l_lambda - l_H_r_to_cam_(2, 0) * l_num_u) / l_lambda_sq;
288  jacobian(0, 1) = (l_H_r_to_cam_(0, 1) * l_lambda - l_H_r_to_cam_(2, 1) * l_num_u) / l_lambda_sq;
289  jacobian(0, 2) = (l_H_r_to_cam_(0, 2) * l_lambda - l_H_r_to_cam_(2, 2) * l_num_u) / l_lambda_sq;
290 
291  jacobian(2, 0) = (l_H_r_to_cam_(1, 0) * l_lambda - l_H_r_to_cam_(2, 0) * l_num_v) / l_lambda_sq;
292  jacobian(2, 1) = (l_H_r_to_cam_(1, 1) * l_lambda - l_H_r_to_cam_(2, 1) * l_num_v) / l_lambda_sq;
293  jacobian(2, 2) = (l_H_r_to_cam_(1, 2) * l_lambda - l_H_r_to_cam_(2, 2) * l_num_v) / l_lambda_sq;
294 
295  Vector r_ee_x = estimates->subVector(6, 8);
296  r_ee_x.push_back(1.0);
297 
298  double r_num_u = dot(r_H_r_to_cam_.subrow(0, 0, 4), r_ee_x);
299 // double r_num_v = dot(r_H_r_to_cam_.subrow(1, 0, 4), r_ee_x);
300  double r_lambda = dot(r_H_r_to_cam_.subrow(2, 0, 4), r_ee_x);
301  double r_lambda_sq = pow(r_lambda, 2.0);
302 
303  jacobian(1, 0) = (r_H_r_to_cam_(0, 0) * r_lambda - r_H_r_to_cam_(2, 0) * r_num_u) / r_lambda_sq;
304  jacobian(1, 1) = (r_H_r_to_cam_(0, 1) * r_lambda - r_H_r_to_cam_(2, 1) * r_num_u) / r_lambda_sq;
305  jacobian(1, 2) = (r_H_r_to_cam_(0, 2) * r_lambda - r_H_r_to_cam_(2, 2) * r_num_u) / r_lambda_sq;
306 
307 
308  double Ts = 0.05; // controller's sample time [s]
309  double K = 1; // how long it takes to move to the target [s]
310  double v_max = 0.005; // max cartesian velocity [m/s]
311 
312  bool done = false;
313  while (!should_stop_ && !done)
314  {
315  Vector e = px_des - px_ee_now;
316 
317  yInfo() << "e = [" << e.toString() << "]";
318 
319  jacobian(0, 0) *= -2.0 * e[0];
320  jacobian(0, 1) *= -2.0 * e[0];
321  jacobian(0, 2) *= -2.0 * e[0];
322 
323  jacobian(1, 0) *= -2.0 * e[1];
324  jacobian(1, 1) *= -2.0 * e[1];
325  jacobian(1, 2) *= -2.0 * e[1];
326 
327  jacobian(2, 0) *= -2.0 * e[2];
328  jacobian(2, 1) *= -2.0 * e[2];
329  jacobian(2, 2) *= -2.0 * e[2];
330 
331  Matrix inv_jacobian = luinv(jacobian);
332 
333  e[0] *= e[0];
334  e[1] *= e[1];
335  e[2] *= e[2];
336  Vector vel_x = -1.0 * K * inv_jacobian * e;
337 
338  yInfo() << "vel_x = [" << vel_x.toString() << "]";
339 
340  /* Enforce velocity bounds */
341  for (size_t i = 0; i < vel_x.length(); ++i)
342  vel_x[i] = sign(vel_x[i]) * std::min(v_max, std::fabs(vel_x[i]));
343 
344  yInfo() << "bounded vel_x = [" << vel_x.toString() << "]";
345  yInfo() << "px_des = [" << px_des.toString() << "]";
346  yInfo() << "px_ee_now = [" << px_ee_now.toString() << "]";
347 
348  itf_rightarm_cart_->setTaskVelocities(vel_x, Vector(4, 0.0));
349 
350  yInfo() << "Pixel error norm (0): " << std::abs(px_des(0) - px_ee_now(0));
351  yInfo() << "Pixel error norm (1): " << std::abs(px_des(1) - px_ee_now(1));
352  yInfo() << "Pixel error norm (2): " << std::abs(px_des(2) - px_ee_now(2));
353  yInfo() << "Poistion error norm: " << norm(vel_x);
354 
355  Time::delay(Ts);
356 
357  done = ((std::abs(px_des(0) - px_ee_now(0)) < 1.0) && (std::abs(px_des(1) - px_ee_now(1)) < 1.0) && (std::abs(px_des(2) - px_ee_now(2)) < 1.0));
358  if (done)
359  {
360  yInfo() << "\npx_des =" << px_des.toString() << "px_ee_now =" << px_ee_now.toString();
361  yInfo() << "Terminating!\n";
362  }
363  else
364  {
365  /* Get the new end-effector pose from hand-tracking */
366  estimates = port_estimates_in_.read(true);
367 
368  /* Get the initial end-effector pose from the cartesian controller */
369 // itf_rightarm_cart_->getPose(pose_x, pose_o);
370 // pose_x.push_back(1.0);
371 // Ha = axis2dcm(pose_o);
372 // Ha.setCol(3, pose_x);
373 //
374 // Vector chain_joints;
375 // icub_index_.getChainJoints(readRootToFingers().subVector(3, 18), chain_joints);
376 // Vector tip_pose_index = (Ha * icub_index_.getH((M_PI/180.0) * chain_joints).getCol(3)).subVector(0, 2);
377 //
378 // pose.setSubvector(0, tip_pose_index);
379 // pose.setSubvector(3, zeros(3));
380 // pose.setSubvector(6, tip_pose_index);
381 // pose.setSubvector(9, zeros(3));
382 
383  /* Simulate reaching starting from the initial position */
384  /* Comment any previous write on variable 'estimates' */
385 // yInfo() << "EE L now: " << estimates->subVector(0, 2).toString();
386 // yInfo() << "EE R now: " << estimates->subVector(6, 8).toString() << "\n";
387 //
388 // estimates->setSubvector(0, estimates->subVector(0, 2) + vel_x);
389 // estimates->setSubvector(6, estimates->subVector(6, 8) + vel_x);
390  /* **************************************************** */
391 
392  yInfo() << "EE L cor: " << estimates->subVector(0, 2).toString();
393  yInfo() << "EE R cor: " << estimates->subVector(6, 8).toString() << "\n";
394 
395  l_px = (l_H_r_to_cam_.submatrix(0, 2, 0, 2) * (estimates->subVector(0, 2) - left_eye_x));
396  r_px = (r_H_r_to_cam_.submatrix(0, 2, 0, 2) * (estimates->subVector(6, 8) - right_eye_x));
397 
398  l_px[0] /= l_px[2];
399  l_px[1] /= l_px[2];
400 
401  r_px[0] /= r_px[2];
402  r_px[1] /= r_px[2];
403 
404  px_ee_now[0] = l_px [0]; /* u_ee_l */
405  px_ee_now[1] = r_px[0]; /* u_ee_r */
406  px_ee_now[2] = l_px [1]; /* v_ee_l */
407 
408 
409  /* Dump pixel coordinates of the end-effector */
410  Bottle& l_px_endeffector = port_px_left_endeffector.prepare();
411  l_px_endeffector.clear();
412  l_px_endeffector.addInt(l_px[0]);
413  l_px_endeffector.addInt(l_px[1]);
414  port_px_left_endeffector.write();
415 
416  Bottle& r_px_endeffector = port_px_right_endeffector.prepare();
417  r_px_endeffector.clear();
418  r_px_endeffector.addInt(r_px[0]);
419  r_px_endeffector.addInt(r_px[1]);
420  port_px_right_endeffector.write();
421 
422 
423  /* Update Jacobian */
424  jacobian = zeros(3, 3);
425  l_ee_x = estimates->subVector(0, 2);
426  l_ee_x.push_back(1.0);
427 
428  l_num_u = dot(l_H_r_to_cam_.subrow(0, 0, 4), l_ee_x);
429  l_num_v = dot(l_H_r_to_cam_.subrow(1, 0, 4), l_ee_x);
430  l_lambda = dot(l_H_r_to_cam_.subrow(2, 0, 4), l_ee_x);
431  l_lambda_sq = pow(l_lambda, 2.0);
432 
433  jacobian(0, 0) = (l_H_r_to_cam_(0, 0) * l_lambda - l_H_r_to_cam_(2, 0) * l_num_u) / l_lambda_sq;
434  jacobian(0, 1) = (l_H_r_to_cam_(0, 1) * l_lambda - l_H_r_to_cam_(2, 1) * l_num_u) / l_lambda_sq;
435  jacobian(0, 2) = (l_H_r_to_cam_(0, 2) * l_lambda - l_H_r_to_cam_(2, 2) * l_num_u) / l_lambda_sq;
436 
437  jacobian(2, 0) = (l_H_r_to_cam_(1, 0) * l_lambda - l_H_r_to_cam_(2, 0) * l_num_v) / l_lambda_sq;
438  jacobian(2, 1) = (l_H_r_to_cam_(1, 1) * l_lambda - l_H_r_to_cam_(2, 1) * l_num_v) / l_lambda_sq;
439  jacobian(2, 2) = (l_H_r_to_cam_(1, 2) * l_lambda - l_H_r_to_cam_(2, 2) * l_num_v) / l_lambda_sq;
440 
441  r_ee_x = estimates->subVector(6, 8);
442  r_ee_x.push_back(1.0);
443 
444  r_num_u = dot(r_H_r_to_cam_.subrow(0, 0, 4), r_ee_x);
445 // r_num_v = dot(r_H_r_to_cam_.subrow(1, 0, 4), r_ee_x);
446  r_lambda = dot(r_H_r_to_cam_.subrow(2, 0, 4), r_ee_x);
447  r_lambda_sq = pow(r_lambda, 2.0);
448 
449  jacobian(1, 0) = (r_H_r_to_cam_(0, 0) * r_lambda - r_H_r_to_cam_(2, 0) * r_num_u) / r_lambda_sq;
450  jacobian(1, 1) = (r_H_r_to_cam_(0, 1) * r_lambda - r_H_r_to_cam_(2, 1) * r_num_u) / r_lambda_sq;
451  jacobian(1, 2) = (r_H_r_to_cam_(0, 2) * r_lambda - r_H_r_to_cam_(2, 2) * r_num_u) / r_lambda_sq;
452 
453 
454  /* Left eye end-effector superimposition */
455  ImageOf<PixelRgb>* l_imgin = port_image_left_in_.read(true);
456  ImageOf<PixelRgb>& l_imgout = port_image_left_out_.prepare();
457  l_imgout = *l_imgin;
458  cv::Mat l_img = cv::cvarrToMat(l_imgout.getIplImage());
459 
460  cv::circle(l_img, cv::Point(l_px[0], l_px[1]), 4, cv::Scalar(0, 255, 0), 4);
461  cv::circle(l_img, cv::Point(l_px_goal_[0], l_px_goal_[1]), 4, cv::Scalar(0, 255, 0), 4);
462 
463  port_image_left_out_.write();
464 
465  /* Right eye end-effector superimposition */
466  ImageOf<PixelRgb>* r_imgin = port_image_right_in_.read(true);
467  ImageOf<PixelRgb>& r_imgout = port_image_right_out_.prepare();
468  r_imgout = *r_imgin;
469  cv::Mat r_img = cv::cvarrToMat(r_imgout.getIplImage());
470 
471  cv::circle(r_img, cv::Point(r_px[0], r_px[1]), 4, cv::Scalar(0, 255, 0), 4);
472  cv::circle(r_img, cv::Point(r_px_goal_[0], r_px_goal_[1]), 4, cv::Scalar(0, 255, 0), 4);
473 
474  port_image_right_out_.write();
475  }
476  }
477 
478  itf_rightarm_cart_->stopControl();
479 
480  Time::delay(0.5);
481 
482  return false;
483  }
484 
485 
486  bool respond(const Bottle& command, Bottle& reply)
487  {
488  int cmd = command.get(0).asVocab();
489  switch (cmd)
490  {
491  /* Safely close the application */
492  case VOCAB4('q','u','i','t'):
493  {
494  itf_rightarm_cart_->stopControl();
495 
496  take_estimates_ = true;
497  should_stop_ = true;
498 
499  this->interruptModule();
500 
501  reply = command;
502 
503  break;
504  }
505  /* Take pixel coordinates from the left and right camera images */
506  /* PLUS: Compute again the roto-translation and projection matrices from root to left and right camera planes */
507  case VOCAB3('i','m','g'):
508  {
509  Vector left_eye_x;
510  Vector left_eye_o;
511  itf_gaze_->getLeftEyePose(left_eye_x, left_eye_o);
512 
513  Vector right_eye_x;
514  Vector right_eye_o;
515  itf_gaze_->getRightEyePose(right_eye_x, right_eye_o);
516 
517  yInfo() << "left_eye_o =" << left_eye_o.toString();
518  yInfo() << "right_eye_o =" << right_eye_o.toString();
519 
520 
521  Matrix l_H_eye = axis2dcm(left_eye_o);
522  left_eye_x.push_back(1.0);
523  l_H_eye.setCol(3, left_eye_x);
524  Matrix l_H_r_to_eye = SE3inv(l_H_eye);
525 
526  Matrix r_H_eye = axis2dcm(right_eye_o);
527  right_eye_x.push_back(1.0);
528  r_H_eye.setCol(3, right_eye_x);
529  Matrix r_H_r_to_eye = SE3inv(r_H_eye);
530 
531  yInfo() << "l_H_r_to_eye =\n" << l_H_r_to_eye.toString();
532  yInfo() << "r_H_r_to_eye =\n" << r_H_r_to_eye.toString();
533 
534 
535  l_H_r_to_cam_ = left_proj_ * l_H_r_to_eye;
536  r_H_r_to_cam_ = right_proj_ * r_H_r_to_eye;
537 
538 
539  Bottle* click_left = port_click_left_.read (true);
540  Bottle* click_right = port_click_right_.read (true);
541 
542  l_px_goal_.resize(2);
543  l_px_goal_[0] = click_left->get(0).asDouble();
544  l_px_goal_[1] = click_left->get(1).asDouble();
545 
546  r_px_goal_.resize(2);
547  r_px_goal_[0] = click_right->get(0).asDouble();
548  r_px_goal_[1] = click_right->get(1).asDouble();
549 
550  reply = command;
551 
552  break;
553  }
554  /* Set a fixed goal in pixel coordinates */
555  /* PLUS: Compute again the roto-translation and projection matrices from root to left and right camera planes */
556  case VOCAB4('g', 'o', 'a', 'l'):
557  {
558  Vector left_eye_x;
559  Vector left_eye_o;
560  itf_gaze_->getLeftEyePose(left_eye_x, left_eye_o);
561 
562  Vector right_eye_x;
563  Vector right_eye_o;
564  itf_gaze_->getRightEyePose(right_eye_x, right_eye_o);
565 
566  yInfo() << "left_eye_o =" << left_eye_o.toString();
567  yInfo() << "right_eye_o =" << right_eye_o.toString();
568 
569 
570  Matrix l_H_eye = axis2dcm(left_eye_o);
571  left_eye_x.push_back(1.0);
572  l_H_eye.setCol(3, left_eye_x);
573  Matrix l_H_r_to_eye = SE3inv(l_H_eye);
574 
575  Matrix r_H_eye = axis2dcm(right_eye_o);
576  right_eye_x.push_back(1.0);
577  r_H_eye.setCol(3, right_eye_x);
578  Matrix r_H_r_to_eye = SE3inv(r_H_eye);
579 
580  yInfo() << "l_H_r_to_eye =\n" << l_H_r_to_eye.toString();
581  yInfo() << "r_H_r_to_eye =\n" << r_H_r_to_eye.toString();
582 
583  l_H_r_to_cam_ = left_proj_ * l_H_r_to_eye;
584  r_H_r_to_cam_ = right_proj_ * r_H_r_to_eye;
585 
586 
587  l_px_goal_.resize(2);
588  l_px_goal_[0] = 125;
589  l_px_goal_[1] = 135;
590 
591  r_px_goal_.resize(2);
592  r_px_goal_[0] = 89;
593  r_px_goal_[1] = 135;
594 
595  reply = command;
596 
597  break;
598  }
599  /* Start reaching phase */
600  case VOCAB2('g','o'):
601  {
602  reply = command;
603  take_estimates_ = true;
604 
605  break;
606  }
607  /* Get 3D information from the OPC of IOL */
608  case VOCAB3('o', 'p', 'c'):
609  {
610  Network yarp;
611  Bottle cmd;
612  Bottle rep;
613 
614  RpcClient port_memory;
615  port_memory.open("/reaching/tomemory");
616  yarp.connect("/reaching/tomemory", "/memory/rpc");
617 
618  cmd.addVocab(Vocab::encode("ask"));
619  Bottle &content = cmd.addList().addList();
620  content.addString("name");
621  content.addString("==");
622  content.addString("Duck");
623 
624  port_memory.write(cmd, rep);
625 
626  if (rep.size()>1)
627  {
628  if (rep.get(0).asVocab() == Vocab::encode("ack"))
629  {
630  if (Bottle *idField = rep.get(1).asList())
631  {
632  if (Bottle *idValues = idField->get(1).asList())
633  {
634  int id = idValues->get(0).asInt();
635 
636  cmd.clear();
637 
638  cmd.addVocab(Vocab::encode("get"));
639  Bottle& content = cmd.addList();
640  Bottle& list_bid = content.addList();
641 
642  list_bid.addString("id");
643  list_bid.addInt(id);
644 
645  Bottle& list_propSet = content.addList();
646  list_propSet.addString("propSet");
647 
648  Bottle& list_items = list_propSet.addList();
649  list_items.addString("position_2d_left");
650 
651  Bottle reply_prop;
652  port_memory.write(cmd, reply_prop);
653 
654  if (reply_prop.get(0).asVocab() == Vocab::encode("ack"))
655  {
656  if (Bottle* propField = reply_prop.get(1).asList())
657  {
658  if (Bottle* position_2d = propField->find("position_2d_left").asList())
659  {
660  if (position_2d->size() == 4)
661  {
662  l_px_goal_.resize(2);
663  l_px_goal_[0] = position_2d->get(0).asDouble() + (position_2d->get(2).asDouble() - position_2d->get(0).asDouble()) / 2;
664  l_px_goal_[1] = position_2d->get(1).asDouble() + (position_2d->get(3).asDouble() - position_2d->get(1).asDouble()) / 2;
665 
666  RpcClient port_sfm;
667  port_sfm.open("/reaching/tosfm");
668  yarp.connect("/reaching/tosfm", "/SFM/rpc");
669 
670  cmd.clear();
671 
672  cmd.addInt(l_px_goal_[0]);
673  cmd.addInt(l_px_goal_[1]);
674 
675  Bottle reply_pos;
676  port_sfm.write(cmd, reply_pos);
677 
678  if (reply_pos.size() == 5)
679  {
680  location_.resize(3);
681  location_[0] = reply_pos.get(0).asDouble();
682  location_[1] = reply_pos.get(1).asDouble();
683  location_[2] = reply_pos.get(2).asDouble();
684 
685  r_px_goal_.resize(2);
686  r_px_goal_[0] = reply_pos.get(3).asDouble();
687  r_px_goal_[1] = reply_pos.get(4).asDouble();
688  }
689  else
690  {
691  reply.addString("nack_9");
692  }
693 
694  yarp.disconnect("/reaching/tosfm", "/SFM/rpc");
695  port_sfm.close();
696  }
697  else
698  {
699  reply.addString("nack_8");
700  }
701  }
702  else
703  {
704  reply.addString("nack_7");
705  }
706  }
707  else
708  {
709  reply.addString("nack_6");
710  }
711  }
712  else
713  {
714  reply.addString("nack_5");
715  }
716  }
717  else
718  {
719  reply.addString("nack_4");
720  }
721  }
722  else
723  {
724  reply.addString("nack_3");
725  }
726  }
727  else
728  {
729  reply.addString("nack_2");
730  }
731  }
732  else
733  {
734  reply.addString("nack_1");
735  }
736  yarp.disconnect("/reaching/tomemory", "/memory/rpc");
737  port_memory.close();
738 
739  yInfo() << "l_px_location: " << l_px_goal_.toString();
740  yInfo() << "r_px_location: " << r_px_goal_.toString();
741  yInfo() << "location: " << location_.toString();
742 
743  reply.addString("ack");
744 
745  break;
746  }
747  /* Set a fixed (hard-coded) 3D position for open-loop reaching */
748  case VOCAB3('p', 'o', 's'):
749  {
750  Bottle cmd;
751 
752  location_.resize(3);
753  location_[0] = -0.412;
754  location_[1] = 0.0435;
755  location_[2] = 0.0524;
756 
757  yInfo() << "location: " << location_.toString();
758 
759  reply = command;
760 
761  break;
762  }
763  /* Get 3D point from Structure From Motion clicking on the left camera image */
764  case VOCAB3('s', 'f', 'm'):
765  {
766  Network yarp;
767  Bottle cmd;
768  Bottle rep;
769 
770 
771  Bottle* click_left = port_click_left_.read (true);
772 
773  l_px_goal_.resize(2);
774  l_px_goal_[0] = click_left->get(0).asDouble();
775  l_px_goal_[1] = click_left->get(1).asDouble();
776 
777 
778  RpcClient port_sfm;
779  port_sfm.open("/reaching/tosfm");
780  yarp.connect("/reaching/tosfm", "/SFM/rpc");
781 
782  cmd.clear();
783 
784  cmd.addInt(l_px_goal_[0]);
785  cmd.addInt(l_px_goal_[1]);
786 
787  Bottle reply_pos;
788  port_sfm.write(cmd, reply_pos);
789 
790  if (reply_pos.size() == 5)
791  {
792  location_.resize(3);
793  location_[0] = reply_pos.get(0).asDouble();
794  location_[1] = reply_pos.get(1).asDouble();
795  location_[2] = reply_pos.get(2).asDouble();
796 
797  yInfo() << "location: " << location_.toString();
798 
799  r_px_goal_.resize(2);
800  r_px_goal_[0] = reply_pos.get(3).asDouble();
801  r_px_goal_[1] = reply_pos.get(4).asDouble();
802  }
803  else
804  {
805  reply.addString("nack");
806  }
807 
808  yarp.disconnect("/reaching/tosfm", "/SFM/rpc");
809  port_sfm.close();
810 
811  reply = command;
812 
813  break;
814  }
815  /* Go to initial position (open-loop) */
816  case VOCAB4('i', 'n', 'i', 't'):
817  {
818  /* FINGERTIP */
819  Matrix Od(3, 3);
820  Od(0, 0) = -1.0;
821  Od(1, 1) = 1.0;
822  Od(2, 2) = -1.0;
823  Vector od = dcm2axis(Od);
824 
825  /* KARATE */
826 // Matrix Od = zeros(3, 3);
827 // Od(0, 0) = -1.0;
828 // Od(2, 1) = -1.0;
829 // Od(1, 2) = -1.0;
830 // Vector od = dcm2axis(Od);
831 
832  double traj_time = 0.0;
833  itf_rightarm_cart_->getTrajTime(&traj_time);
834 
835  if (traj_time == traj_time_)
836  {
837  /* FINGERTIP */
838  Vector chain_joints;
839  icub_index_.getChainJoints(readRootToFingers().subVector(3, 18), chain_joints);
840 
841  Matrix tip_pose_index = icub_index_.getH((M_PI/180.0) * chain_joints);
842  Vector tip_x = tip_pose_index.getCol(3);
843  Vector tip_o = dcm2axis(tip_pose_index);
844  itf_rightarm_cart_->attachTipFrame(tip_x, tip_o);
845 
846  location_[0] += 0.03;
847  location_[1] += 0.07;
848  location_[2] = 0.12;
849 
850  setTorsoDOF();
851 
852  /* KARATE */
853 // location_[0] += 0.10;
854 // location_[1] += 0.10;
855 // location_[2] = 0.06;
856 
857  Vector gaze_loc(3);
858  gaze_loc(0) = -0.579;
859  gaze_loc(1) = 0.472;
860  gaze_loc(2) = -0.280;
861 
862 
863 // itf_gaze_->lookAtFixationPointSync(gaze_loc);
864 // itf_gaze_->waitMotionDone();
865 
866  int ctxt;
867  itf_rightarm_cart_->storeContext(&ctxt);
868 
869  itf_rightarm_cart_->setLimits(0, 20.0, 20.0);
870 
871  itf_rightarm_cart_->goToPoseSync(location_, od);
872  itf_rightarm_cart_->waitMotionDone();
873  itf_rightarm_cart_->stopControl();
874 
875  itf_rightarm_cart_->restoreContext(ctxt);
876  itf_rightarm_cart_->deleteContext(ctxt);
877 
878  itf_gaze_->lookAtFixationPointSync(gaze_loc);
879  itf_gaze_->waitMotionDone();
880 
881  unsetTorsoDOF();
882  itf_rightarm_cart_->removeTipFrame();
883 
884  reply.addString("ack");
885  }
886  else
887  {
888  reply.addString("nack");
889  }
890 
891  break;
892  }
893  /* Stop the Cartesian controller */
894  case VOCAB4('s', 't', 'o', 'p'):
895  {
896  if (itf_rightarm_cart_->stopControl())
897  {
898  itf_rightarm_cart_->removeTipFrame();
899 
900  reply.addString("ack");
901  }
902  else
903  {
904  reply.addString("nack_2");
905  }
906 
907  break;
908  }
909  default:
910  {
911  reply.addString("nack");
912  }
913  }
914 
915  return true;
916  }
917 
919  {
920  yInfo() << "Interrupting module.\nPort cleanup...";
921 
922  Time::delay(3.0);
923 
924  port_estimates_in_.interrupt();
925  port_image_left_in_.interrupt();
926  port_image_left_out_.interrupt();
927  port_click_left_.interrupt();
928  port_image_right_in_.interrupt();
929  port_image_right_out_.interrupt();
930  port_click_right_.interrupt();
931  handler_port_.interrupt();
932 
933  return true;
934  }
935 
936  bool close()
937  {
938  yInfo() << "Calling close functions...";
939 
940  port_estimates_in_.close();
941  port_image_left_in_.close();
942  port_image_left_out_.close();
943  port_click_left_.close();
944  port_image_right_in_.close();
945  port_image_right_out_.close();
946  port_click_right_.close();
947 
948  itf_rightarm_cart_->removeTipFrame();
949 
950  if (rightarm_cartesian_driver_.isValid()) rightarm_cartesian_driver_.close();
951  if (gaze_driver_.isValid()) gaze_driver_.close();
952 
953  handler_port_.close();
954 
955  return true;
956  }
957 
958 private:
960  bool should_stop_ = false;
961 
962  SISkeleton * l_si_skel_;
963  SISkeleton * r_si_skel_;
964 
965  BufferedPort<Vector> port_estimates_in_;
966 
967  BufferedPort<ImageOf<PixelRgb>> port_image_left_in_;
968  BufferedPort<ImageOf<PixelRgb>> port_image_left_out_;
969  BufferedPort<Bottle> port_click_left_;
970 
971  BufferedPort<ImageOf<PixelRgb>> port_image_right_in_;
972  BufferedPort<ImageOf<PixelRgb>> port_image_right_out_;
973  BufferedPort<Bottle> port_click_right_;
974 
975  BufferedPort<Bottle> port_px_left_endeffector;
976  BufferedPort<Bottle> port_px_right_endeffector;
977 
979  ICartesianControl * itf_rightarm_cart_;
980 
981  PolyDriver gaze_driver_;
982  IGazeControl * itf_gaze_;
983 
985  IEncoders * itf_rightarm_enc_;
986  IControlLimits * itf_fingers_lim_;
987 
989  IEncoders * itf_torso_enc_;
990 
991  iCubFinger icub_index_;
992 
993  Matrix left_proj_;
994  Matrix right_proj_;
998 
999  double traj_time_ = 2.5;
1000  Vector l_px_goal_;
1001  Vector r_px_goal_;
1002  Vector location_;
1003  bool take_estimates_ = false;
1004 
1005  enum camsel
1006  {
1007  LEFT = 0,
1008  RIGHT = 1
1009  };
1010 
1012  {
1013  Property rightarm_cartesian_options;
1014  rightarm_cartesian_options.put("device", "cartesiancontrollerclient");
1015  rightarm_cartesian_options.put("local", "/reaching/cart_right_arm");
1016  rightarm_cartesian_options.put("remote", "/icub/cartesianController/right_arm");
1017 
1018  rightarm_cartesian_driver_.open(rightarm_cartesian_options);
1019  if (rightarm_cartesian_driver_.isValid())
1020  {
1021  rightarm_cartesian_driver_.view(itf_rightarm_cart_);
1022  if (!itf_rightarm_cart_)
1023  {
1024  yError() << "Error getting ICartesianControl interface.";
1025  return false;
1026  }
1027  yInfo() << "cartesiancontrollerclient succefully opened.";
1028  }
1029  else
1030  {
1031  yError() << "Error opening cartesiancontrollerclient device.";
1032  return false;
1033  }
1034 
1035  if (!itf_rightarm_cart_->setTrajTime(traj_time_))
1036  {
1037  yError() << "Error setting ICartesianControl trajectory time.";
1038  return false;
1039  }
1040  yInfo() << "Succesfully set ICartesianControl trajectory time!";
1041 
1042  if (!itf_rightarm_cart_->setInTargetTol(0.01))
1043  {
1044  yError() << "Error setting ICartesianControl target tolerance.";
1045  return false;
1046  }
1047  yInfo() << "Succesfully set ICartesianControl target tolerance!";
1048 
1049  return true;
1050  }
1051 
1053  {
1054  Property gaze_option;
1055  gaze_option.put("device", "gazecontrollerclient");
1056  gaze_option.put("local", "/reaching/gaze");
1057  gaze_option.put("remote", "/iKinGazeCtrl");
1058 
1059  gaze_driver_.open(gaze_option);
1060  if (gaze_driver_.isValid())
1061  {
1062  gaze_driver_.view(itf_gaze_);
1063  if (!itf_gaze_)
1064  {
1065  yError() << "Error getting IGazeControl interface.";
1066  return false;
1067  }
1068  }
1069  else
1070  {
1071  yError() << "Gaze control device not available.";
1072  return false;
1073  }
1074 
1075  return true;
1076  }
1077 
1079  {
1080  Property rightarm_remote_options;
1081  rightarm_remote_options.put("device", "remote_controlboard");
1082  rightarm_remote_options.put("local", "/reaching/control_right_arm");
1083  rightarm_remote_options.put("remote", "/icub/right_arm");
1084 
1085  rightarm_remote_driver_.open(rightarm_remote_options);
1086  if (rightarm_remote_driver_.isValid())
1087  {
1088  yInfo() << "Right arm remote_controlboard succefully opened.";
1089 
1090  rightarm_remote_driver_.view(itf_rightarm_enc_);
1091  if (!itf_rightarm_enc_)
1092  {
1093  yError() << "Error getting right arm IEncoders interface.";
1094  return false;
1095  }
1096 
1097  rightarm_remote_driver_.view(itf_fingers_lim_);
1098  if (!itf_fingers_lim_)
1099  {
1100  yError() << "Error getting IControlLimits interface.";
1101  return false;
1102  }
1103  }
1104  else
1105  {
1106  yError() << "Error opening right arm remote_controlboard device.";
1107  return false;
1108  }
1109 
1110  return true;
1111  }
1112 
1114  {
1115  Property torso_remote_options;
1116  torso_remote_options.put("device", "remote_controlboard");
1117  torso_remote_options.put("local", "/reaching/control_torso");
1118  torso_remote_options.put("remote", "/icub/torso");
1119 
1120  torso_remote_driver_.open(torso_remote_options);
1121  if (torso_remote_driver_.isValid())
1122  {
1123  yInfo() << "Torso remote_controlboard succefully opened.";
1124 
1125  torso_remote_driver_.view(itf_torso_enc_);
1126  if (!itf_torso_enc_)
1127  {
1128  yError() << "Error getting torso IEncoders interface.";
1129  return false;
1130  }
1131 
1132  return true;
1133  }
1134  else
1135  {
1136  yError() << "Error opening Torso remote_controlboard device.";
1137  return false;
1138  }
1139  }
1140 
1142  {
1143  Vector curDOF;
1144  itf_rightarm_cart_->getDOF(curDOF);
1145  yInfo() << "Old DOF: [" + curDOF.toString(0) + "].";
1146  yInfo() << "Setting iCub to use the DOF from the torso.";
1147  Vector newDOF(curDOF);
1148  newDOF[0] = 1;
1149  newDOF[1] = 2;
1150  newDOF[2] = 1;
1151  if (!itf_rightarm_cart_->setDOF(newDOF, curDOF))
1152  {
1153  yError() << "Cannot use torso DOF.";
1154  return false;
1155  }
1156  yInfo() << "Setting the DOF done.";
1157  yInfo() << "New DOF: [" + curDOF.toString(0) + "]";
1158 
1159  return true;
1160  }
1161 
1163  {
1164  Vector curDOF;
1165  itf_rightarm_cart_->getDOF(curDOF);
1166  yInfo() << "Old DOF: [" + curDOF.toString(0) + "].";
1167  yInfo() << "Setting iCub to use the DOF from the torso.";
1168  Vector newDOF(curDOF);
1169  newDOF[0] = 0;
1170  newDOF[1] = 2;
1171  newDOF[2] = 0;
1172  if (!itf_rightarm_cart_->setDOF(newDOF, curDOF))
1173  {
1174  yError() << "Cannot use torso DOF.";
1175  return false;
1176  }
1177  yInfo() << "Setting the DOF done.";
1178  yInfo() << "New DOF: [" + curDOF.toString(0) + "]";
1179 
1180  return true;
1181  }
1182 
1183  Vector readTorso()
1184  {
1185  Vector torso_enc(3);
1186  itf_torso_enc_->getEncoders(torso_enc.data());
1187 
1188  std::swap(torso_enc(0), torso_enc(2));
1189 
1190  return torso_enc;
1191  }
1192 
1194  {
1195  Vector rightarm_encoder(16);
1196  itf_rightarm_enc_->getEncoders(rightarm_encoder.data());
1197 
1198  Vector root_fingers_enc(19);
1199  root_fingers_enc.setSubvector(0, readTorso());
1200 
1201  root_fingers_enc.setSubvector(3, rightarm_encoder);
1202 
1203  return root_fingers_enc;
1204  }
1205 };
1206 
1207 
1208 int main()
1209 {
1210  Network yarp;
1211  if (!yarp.checkNetwork(3.0))
1212  {
1213  yError() << "YARP seems unavailable!";
1214  return EXIT_FAILURE;
1215  }
1216 
1217  ResourceFinder rf;
1218  RFMReaching reaching;
1219  reaching.runModule(rf);
1220 
1221  return EXIT_SUCCESS;
1222 }
int main(int argc, char *argv[])
Definition: main.cpp:38
Matrix l_H_r_to_cam_
Definition: main.cpp:995
double getPeriod()
Definition: main.cpp:186
Matrix right_proj_
Definition: main.cpp:994
SISkeleton * l_si_skel_
Definition: main.cpp:962
BufferedPort< Bottle > port_px_right_endeffector
Definition: main.cpp:976
IControlLimits * itf_fingers_lim_
Definition: main.cpp:986
iCubFinger icub_index_
Definition: main.cpp:991
Vector readTorso()
Definition: main.cpp:1183
bool setRightArmRemoteControlboard()
Definition: main.cpp:1078
BufferedPort< ImageOf< PixelRgb > > port_image_right_in_
Definition: main.cpp:971
BufferedPort< Bottle > port_px_left_endeffector
Definition: main.cpp:975
bool setTorsoDOF()
Definition: main.cpp:1141
PolyDriver rightarm_cartesian_driver_
Definition: main.cpp:978
bool configure(ResourceFinder &rf)
Definition: main.cpp:36
IEncoders * itf_rightarm_enc_
Definition: main.cpp:985
Port handler_port_
Definition: main.cpp:959
bool close()
Definition: main.cpp:936
BufferedPort< ImageOf< PixelRgb > > port_image_left_out_
Definition: main.cpp:968
Matrix r_H_r_to_cam_
Definition: main.cpp:996
Vector r_px_goal_
Definition: main.cpp:1001
Matrix left_proj_
Definition: main.cpp:993
bool setGazeController()
Definition: main.cpp:1052
bool setTorsoRemoteControlboard()
Definition: main.cpp:1113
BufferedPort< Bottle > port_click_left_
Definition: main.cpp:969
PolyDriver gaze_driver_
Definition: main.cpp:981
BufferedPort< ImageOf< PixelRgb > > port_image_left_in_
Definition: main.cpp:967
Matrix px_to_cartesian_
Definition: main.cpp:997
bool interruptModule()
Definition: main.cpp:918
PolyDriver rightarm_remote_driver_
Definition: main.cpp:984
bool setRightArmCartesianController()
Definition: main.cpp:1011
SISkeleton * r_si_skel_
Definition: main.cpp:963
bool respond(const Bottle &command, Bottle &reply)
Definition: main.cpp:486
Vector location_
Definition: main.cpp:1002
bool updateModule()
Definition: main.cpp:189
IEncoders * itf_torso_enc_
Definition: main.cpp:989
Vector readRootToFingers()
Definition: main.cpp:1193
IGazeControl * itf_gaze_
Definition: main.cpp:982
Vector l_px_goal_
Definition: main.cpp:1000
PolyDriver torso_remote_driver_
Definition: main.cpp:988
BufferedPort< ImageOf< PixelRgb > > port_image_right_out_
Definition: main.cpp:972
bool unsetTorsoDOF()
Definition: main.cpp:1162
ICartesianControl * itf_rightarm_cart_
Definition: main.cpp:979
BufferedPort< Bottle > port_click_right_
Definition: main.cpp:973
BufferedPort< Vector > port_estimates_in_
Definition: main.cpp:965