00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <ros/ros.h>
00036 #include <ros/package.h>
00037
00038 #include <std_msgs/Header.h>
00039 #include <geometry_msgs/PointStamped.h>
00040 #include <geometry_msgs/PoseStamped.h>
00041 #include <geometry_msgs/TwistStamped.h>
00042 #include <geometry_msgs/Pose2D.h>
00043 #include <sensor_msgs/Image.h>
00044 #include <sensor_msgs/PointCloud2.h>
00045 #include <sensor_msgs/CameraInfo.h>
00046 #include <sensor_msgs/image_encodings.h>
00047
00048
00049 #include <tf/transform_listener.h>
00050 #include <tf/transform_datatypes.h>
00051
00052
00053 #include <pcl/point_cloud.h>
00054 #include <pcl/point_types.h>
00055 #include <pcl_ros/transforms.h>
00056
00057
00058 #include <opencv2/core/core.hpp>
00059 #include <opencv2/imgproc/imgproc.hpp>
00060 #include <opencv2/highgui/highgui.hpp>
00061
00062
00063 #include <boost/shared_ptr.hpp>
00064
00065
00066 #include <vector>
00067 #include <deque>
00068 #include <queue>
00069 #include <string>
00070 #include <sstream>
00071 #include <iostream>
00072 #include <fstream>
00073 #include <utility>
00074 #include <stdexcept>
00075 #include <float.h>
00076 #include <math.h>
00077 #include <time.h>
00078 #include <cstdlib>
00079
00080
00081 #include <visual_servo/VisualServoTwist.h>
00082
00083 #define DEBUG_MODE 0
00084 #define JACOBIAN_TYPE_INV 1
00085 #define JACOBIAN_TYPE_PSEUDO 2
00086 #define JACOBIAN_TYPE_AVG 3
00087 #define PBVS 0
00088 #define IBVS 1
00089 #define PI 3.14159265359
00090
00091 typedef pcl::PointCloud<pcl::PointXYZ> XYZPointCloud;
00092 typedef struct {
00093
00094 cv::Point image;
00095
00096 pcl::PointXYZ camera;
00097
00098 pcl::PointXYZ workspace;
00099 pcl::PointXYZ workspace_angular;
00100 } VSXYZ;
00101
00102 namespace VisualServoMsg
00103 {
00104 visual_servo::VisualServoPose createPoseMsg(float px, float py, float pz, float ox, float oy, float oz, float ow)
00105 {
00106 visual_servo::VisualServoPose p_srv;
00107 p_srv.request.p.header.stamp = ros::Time::now();
00108 p_srv.request.p.header.frame_id = "torso_lift_link";
00109 p_srv.request.p.pose.position.x = px;
00110 p_srv.request.p.pose.position.y = py;
00111 p_srv.request.p.pose.position.z = pz;
00112 p_srv.request.p.pose.orientation.x = ox;
00113 p_srv.request.p.pose.orientation.y = oy;
00114 p_srv.request.p.pose.orientation.z = oz;
00115 p_srv.request.p.pose.orientation.w = ow;
00116 return p_srv;
00117 }
00118
00119 visual_servo::VisualServoTwist createTwistMsg(float err, double lx, double ly, double lz, double ax, double ay, double az)
00120 {
00121 visual_servo::VisualServoTwist msg;
00122 msg.request.error = err;
00123 msg.request.twist.header.stamp = ros::Time::now();
00124 msg.request.twist.header.frame_id = "torso_lift_link";
00125 msg.request.twist.twist.linear.x = lx;
00126 msg.request.twist.twist.linear.y = ly;
00127 msg.request.twist.twist.linear.z = lz;
00128 msg.request.twist.twist.angular.x = ax;
00129 msg.request.twist.twist.angular.y = ay;
00130 msg.request.twist.twist.angular.z = az;
00131 return msg;
00132 }
00133
00134 visual_servo::VisualServoTwist createTwistMsg(cv::Mat velpos, cv::Mat velrot)
00135 {
00136 visual_servo::VisualServoTwist msg;
00137 msg.request.twist.twist.linear.x = velpos.at<float>(0,0);
00138 msg.request.twist.twist.linear.y = velpos.at<float>(1,0);
00139 msg.request.twist.twist.linear.z = velpos.at<float>(2,0);
00140 msg.request.twist.twist.angular.x = velrot.at<float>(0,0);
00141 msg.request.twist.twist.angular.y = velrot.at<float>(1,0);
00142 msg.request.twist.twist.angular.z = velrot.at<float>(2,0);
00143 return msg;
00144 }
00145 visual_servo::VisualServoTwist createTwistMsg(double lx, double ly, double lz, double ax, double ay, double az)
00146 {
00147 return createTwistMsg(0.0, lx, ly, lz, ax, ay, az);
00148 }
00149
00150 visual_servo::VisualServoTwist createTwistMsg(float err, std::vector<double> in)
00151 {
00152 if (in.size() >= 6)
00153 return createTwistMsg(err, in.at(0), in.at(1), in.at(2),
00154 in.at(3), in.at(4), in.at(5));
00155 else
00156 {
00157 ROS_WARN("VisuaServoMsg >> Valid input needs 6 values. Returning 0");
00158 visual_servo::VisualServoTwist msg;
00159 return msg;
00160 }
00161 }
00162
00163 visual_servo::VisualServoTwist createTwistMsg(float err, cv::Mat twist)
00164 {
00165 std::vector<double> vals;
00166 for (int i = 0; i < twist.rows; i++)
00167 {
00168 for (int j = 0; j < twist.cols; j++)
00169 {
00170 vals.push_back((double) twist.at<float>(i,j));
00171 }
00172 }
00173 return createTwistMsg(err, vals);
00174 }
00175 }
00176
00177 using geometry_msgs::TwistStamped;
00178 using geometry_msgs::PointStamped;
00179 using geometry_msgs::PoseStamped;
00180 using visual_servo::VisualServoTwist;
00181 using boost::shared_ptr;
00182
00188 class VisualServo
00189 {
00190 public:
00191 VisualServo(int jacobian_type) :
00192 n_private_("~"), desired_jacobian_set_(false)
00193 {
00194
00195 jacobian_type_ = jacobian_type;
00196 std::string default_optical_frame = "/head_mount_kinect_rgb_optical_frame";
00197 n_private_.param("optical_frame", optical_frame_, default_optical_frame);
00198 std::string default_workspace_frame = "/torso_lift_link";
00199 n_private_.param("workspace_frame", workspace_frame_, default_workspace_frame);
00200
00201
00202 n_private_.param("gain_vel", gain_vel_, 1.0);
00203 n_private_.param("gain_rot", gain_rot_, 1.0);
00204
00205
00206 try
00207 {
00208 ros::Time now = ros::Time(0);
00209 listener_.waitForTransform(workspace_frame_, optical_frame_, now, ros::Duration(2.0));
00210 }
00211 catch (tf::TransformException e)
00212 {
00213 ROS_WARN_STREAM(e.what());
00214 }
00215 }
00216
00217 void setCamInfo(sensor_msgs::CameraInfo cam_info)
00218 {
00219 cam_info_ = cam_info;
00220 }
00221
00222 visual_servo::VisualServoTwist getTwist(std::vector<PoseStamped> goal, std::vector<PoseStamped> gripper)
00223 {
00224
00225 return getTwist(goal, gripper, PBVS);
00226 }
00227
00228 visual_servo::VisualServoTwist getTwist(std::vector<PoseStamped> goal, std::vector<PoseStamped> gripper, int mode)
00229 {
00230 switch (mode)
00231 {
00232 case PBVS:
00233 return PBVSTwist(goal, gripper);
00234 default:
00235 return IBVSTwist(goal, gripper);
00236 }
00237 }
00238
00239 visual_servo::VisualServoTwist getTwist(std::vector<VSXYZ> goal, std::vector<VSXYZ> gripper, cv::Mat error)
00240 {
00241 return IBVSTwist(goal, gripper, error);
00242 }
00243
00244 visual_servo::VisualServoTwist getTwist(std::vector<VSXYZ> goal, std::vector<VSXYZ> gripper)
00245 {
00246 return IBVSTwist(goal, gripper);
00247 }
00248
00249 bool setDesiredInteractionMatrix(std::vector<VSXYZ> &pts)
00250 {
00251 try
00252 {
00253 cv::Mat im = getMeterInteractionMatrix(pts);
00254 if (countNonZero(im) > 0)
00255 {
00256 desired_jacobian_ = im;
00257 desired_jacobian_set_ = true;
00258 return true;
00259 }
00260 }
00261 catch(ros::Exception e)
00262 {
00263 }
00264 return false;
00265 }
00266
00267
00268
00269
00270 std::vector<VSXYZ> Point3DToVSXYZ(std::vector<pcl::PointXYZ> in, shared_ptr<tf::TransformListener> tf_)
00271 {
00272 std::vector<VSXYZ> ret;
00273 for (unsigned int i = 0; i < in.size(); i++)
00274 {
00275 ret.push_back(point3DToVSXYZ(in.at(i), tf_));
00276 }
00277 return ret;
00278 }
00279
00280 VSXYZ point3DToVSXYZ(pcl::PointXYZ in, shared_ptr<tf::TransformListener> tf_)
00281 {
00282
00283 VSXYZ ret;
00284
00285
00286 pcl::PointXYZ in_c = in;
00287 cv::Point img = projectPointIntoImage(in_c, workspace_frame_, optical_frame_, tf_);
00288 cv::Mat temp = projectImagePointToPoint(img);
00289
00290 float depth = sqrt(pow(in_c.z,2) + pow(temp.at<float>(0,0),2) + pow(temp.at<float>(1,0),2));
00291 pcl::PointXYZ _2d(temp.at<float>(0,0), temp.at<float>(1,0), depth);
00292 ret.image = img;
00293
00294 ret.camera = _2d;
00295 ret.workspace= in;
00296 return ret;
00297 }
00298 PoseStamped VSXYZToPoseStamped(VSXYZ v)
00299 {
00300 PoseStamped p;
00301 p.pose.position.x = v.workspace.x;
00302 p.pose.position.y = v.workspace.y;
00303 p.pose.position.z = v.workspace.z;
00304 pcl::PointXYZ a = v.workspace_angular;
00305 p.pose.orientation = tf::createQuaternionMsgFromRollPitchYaw(a.x, a.y, a.z);
00306 return p;
00307 }
00308 std::vector<VSXYZ> CVPointToVSXYZ(XYZPointCloud cloud, cv::Mat depth_frame, std::vector<cv::Point> in)
00309 {
00310 std::vector<VSXYZ> ret;
00311 for (unsigned int i = 0; i < in.size(); i++)
00312 {
00313 ret.push_back(CVPointToVSXYZ(cloud, depth_frame, in.at(i)));
00314 }
00315 return ret;
00316 }
00317
00318 VSXYZ CVPointToVSXYZ(XYZPointCloud cloud, cv::Mat depth_frame, cv::Point in)
00319 {
00320
00321 VSXYZ ret;
00322
00323 cv::Mat temp = projectImagePointToPoint(in);
00324
00325
00326 pcl::PointXYZ _2d(temp.at<float>(0,0), temp.at<float>(1,0), getZValue(depth_frame, in.x, in.y));
00327 pcl::PointXYZ _3d = cloud.at(in.x, in.y);
00328
00329 ret.image = in;
00330 ret.camera = _2d;
00331 ret.workspace= _3d;
00332 return ret;
00333 }
00334 cv::Point projectPointIntoImage(pcl::PointXYZ cur_point_pcl,
00335 std::string point_frame, std::string target_frame, shared_ptr<tf::TransformListener> tf_)
00336 {
00337 PointStamped cur_point;
00338 cur_point.header.frame_id = point_frame;
00339 cur_point.point.x = cur_point_pcl.x;
00340 cur_point.point.y = cur_point_pcl.y;
00341 cur_point.point.z = cur_point_pcl.z;
00342 return projectPointIntoImage(cur_point, target_frame, tf_);
00343 }
00344
00345 void printVSXYZ(VSXYZ i)
00346 {
00347 printf("Im: %+.3d %+.3d\tCam: %+.3f %+.3f %+.3f\twork: %+.3f %+.3f %+.3f\n",\
00348 i.image.x, i.image.y, i.camera.x, i.camera.y, i.camera.z, i.workspace.x, i.workspace.y, i.workspace.z);
00349 }
00350
00351 protected:
00352 ros::NodeHandle n_;
00353 ros::NodeHandle n_private_;
00354
00355 std::string workspace_frame_;
00356 std::string optical_frame_;
00357 tf::StampedTransform transform;
00358
00359 tf::TransformListener listener_;
00360
00361 int jacobian_type_;
00362 double gain_vel_;
00363 double gain_rot_;
00364 double term_threshold_;
00365 bool desired_jacobian_set_;
00366 cv::Mat desired_jacobian_;
00367 cv::Mat K;
00368 sensor_msgs::CameraInfo cam_info_;
00369
00370 visual_servo::VisualServoTwist PBVSTwist(cv::Mat error_pose, cv::Mat error_rot)
00371 {
00372 cv::Mat velpos = -gain_vel_*error_pose;
00373 cv::Mat velrot = -gain_rot_*error_rot;
00374 return VisualServoMsg::createTwistMsg(velpos, velrot);
00375 }
00376
00377 visual_servo::VisualServoTwist PBVSTwist(std::vector<PoseStamped> desired, std::vector<PoseStamped> pts)
00378 {
00379
00380 if (pts.size() != 1 || desired.size() != 1)
00381 {
00382 ROS_WARN("Visual Servo: Incorrect input to PBVS. Returning Zero Twist");
00383 return visual_servo::VisualServoTwist();
00384 }
00385
00386
00387
00388
00389
00390
00391 geometry_msgs::Point cpos = pts.front().pose.position;
00392 geometry_msgs::Quaternion cquat = pts.front().pose.orientation;
00393 geometry_msgs::Point gpos = desired.front().pose.position;
00394 geometry_msgs::Quaternion gquat = desired.front().pose.orientation;
00395
00396 float tcpos[3] = {cpos.x, cpos.y, cpos.z};
00397 cv::Mat mcpos = cv::Mat(1, 3, CV_32F, tcpos).t();
00398
00399 float tgpos[3] = {gpos.x, gpos.y, gpos.z};
00400 cv::Mat mgpos = cv::Mat(1, 3, CV_32F, tgpos).t();
00401
00402
00403 double tr, tp, ty;
00404 btQuaternion q1(gquat.x, gquat.y, gquat.z, gquat.w);
00405 btMatrix3x3(q1).getEulerYPR(ty, tp, tr);
00406 float tgquat[3] = {tr, tp, ty};
00407
00408 cv::Mat mgrot = cv::Mat(1, 3, CV_32F, tgquat).t();
00409
00410 btQuaternion q2(cquat.x, cquat.y, cquat.z, cquat.w);
00411 btMatrix3x3(q2).getEulerYPR(ty, tp, tr);
00412 float tcquat[3] = {tr, tp, ty};
00413
00414 cv::Mat mcrot = cv::Mat(1, 3, CV_32F, tcquat).t();
00415 cv::Mat ang_diff = -1*MatDiffAngle(mcrot, mgrot);
00416
00417
00418
00419 ang_diff.at<float>(2) = -ang_diff.at<float>(2);
00420 return PBVSTwist(mcpos - mgpos, ang_diff);
00421
00438 }
00439
00440 cv::Mat MatDiffAngle(cv::Mat m0, cv::Mat m1)
00441 {
00442 cv::Mat ret = cv::Mat::zeros(m0.size(), CV_32F);
00443 if (m0.size() != m1.size())
00444 return ret;
00445 for (int i = 0; i < m0.rows; i++)
00446 {
00447 for (int j = 0; j < m0.cols; j++)
00448 {
00449 ret.at<float>(i,j) = diffAngle(m0.at<float>(i,j), m1.at<float>(i,j));
00450 }
00451 }
00452 return ret;
00453 }
00454
00455 float diffAngle(float a0, float a1)
00456 {
00457
00458 float t = a0 - a1;
00459 if (t > PI)
00460 t = t - 2*PI;
00461 else if (t < -PI)
00462 t = t + 2*PI;
00463 return t;
00464 }
00465
00466
00467 visual_servo::VisualServoTwist IBVSTwist(std::vector<VSXYZ> desired, std::vector<VSXYZ> pts)
00468 {
00469 cv::Mat error_mat;
00470
00471
00472 if (pts.size() != desired.size())
00473 return visual_servo::VisualServoTwist();
00474
00475
00476 for (unsigned int i = 0; i < desired.size(); i++)
00477 {
00478 cv::Mat error = cv::Mat::zeros(2, 1, CV_32F);
00479 error.at<float>(0,0) = (pts.at(i)).camera.x - (desired.at(i)).camera.x;
00480 error.at<float>(1,0) = (pts.at(i)).camera.y - (desired.at(i)).camera.y;
00481 error_mat.push_back(error);
00482 }
00483 return IBVSTwist(desired, pts, error_mat);
00484 }
00485
00486
00487 visual_servo::VisualServoTwist IBVSTwist(std::vector<VSXYZ> desired, std::vector<VSXYZ> pts, cv::Mat error_mat)
00488 {
00489 cv::Mat im;
00490 if (im.cols != 1 || im.rows != 6)
00491 im = im.reshape(1, 6);
00492
00493
00494 if (pts.size() != desired.size())
00495 return visual_servo::VisualServoTwist();
00496
00497 im = getMeterInteractionMatrix(pts);
00498 return computeTwist(error_mat, im, optical_frame_);
00499 }
00500
00501
00502 visual_servo::VisualServoTwist IBVSTwist(std::vector<PoseStamped> desired, std::vector<PoseStamped> pts)
00503 {
00504 cv::Mat error_mat;
00505 cv::Mat im;
00506
00507
00508 if (pts.size() != desired.size())
00509 return visual_servo::VisualServoTwist();
00510
00511
00512
00513 for (unsigned int i = 0; i < desired.size(); i++)
00514 {
00515 cv::Mat error = cv::Mat::zeros(2, 1, CV_32F);
00516 error.at<float>(0,0) = (pts.at(i)).pose.position.x -
00517 (desired.at(i)).pose.position.x;
00518 error.at<float>(1,0) = (pts.at(i)).pose.position.y -
00519 (desired.at(i)).pose.position.y;
00520 error_mat.push_back(error);
00521 }
00522
00523 im = getMeterInteractionMatrix(pts);
00524 std::string of = pts.at(0).header.frame_id;
00525 return computeTwist(error_mat, im, of);
00526 }
00527
00528 visual_servo::VisualServoTwist computeTwist(cv::Mat error_mat, cv::Mat im, std::string optical_frame)
00529 {
00530
00531 if (countNonZero(im) == 0) return visual_servo::VisualServoTwist();
00532
00533
00534 cv::Mat iim;
00535 switch (jacobian_type_)
00536 {
00537 case JACOBIAN_TYPE_INV:
00538 iim = (im).inv();
00539 break;
00540 case JACOBIAN_TYPE_PSEUDO:
00541 iim = pseudoInverse(im);
00542 break;
00543 default:
00544
00545
00546 if (!desired_jacobian_set_)
00547 return visual_servo::VisualServoTwist();
00548
00549 cv::Mat temp = desired_jacobian_ + im;
00550 iim = 0.5 * pseudoInverse(temp);
00551 }
00552
00553
00554 cv::Mat gain = cv::Mat::eye(6,6, CV_32F);
00555
00556
00557 cv::Mat temp = gain*iim*error_mat;
00558 return transformVelocity(temp);
00559 }
00560
00561 cv::Mat pseudoInverse(cv::Mat im)
00562 {
00563 return (im.t() * im).inv()*im.t();
00564 }
00565
00572 cv::Mat getMeterInteractionMatrix(std::vector<PoseStamped> &pts)
00573 {
00574 int size = (int)pts.size();
00575
00576 cv::Mat L = cv::Mat::zeros(size*2, 6,CV_32F);
00577
00578
00579 for (int i = 0; i < size; i++) {
00580 PoseStamped ps = pts.at(i);
00581 float x = ps.pose.position.x;
00582 float y = ps.pose.position.y;
00583 float Z = ps.pose.position.z;
00584 if (Z < 0.01 || Z > 0.95)
00585 {
00586 ROS_ERROR("Incorrect Z (%f). Cannot Compute Jacobian", Z);
00587 return cv::Mat::zeros(size*2, 6, CV_32F);
00588 }
00589
00590 int l = i * 2;
00591 if (isnan(Z)) return cv::Mat::zeros(6,6, CV_32F);
00592 L.at<float>(l,0) = -1/Z; L.at<float>(l+1,0) = 0;
00593 L.at<float>(l,1) = 0; L.at<float>(l+1,1) = -1/Z;
00594 L.at<float>(l,2) = x/Z; L.at<float>(l+1,2) = y/Z;
00595 L.at<float>(l,3) = x*y; L.at<float>(l+1,3) = (1 + pow(y,2));
00596 L.at<float>(l,4) = -(1+pow(x,2)); L.at<float>(l+1,4) = -x*y;
00597 L.at<float>(l,5) = y; L.at<float>(l+1,5) = -x;
00598 }
00599 return L;
00600 }
00601
00602 cv::Mat getMeterInteractionMatrix(std::vector<VSXYZ> &pts)
00603 {
00604 int size = (int)pts.size();
00605
00606 cv::Mat L = cv::Mat::zeros(size*2, 6,CV_32F);
00607
00608
00609 for (int i = 0; i < size; i++) {
00610 pcl::PointXYZ xyz= pts.at(i).camera;
00611 float x = xyz.x;
00612 float y = xyz.y;
00613 float Z = xyz.z;
00614 if (Z < 0.01 || Z > 0.95)
00615 {
00616 ROS_ERROR("Incorrect Z (%f). Cannot Compute Jacobian", Z);
00617 return cv::Mat::zeros(size*2, 6, CV_32F);
00618 }
00619
00620 int l = i * 2;
00621 if (isnan(Z)) return cv::Mat::zeros(6,6, CV_32F);
00622 L.at<float>(l,0) = -1/Z; L.at<float>(l+1,0) = 0;
00623 L.at<float>(l,1) = 0; L.at<float>(l+1,1) = -1/Z;
00624 L.at<float>(l,2) = x/Z; L.at<float>(l+1,2) = y/Z;
00625 L.at<float>(l,3) = x*y; L.at<float>(l+1,3) = (1 + pow(y,2));
00626 L.at<float>(l,4) = -(1+pow(x,2)); L.at<float>(l+1,4) = -x*y;
00627 L.at<float>(l,5) = y; L.at<float>(l+1,5) = -x;
00628 }
00629 return L;
00630 }
00631
00632
00633
00634
00641 cv::Mat projectImagePointToPoint(cv::Point in)
00642 {
00643 if (K.rows == 0 || K.cols == 0) {
00644
00645
00646 K = cv::Mat(cv::Size(3,3), CV_64F, &(cam_info_.K));
00647 K.convertTo(K, CV_32F);
00648 }
00649
00650 cv::Mat k_inv = K.inv();
00651
00652 cv::Mat mIn = cv::Mat(3,1,CV_32F);
00653 mIn.at<float>(0,0) = in.x;
00654 mIn.at<float>(1,0) = in.y;
00655 mIn.at<float>(2,0) = 1;
00656 return k_inv * mIn;
00657 }
00658
00665 cv::Mat projectImageMatToPoint(cv::Mat in)
00666 {
00667 cv::Point p(in.at<float>(0,0), in.at<float>(1,0));
00668 return projectImagePointToPoint(p);
00669 }
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682 cv::Point projectPointIntoImage(PointStamped cur_point,
00683 std::string target_frame, shared_ptr<tf::TransformListener> tf_)
00684 {
00685 if (K.rows == 0 || K.cols == 0) {
00686
00687 K = cv::Mat(cv::Size(3,3), CV_64F, &(cam_info_.K));
00688 K.convertTo(K, CV_32F);
00689 }
00690 cv::Point img_loc;
00691 try
00692 {
00693
00694 PointStamped image_frame_loc_m;
00695 tf_->transformPoint(target_frame, cur_point, image_frame_loc_m);
00696
00697 img_loc.x = static_cast<int>((K.at<float>(0,0)*image_frame_loc_m.point.x +
00698 K.at<float>(0,2)*image_frame_loc_m.point.z) /
00699 image_frame_loc_m.point.z);
00700 img_loc.y = static_cast<int>((K.at<float>(1,1)*image_frame_loc_m.point.y +
00701 K.at<float>(1,2)*image_frame_loc_m.point.z) /
00702 image_frame_loc_m.point.z);
00703 }
00704 catch (tf::TransformException e)
00705 {
00706 ROS_ERROR_STREAM(e.what());
00707 }
00708 return img_loc;
00709 }
00710
00711 float getZValue(cv::Mat depth_frame, int x, int y)
00712 {
00713 int window_size = 3;
00714 float value = 0;
00715 int size = 0;
00716 for (int i = 0; i < window_size; i++)
00717 {
00718 for (int j = 0; j < window_size; j++)
00719 {
00720
00721 float temp = depth_frame.at<float>(y-(int)(window_size/2)+j, x-(int)(window_size/2)+i);
00722
00723 if (!isnan(temp) && temp > 0 && temp < 2.0)
00724 {
00725 size++;
00726 value += temp;
00727 }
00728 else
00729 {
00730 }
00731 }
00732 }
00733 if (size == 0)
00734 return -1;
00735 return value/size;
00736 }
00737
00738 visual_servo::VisualServoTwist transformVelocity(cv::Mat in)
00739 {
00740 ros::Time now = ros::Time(0);
00741 listener_.lookupTransform(workspace_frame_, optical_frame_, now, transform);
00742
00743
00744 tf::Vector3 twist_rot(in.at<float>(3), in.at<float>(4), in.at<float>(5));
00745 tf::Vector3 twist_vel(in.at<float>(0), in.at<float>(1), in.at<float>(2));
00746
00747
00748 tf::Vector3 out_rot = transform.getBasis() * twist_rot;
00749 tf::Vector3 out_vel = transform.getBasis() * twist_vel + transform.getOrigin().cross(out_rot);
00750
00751 std::vector<double> vels;
00752 vels.push_back(out_vel.x()*gain_vel_);
00753 vels.push_back(out_vel.y()*gain_vel_);
00754 vels.push_back(out_vel.z()*gain_vel_);
00755 vels.push_back(out_rot.x()*gain_rot_);
00756 vels.push_back(out_rot.y()*gain_rot_);
00757 vels.push_back(out_rot.z()*gain_rot_);
00758 return VisualServoMsg::createTwistMsg(1.0, vels);
00759 }
00760
00761
00762 void printMatrix(cv::Mat_<double> in)
00763 {
00764 for (int i = 0; i < in.rows; i++) {
00765 for (int j = 0; j < in.cols; j++) {
00766 printf("%+.5f\t", in(i,j));
00767 }
00768 printf("\n");
00769 }
00770 }
00771 };