3 #include <iCub/ctrl/minJerkCtrl.h> 4 #include <opencv2/core/core.hpp> 5 #include <opencv2/imgproc/imgproc.hpp> 6 #include <yarp/math/Math.h> 7 #include <yarp/math/SVD.h> 8 #include <yarp/os/Network.h> 9 #include <yarp/os/Property.h> 10 #include <yarp/os/Time.h> 22 yInfo() <<
"*** Invoked VisualServoingServer ctor ***";
23 yInfo() <<
"*** VisualServoingServer constructed ***";
29 yInfo() <<
"*** Invoked VisualServoingServer dtor ***";
30 yInfo() <<
"*** VisualServoingServer destructed ***";
37 verbosity_ = config.check(
"verbosity", Value(
false)).asBool();
38 yInfo() <<
"|> Verbosity: " + ConstString(verbosity_?
"ON" :
"OFF");
40 sim_ = config.check(
"simulate", Value(
false)).asBool();
41 yInfo() <<
"|> Simulation: " + ConstString(sim_?
"TRUE" :
"FALSE");
44 yInfoVerbose(
"*** Configuring VisualServoingServer ***");
47 robot_name_ = config.check(
"robot", Value(
"icub")).asString();
48 if (robot_name_.empty())
50 yErrorVerbose(
"Robot name not provided!");
54 yInfoVerbose(
"|> Robot name: " + robot_name_);
57 if (!port_pose_left_in_.open(
"/visualservoing/pose/left:i"))
59 yErrorVerbose(
"Could not open /visualservoing/pose/left:i port!");
62 if (!port_pose_right_in_.open(
"/visualservoing/pose/right:i"))
64 yErrorVerbose(
"Could not open /visualservoing/pose/right:i port!");
69 if (!port_image_left_in_.open(
"/visualservoing/cam_left/img:i"))
71 yErrorVerbose(
"Could not open /visualservoing/cam_left/img:i port!");
74 if (!port_image_left_out_.open(
"/visualservoing/cam_left/img:o"))
76 yErrorVerbose(
"Could not open /visualservoing/cam_left/img:o port!");
81 if (!port_image_right_in_.open(
"/visualservoing/cam_right/img:i"))
83 yErrorVerbose(
"Could not open /visualservoing/cam_right/img:i port!");
86 if (!port_image_right_out_.open(
"/visualservoing/cam_right/img:o"))
88 yErrorVerbose(
"Could not open /visualservoing/cam_right/img:o port!");
93 if (!port_click_left_.open(
"/visualservoing/cam_left/click:i"))
95 yErrorVerbose(
"Could not open /visualservoing/cam_left/click:in port!");
98 if (!port_click_right_.open(
"/visualservoing/cam_right/click:i"))
100 yErrorVerbose(
"Could not open /visualservoing/cam_right/click:i port!");
105 if (!setGazeController())
return false;
107 if (!setRightArmCartesianController())
return false;
111 itf_gaze_->getInfo(btl_cam_info);
112 yInfoVerbose(
"[CAM]" + btl_cam_info.toString());
113 Bottle* cam_left_info = btl_cam_info.findGroup(
"camera_intrinsics_left").get(1).asList();
114 Bottle* cam_right_info = btl_cam_info.findGroup(
"camera_intrinsics_right").get(1).asList();
116 double left_fx = cam_left_info->get(0).asDouble();
117 double left_cx = cam_left_info->get(2).asDouble();
118 double left_fy = cam_left_info->get(5).asDouble();
119 double left_cy = cam_left_info->get(6).asDouble();
121 yInfoVerbose(
"[CAM] Left camera intrinsic parameters:");
122 yInfoVerbose(
"[CAM] - fx: " + std::to_string(left_fx));
123 yInfoVerbose(
"[CAM] - fy: " + std::to_string(left_fy));
124 yInfoVerbose(
"[CAM] - cx: " + std::to_string(left_cx));
125 yInfoVerbose(
"[CAM] - cy: " + std::to_string(left_cy));
127 l_proj_ = zeros(3, 4);
128 l_proj_(0, 0) = left_fx;
129 l_proj_(0, 2) = left_cx;
130 l_proj_(1, 1) = left_fy;
131 l_proj_(1, 2) = left_cy;
134 yInfoVerbose(
"Left projection matrix = [\n" + l_proj_.toString() +
"\n]");
136 double right_fx = cam_right_info->get(0).asDouble();
137 double right_cx = cam_right_info->get(2).asDouble();
138 double right_fy = cam_right_info->get(5).asDouble();
139 double right_cy = cam_right_info->get(6).asDouble();
141 yInfoVerbose(
"[CAM] Right camera intrinsic paramenter:");
142 yInfoVerbose(
"[CAM] - fx: " + std::to_string(right_fx));
143 yInfoVerbose(
"[CAM] - fy: " + std::to_string(right_fy));
144 yInfoVerbose(
"[CAM] - cx: " + std::to_string(right_cx));
145 yInfoVerbose(
"[CAM] - cy: " + std::to_string(right_cy));
147 r_proj_ = zeros(3, 4);
148 r_proj_(0, 0) = right_fx;
149 r_proj_(0, 2) = right_cx;
150 r_proj_(1, 1) = right_fy;
151 r_proj_(1, 2) = right_cy;
154 yInfoVerbose(
"Right projection matrix = [\n" + r_proj_.toString() +
"\n]");
158 port_pose_px_l_.open(
"/visualservoing/cam_left/ctrl:o");
159 port_pose_px_r_.open(
"/visualservoing/cam_right/ctrl:o");
161 port_kin_px_l_.open(
"/visualservoing/cam_left/kin:o");
162 port_kin_px_r_.open(
"/visualservoing/cam_right/kin:o");
164 port_goal_px_l_.open(
"/visualservoing/cam_left/goal:o");
165 port_goal_px_r_.open(
"/visualservoing/cam_right/goal:o");
167 port_pose_avg_.open(
"/visualservoing/pose/ctrl:o");
168 port_pose_kin_.open(
"/visualservoing/pose/kin:o");
169 port_pose_goal_.open(
"/visualservoing/pose/goal:o");
172 if (!setCommandPort())
174 yErrorVerbose(
"Could not open /visualservoing/cmd:i port!");
179 yInfoVerbose(
"*** VisualServoingServer configured! ***");
187 yInfoVerbose(
"*** Interrupting VisualServoingServer ***");
189 yInfoVerbose(
"Ensure controllers are stopped...");
190 itf_rightarm_cart_->stopControl();
191 itf_gaze_->stopControl();
193 yInfoVerbose(
"...interrupting ports.");
194 port_pose_left_in_.interrupt();
195 port_pose_right_in_.interrupt();
196 port_image_left_in_.interrupt();
197 port_image_left_out_.interrupt();
198 port_click_left_.interrupt();
199 port_image_right_in_.interrupt();
200 port_image_right_out_.interrupt();
201 port_click_right_.interrupt();
203 port_pose_px_l_.interrupt();
204 port_pose_px_r_.interrupt();
205 port_kin_px_l_.interrupt();
206 port_kin_px_r_.interrupt();
207 port_goal_px_l_.interrupt();
208 port_goal_px_r_.interrupt();
209 port_pose_avg_.interrupt();
210 port_pose_kin_.interrupt();
211 port_pose_goal_.interrupt();
213 yInfoVerbose(
"*** Interrupting VisualServoingServer done! ***");
216 yInfoVerbose(
"*** Closing VisualServoingServer ***");
218 yInfoVerbose(
"Closing ports...");
219 port_pose_left_in_.close();
220 port_pose_right_in_.close();
221 port_image_left_in_.close();
222 port_image_left_out_.close();
223 port_click_left_.close();
224 port_image_right_in_.close();
225 port_image_right_out_.close();
226 port_click_right_.close();
228 port_pose_px_l_.close();
229 port_pose_px_r_.close();
230 port_kin_px_l_.close();
231 port_kin_px_r_.close();
232 port_goal_px_l_.close();
233 port_goal_px_r_.close();
234 port_pose_avg_.close();
235 port_pose_kin_.close();
236 port_pose_goal_.close();
238 yInfoVerbose(
"...removing frames...");
239 itf_rightarm_cart_->removeTipFrame();
241 yInfoVerbose(
"...closing drivers.");
242 if (rightarm_cartesian_driver_.isValid()) rightarm_cartesian_driver_.close();
243 if (gaze_driver_.isValid()) gaze_driver_.close();
245 yInfoVerbose(
"*** Closing VisualServoingServer done! ***");
257 yInfoVerbose(
"Connecting to Cartesian controller right arm output state.");
259 if (!Network::connect(
"/" + robot_name_ +
"/cartesianController/right_arm/state:o", port_pose_left_in_.getName(),
"tcp", !verbosity_))
262 if (!Network::connect(
"/" + robot_name_ +
"/cartesianController/right_arm/state:o", port_pose_right_in_.getName(),
"tcp", !verbosity_))
265 yInfoVerbose(
"Using direct kinematics information for visual servoing.");
269 yInfoVerbose(
"Connecting to external pose trackers command ports.");
271 if (!Network::connect(port_rpc_tracker_left_.getName(),
"/hand-tracking/left/cmd:i",
"tcp", !verbosity_))
274 if (!Network::connect(port_rpc_tracker_right_.getName(),
"/hand-tracking/right/cmd:i",
"tcp", !verbosity_))
278 yInfoVerbose(
"Sending commands to external pose trackers.");
281 cmd.addString(
"run_filter");
283 Bottle response_left;
284 if (!port_rpc_tracker_left_.write(cmd, response_left))
287 if (!response_left.get(0).asBool())
290 yInfoVerbose(
"Left camera external pose tracker running.");
293 Bottle response_right;
294 if (!port_rpc_tracker_right_.write(cmd, response_right))
297 if (!response_right.get(0).asBool())
300 yInfoVerbose(
"Right camera external pose tracker running.");
303 yInfoVerbose(
"Using external pose trackers information for visual servoing.");
306 yInfoVerbose(
"Waiting for the filter to provide good estimates...");
307 yarp::os::Time::delay(10);
308 yInfoVerbose(
"...done!");
311 yInfoVerbose(
"Skipping state model propagation and correction to use only known exogenous robot inputs...");
314 cmd.addString(
"skip_step");
315 cmd.addString(
"state");
318 response_left.clear();
319 if (!port_rpc_tracker_left_.write(cmd, response_left))
322 if (!response_left.get(0).asBool())
325 response_right.clear();
326 if (!port_rpc_tracker_right_.write(cmd, response_right))
329 if (!response_right.get(0).asBool())
334 cmd.addString(
"skip_step");
335 cmd.addString(
"correction");
338 response_left.clear();
339 if (!port_rpc_tracker_left_.write(cmd, response_left))
342 if (!response_left.get(0).asBool())
345 response_right.clear();
346 if (!port_rpc_tracker_right_.write(cmd, response_right))
349 yInfoVerbose(
"...done!");
352 yInfoVerbose(
"Connecting to external pose trackers output ports.");
354 if (!Network::connect(
"/hand-tracking/left/result/estimates:o", port_pose_left_in_.getName(),
"tcp", !verbosity_))
357 if (!Network::connect(
"/hand-tracking/right/result/estimates:o", port_pose_right_in_.getName(),
"tcp", !verbosity_))
360 yInfoVerbose(
"Receiving end-effector pose from external trackers.");
369 if (port_rpc_tracker_left_.getOutputCount() > 0 && port_rpc_tracker_right_.getOutputCount() > 0)
371 yInfoVerbose(
"Sending commands to external pose trackers.");
374 cmd.addString(
"rest_filter");
376 Bottle response_left;
377 if (!port_rpc_tracker_left_.write(cmd, response_left))
380 if (!response_left.get(0).asBool())
383 yInfoVerbose(
"Left camera external pose tracker reset.");
386 Bottle response_right;
387 if (!port_rpc_tracker_right_.write(cmd, response_right))
390 if (!response_right.get(0).asBool())
393 yInfoVerbose(
"Right camera external pose tracker reset.");
404 if (port_rpc_tracker_left_.getOutputCount() > 0 && port_rpc_tracker_right_.getOutputCount() > 0)
406 yInfoVerbose(
"Sending commands to external pose trackers.");
409 yInfoVerbose(
"Disable skipping state model propagation and correction...");
412 cmd.addString(
"skip_step");
413 cmd.addString(
"correction");
416 Bottle response_left;
417 if (!port_rpc_tracker_left_.write(cmd, response_left))
420 if (!response_left.get(0).asBool())
423 Bottle response_right;
424 if (!port_rpc_tracker_right_.write(cmd, response_right))
429 cmd.addString(
"skip_step");
430 cmd.addString(
"state");
433 response_left.clear();
434 if (!port_rpc_tracker_left_.write(cmd, response_left))
437 if (!response_left.get(0).asBool())
440 response_right.clear();
441 if (!port_rpc_tracker_right_.write(cmd, response_right))
444 if (!response_right.get(0).asBool())
447 yInfoVerbose(
"...done!");
451 cmd.addString(
"stop_filter");
453 response_left.clear();
454 if (!port_rpc_tracker_left_.write(cmd, response_left))
457 if (!response_left.get(0).asBool())
460 yInfoVerbose(
"Left camera external pose tracker stopped.");
463 if (!Network::disconnect(port_rpc_tracker_left_.getName(),
"/hand-tracking/left/cmd:i", !verbosity_))
467 response_right.clear();
468 if (!port_rpc_tracker_right_.write(cmd, response_right))
471 if (!response_right.get(0).asBool())
474 yInfoVerbose(
"Right camera external pose tracker stopped.");
477 if (!Network::disconnect(port_rpc_tracker_right_.getName(),
"/hand-tracking/right/cmd:i", !verbosity_))
481 yInfoVerbose(
"Disconnecting from external pose trackers output ports.");
483 if (!Network::disconnect(
"/hand-tracking/left/result/estimates:o", port_pose_left_in_.getName(), !verbosity_))
486 if (!Network::disconnect(
"/hand-tracking/right/result/estimates:o", port_pose_right_in_.getName(), !verbosity_))
489 yInfoVerbose(
"Disconnected from external trackers.");
501 yInfoVerbose(
"*** VisualServoingServer::goToGoal with pose goal invoked ***");
503 std::vector<Vector> vec_px_l = getGoalPixelsFrom3DPose(vec_x, vec_o, CamSel::left);
504 if (vec_px_l.size() == 0)
507 std::vector<Vector> vec_px_r = getGoalPixelsFrom3DPose(vec_x, vec_o, CamSel::right);
508 if (vec_px_r.size() == 0)
511 setPoseGoal(vec_x, vec_o);
512 setPixelGoal(vec_px_l, vec_px_r);
520 yInfoVerbose(
"*** VisualServoingServer::goToGoal with pixel goal invoked ***");
522 yWarningVerbose(
"<!-- If you did not invoke either one of:");
523 yWarningVerbose(
"<!-- 1. get3DPositionGoalFrom3DPose()");
524 yWarningVerbose(
"<!-- 2. getGoalPixelsFrom3DPose");
525 yWarningVerbose(
"<!-- visual servoing will just not work, and the server may also close.");
526 yWarningVerbose(
"<!-- To the current implementation, this behaviour is intentional.");
527 yWarningVerbose(
"<!-- Upcoming releases will change the behaviour of this method.");
529 setPixelGoal(vec_px_l, vec_px_r);
537 if (mode ==
"position")
538 op_mode_ = OperatingMode::position;
539 else if (mode ==
"orientation")
540 op_mode_ = OperatingMode::orientation;
541 else if (mode ==
"pose")
542 op_mode_ = OperatingMode::pose;
552 if (control ==
"decoupled")
553 vs_control_ = VisualServoControl::decoupled;
554 else if (control ==
"robust")
555 vs_control_ = VisualServoControl::robust;
556 else if (control ==
"cartesian")
557 vs_control_ = VisualServoControl::cartesian;
567 yWarningVerbose(
"*** Service setControlPoint is unimplemented. ***");
575 yWarningVerbose(
"*** Service getVisualServoingInfo is unimplemented. ***");
592 yInfoVerbose(
"*** Checking visual servoing controller ***");
593 yInfoVerbose(
" |> Controller: " + ConstString(vs_control_running_ ?
"running." :
"idle."));
594 yInfoVerbose(
" |> Goal: " + ConstString(vs_goal_reached_ ?
"" :
"not ") +
"reached.");
597 return vs_control_running_;
604 yInfoVerbose(
"*** Joining visual servoing control thread ***");
605 yInfoVerbose(
" |> Controller: " + ConstString(vs_control_running_ ?
"running." :
"idle."));
606 yInfoVerbose(
" |> Goal: " + ConstString(vs_goal_reached_ ?
"" :
"not ") +
"reached.");
616 yInfoVerbose(
"*** Stopping visual servoing controller ***");
617 yInfoVerbose(
" |> Controller: " + ConstString(vs_control_running_ ?
"running." :
"idle."));
618 yInfoVerbose(
" |> Goal: " + ConstString(vs_goal_reached_ ?
"" :
"not ") +
"reached.");
636 max_x_dot_ = max_x_dot;
661 max_o_dot_ = max_o_dot;
677 if (x.length() != 3 || o.length() != 4)
678 return std::vector<Vector>();
682 pose.setSubvector(0, x);
683 pose.setSubvector(3, o);
685 yWarningVerbose(
"<!-- Invoking setPoseGoal() to set the goal pose for visual servoing.");
686 yWarningVerbose(
"<!-- Be warned that this specific invokation will be removed in upcoming releases.");
689 std::vector<Vector> vec_goal_points = getControlPointsFromPose(pose);
691 return vec_goal_points;
697 if (x.length() != 3 || o.length() != 4)
698 return std::vector<Vector>();
702 pose.setSubvector(0, x);
703 pose.setSubvector(3, o);
709 setCameraTransformations();
711 std::vector<Vector> vec_goal_points = getPixelsFromPose(pose, cam);
713 return vec_goal_points;
720 itf_rightarm_cart_->storeContext(&ctx_remote_cart_);
721 itf_rightarm_cart_->restoreContext(ctx_local_cart_);
723 Vector xd = zeros(3);
724 Vector od = zeros(4);
725 Vector gaze_loc = zeros(3);
727 if (label ==
"t170427")
740 gaze_loc[0] = -6.706;
742 gaze_loc[2] = -3.618;
744 else if (label ==
"t170517")
757 gaze_loc[0] = -5.938;
759 gaze_loc[2] = -4.724;
761 else if (label ==
"t170713")
774 gaze_loc[0] = -5.938;
776 gaze_loc[2] = -4.724;
778 else if (label ==
"t170904")
791 gaze_loc[0] = -5.938;
793 gaze_loc[2] = -4.724;
795 else if (label ==
"sfm300517")
808 gaze_loc[0] = -0.589;
810 gaze_loc[2] = -0.409;
812 itf_rightarm_cart_->setLimits(0, 25.0, 25.0);
817 yInfoVerbose(
"Init position: " + xd.toString());
818 yInfoVerbose(
"Init orientation: " + od.toString());
823 itf_rightarm_cart_->goToPoseSync(xd, od);
824 itf_rightarm_cart_->waitMotionDone(0.1, 10.0);
825 itf_rightarm_cart_->stopControl();
827 itf_rightarm_cart_->removeTipFrame();
832 yInfoVerbose(
"Fixation point: " + gaze_loc.toString());
834 itf_gaze_->lookAtFixationPointSync(gaze_loc);
835 itf_gaze_->waitMotionDone(0.1, 10.0);
836 itf_gaze_->stopControl();
839 itf_rightarm_cart_->restoreContext(ctx_remote_cart_);
848 if (label ==
"t170427")
851 goal_pose_[0] = -0.323;
852 goal_pose_[1] = 0.018;
853 goal_pose_[2] = 0.121;
855 goal_pose_[3] = 0.310;
856 goal_pose_[4] = -0.873;
857 goal_pose_[5] = 0.374;
858 goal_pose_[6] = 3.008;
860 else if (label ==
"t170517")
863 goal_pose_[0] = -0.284;
864 goal_pose_[1] = 0.013;
865 goal_pose_[2] = 0.104;
867 goal_pose_[3] = -0.370;
868 goal_pose_[4] = 0.799;
869 goal_pose_[5] = -0.471;
870 goal_pose_[6] = 2.781;
872 else if (label ==
"t170711")
875 goal_pose_[0] = -0.356;
876 goal_pose_[1] = 0.024;
877 goal_pose_[2] = -0.053;
879 goal_pose_[3] = 0.057;
880 goal_pose_[4] = 0.980;
881 goal_pose_[5] = -0.189;
882 goal_pose_[6] = 2.525;
884 else if (label ==
"t170713")
887 goal_pose_[0] = -0.282;
888 goal_pose_[1] = 0.061;
889 goal_pose_[2] = 0.068;
891 goal_pose_[3] = 0.213;
892 goal_pose_[4] = -0.94 ;
893 goal_pose_[5] = 0.265;
894 goal_pose_[6] = 2.911;
896 else if (label ==
"t170904")
899 goal_pose_[0] = -0.288;
900 goal_pose_[1] = 0.085;
901 goal_pose_[2] = 0.025;
903 goal_pose_[3] = 0.166;
904 goal_pose_[4] = -0.98;
905 goal_pose_[5] = 0.101;
906 goal_pose_[6] = 3.031;
911 yInfoVerbose(
"6D goal: " + goal_pose_.toString());
913 setCameraTransformations();
915 std::vector<Vector> l_px_from_pose = getPixelsFromPose(goal_pose_, CamSel::left);
916 std::vector<Vector> r_px_from_pose = getPixelsFromPose(goal_pose_, CamSel::right);
918 setPixelGoal(l_px_from_pose, r_px_from_pose);
930 Bottle* click_left = port_click_left_.read(
true);
931 Vector l_click = zeros(2);
932 l_click[0] = click_left->get(0).asDouble();
933 l_click[1] = click_left->get(1).asDouble();
936 port_sfm.open(
"/visualservoing/tosfm");
937 Network::connect(
"/visualservoing/tosfm",
"/SFM/rpc");
941 cmd.addInt(l_click[0]);
942 cmd.addInt(l_click[1]);
945 port_sfm.write(cmd, reply_pos);
946 if (reply_pos.size() == 5)
948 Matrix R_ee = zeros(3, 3);
954 Vector ee_o = dcm2axis(R_ee);
956 Vector sfm_pos = zeros(3);
957 sfm_pos[0] = reply_pos.get(0).asDouble();
958 sfm_pos[1] = reply_pos.get(1).asDouble();
959 sfm_pos[2] = reply_pos.get(2).asDouble();
962 p.setSubvector(0, sfm_pos.subVector(0, 2));
963 p.setSubvector(3, ee_o.subVector(0, 3));
966 yInfoVerbose(
"6D goal: " + goal_pose_.toString());
968 setCameraTransformations();
970 std::vector<Vector> l_px_from_pose = getPixelsFromPose(goal_pose_, CamSel::left);
971 std::vector<Vector> r_px_from_pose = getPixelsFromPose(goal_pose_, CamSel::right);
973 setPixelGoal(l_px_from_pose, r_px_from_pose);
978 Network::disconnect(
"/visualservoing/tosfm",
"/SFM/rpc");
988 yInfoVerbose(
"*** Thread::beforeStart invoked ***");
994 yInfoVerbose(
"*** Thread::threadInit invoked ***");
998 vs_control_running_ =
true;
999 vs_goal_reached_ =
false;
1003 itf_rightarm_cart_->storeContext(&ctx_remote_cart_);
1004 itf_rightarm_cart_->restoreContext(ctx_local_cart_);
1008 yInfoVerbose(
"*** Launching background process UpdateVisualServoingParamters ***");
1009 is_stopping_backproc_update_vs_params =
false;
1014 yInfoVerbose(
"*** Running visual servoing! ***");
1023 if (vs_control_ == VisualServoControl::decoupled)
1024 decoupledImageBasedVisualServoControl();
1025 else if (vs_control_ == VisualServoControl::robust)
1026 robustImageBasedVisualServoControl();
1027 else if (vs_control_ == VisualServoControl::cartesian)
1028 cartesianPositionBasedVisualServoControl();
1034 yInfoVerbose(
"*** Thread::afterStart invoked ***");
1038 yInfoVerbose(
"Visual servoing controller status report:");
1039 yInfoVerbose(
" |> Controller: " + ConstString(vs_control_running_ ?
"running." :
"idle."));
1040 yInfoVerbose(
" |> Goal: " + ConstString(vs_goal_reached_ ?
"" :
"not") +
"reached.");
1044 yInfoVerbose(
"Visual servoing controller failed to start!");
1045 vs_control_running_ =
false;
1046 vs_goal_reached_ =
false;
1053 yInfoVerbose(
"*** Thread::onStop invoked ***");
1059 yInfoVerbose(
"*** Thread::threadRelease invoked ***");
1063 itf_rightarm_cart_->stopControl();
1064 itf_gaze_->stopControl();
1068 yInfoVerbose(
"*** Stopping background process UpdateVisualServoingParamters ***");
1069 is_stopping_backproc_update_vs_params =
true;
1070 thr_background_update_params_->join();
1071 delete thr_background_update_params_;
1075 itf_rightarm_cart_->restoreContext(ctx_remote_cart_);
1078 vs_control_running_ =
false;
1081 yInfoVerbose(
"*** Visual servoing terminated! ***");
1089 return storedInit(label);
1095 return storedGoToGoal(label);
1101 return goToSFMGoal();
1107 yInfoVerbose(
"*** Quitting visual servoing server ***");
1109 bool is_stopping_controller = stopController();
1110 if (!is_stopping_controller)
1112 yWarningVerbose(
"Could not stop visual servoing controller!");
1116 bool is_closing = close();
1119 yWarningVerbose(
"Could not close visual servoing server!");
1129 return initFacilities(use_direct_kin);
1135 return resetFacilities();
1141 return stopFacilities();
1147 if (vec_px_l.size() != 4 || vec_px_l.size() != 4)
1150 std::vector<Vector> yvec_px_l;
1151 for (
const std::vector<double>& vec : vec_px_l)
1153 if (vec.size() != 2)
1156 yvec_px_l.emplace_back(Vector(vec.size(), vec.data()));
1159 std::vector<Vector> yvec_px_r;
1160 for (
const std::vector<double>& vec : vec_px_r)
1162 if (vec.size() != 2)
1165 yvec_px_r.emplace_back(Vector(vec.size(), vec.data()));
1168 return goToGoal(yvec_px_l, yvec_px_r);
1174 if (vec_x.size() != 3 || vec_o.size() != 4)
1177 Vector yvec_x(vec_x.size(), vec_x.data());
1178 Vector yvec_o(vec_o.size(), vec_o.data());
1180 return goToGoal(yvec_x, yvec_o);
1186 return setModality(mode);
1192 return setVisualServoControl(control);
1198 return setControlPoint(point);
1205 getVisualServoingInfo(info);
1207 std::vector<std::string> info_str;
1208 info_str.emplace_back(info.toString());
1216 return setGoToGoalTolerance(tol);
1222 return checkVisualServoingController();
1228 return waitVisualServoingDone(period, timeout);
1234 return stopController();
1240 return setTranslationGain(K_x_1, K_x_2);
1246 return setMaxTranslationVelocity(max_x_dot);
1252 return setTranslationGainSwitchTolerance(K_x_tol);
1258 return setOrientationGain(K_o_1, K_o_2);
1264 return setMaxOrientationVelocity(max_o_dot);
1270 return setOrientationGainSwitchTolerance(K_o_tol);
1276 if (x.size() != 3 || o.size() != 4)
1277 return std::vector<std::vector<double>>();
1280 Vector yx(x.size(), x.data());
1281 Vector yo(o.size(), o.data());
1282 std::vector<Vector> yvec_3d_goal_points = get3DGoalPositionsFrom3DPose(yx, yo);
1284 std::vector<std::vector<double>> vec_3d_goal_points;
1285 for (
const Vector& yvec_3d_goal : yvec_3d_goal_points)
1286 vec_3d_goal_points.emplace_back(std::vector<double>(yvec_3d_goal.data(), yvec_3d_goal.data() + yvec_3d_goal.size()));
1288 return vec_3d_goal_points;
1294 if (x.size() != 3 || o.size() != 4 || (cam !=
"left" && cam !=
"right"))
1295 return std::vector<std::vector<double>>();
1298 Vector yx(x.size(), x.data());
1299 Vector yo(o.size(), o.data());
1300 CamSel e_cam = cam ==
"left" ? CamSel::left : CamSel::right;
1302 std::vector<Vector> yvec_px_goal_points = getGoalPixelsFrom3DPose(yx, yo, e_cam);
1303 if (yvec_px_goal_points.size() == 0)
1304 return std::vector<std::vector<double>>();
1306 std::vector<std::vector<double>> vec_px_goal_points;
1307 for (
const Vector& yvec_px_goal : yvec_px_goal_points)
1308 vec_px_goal_points.emplace_back(std::vector<double>(yvec_px_goal.data(), yvec_px_goal.data() + yvec_px_goal.size()));
1310 return vec_px_goal_points;
1318 Vector* endeffector_pose;
1319 Vector eepose_copy_left(7);
1320 Vector eepose_copy_right(7);
1321 Vector eepose_averaged(7);
1323 std::vector<Vector> l_px_position;
1324 std::vector<Vector> l_px_orientation;
1326 std::vector<Vector> r_px_position;
1327 std::vector<Vector> r_px_orientation;
1329 Vector px_ee_cur_position = zeros(16);
1330 Matrix jacobian_position = zeros(16, 6);
1331 Vector px_ee_cur_orientation = zeros(16);
1332 Matrix jacobian_orientation = zeros(16, 6);
1336 endeffector_pose = port_pose_left_in_.read(
true);
1337 eepose_copy_left = *endeffector_pose;
1339 yInfoVerbose(
"Got [" + eepose_copy_left.toString() +
"] end-effector pose for the left eye.");
1342 endeffector_pose = port_pose_right_in_.read(
true);
1343 eepose_copy_right = *endeffector_pose;
1345 yInfoVerbose(
"Got [" + eepose_copy_right.toString() +
"] end-effector pose for the right eye.");
1348 eepose_averaged = averagePose(eepose_copy_left, eepose_copy_right);
1349 eepose_copy_left = eepose_averaged;
1350 eepose_copy_right = eepose_averaged;
1352 yInfoVerbose(
"Got [" + eepose_averaged.toString() +
"] averaged end-effector pose.");
1355 while (!isStopping() && !vs_goal_reached_)
1357 yInfoVerbose(
"Desired goal pixels = [" + px_des_.toString() +
"]");
1361 l_px_position = getControlPixelsFromPose(eepose_copy_left, CamSel::left, PixelControlMode::x);
1362 l_px_orientation = getControlPixelsFromPose(eepose_copy_left, CamSel::left, PixelControlMode::o);
1364 r_px_position = getControlPixelsFromPose(eepose_copy_right, CamSel::right, PixelControlMode::x);
1365 r_px_orientation = getControlPixelsFromPose(eepose_copy_right, CamSel::right, PixelControlMode::o);
1369 getCurrentStereoFeaturesAndJacobian(l_px_position, r_px_position,
1370 px_ee_cur_position, jacobian_position);
1372 yInfoVerbose(
"Position controlled pixels = [" + px_ee_cur_position.toString() +
"]");
1373 yInfoVerbose(
"Position image Jacobian = [\n" + jacobian_position.toString() +
"]");
1377 getCurrentStereoFeaturesAndJacobian(l_px_orientation, r_px_orientation,
1378 px_ee_cur_orientation, jacobian_orientation);
1380 yInfoVerbose(
"Orientation controlled pixels = [" + px_ee_cur_orientation.toString() +
"]");
1381 yInfoVerbose(
"Orientation image Jacobian = [\n" + jacobian_orientation.toString() +
"]");
1385 std::vector<cv::Scalar> color;
1386 color.emplace_back(cv::Scalar(255, 0, 0));
1387 color.emplace_back(cv::Scalar( 0, 255, 0));
1388 color.emplace_back(cv::Scalar( 0, 0, 255));
1389 color.emplace_back(cv::Scalar(255, 127, 51));
1393 ImageOf<PixelRgb>* l_imgin = port_image_left_in_.read(
true);
1394 ImageOf<PixelRgb>& l_imgout = port_image_left_out_.prepare();
1395 l_imgout = *l_imgin;
1396 cv::Mat l_img = cv::cvarrToMat(l_imgout.getIplImage());
1399 ImageOf<PixelRgb>* r_imgin = port_image_right_in_.read(
true);
1400 ImageOf<PixelRgb>& r_imgout = port_image_right_out_.prepare();
1401 r_imgout = *r_imgin;
1402 cv::Mat r_img = cv::cvarrToMat(r_imgout.getIplImage());
1406 std::vector<Vector> l_px_pose = getPixelsFromPose(eepose_copy_left, CamSel::left);
1407 std::vector<Vector> r_px_pose = getPixelsFromPose(eepose_copy_right, CamSel::right);
1409 for (
int i = 0; i < l_px_pose.size(); ++i)
1411 const Vector& l_cur_px_p = l_px_pose[i];
1412 const Vector& l_pre_px_p = l_px_pose[(3 + i) % 4];
1414 const Vector& r_cur_px_p = r_px_pose[i];
1415 const Vector& r_pre_px_p = r_px_pose[(3 + i) % 4];
1417 const Vector& l_cur_px_g = l_px_goal_[i];
1418 const Vector& l_pre_px_g = l_px_goal_[(3 + i) % 4];
1420 const Vector& r_cur_px_g = r_px_goal_[i];
1421 const Vector& r_pre_px_g = r_px_goal_[(3 + i) % 4];
1424 cv::line(l_img, cv::Point(l_pre_px_p[0], l_pre_px_p[1]), cv::Point(l_cur_px_p[0], l_cur_px_p[1]), color[3], 4, cv::LineTypes::LINE_AA);
1425 cv::line(r_img, cv::Point(r_pre_px_p[0], r_pre_px_p[1]), cv::Point(r_cur_px_p[0], r_cur_px_p[1]), color[3], 4, cv::LineTypes::LINE_AA);
1427 cv::line(l_img, cv::Point(l_pre_px_g[0], l_pre_px_g[1]), cv::Point(l_cur_px_g[0], l_cur_px_g[1]), color[3], 4, cv::LineTypes::LINE_AA);
1428 cv::line(r_img, cv::Point(r_pre_px_g[0], r_pre_px_g[1]), cv::Point(r_cur_px_g[0], r_cur_px_g[1]), color[3], 4, cv::LineTypes::LINE_AA);
1430 if (i == 2 || i == 3)
1432 cv::circle(l_img, cv::Point(l_cur_px_p[0], l_cur_px_p[1]), 4, color[i - 1], 4);
1433 cv::circle(r_img, cv::Point(r_cur_px_p[0], r_cur_px_p[1]), 4, color[i - 1], 4);
1435 cv::circle(l_img, cv::Point(l_cur_px_g[0], l_cur_px_g[1]), 4, color[i - 1], 4);
1436 cv::circle(r_img, cv::Point(r_cur_px_g[0], r_cur_px_g[1]), 4, color[i - 1], 4);
1441 Vector l_cur_px_ee = getPixelFromPoint(CamSel::left, cat(eepose_copy_left.subVector(0, 2), 1.0));
1442 Vector r_cur_px_ee = getPixelFromPoint(CamSel::right, cat(eepose_copy_right.subVector(0, 2), 1.0));
1444 cv::circle(l_img, cv::Point(l_cur_px_ee[0], l_cur_px_ee[1]), 4, color[0], 4);
1445 cv::circle(r_img, cv::Point(r_cur_px_ee[0], r_cur_px_ee[1]), 4, color[0], 4);
1448 Vector l_cur_px_g = getPixelFromPoint(CamSel::left, cat(goal_pose_.subVector(0, 2), 1.0));
1449 Vector r_cur_px_g = getPixelFromPoint(CamSel::right, cat(goal_pose_.subVector(0, 2), 1.0));
1451 cv::circle(l_img, cv::Point(l_cur_px_g[0], l_cur_px_g[1]), 4, color[0], 4);
1452 cv::circle(r_img, cv::Point(r_cur_px_g[0], r_cur_px_g[1]), 4, color[0], 4);
1454 port_image_left_out_.write();
1455 port_image_right_out_.write();
1461 Vector& pose_px_l = port_pose_px_l_.prepare();
1462 pose_px_l = stdVectorOfVectorsToVector(getControlPixelsFromPose(eepose_copy_left, CamSel::left, PixelControlMode::all));
1463 port_pose_px_l_.write();
1465 Vector& pose_px_r = port_pose_px_r_.prepare();
1466 pose_px_r = stdVectorOfVectorsToVector(getControlPixelsFromPose(eepose_copy_right, CamSel::right, PixelControlMode::all));
1467 port_pose_px_r_.write();
1471 itf_rightarm_cart_->getPose(kin_x, kin_o);
1473 Vector& pose_kin_px_l = port_kin_px_l_.prepare();
1474 pose_kin_px_l = stdVectorOfVectorsToVector(getControlPixelsFromPose(cat(kin_x, kin_o), CamSel::left, PixelControlMode::all));
1475 port_kin_px_l_.write();
1477 Vector& pose_kin_px_r = port_kin_px_r_.prepare();
1478 pose_kin_px_r = stdVectorOfVectorsToVector(getControlPixelsFromPose(cat(kin_x, kin_o), CamSel::right, PixelControlMode::all));
1479 port_kin_px_r_.write();
1481 Vector& goal_px_l_ = port_goal_px_l_.prepare();
1482 goal_px_l_ = stdVectorOfVectorsToVector(l_px_goal_);
1483 port_goal_px_l_.write();
1485 Vector& goal_px_r_ = port_goal_px_r_.prepare();
1486 goal_px_r_ = stdVectorOfVectorsToVector(r_px_goal_);
1487 port_goal_px_r_.write();
1489 Vector& pose_avg_ = port_pose_avg_.prepare();
1490 pose_avg_ = eepose_averaged;
1491 port_pose_avg_.write();
1493 Vector& pose_kin_ = port_pose_kin_.prepare();
1494 pose_kin_ = cat(kin_x, kin_o);
1495 port_pose_kin_.write();
1497 Vector& pose_goal_ = port_pose_goal_.prepare();
1498 pose_goal_ = goal_pose_;
1499 port_pose_goal_.write();
1507 bool is_pos_done = checkVisualServoingStatus(px_ee_cur_position, tol_px_);
1508 bool is_orient_done = checkVisualServoingStatus(px_ee_cur_orientation, tol_px_);
1510 mtx_px_des_.unlock();
1513 if (op_mode_ == OperatingMode::position)
1514 vs_goal_reached_ = is_pos_done;
1515 else if (op_mode_ == OperatingMode::orientation)
1516 vs_goal_reached_ = is_orient_done;
1517 else if (op_mode_ == OperatingMode::pose)
1518 vs_goal_reached_ = is_pos_done && is_orient_done;
1521 if (vs_goal_reached_)
1524 yInfoVerbose(
"*** Goal reached! ***");
1525 yInfoVerbose(
"Desired goal pixels = " + px_des_.toString());
1526 yInfoVerbose(
"Current position controlled pixels = " + px_ee_cur_position.toString());
1527 yInfoVerbose(
"Current orientation controlled pixels = " + px_ee_cur_orientation.toString());
1528 yInfoVerbose(
"*** ------------- ***");
1536 Vector e_position = px_des_ - px_ee_cur_position;
1537 Matrix inv_jacobian_position = pinv(jacobian_position);
1539 Vector e_orientation = px_des_ - px_ee_cur_orientation;
1540 Matrix inv_jacobian_orientation = pinv(jacobian_orientation);
1542 yInfoVerbose(
"Position error in pixels = [" + e_position.toString() +
"]");
1543 yInfoVerbose(
"Orientation error in pixels = [" + e_orientation.toString() +
"]");
1545 mtx_px_des_.unlock();
1549 mtx_H_eye_cam_.lock();
1551 Vector vel_x = zeros(3);
1552 Vector vel_o = zeros(3);
1553 for (
int i = 0; i < inv_jacobian_position.cols(); ++i)
1555 Vector delta_vel_position = inv_jacobian_position.getCol(i) * e_position(i);
1556 Vector delta_vel_orientation = inv_jacobian_orientation.getCol(i) * e_orientation(i);
1558 if (i == 1 || i == 3 || i == 5 || i == 7 || i == 9 || i == 11 || i == 13 || i == 15)
1560 vel_x += r_H_eye_to_r_.submatrix(0, 2, 0, 2) * delta_vel_position.subVector(0, 2);
1561 vel_o += r_H_eye_to_r_.submatrix(0, 2, 0, 2) * delta_vel_orientation.subVector(3, 5);
1565 vel_x += l_H_eye_to_r_.submatrix(0, 2, 0, 2) * delta_vel_position.subVector(0, 2);
1566 vel_o += l_H_eye_to_r_.submatrix(0, 2, 0, 2) * delta_vel_orientation.subVector(3, 5);
1570 mtx_H_eye_cam_.unlock();
1572 double ang = norm(vel_o);
1574 vel_o.push_back(ang);
1576 yInfoVerbose(
"Translational velocity = [" + vel_x.toString() +
"]");
1577 yInfoVerbose(
"Orientation velocity = [" + vel_o.toString() +
"]");
1581 for (
size_t i = 0; i < vel_x.length(); ++i)
1583 if (!std::isnan(vel_x[i]) && !std::isinf(vel_x[i]))
1584 vel_x[i] = sign(vel_x[i]) * std::min(max_x_dot_, std::fabs(vel_x[i]));
1587 vel_x = Vector(3, 0.0);
1591 yInfoVerbose(
"Bounded translational velocity = [" + vel_x.toString() +
"]");
1595 if (!std::isnan(vel_o[0]) && !std::isinf(vel_x[0]) &&
1596 !std::isnan(vel_o[1]) && !std::isinf(vel_x[1]) &&
1597 !std::isnan(vel_o[2]) && !std::isinf(vel_x[2]) &&
1598 !std::isnan(vel_o[3]) && !std::isinf(vel_x[3]))
1599 vel_o[3] = sign(vel_o[3]) * std::min(max_o_dot_, std::fabs(vel_o[3]));
1601 vel_o = Vector(4, 0.0);
1602 yInfoVerbose(
"Bounded orientation velocity = [" + vel_o.toString() +
"]");
1606 if (!checkVisualServoingStatus(px_ee_cur_position, K_x_tol_))
1609 if (K_x_hysteresis_)
1611 K_x_hysteresis_ =
false;
1619 if (!K_x_hysteresis_)
1621 K_x_hysteresis_ =
true;
1627 if (!checkVisualServoingStatus(px_ee_cur_orientation, K_o_tol_))
1629 vel_o(3) *= K_o_[0];
1630 if (K_o_hysteresis_)
1632 K_o_hysteresis_ =
false;
1639 vel_o(3) *= K_o_[1];
1640 if (!K_o_hysteresis_)
1642 K_o_hysteresis_ =
true;
1652 if (op_mode_ == OperatingMode::position)
1653 itf_rightarm_cart_->setTaskVelocities(vel_x, Vector(4, 0.0));
1654 else if (op_mode_ == OperatingMode::orientation)
1655 itf_rightarm_cart_->setTaskVelocities(Vector(3, 0.0), vel_o);
1656 else if (op_mode_ == OperatingMode::pose)
1657 itf_rightarm_cart_->setTaskVelocities(vel_x, vel_o);
1665 endeffector_pose = port_pose_left_in_.read(
true);
1666 eepose_copy_left = *endeffector_pose;
1669 endeffector_pose = port_pose_right_in_.read(
true);
1670 eepose_copy_right = *endeffector_pose;
1673 eepose_averaged = averagePose(eepose_copy_left, eepose_copy_right);
1674 eepose_copy_left = eepose_averaged;
1675 eepose_copy_right = eepose_averaged;
1680 Matrix l_R = axis2dcm(eepose_copy_left.subVector(3, 6));
1681 Matrix r_R = axis2dcm(eepose_copy_right.subVector(3, 6));
1685 l_R = axis2dcm(vel_o) * l_R;
1686 r_R = axis2dcm(vel_o) * r_R;
1689 Vector l_new_o = dcm2axis(l_R);
1690 Vector r_new_o = dcm2axis(r_R);
1693 if (op_mode_ == OperatingMode::position)
1695 eepose_copy_left.setSubvector(0, eepose_copy_left.subVector(0, 2) + vel_x * Ts_);
1696 eepose_copy_right.setSubvector(0, eepose_copy_right.subVector(0, 2) + vel_x * Ts_);
1698 else if (op_mode_ == OperatingMode::orientation)
1700 eepose_copy_left.setSubvector(3, l_new_o);
1701 eepose_copy_right.setSubvector(3, r_new_o);
1703 else if (op_mode_ == OperatingMode::pose)
1705 eepose_copy_left.setSubvector(0, eepose_copy_left.subVector(0, 2) + vel_x * Ts_);
1706 eepose_copy_right.setSubvector(0, eepose_copy_right.subVector(0, 2) + vel_x * Ts_);
1707 eepose_copy_left.setSubvector(3, l_new_o);
1708 eepose_copy_right.setSubvector(3, r_new_o);
1719 Vector* endeffector_pose;
1720 Vector eepose_copy_left(7);
1721 Vector eepose_copy_right(7);
1722 Vector eepose_averaged(7);
1724 std::vector<Vector> l_px_pose;
1725 std::vector<Vector> r_px_pose;
1727 Vector px_ee_cur_pose = zeros(16);
1728 Matrix jacobian_pose = zeros(16, 6);
1729 Vector px_ee_cur_goal = zeros(16);
1730 Matrix jacobian_goal = zeros(16, 6);
1734 endeffector_pose = port_pose_left_in_.read(
true);
1735 eepose_copy_left = *endeffector_pose;
1737 yInfoVerbose(
"Got [" + eepose_copy_left.toString() +
"] end-effector pose for the left eye.");
1740 endeffector_pose = port_pose_right_in_.read(
true);
1741 eepose_copy_right = *endeffector_pose;
1744 eepose_averaged = averagePose(eepose_copy_left, eepose_copy_right);
1745 eepose_copy_left = eepose_averaged;
1746 eepose_copy_right = eepose_averaged;
1748 yInfoVerbose(
"Got [" + eepose_copy_right.toString() +
"] end-effector pose for the right eye.");
1750 while (!isStopping() && !vs_goal_reached_)
1752 yInfoVerbose(
"Desired goal pixels = [" + px_des_.toString() +
"]");
1756 l_px_pose = getControlPixelsFromPose(eepose_copy_left, CamSel::left, PixelControlMode::all);
1757 r_px_pose = getControlPixelsFromPose(eepose_copy_right, CamSel::right, PixelControlMode::all);
1761 getCurrentStereoFeaturesAndJacobian(l_px_pose, r_px_pose,
1762 px_ee_cur_pose, jacobian_pose);
1764 yInfoVerbose(
"Pose controlled pixels = [" + px_ee_cur_pose.toString() +
"]");
1765 yInfoVerbose(
"Pose image Jacobian = [\n" + jacobian_pose.toString() +
"]");
1768 getCurrentStereoFeaturesAndJacobian(l_px_goal_, r_px_goal_,
1769 px_ee_cur_goal, jacobian_goal);
1771 yInfoVerbose(
"Goal 'controlled' pixels = [" + px_ee_cur_goal.toString() +
"]");
1772 yInfoVerbose(
"Desired goal pixels = [" + px_des_.toString() +
"]");
1773 yInfoVerbose(
"Goal image Jacobian = [\n" + jacobian_goal.toString() +
"]");
1777 std::vector<cv::Scalar> color;
1778 color.emplace_back(cv::Scalar(255, 0, 0));
1779 color.emplace_back(cv::Scalar( 0, 255, 0));
1780 color.emplace_back(cv::Scalar( 0, 0, 255));
1781 color.emplace_back(cv::Scalar(255, 127, 51));
1785 ImageOf<PixelRgb>* l_imgin = port_image_left_in_.read(
true);
1786 ImageOf<PixelRgb>& l_imgout = port_image_left_out_.prepare();
1787 l_imgout = *l_imgin;
1788 cv::Mat l_img = cv::cvarrToMat(l_imgout.getIplImage());
1791 ImageOf<PixelRgb>* r_imgin = port_image_right_in_.read(
true);
1792 ImageOf<PixelRgb>& r_imgout = port_image_right_out_.prepare();
1793 r_imgout = *r_imgin;
1794 cv::Mat r_img = cv::cvarrToMat(r_imgout.getIplImage());
1798 for (
int i = 0; i < l_px_pose.size(); ++i)
1800 const Vector& l_cur_px_p = l_px_pose[i];
1801 const Vector& l_pre_px_p = l_px_pose[(3 + i) % 4];
1803 const Vector& r_cur_px_p = r_px_pose[i];
1804 const Vector& r_pre_px_p = r_px_pose[(3 + i) % 4];
1806 const Vector& l_cur_px_g = l_px_goal_[i];
1807 const Vector& l_pre_px_g = l_px_goal_[(3 + i) % 4];
1809 const Vector& r_cur_px_g = r_px_goal_[i];
1810 const Vector& r_pre_px_g = r_px_goal_[(3 + i) % 4];
1813 cv::line(l_img, cv::Point(l_pre_px_p[0], l_pre_px_p[1]), cv::Point(l_cur_px_p[0], l_cur_px_p[1]), color[3], 4, cv::LineTypes::LINE_AA);
1814 cv::line(r_img, cv::Point(r_pre_px_p[0], r_pre_px_p[1]), cv::Point(r_cur_px_p[0], r_cur_px_p[1]), color[3], 4, cv::LineTypes::LINE_AA);
1816 cv::line(l_img, cv::Point(l_pre_px_g[0], l_pre_px_g[1]), cv::Point(l_cur_px_g[0], l_cur_px_g[1]), color[3], 4, cv::LineTypes::LINE_AA);
1817 cv::line(r_img, cv::Point(r_pre_px_g[0], r_pre_px_g[1]), cv::Point(r_cur_px_g[0], r_cur_px_g[1]), color[3], 4, cv::LineTypes::LINE_AA);
1819 if (i == 2 || i == 3)
1821 cv::circle(l_img, cv::Point(l_cur_px_p[0], l_cur_px_p[1]), 4, color[i - 1], 4);
1822 cv::circle(r_img, cv::Point(r_cur_px_p[0], r_cur_px_p[1]), 4, color[i - 1], 4);
1824 cv::circle(l_img, cv::Point(l_cur_px_g[0], l_cur_px_g[1]), 4, color[i - 1], 4);
1825 cv::circle(r_img, cv::Point(r_cur_px_g[0], r_cur_px_g[1]), 4, color[i - 1], 4);
1830 Vector l_cur_px_ee = getPixelFromPoint(CamSel::left, cat(eepose_copy_left.subVector(0, 2), 1.0));
1831 Vector r_cur_px_ee = getPixelFromPoint(CamSel::right, cat(eepose_copy_right.subVector(0, 2), 1.0));
1833 cv::circle(l_img, cv::Point(l_cur_px_ee[0], l_cur_px_ee[1]), 4, color[0], 4);
1834 cv::circle(r_img, cv::Point(r_cur_px_ee[0], r_cur_px_ee[1]), 4, color[0], 4);
1837 Vector l_cur_px_g = getPixelFromPoint(CamSel::left, cat(goal_pose_.subVector(0, 2), 1.0));
1838 Vector r_cur_px_g = getPixelFromPoint(CamSel::right, cat(goal_pose_.subVector(0, 2), 1.0));
1840 cv::circle(l_img, cv::Point(l_cur_px_g[0], l_cur_px_g[1]), 4, color[0], 4);
1841 cv::circle(r_img, cv::Point(r_cur_px_g[0], r_cur_px_g[1]), 4, color[0], 4);
1843 port_image_left_out_.write();
1844 port_image_right_out_.write();
1849 Vector& pose_px_l = port_pose_px_l_.prepare();
1850 pose_px_l = stdVectorOfVectorsToVector(getControlPixelsFromPose(eepose_copy_left, CamSel::left, PixelControlMode::all));
1851 port_pose_px_l_.write();
1853 Vector& pose_px_r = port_pose_px_r_.prepare();
1854 pose_px_r = stdVectorOfVectorsToVector(getControlPixelsFromPose(eepose_copy_right, CamSel::right, PixelControlMode::all));
1855 port_pose_px_r_.write();
1859 itf_rightarm_cart_->getPose(kin_x, kin_o);
1861 Vector& pose_kin_px_l = port_kin_px_l_.prepare();
1862 pose_kin_px_l = stdVectorOfVectorsToVector(getControlPixelsFromPose(cat(kin_x, kin_o), CamSel::left, PixelControlMode::all));
1863 port_kin_px_l_.write();
1865 Vector& pose_kin_px_r = port_kin_px_r_.prepare();
1866 pose_kin_px_r = stdVectorOfVectorsToVector(getControlPixelsFromPose(cat(kin_x, kin_o), CamSel::right, PixelControlMode::all));
1867 port_kin_px_r_.write();
1869 Vector& goal_px_l_ = port_goal_px_l_.prepare();
1870 goal_px_l_ = stdVectorOfVectorsToVector(l_px_goal_);
1871 port_goal_px_l_.write();
1873 Vector& goal_px_r_ = port_goal_px_r_.prepare();
1874 goal_px_r_ = stdVectorOfVectorsToVector(r_px_goal_);
1875 port_goal_px_r_.write();
1877 Vector& pose_avg_ = port_pose_avg_.prepare();
1878 pose_avg_ = eepose_averaged;
1879 port_pose_avg_.write();
1881 Vector& pose_kin_ = port_pose_kin_.prepare();
1882 pose_kin_ = cat(kin_x, kin_o);
1883 port_pose_kin_.write();
1885 Vector& pose_goal_ = port_pose_goal_.prepare();
1886 pose_goal_ = goal_pose_;
1887 port_pose_goal_.write();
1895 vs_goal_reached_ = checkVisualServoingStatus(px_ee_cur_pose, tol_px_);
1897 mtx_px_des_.unlock();
1900 if (vs_goal_reached_)
1903 yInfoVerbose(
"*** Goal reached! ***");
1904 yInfoVerbose(
"Desired goal pixels = " + px_des_.toString());
1905 yInfoVerbose(
"Current position controlled pixels = " + px_ee_cur_pose.toString());
1906 yInfoVerbose(
"*** ------------- ***");
1914 Vector e = px_des_ - px_ee_cur_pose;
1915 Matrix inv_jacobian = pinv(0.5 * (jacobian_pose + jacobian_goal));
1917 yInfoVerbose(
"Position error in pixels = [" + e.toString() +
"]");
1919 mtx_px_des_.unlock();
1923 mtx_H_eye_cam_.lock();
1925 Vector vel_x = zeros(3);
1926 Vector vel_o = zeros(3);
1927 for (
int i = 0; i < inv_jacobian.cols(); ++i)
1929 Vector delta_vel = inv_jacobian.getCol(i) * e(i);
1931 if (i == 1 || i == 3 || i == 5 || i == 7 || i == 9 || i == 11 || i == 13 || i == 15)
1933 vel_x += r_H_eye_to_r_.submatrix(0, 2, 0, 2) * delta_vel.subVector(0, 2);
1934 vel_o += r_H_eye_to_r_.submatrix(0, 2, 0, 2) * delta_vel.subVector(3, 5);
1938 vel_x += l_H_eye_to_r_.submatrix(0, 2, 0, 2) * delta_vel.subVector(0, 2);
1939 vel_o += l_H_eye_to_r_.submatrix(0, 2, 0, 2) * delta_vel.subVector(3, 5);
1943 mtx_H_eye_cam_.unlock();
1945 double ang = norm(vel_o);
1947 vel_o.push_back(ang);
1949 yInfoVerbose(
"Translational velocity = [" + vel_x.toString() +
"]");
1950 yInfoVerbose(
"Orientation velocity = [" + vel_o.toString() +
"]");
1954 for (
size_t i = 0; i < vel_x.length(); ++i)
1956 if (!std::isnan(vel_x[i]) && !std::isinf(vel_x[i]))
1957 vel_x[i] = sign(vel_x[i]) * std::min(max_x_dot_, std::fabs(vel_x[i]));
1960 vel_x = Vector(3, 0.0);
1964 yInfoVerbose(
"Bounded translational velocity = [" + vel_x.toString() +
"]");
1968 if (!std::isnan(vel_o[0]) && !std::isinf(vel_x[0]) &&
1969 !std::isnan(vel_o[1]) && !std::isinf(vel_x[1]) &&
1970 !std::isnan(vel_o[2]) && !std::isinf(vel_x[2]) &&
1971 !std::isnan(vel_o[3]) && !std::isinf(vel_x[3]))
1972 vel_o[3] = sign(vel_o[3]) * std::min(max_o_dot_, std::fabs(vel_o[3]));
1974 vel_o = Vector(4, 0.0);
1975 yInfoVerbose(
"Bounded orientation velocity = [" + vel_o.toString() +
"]");
1979 if (!checkVisualServoingStatus(px_ee_cur_pose, K_x_tol_))
1982 if (K_x_hysteresis_)
1984 K_x_hysteresis_ =
false;
1992 if (!K_x_hysteresis_)
1994 K_x_hysteresis_ =
true;
2000 if (!checkVisualServoingStatus(px_ee_cur_goal, K_o_tol_))
2002 vel_o(3) *= K_o_[0];
2003 if (K_o_hysteresis_)
2005 K_o_hysteresis_ =
false;
2012 vel_o(3) *= K_o_[1];
2013 if (!K_o_hysteresis_)
2015 K_o_hysteresis_ =
true;
2025 itf_rightarm_cart_->setTaskVelocities(vel_x, vel_o);
2033 endeffector_pose = port_pose_left_in_.read(
true);
2034 eepose_copy_left = *endeffector_pose;
2037 endeffector_pose = port_pose_right_in_.read(
true);
2038 eepose_copy_right = *endeffector_pose;
2041 eepose_averaged = averagePose(eepose_copy_left, eepose_copy_right);
2042 eepose_copy_left = eepose_averaged;
2043 eepose_copy_right = eepose_averaged;
2047 Matrix l_R = axis2dcm(eepose_copy_left.subVector(3, 6));
2048 Matrix r_R = axis2dcm(eepose_copy_right.subVector(3, 6));
2052 l_R = axis2dcm(vel_o) * l_R;
2053 r_R = axis2dcm(vel_o) * r_R;
2056 Vector l_new_o = dcm2axis(l_R);
2057 Vector r_new_o = dcm2axis(r_R);
2061 eepose_copy_left.setSubvector(0, eepose_copy_left.subVector(0, 2) + vel_x * Ts_);
2062 eepose_copy_right.setSubvector(0, eepose_copy_right.subVector(0, 2) + vel_x * Ts_);
2063 eepose_copy_left.setSubvector(3, l_new_o);
2064 eepose_copy_right.setSubvector(3, r_new_o);
2074 Vector* endeffector_pose;
2075 Vector eepose_copy_left(7);
2076 Vector eepose_copy_right(7);
2077 Vector eepose_averaged(7);
2080 endeffector_pose = port_pose_left_in_.read(
true);
2081 eepose_copy_left = *endeffector_pose;
2083 yInfoVerbose(
"Got [" + eepose_copy_left.toString() +
"] end-effector pose for the left eye.");
2086 endeffector_pose = port_pose_right_in_.read(
true);
2087 eepose_copy_right = *endeffector_pose;
2089 yInfoVerbose(
"Got [" + eepose_copy_right.toString() +
"] end-effector pose for the right eye.");
2092 eepose_averaged = averagePose(eepose_copy_left, eepose_copy_right);
2093 eepose_copy_left = eepose_averaged;
2094 eepose_copy_right = eepose_averaged;
2096 yInfoVerbose(
"Averaged end-effector pose: [" + eepose_averaged.toString() +
"].");
2099 while (!isStopping() && !vs_goal_reached_)
2101 yInfoVerbose(
"Desired goal pose = [" + goal_pose_.toString() +
"]");
2105 std::vector<cv::Scalar> color;
2106 color.emplace_back(cv::Scalar(255, 0, 0));
2107 color.emplace_back(cv::Scalar( 0, 255, 0));
2108 color.emplace_back(cv::Scalar( 0, 0, 255));
2109 color.emplace_back(cv::Scalar(255, 127, 51));
2113 ImageOf<PixelRgb>* l_imgin = port_image_left_in_.read(
true);
2114 ImageOf<PixelRgb>& l_imgout = port_image_left_out_.prepare();
2115 l_imgout = *l_imgin;
2116 cv::Mat l_img = cv::cvarrToMat(l_imgout.getIplImage());
2119 ImageOf<PixelRgb>* r_imgin = port_image_right_in_.read(
true);
2120 ImageOf<PixelRgb>& r_imgout = port_image_right_out_.prepare();
2121 r_imgout = *r_imgin;
2122 cv::Mat r_img = cv::cvarrToMat(r_imgout.getIplImage());
2126 Vector l_position_ee = getPixelFromPoint(CamSel::left, cat(eepose_averaged.subVector(0, 2), 1.0));
2127 Vector r_position_ee = getPixelFromPoint(CamSel::right, cat(eepose_averaged.subVector(0, 2), 1.0));
2129 Matrix H_ee_to_root = axis2dcm(eepose_averaged.subVector(3, 6));
2130 H_ee_to_root.setCol(3, cat(eepose_averaged.subVector(0, 2), 1.0));
2132 Vector versor_x_ee = H_ee_to_root * cat(0.03, 0, 0, 1.0);
2133 Vector versor_y_ee = H_ee_to_root * cat( 0, 0.03, 0, 1.0);
2134 Vector versor_z_ee = H_ee_to_root * cat( 0, 0, 0.03, 1.0);
2136 Vector l_versor_x_ee = getPixelFromPoint(CamSel::left, versor_x_ee);
2137 Vector l_versor_y_ee = getPixelFromPoint(CamSel::left, versor_y_ee);
2138 Vector l_versor_z_ee = getPixelFromPoint(CamSel::left, versor_z_ee);
2140 Vector r_versor_x_ee = getPixelFromPoint(CamSel::right, versor_x_ee);
2141 Vector r_versor_y_ee = getPixelFromPoint(CamSel::right, versor_y_ee);
2142 Vector r_versor_z_ee = getPixelFromPoint(CamSel::right, versor_z_ee);
2144 cv::circle(l_img, cv::Point(l_position_ee[0], l_position_ee[1]), 4, color[3], 4);
2145 cv::line (l_img, cv::Point(l_position_ee[0], l_position_ee[1]), cv::Point(l_versor_x_ee[0], l_versor_x_ee[1]), color[0], 4, cv::LineTypes::LINE_AA);
2146 cv::line (l_img, cv::Point(l_position_ee[0], l_position_ee[1]), cv::Point(l_versor_y_ee[0], l_versor_y_ee[1]), color[1], 4, cv::LineTypes::LINE_AA);
2147 cv::line (l_img, cv::Point(l_position_ee[0], l_position_ee[1]), cv::Point(l_versor_z_ee[0], l_versor_z_ee[1]), color[2], 4, cv::LineTypes::LINE_AA);
2149 cv::circle(r_img, cv::Point(r_position_ee[0], r_position_ee[1]), 4, color[3], 4);
2150 cv::line (r_img, cv::Point(r_position_ee[0], r_position_ee[1]), cv::Point(r_versor_x_ee[0], r_versor_x_ee[1]), color[0], 4, cv::LineTypes::LINE_AA);
2151 cv::line (r_img, cv::Point(r_position_ee[0], r_position_ee[1]), cv::Point(r_versor_y_ee[0], r_versor_y_ee[1]), color[1], 4, cv::LineTypes::LINE_AA);
2152 cv::line (r_img, cv::Point(r_position_ee[0], r_position_ee[1]), cv::Point(r_versor_z_ee[0], r_versor_z_ee[1]), color[2], 4, cv::LineTypes::LINE_AA);
2155 Vector l_position_g = getPixelFromPoint(CamSel::left, cat(goal_pose_.subVector(0, 2), 1.0));
2156 Vector r_position_g = getPixelFromPoint(CamSel::right, cat(goal_pose_.subVector(0, 2), 1.0));
2158 Matrix H_goal_to_root = axis2dcm(goal_pose_.subVector(3, 6));
2159 H_goal_to_root.setCol(3, cat(goal_pose_.subVector(0, 2), 1.0));
2161 Vector versor_x_g = H_goal_to_root * cat(0.03, 0, 0, 1.0);
2162 Vector versor_y_g = H_goal_to_root * cat( 0, 0.03, 0, 1.0);
2163 Vector versor_z_g = H_goal_to_root * cat( 0, 0, 0.03, 1.0);
2165 Vector l_versor_x_g = getPixelFromPoint(CamSel::left, versor_x_g);
2166 Vector l_versor_y_g = getPixelFromPoint(CamSel::left, versor_y_g);
2167 Vector l_versor_z_g = getPixelFromPoint(CamSel::left, versor_z_g);
2169 Vector r_versor_x_g = getPixelFromPoint(CamSel::right, versor_x_g);
2170 Vector r_versor_y_g = getPixelFromPoint(CamSel::right, versor_y_g);
2171 Vector r_versor_z_g = getPixelFromPoint(CamSel::right, versor_z_g);
2173 cv::circle(l_img, cv::Point(l_position_g[0], l_position_g[1]), 4, color[3], 4);
2174 cv::line (l_img, cv::Point(l_position_g[0], l_position_g[1]), cv::Point(l_versor_x_g[0], l_versor_x_g[1]), color[0], 4, cv::LineTypes::LINE_AA);
2175 cv::line (l_img, cv::Point(l_position_g[0], l_position_g[1]), cv::Point(l_versor_y_g[0], l_versor_y_g[1]), color[1], 4, cv::LineTypes::LINE_AA);
2176 cv::line (l_img, cv::Point(l_position_g[0], l_position_g[1]), cv::Point(l_versor_z_g[0], l_versor_z_g[1]), color[2], 4, cv::LineTypes::LINE_AA);
2178 cv::circle(r_img, cv::Point(r_position_g[0], r_position_g[1]), 4, color[3], 4);
2179 cv::line (r_img, cv::Point(r_position_g[0], r_position_g[1]), cv::Point(r_versor_x_g[0], r_versor_x_g[1]), color[0], 4, cv::LineTypes::LINE_AA);
2180 cv::line (r_img, cv::Point(r_position_g[0], r_position_g[1]), cv::Point(r_versor_y_g[0], r_versor_y_g[1]), color[1], 4, cv::LineTypes::LINE_AA);
2181 cv::line (r_img, cv::Point(r_position_g[0], r_position_g[1]), cv::Point(r_versor_z_g[0], r_versor_z_g[1]), color[2], 4, cv::LineTypes::LINE_AA);
2184 port_image_left_out_.write();
2185 port_image_right_out_.write();
2190 Vector& pose_avg_ = port_pose_avg_.prepare();
2191 pose_avg_ = eepose_averaged;
2192 port_pose_avg_.write();
2196 itf_rightarm_cart_->getPose(kin_x, kin_o);
2198 Vector& pose_kin_ = port_pose_kin_.prepare();
2199 pose_kin_ = cat(kin_x, kin_o);
2200 port_pose_kin_.write();
2202 Vector& pose_goal_ = port_pose_goal_.prepare();
2203 pose_goal_ = goal_pose_;
2204 port_pose_goal_.write();
2211 vs_goal_reached_ = checkVisualServoingStatus(eepose_averaged, tol_position_, tol_orientation_, tol_angle_);
2213 mtx_px_des_.unlock();
2216 if (vs_goal_reached_)
2219 yInfoVerbose(
"*** Goal reached! ***");
2220 yInfoVerbose(
"Desired goal pose = " + goal_pose_.toString());
2221 yInfoVerbose(
"Reached pose = " + eepose_averaged.toString());
2222 yInfoVerbose(
"*** ------------- ***");
2230 Vector e_pos = goal_pose_.subVector(0, 2) - eepose_averaged.subVector(0, 2);
2231 Vector e_orientation = dcm2axis(axis2dcm(goal_pose_.subVector(3, 6)) * axis2dcm(eepose_averaged.subVector(3, 6)).transposed());
2233 yInfoVerbose(
"Position error = [" + e_pos.toString() +
"]");
2234 yInfoVerbose(
"Orientation error = [" + e_orientation.toString() +
"]");
2236 mtx_px_des_.unlock();
2240 Vector vel_o = cat(e_orientation.subVector(0, 2), e_orientation(3));
2241 Vector vel_x = e_pos;
2243 yInfoVerbose(
"Translational velocity = [" + vel_x.toString() +
"]");
2244 yInfoVerbose(
"Orientation velocity = [" + vel_o.toString() +
"]");
2248 for (
size_t i = 0; i < vel_x.length(); ++i)
2250 if (!std::isnan(vel_x[i]) && !std::isinf(vel_x[i]))
2251 vel_x[i] = sign(vel_x[i]) * std::min(max_x_dot_, std::fabs(vel_x[i]));
2254 vel_x = Vector(3, 0.0);
2258 yInfoVerbose(
"Bounded translational velocity = [" + vel_x.toString() +
"]");
2262 if (!std::isnan(vel_o[0]) && !std::isinf(vel_x[0]) &&
2263 !std::isnan(vel_o[1]) && !std::isinf(vel_x[1]) &&
2264 !std::isnan(vel_o[2]) && !std::isinf(vel_x[2]) &&
2265 !std::isnan(vel_o[3]) && !std::isinf(vel_x[3]))
2266 vel_o[3] = sign(vel_o[3]) * std::min(max_o_dot_, std::fabs(vel_o[3]));
2268 vel_o = Vector(4, 0.0);
2269 yInfoVerbose(
"Bounded orientation velocity = [" + vel_o.toString() +
"]");
2273 if (!checkVisualServoingStatus(eepose_averaged, K_position_tol_, K_orientation_tol_, K_angle_tol_))
2276 vel_o(3) *= K_o_[0];
2277 if (K_pose_hysteresis_)
2279 K_pose_hysteresis_ =
false;
2281 K_position_tol_ -= 0.02;
2282 K_orientation_tol_ -= (2.0 * M_PI / 180.0);
2288 vel_o(3) *= K_o_[1];
2289 if (!K_pose_hysteresis_)
2291 K_pose_hysteresis_ =
true;
2293 K_position_tol_ += 0.02;
2294 K_orientation_tol_ += (2.0 * M_PI / 180.0);
2302 itf_rightarm_cart_->setTaskVelocities(vel_x, vel_o);
2310 endeffector_pose = port_pose_left_in_.read(
true);
2311 eepose_copy_left = *endeffector_pose;
2314 endeffector_pose = port_pose_right_in_.read(
true);
2315 eepose_copy_right = *endeffector_pose;
2318 eepose_averaged = averagePose(eepose_copy_left, eepose_copy_right);
2319 eepose_copy_left = eepose_averaged;
2320 eepose_copy_right = eepose_averaged;
2324 Matrix l_R = axis2dcm(eepose_copy_left.subVector(3, 6));
2325 Matrix r_R = axis2dcm(eepose_copy_right.subVector(3, 6));
2329 l_R = axis2dcm(vel_o) * l_R;
2330 r_R = axis2dcm(vel_o) * r_R;
2333 Vector l_new_o = dcm2axis(l_R);
2334 Vector r_new_o = dcm2axis(r_R);
2338 eepose_copy_left.setSubvector(0, eepose_copy_left.subVector(0, 2) + vel_x * Ts_);
2339 eepose_copy_right.setSubvector(0, eepose_copy_right.subVector(0, 2) + vel_x * Ts_);
2340 eepose_copy_left.setSubvector(3, l_new_o);
2341 eepose_copy_right.setSubvector(3, r_new_o);
2344 eepose_averaged = averagePose(eepose_copy_left, eepose_copy_right);
2345 eepose_copy_left = eepose_averaged;
2346 eepose_copy_right = eepose_averaged;
2355 Property rightarm_cartesian_options;
2356 rightarm_cartesian_options.put(
"device",
"cartesiancontrollerclient");
2357 rightarm_cartesian_options.put(
"local",
"/visualservoing/cart_right_arm");
2358 rightarm_cartesian_options.put(
"remote",
"/" + robot_name_ +
"/cartesianController/right_arm");
2360 rightarm_cartesian_driver_.open(rightarm_cartesian_options);
2361 if (rightarm_cartesian_driver_.isValid())
2363 rightarm_cartesian_driver_.view(itf_rightarm_cart_);
2364 if (!itf_rightarm_cart_)
2366 yErrorVerbose(
"Error getting ICartesianControl interface!");
2369 yInfoVerbose(
"cartesiancontrollerclient succefully opened.");
2373 yErrorVerbose(
"Error opening cartesiancontrollerclient device!");
2378 if (!itf_rightarm_cart_->storeContext(&ctx_remote_cart_))
2380 yErrorVerbose(
"Error storing remote ICartesianControl context!");
2383 yInfoVerbose(
"Remote ICartesianControl context stored.");
2386 if (!itf_rightarm_cart_->setTrajTime(traj_time_))
2388 yErrorVerbose(
"Error setting ICartesianControl trajectory time!");
2391 yInfoVerbose(
"Succesfully set ICartesianControl trajectory time.");
2394 if (!itf_rightarm_cart_->setInTargetTol(0.01))
2396 yErrorVerbose(
"Error setting ICartesianControl target tolerance!");
2399 yInfoVerbose(
"Succesfully set ICartesianControl target tolerance.");
2404 yErrorVerbose(
"Unable to change torso DOF!");
2407 yInfoVerbose(
"Succesfully changed torso DOF.");
2410 if (!itf_rightarm_cart_->storeContext(&ctx_local_cart_))
2412 yErrorVerbose(
"Error storing local ICartesianControl context!");
2415 yInfoVerbose(
"Local ICartesianControl context stored.");
2418 if (!itf_rightarm_cart_->restoreContext(ctx_remote_cart_))
2420 yErrorVerbose(
"Error restoring remote ICartesianControl context!");
2423 yInfoVerbose(
"Remote ICartesianControl context restored.");
2432 Property gaze_option;
2433 gaze_option.put(
"device",
"gazecontrollerclient");
2434 gaze_option.put(
"local",
"/visualservoing/gaze");
2435 gaze_option.put(
"remote",
"/iKinGazeCtrl");
2437 gaze_driver_.open(gaze_option);
2438 if (gaze_driver_.isValid())
2440 gaze_driver_.view(itf_gaze_);
2443 yErrorVerbose(
"Error getting IGazeControl interface!");
2449 yErrorVerbose(
"Gaze control device not available!");
2459 yInfoVerbose(
"Opening RPC command port.");
2461 if (!port_rpc_command_.open(
"/visualservoing/cmd:i"))
2463 yErrorVerbose(
"Cannot open the RPC server command port!");
2466 if (!yarp().attachAsServer(port_rpc_command_))
2468 yErrorVerbose(
"Cannot attach the RPC server command port!");
2473 if (!port_rpc_tracker_left_.open(
"/visualservoing/toTracker/left/cmd:o"))
2475 yErrorVerbose(
"Cannot open the RPC command port to left camera tracker!");
2478 if (!port_rpc_tracker_right_.open(
"/visualservoing/toTracker/right/cmd:o"))
2480 yErrorVerbose(
"Cannot open the RPC command port to right camera tracker!");
2485 yInfoVerbose(
"RPC command port opened and attached. Ready to recieve commands.");
2494 itf_rightarm_cart_->getDOF(curDOF);
2495 yInfoVerbose(
"Old DOF: [" + curDOF.toString(0) +
"].");
2497 yInfoVerbose(
"Setting iCub to use torso DOF.");
2499 Vector newDOF(curDOF);
2503 if (!itf_rightarm_cart_->setDOF(newDOF, curDOF))
2506 yInfoVerbose(
"New DOF: Yaw " + ConstString(curDOF[0] == 0 ?
"blocked, " :
"actuated, ") +
2507 "Roll " + ConstString(curDOF[1] == 0 ?
"blocked, " :
"actuated, ") +
2508 "Pitch " + ConstString(curDOF[2] == 0 ?
"blocked." :
"actuated." ));
2517 itf_rightarm_cart_->getDOF(curDOF);
2518 yInfoVerbose(
"Old DOF: [" + curDOF.toString(0) +
"].");
2520 yInfoVerbose(
"Setting iCub to block torso DOF.");
2522 Vector newDOF(curDOF);
2526 if (!itf_rightarm_cart_->setDOF(newDOF, curDOF))
2529 yInfoVerbose(
"New DOF: Yaw " + ConstString(curDOF[0] == 0 ?
"blocked, " :
"actuated, ") +
2530 "Roll " + ConstString(curDOF[1] == 0 ?
"blocked, " :
"actuated, ") +
2531 "Pitch " + ConstString(curDOF[2] == 0 ?
"blocked." :
"actuated." ));
2539 yAssert(pose.length() == 7);
2540 yAssert(cam == CamSel::left || cam == CamSel::right);
2543 std::vector<Vector> pt_from_pose = getControlPointsFromPose(pose);
2545 std::vector<Vector> px_from_pose;
2546 for (
const Vector& v : pt_from_pose)
2547 px_from_pose.emplace_back(getPixelFromPoint(cam, v));
2549 return px_from_pose;
2555 yAssert(pose.length() == 7);
2556 yAssert(cam == CamSel::left || cam == CamSel::right);
2557 yAssert(mode == PixelControlMode::all || mode == PixelControlMode::x || mode == PixelControlMode::o);
2560 Vector control_pose = pose;
2561 if (mode == PixelControlMode::x)
2562 control_pose.setSubvector(3, goal_pose_.subVector(3, 6));
2563 else if (mode == PixelControlMode::o)
2564 control_pose.setSubvector(0, goal_pose_.subVector(0, 2));
2566 std::vector<Vector> control_pt_from_pose = getControlPointsFromPose(control_pose);
2568 std::vector<Vector> control_px_from_pose;
2569 for (
const Vector& v : control_pt_from_pose)
2570 control_px_from_pose.emplace_back(getControlPixelFromPoint(cam, v));
2572 return control_px_from_pose;
2578 Vector ee_x = pose.subVector(0, 2);
2579 ee_x.push_back(1.0);
2581 Vector ee_o = pose.subVector(3, 6);
2584 Matrix H_ee_to_root = axis2dcm(ee_o);
2585 H_ee_to_root.setCol(3, ee_x);
2588 Vector p = zeros(4);
2589 std::vector<Vector> control_pt_from_pose;
2595 control_pt_from_pose.emplace_back(H_ee_to_root * p);
2601 control_pt_from_pose.emplace_back(H_ee_to_root * p);
2607 control_pt_from_pose.emplace_back(H_ee_to_root * p);
2613 control_pt_from_pose.emplace_back(H_ee_to_root * p);
2616 return control_pt_from_pose;
2622 return getControlPixelFromPoint(cam, p).subVector(0, 1);
2628 yAssert(cam == CamSel::left || cam == CamSel::right);
2629 yAssert(p.size() == 4);
2634 if (cam == CamSel::left)
2635 px = l_H_r_to_cam_ * p;
2636 else if (cam == CamSel::right)
2637 px = r_H_r_to_cam_ * p;
2647 Vector& features, Matrix& jacobian)
2649 yAssert(left_px.size() == right_px.size());
2651 if (features.length() != 16)
2652 features.resize(16);
2654 if (jacobian.rows() != 16 || jacobian.cols() != 6)
2655 jacobian.resize(16, 6);
2658 auto iter_left_px = left_px.cbegin();
2659 auto iter_right_px = right_px.cbegin();
2660 unsigned int offset = 0;
2661 while (iter_left_px != left_px.cend() && iter_right_px != right_px.cend())
2663 const Vector& l_v = (*iter_left_px);
2664 const Vector& r_v = (*iter_right_px);
2667 features[4 * offset ] = l_v[0];
2668 features[4 * offset + 1] = r_v[0];
2669 features[4 * offset + 2] = l_v[1];
2670 features[4 * offset + 3] = r_v[1];
2673 jacobian.setRow(4 * offset, getJacobianU(CamSel::left, l_v));
2674 jacobian.setRow(4 * offset + 1, getJacobianU(CamSel::right, r_v));
2675 jacobian.setRow(4 * offset + 2, getJacobianV(CamSel::left, l_v));
2676 jacobian.setRow(4 * offset + 3, getJacobianV(CamSel::right, r_v));
2687 Vector jacobian = zeros(6);
2689 if (cam == CamSel::left)
2691 jacobian(0) = l_proj_(0, 0) / px(2);
2692 jacobian(2) = - (px(0) - l_proj_(0, 2)) / px(2);
2693 jacobian(3) = - ((px(0) - l_proj_(0, 2)) * (px(1) - l_proj_(1, 2))) / l_proj_(1, 1);
2694 jacobian(4) = (pow(l_proj_(0, 0), 2.0) + pow(px(0) - l_proj_(0, 2), 2.0)) / l_proj_(0, 0);
2695 jacobian(5) = - l_proj_(0, 0) / l_proj_(1, 1) * (px(1) - l_proj_(1, 2));
2697 else if (cam == CamSel::right)
2699 jacobian(0) = r_proj_(0, 0) / px(2);
2700 jacobian(2) = - (px(0) - r_proj_(0, 2)) / px(2);
2701 jacobian(3) = - ((px(0) - r_proj_(0, 2)) * (px(1) - r_proj_(1, 2))) / r_proj_(1, 1);
2702 jacobian(4) = (pow(r_proj_(0, 0), 2.0) + pow(px(0) - r_proj_(0, 2), 2.0)) / r_proj_(0, 0);
2703 jacobian(5) = - r_proj_(0, 0) / r_proj_(1, 1) * (px(1) - r_proj_(1, 2));
2712 Vector jacobian = zeros(6);
2714 if (cam == CamSel::left)
2716 jacobian(1) = l_proj_(1, 1) / px(2);
2717 jacobian(2) = - (px(1) - l_proj_(1, 2)) / px(2);
2718 jacobian(3) = - (pow(l_proj_(1, 1), 2.0) + pow(px(1) - l_proj_(1, 2), 2.0)) / l_proj_(1, 1);
2719 jacobian(4) = ((px(0) - l_proj_(0, 2)) * (px(1) - l_proj_(1, 2))) / l_proj_(0, 0);
2720 jacobian(5) = l_proj_(1, 1) / l_proj_(0, 0) * (px(0) - l_proj_(0, 2));
2722 else if (cam == CamSel::right)
2724 jacobian(1) = r_proj_(1, 1) / px(2);
2725 jacobian(2) = - (px(1) - r_proj_(1, 2)) / px(2);
2726 jacobian(3) = - (pow(r_proj_(1, 1), 2.0) + pow(px(1) - r_proj_(1, 2), 2.0)) / r_proj_(1, 1);
2727 jacobian(4) = ((px(0) - r_proj_(0, 2)) * (px(1) - r_proj_(1, 2))) / r_proj_(0, 0);
2728 jacobian(5) = r_proj_(1, 1) / r_proj_(0, 0) * (px(0) - r_proj_(0, 2));
2737 std::lock_guard<std::mutex> lock(mtx_H_eye_cam_);
2741 if (!itf_gaze_->getLeftEyePose(left_eye_x, left_eye_o))
2746 if (!itf_gaze_->getRightEyePose(right_eye_x, right_eye_o))
2750 l_H_eye_to_r_ = axis2dcm(left_eye_o);
2751 left_eye_x.push_back(1.0);
2752 l_H_eye_to_r_.setCol(3, left_eye_x);
2753 Matrix l_H_r_to_eye = SE3inv(l_H_eye_to_r_);
2755 r_H_eye_to_r_ = axis2dcm(right_eye_o);
2756 right_eye_x.push_back(1.0);
2757 r_H_eye_to_r_.setCol(3, right_eye_x);
2758 Matrix r_H_r_to_eye = SE3inv(r_H_eye_to_r_);
2760 l_H_r_to_cam_ = l_proj_ * l_H_r_to_eye;
2761 r_H_r_to_cam_ = r_proj_ * r_H_r_to_eye;
2769 goal_pose_.setSubvector(0, goal_x);
2770 goal_pose_.setSubvector(3, goal_o);
2778 std::lock_guard<std::mutex> lock(mtx_px_des_);
2781 l_px_goal_ = l_px_goal;
2782 r_px_goal_ = r_px_goal;
2784 for (
unsigned int i = 0; i < l_px_goal_.size(); ++i)
2786 px_des_[4 * i ] = l_px_goal_[i][0];
2787 px_des_[4 * i + 1] = r_px_goal_[i][0];
2788 px_des_[4 * i + 2] = l_px_goal_[i][1];
2789 px_des_[4 * i + 3] = r_px_goal_[i][1];
2798 yInfoVerbose(
"*** Started background process UpdateVisualServoingParamters ***");
2800 while (!is_stopping_backproc_update_vs_params)
2802 Vector vec_x = goal_pose_.subVector(0, 2);
2803 Vector vec_o = goal_pose_.subVector(3, 6);
2805 std::vector<Vector> vec_px_l = getGoalPixelsFrom3DPose(vec_x, vec_o, CamSel::left);
2806 std::vector<Vector> vec_px_r = getGoalPixelsFrom3DPose(vec_x, vec_o, CamSel::right);
2808 if (vec_px_l.size() != 0 && vec_px_r.size() != 0)
2809 setPixelGoal(vec_px_l, vec_px_r);
2811 yErrorVerbose(
"[BACKPROC] Could not update goal pixels from 3D pose.");
2814 yInfoVerbose(
"*** Stopped background process UpdateVisualServoingParamters ***");
2820 Vector pose_out = zeros(7);
2822 pose_out.setSubvector(0, 0.5 * l_pose.subVector(0, 2) + 0.5 * r_pose.subVector(0, 2));
2824 pose_out.setSubvector(3, 0.5 * l_pose.subVector(3, 5) + 0.5 * r_pose.subVector(3, 5));
2825 pose_out.setSubvector(3, pose_out.subVector(3, 5) / norm(pose_out.subVector(3, 5)));
2827 float s_ang = 0.5 * std::sin(l_pose(6)) + 0.5 * std::sin(r_pose(6));
2828 float c_ang = 0.5 * std::cos(l_pose(6)) + 0.5 * std::cos(r_pose(6));
2829 pose_out(6) = std::atan2(s_ang, c_ang);
2837 yAssert(px_cur.size() == 16);
2840 return ((std::abs(px_des_(0) - px_cur(0)) < tol) && (std::abs(px_des_(1) - px_cur(1)) < tol) && (std::abs(px_des_(2) - px_cur(2)) < tol) && (std::abs(px_des_(3) - px_cur(3)) < tol) &&
2841 (std::abs(px_des_(4) - px_cur(4)) < tol) && (std::abs(px_des_(5) - px_cur(5)) < tol) && (std::abs(px_des_(6) - px_cur(6)) < tol) && (std::abs(px_des_(7) - px_cur(7)) < tol) &&
2842 (std::abs(px_des_(8) - px_cur(8)) < tol) && (std::abs(px_des_(9) - px_cur(9)) < tol) && (std::abs(px_des_(10) - px_cur(10)) < tol) && (std::abs(px_des_(11) - px_cur(11)) < tol) &&
2843 (std::abs(px_des_(12) - px_cur(12)) < tol) && (std::abs(px_des_(13) - px_cur(13)) < tol) && (std::abs(px_des_(14) - px_cur(14)) < tol) && (std::abs(px_des_(15) - px_cur(15)) < tol));
2849 bool reached_position = (norm(pose_cur.subVector(0, 2) - goal_pose_.subVector(0, 2)) < tol_position);
2851 bool reached_axis = std::abs(std::acos(dot(pose_cur.subVector(3, 5), goal_pose_.subVector(3, 5)))) < tol_orientation;
2853 double ang = pose_cur(6) - goal_pose_(6);
2854 if (ang > M_PI) ang -= 2.0 * M_PI;
2855 else if (ang <= -M_PI) ang += 2.0 * M_PI;
2857 bool reached_angle = std::abs(ang) < tol_angle;
2859 return reached_position && reached_axis && reached_angle;
2867 for (
const Vector& yv : vectors)
bool checkVisualServoingStatus(const yarp::sig::Vector &px_cur, const double tol)
bool set_translation_gain(const double K_x_1, const double K_x_2) override
Set the translation gains of the visual servoing control algorithm.
bool set_max_translation_velocity(const double max_x_dot) override
Set the maximum translation velocity of the visual servoing control algorithm (same for each axis)...
bool initFacilities(const bool use_direct_kin) override
bool check_visual_servoing_controller() override
Check once whether the visual servoing controller is running or not.
bool setOrientationGain(const double K_x_1=1.5, const double K_x_2=0.375) override
bool stop_facilities() override
Stop and disconnect support modules and connections used for visual servoing.
std::vector< yarp::sig::Vector > get3DGoalPositionsFrom3DPose(const yarp::sig::Vector &x, const yarp::sig::Vector &o) override
void getCurrentStereoFeaturesAndJacobian(const std::vector< yarp::sig::Vector > &left_px, const std::vector< yarp::sig::Vector > &right_px, yarp::sig::Vector &features, yarp::sig::Matrix &jacobian)
bool getVisualServoingInfo(yarp::os::Bottle &info) override
bool set_orientation_gain(const double K_o_1, const double K_o_2) override
Set the orientation gains of the visual servoing control algorithm.
yarp::sig::Vector getJacobianU(const CamSel &cam, const yarp::sig::Vector &px)
bool setVisualServoControl(const std::string &control) override
bool storedInit(const std::string &label) override
bool reset_facilities() override
Reset support modules and connections to perform the current initialized visual servoing task...
bool set_modality(const std::string &mode) override
Set visual servoing operating mode between:
yarp::sig::Vector stdVectorOfVectorsToVector(const std::vector< yarp::sig::Vector > &vectors)
void cartesianPositionBasedVisualServoControl()
void decoupledImageBasedVisualServoControl()
void afterStart(bool success) override
bool setOrientationGainSwitchTolerance(const double K_o_tol=30.0) override
bool waitVisualServoingDone(const double period=0.1, const double timeout=0.0) override
void backproc_UpdateVisualServoingParamters()
bool stored_init(const std::string &label) override
Initialize the robot to an initial position.
bool threadInit() override
bool set_go_to_goal_tolerance(const double tol) override
Set visual servoing goal tolerance.
bool stopFacilities() override
std::vector< std::string > get_visual_servoing_info() override
Return useful information for visual servoing.
bool stored_go_to_goal(const std::string &label) override
Set the robot visual servoing goal.
bool checkVisualServoingController() override
bool setPoseGoal(const yarp::sig::Vector &goal_x, const yarp::sig::Vector &goal_o)
bool set_translation_gain_switch_tolerance(const double K_x_tol) override
Set the tolerance, in pixels, at which the translation control law swithces its gain value...
bool set_orientation_gain_switch_tolerance(const double K_o_tol) override
Set the tolerance, in pixels, at which the orientation control law swithces its gain value...
std::vector< yarp::sig::Vector > getGoalPixelsFrom3DPose(const yarp::sig::Vector &x, const yarp::sig::Vector &o, const CamSel &cam) override
bool setTranslationGainSwitchTolerance(const double K_x_tol=30.0) override
yarp::sig::Vector getJacobianV(const CamSel &cam, const yarp::sig::Vector &px)
bool stop_controller() override
Ask for an immediate stop of the visual servoing controller.
std::vector< std::vector< double > > get_3D_goal_positions_from_3D_pose(const std::vector< double > &x, const std::vector< double > &o) override
Helper function: extract four Cartesian points lying on the plane defined by the frame o in the posit...
bool goToSFMGoal() override
yarp::sig::Vector getControlPixelFromPoint(const CamSel &cam, const yarp::sig::Vector &p) const
void threadRelease() override
std::vector< yarp::sig::Vector > getPixelsFromPose(const yarp::sig::Vector &pose, const CamSel &cam)
std::vector< std::vector< double > > get_goal_pixels_from_3D_pose(const std::vector< double > &x, const std::vector< double > &o, const std::string &cam) override
Helper function: extract four 2D pixel points lying on the plane defined by the frame o in the positi...
void beforeStart() override
bool setGoToGoalTolerance(const double tol=15.0) override
bool setTranslationGain(const double K_x_1=1.0, const double K_x_2=0.25) override
bool setPixelGoal(const std::vector< yarp::sig::Vector > &l_px_goal, const std::vector< yarp::sig::Vector > &r_px_goal)
bool setRightArmCartesianController()
bool set_visual_servo_control(const std::string &control) override
Set visual servo control law between:
bool resetFacilities() override
bool stopController() override
std::vector< yarp::sig::Vector > getControlPixelsFromPose(const yarp::sig::Vector &pose, const CamSel &cam, const PixelControlMode &mode)
bool go_to_pose_goal(const std::vector< double > &vec_x, const std::vector< double > &vec_o) override
Set the goal point (3D for the position + 4D axis-angle for the orientation) and start visual servoin...
bool setCameraTransformations()
bool setModality(const std::string &mode) override
bool init_facilities(const bool use_direct_kin) override
Initialize support modules and connections to perform a visual servoing task.
bool goToGoal(const yarp::sig::Vector &vec_x, const yarp::sig::Vector &vec_o) override
void robustImageBasedVisualServoControl()
bool go_to_px_goal(const std::vector< std::vector< double >> &vec_px_l, const std::vector< std::vector< double >> &vec_px_r) override
yarp::sig::Vector getPixelFromPoint(const CamSel &cam, const yarp::sig::Vector &p) const
bool setControlPoint(const yarp::os::ConstString &point) override
bool quit() override
Gently close the visual servoing device, deallocating resources.
bool wait_visual_servoing_done(const double period, const double timeout) override
Wait until visual servoing reaches the goal.
yarp::sig::Vector averagePose(const yarp::sig::Vector &l_pose, const yarp::sig::Vector &r_pose) const
bool get_goal_from_sfm() override
Get goal point from SFM module.
bool storedGoToGoal(const std::string &label) override
bool setMaxOrientationVelocity(const double max_o_dot) override
bool set_control_point(const std::string &point) override
Set the point controlled during visual servoing.
bool set_max_orientation_velocity(const double max_o_dot) override
Set the maximum angular velocity of the axis-angle velocity vector of the visual servoing control alg...
bool open(yarp::os::Searchable &config) override
std::vector< yarp::sig::Vector > getControlPointsFromPose(const yarp::sig::Vector &pose)
bool setMaxTranslationVelocity(const double max_x_dot) override