00001
00002
00003
00004
00005 #include "ros/ros.h"
00006 #include <sensor_msgs/PointCloud2.h>
00007 #include <geometry_msgs/PoseStamped.h>
00008 #include <geometry_msgs/Pose.h>
00009 #include <tf/transform_datatypes.h>
00010 #include <pcl_ros/transforms.h>
00011 #include <pcl/ros/conversions.h>
00012 #include <sensor_msgs/point_cloud_conversion.h>
00013
00014 #include "tools.h"
00015
00016
00017
00018
00019 #include <iostream>
00020
00021 #include <tf/transform_listener.h>
00022
00023
00024 tf::TransformListener* tflistener;
00025 ros::Publisher handle_pub, pc_pub, vis_pub, pregrasp_pub, postgrasp_pub, grasp_pub;
00026 std::string global_checkerboard_frame;
00027 std::string global_torso_frame;
00028
00029
00030 void poseCallback(const geometry_msgs::PoseStamped::ConstPtr& msg)
00031 {
00032
00033 tf::StampedTransform door_to_torso;
00034 if(tflistener->waitForTransform(global_torso_frame, msg->header.frame_id, msg->header.stamp, ros::Duration(0.5))){
00035 tflistener->lookupTransform(global_torso_frame, msg->header.frame_id, msg->header.stamp, door_to_torso);
00036 } else {
00037 ROS_WARN("No tranform from %s to %s available", msg->header.frame_id.c_str(), global_torso_frame.c_str());
00038 return;
00039 }
00040 tf::Stamped<tf::Pose> handle_pose_in_door_frame;
00041 tf::poseStampedMsgToTF(*msg, handle_pose_in_door_frame);
00043 tf::Transform handle_pose_in_torso_frame = door_to_torso * handle_pose_in_door_frame;
00044 tf::Transform grasp = handle_pose_in_torso_frame * tf::Transform(tf::Quaternion(0,0,0,1), tf::Vector3(0.05,0,0));
00045
00046
00047 tf::Stamped<tf::Pose> graspTF(grasp, msg->header.stamp,global_torso_frame);
00048 geometry_msgs::PoseStamped graspMsg;
00049 tf::poseStampedTFToMsg(graspTF, graspMsg);
00050
00051
00052
00053 tf::Transform pregrasp(handle_pose_in_torso_frame);
00054 pregrasp.getOrigin().setX(pregrasp.getOrigin().getX() - 0.08);
00055 tf::Stamped<tf::Pose> pregraspTF(pregrasp, msg->header.stamp,global_torso_frame);
00056 geometry_msgs::PoseStamped pregraspMsg;
00057 tf::poseStampedTFToMsg(pregraspTF, pregraspMsg);
00058
00059
00060 tf::Vector3 handle_tip_in_handle_frame(0,0,1);
00061 tf::Vector3 handle_tip_in_torso_frame = door_to_torso * handle_pose_in_door_frame * handle_tip_in_handle_frame - handle_pose_in_torso_frame.getOrigin();
00062
00063 tf::Vector3 rotation_axis = handle_tip_in_torso_frame.cross(tf::Vector3(0,0,1));
00064 rotation_axis.normalize();
00065 ROS_DEBUG("rotation_axis (in torso frame) xyz= %f %f %f", rotation_axis.getX(), rotation_axis.getY(), rotation_axis.getY());
00066
00067 tf::Quaternion grasp_to_postgrasp_rot(rotation_axis, -60.0/180.0*3.1415927);
00068 tf::Transform grasp_to_postgrasp(grasp_to_postgrasp_rot, tf::Vector3(0.05,0,0));
00069 tf::Transform postgrasp = grasp * grasp_to_postgrasp;
00070
00071
00072 tf::Stamped<tf::Pose> postgraspTF(postgrasp, msg->header.stamp,global_torso_frame);
00073 geometry_msgs::PoseStamped postgraspMsg;
00074 tf::poseStampedTFToMsg(postgraspTF, postgraspMsg);
00075
00076 if (pregrasp_pub.getNumSubscribers() > 0){
00077 pregrasp_pub.publish(pregraspMsg);
00078 }
00079 if (grasp_pub.getNumSubscribers() > 0){
00080 grasp_pub.publish(graspMsg);
00081 }
00082 if (postgrasp_pub.getNumSubscribers() > 0){
00083 postgrasp_pub.publish(postgraspMsg);
00084 }
00085
00086 }
00087
00088 void pointCloudCallback(const sensor_msgs::PointCloud2::ConstPtr& msg)
00089 {
00090 ROS_DEBUG_THROTTLE(5, "Received a point cloud: [%d, %d, %d] (This message is only printed every 5sec)", msg->width, msg->height, (int)msg->data.size());
00091
00092
00093 tf::StampedTransform torso_transform;
00094 tf::StampedTransform optical_transform;
00095 if(tflistener->waitForTransform(global_torso_frame, global_checkerboard_frame,msg->header.stamp, ros::Duration(0.5))){
00096 tflistener->lookupTransform(global_torso_frame, global_checkerboard_frame, msg->header.stamp, torso_transform);
00097 ROS_DEBUG("Checkerboard xyz= %f %f %f", torso_transform.getOrigin().getX(), torso_transform.getOrigin().getY(), torso_transform.getOrigin().getY());
00098 } else {
00099 ROS_INFO_THROTTLE(30, "No tranform from %s to %s available, probably no checkerboard in sight (or cb-detector not started).", global_torso_frame.c_str(), global_checkerboard_frame.c_str());
00100 return;
00101 }
00102 if(tflistener->waitForTransform(global_checkerboard_frame, msg->header.frame_id, msg->header.stamp, ros::Duration(5.0/30.0))){
00103 tflistener->lookupTransform(global_checkerboard_frame, msg->header.frame_id, msg->header.stamp, optical_transform);
00104 } else {
00105 ROS_WARN("No tranform from %s to %s available", global_checkerboard_frame.c_str(), msg->header.frame_id.c_str());
00106 return;
00107 }
00108
00109
00110
00111 myCloudType::Ptr pc (new myCloudType );
00112
00113 pcl::fromROSMsg(*msg, *pc);
00114 pcl_ros::transformPointCloud(*pc, *pc, optical_transform);
00115
00116
00117 float xmin = -0.10,xmax = 0.25,ymin = 0.00,ymax = 0.32,zmin = -.2 ,zmax = -.03;
00118 if (vis_pub.getNumSubscribers() > 0)
00119 vis_pub.publish(visualize_filter_box(xmin,xmax,ymin,ymax,zmin,zmax, pc->header));
00120 box_filter(pc, xmin,xmax,ymin,ymax,zmin,zmax);
00121
00122 if(pc->points.size() == 0){
00123 ROS_INFO_THROTTLE(5, "Empty Result Set");
00124 ros::Duration(0.5).sleep();
00125 return;
00126 }
00127
00128 pcl_ros::transformPointCloud(*pc, *pc, torso_transform);
00129 pc->header.frame_id =global_torso_frame;
00130 sensor_msgs::PointCloud2 outmsg;
00131 pcl::toROSMsg(*pc,outmsg);
00132 if (pc_pub.getNumSubscribers() > 0)
00133 pc_pub.publish(outmsg);
00134
00135
00136 Eigen::Vector3f mean, principalAxis;
00137 if(!computeMainAxis(*pc, mean, principalAxis, 20.0)) return;
00138
00139 if (!((principalAxis.array() == principalAxis.array())).all() ||
00140 !((mean.array() == mean.array())).all()) ROS_WARN("No valid axis for grasp");
00141 ROS_DEBUG("Mean xyz= %f %f %f", mean(0), mean(1), mean(2));
00142
00143 Eigen::Matrix4f torso_trans_mat;
00144 pcl_ros::transformAsMatrix(torso_transform, torso_trans_mat);
00145 Eigen::Matrix3f torso_rot_mat = torso_trans_mat.block<3,3>(0,0);
00146
00147
00148
00149 Eigen::Vector3f door_normal(0,0,mean(2) - torso_transform.getOrigin().getZ());
00150 door_normal.normalize();
00151 door_normal = torso_rot_mat * door_normal;
00152 Eigen::Vector3f handle_axis(principalAxis);
00153 Eigen::Vector3f y_axis = handle_axis.cross(door_normal);
00154 y_axis.normalize();
00155 door_normal = y_axis.cross(handle_axis);
00156 ROS_DEBUG_STREAM("Door Normal:\n" << door_normal);
00157 ROS_DEBUG_STREAM("Handle Axis:\n" << handle_axis);
00158 ROS_DEBUG_STREAM("Third Axis:\n" << y_axis);
00159 Eigen::Matrix3f grm;
00160 grm << -door_normal, -y_axis, handle_axis;
00161 ROS_DEBUG_STREAM("Desired Gripper Coord Frame\n: " << grm);
00162
00163
00164
00165
00166 tf::Matrix3x3 toGripperTargetCoordFrame(grm(0,0), grm(0,1), grm(0,2),
00167 grm(1,0), grm(1,1), grm(1,2),
00168 grm(2,0), grm(2,1), grm(2,2)) ;
00169
00170 tf::Quaternion gripperRotation;
00171 toGripperTargetCoordFrame.getRotation(gripperRotation);
00172
00173
00174 geometry_msgs::PoseStamped handle_pose = getPoseStamped(mean, gripperRotation);
00175 if (handle_pub.getNumSubscribers() > 0)
00176 handle_pub.publish(handle_pose);
00177
00178
00179
00180
00181
00182
00183
00184
00185 geometry_msgs::PoseStamped pregrasp, grasp, postgrasp;
00186
00187 pregrasp = getPoseStamped(mean+0.16*door_normal, gripperRotation);
00188 pregrasp.header.stamp = msg->header.stamp;
00189 if (pregrasp_pub.getNumSubscribers() > 0)
00190 pregrasp_pub.publish(pregrasp);
00191
00192 grasp = getPoseStamped(mean-(0.03*door_normal), gripperRotation);
00193 grasp.header.stamp = msg->header.stamp;
00194 if (grasp_pub.getNumSubscribers() > 0)
00195 grasp_pub.publish(grasp);
00196
00197 ROS_DEBUG_COND(mean(1) > torso_transform.getOrigin().getY(), "Mean left of checkerboard");
00198 double rot_dir = -1.0;
00199 tf::Quaternion handleRotation(tf::Vector3(door_normal(0),door_normal(1),door_normal(2)), rot_dir/4.0*M_PI );
00200 gripperRotation *= handleRotation;
00201 postgrasp.header.stamp = msg->header.stamp;
00202 postgrasp.header.frame_id = global_torso_frame;
00203 postgrasp.pose.position.x = mean(0)- 0.05 * door_normal(0) + 0.05;
00204 postgrasp.pose.position.y = mean(1)- 0.05 * door_normal(1) + rot_dir * 0.02 * principalAxis(1);
00205 postgrasp.pose.position.z = mean(2)- 0.05 * door_normal(2) - 0.08 ;
00206 postgrasp.pose.orientation.w = gripperRotation.getW();
00207 postgrasp.pose.orientation.x = gripperRotation.getX();
00208 postgrasp.pose.orientation.y = gripperRotation.getY();
00209 postgrasp.pose.orientation.z = gripperRotation.getZ();
00210 if (postgrasp_pub.getNumSubscribers() > 0)
00211 postgrasp_pub.publish(postgrasp);
00212 ROS_INFO_THROTTLE(5, "Published all grasping poses");
00213
00214 }
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 int main(int argc, char **argv)
00228 {
00229 ros::init(argc, argv, "handle_grasp_computation");
00230 ros::NodeHandle n;
00231 tflistener = new tf::TransformListener;
00232 global_checkerboard_frame = "/checkerboard_0";
00233 global_torso_frame = "/torso_lift_link";
00234
00235 pc_pub = n.advertise<sensor_msgs::PointCloud2>("handle_segment", 1);
00236 vis_pub = n.advertise<visualization_msgs::Marker>( "/visualization_marker", 2 );
00237 pregrasp_pub = n.advertise<geometry_msgs::PoseStamped>( "pregrasp", 3 );
00238 grasp_pub = n.advertise<geometry_msgs::PoseStamped>( "grasp", 3 );
00239 postgrasp_pub = n.advertise<geometry_msgs::PoseStamped>( "postgrasp", 3 );
00240 handle_pub = n.advertise<geometry_msgs::PoseStamped>( "handle", 3 );
00241
00242
00243
00244 ros::Subscriber subPC = n.subscribe("cloud_in", 10, pointCloudCallback);
00245 ros::Subscriber subPose = n.subscribe("door_handle", 10, poseCallback);
00246 ROS_INFO("Handle extractor started");
00247
00248 ros::MultiThreadedSpinner spinner(2);
00249 spinner.spin();
00250
00251 }