00001 #include <ros/ros.h>
00002
00003 #include <pcl_ros/transforms.h>
00004
00005 #include <tf/tf.h>
00006 #include <tf/transform_listener.h>
00007 #include <tf/transform_broadcaster.h>
00008
00009 #include <visualization_msgs/Marker.h>
00010 #include <visualization_msgs/MarkerArray.h>
00011
00012 #include <object_manipulator/tools/shape_tools.h>
00013
00014
00015 #include "gripper_model.h"
00016 \
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 GripperModel DEFAULT_GRIPPER;
00028
00029 void GripperModel::toPoseStamped(geometry_msgs::PoseStamped &ps)
00030 {
00031 tf::pointTFToMsg(wrist_frame_.getOrigin(), ps.pose.position);
00032 tf::quaternionTFToMsg(wrist_frame_.getRotation(), ps.pose.orientation);
00033 ps.header.frame_id = this->header.frame_id;
00034 ps.header.stamp = this->header.stamp;
00035 }
00036
00037
00038 void GripperModel::transform(const geometry_msgs::Transform &T, const std::string &frame_id){
00039 tf::Transform tfT;
00040 tf::transformMsgToTF(T, tfT);
00041 transform(tfT, frame_id);
00042 }
00043
00044 void GripperModel::transform(const tf::Transform &T, const std::string &frame_id){
00045 palm_.transform(T);
00046 l_finger_.transform(T);
00047 r_finger_.transform(T);
00048 space_.transform(T);
00049 tool_frame_= T*tool_frame_;
00050 extended_.transform(T);
00051 wrist_frame_ = T*wrist_frame_;
00052 bounding_box_.transform(T);
00053 roi_box_.transform(T);
00054
00055 setFrameId(frame_id.c_str());
00056 }
00057
00058 void GripperModel::setFrameId(const std::string &frame_id)
00059 {
00060 if(!frame_id.empty())
00061 {
00062 header.frame_id = frame_id;
00063 palm_.header.frame_id = frame_id;
00064 l_finger_.header.frame_id = frame_id;
00065 r_finger_.header.frame_id = frame_id;
00066 space_.header.frame_id = frame_id;
00067 extended_.header.frame_id = frame_id;
00068 bounding_box_.header.frame_id = frame_id;
00069 roi_box_.header.frame_id = frame_id;
00070 }
00071 }
00072
00073 void GripperModel::setStamp(const ros::Time &stamp)
00074 {
00075 header.stamp = stamp;
00076 palm_.header.stamp = stamp;
00077 l_finger_.header.stamp = stamp;
00078 r_finger_.header.stamp = stamp;
00079 space_.header.stamp = stamp;
00080 extended_.header.stamp = stamp;
00081 bounding_box_.header.stamp = stamp;
00082 roi_box_.header.stamp = stamp;
00083 }
00084
00085 void GripperModel::setHeader(const std_msgs::Header &header)
00086 {
00087 this->setFrameId(header.frame_id.c_str());
00088 this->setStamp(header.stamp);
00089 }
00090
00091 void GripperModel::reset( bool resetStateAndScore)
00092 {
00093
00094
00095
00096
00097
00098
00099 wrist_frame_.setOrigin(tf::Vector3(0,0,0));
00100 wrist_frame_.setRotation(tf::Quaternion(0,0,0,1));
00101 header.frame_id = "r_wrist_roll_link";
00102
00103
00104 palm_ = Box( tf::Pose( tf::Quaternion(0,0,0,1),
00105 tf::Vector3( (.04 + .138)/2, 0, 0 ) ),
00106 tf::Vector3(0.138-0.04, 0.0755 + 0.0755, 0.026 + 0.026) );
00107 l_finger_ = Box( tf::Pose( tf::Quaternion(0,0,0,1),
00108 tf::Vector3( (0.185 + 0.138)/2, (0.0425 + 0.0755)/2, 0 ) ),
00109 tf::Vector3( 0.185 - 0.138, 0.0755 - 0.0425, 0.0115 + 0.0115) );
00110
00111 r_finger_ = Box( tf::Pose( tf::Quaternion(0,0,0,1),
00112 tf::Vector3( (0.185 + 0.138)/2, -(0.0425 + 0.0755)/2, 0 ) ),
00113 tf::Vector3( 0.185 - 0.138, 0.0755 - 0.0425, 0.0115 + 0.0115) );
00114
00115 space_ = Box( tf::Pose( tf::Quaternion(0,0,0,1),
00116 tf::Vector3( (0.175 + .138)/2, 0, 0 ) ),
00117 tf::Vector3(0.175-0.138, 0.015 + 0.015, 0.0075 + 0.0075) );
00118
00119 extended_ = Box( tf::Pose( tf::Quaternion(0,0,0,1),
00120 tf::Vector3( (0.175 + .138)/2, 0, 0 ) ),
00121 tf::Vector3(0.175-0.138, 0.0405 + 0.0405, 0.02 + 0.02) );
00122
00123 bounding_box_ = Box( tf::Pose( tf::Quaternion(0,0,0,1),
00124 tf::Vector3( 0.1, 0, 0 ) ),
00125 tf::Vector3(0.2, 0.2, 0.2) );
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 roi_box_ = Box( tf::Pose( tf::Quaternion(0,0,0,1),
00153 tf::Vector3( 0.25, 0, 0 ) ),
00154 tf::Vector3(0.3, 0.18, 0.18) );
00155
00156 tool_frame_ = tf::Pose( tf::Quaternion(0,0,0,1),
00157 tf::Vector3(0.15, 0, 0) );
00158
00159 if( resetStateAndScore )
00160 {
00161 score_ = 0;
00162 state_.reset();
00163 }
00164 }
00165
00166
00167 void GripperModel::publishModel(ros::Publisher &pub, std::string ns, int id, ros::Duration lifetime, double opacity, int action)
00168 {
00169
00170 if(pub.getNumSubscribers() < 1)
00171 return;
00172
00173 std_msgs::ColorRGBA red = object_manipulator::msg::createColorMsg(0.8, 0.2, 0.2, opacity);
00174 std_msgs::ColorRGBA green = object_manipulator::msg::createColorMsg(0.2, 1.0, 0.2, opacity);
00175 std_msgs::ColorRGBA light_blue = object_manipulator::msg::createColorMsg(0.2, 0.7, 0.8, opacity);
00176 std_msgs::ColorRGBA gray = object_manipulator:: msg::createColorMsg(0.5, 0.5, 0.5, opacity);
00177
00178 visualization_msgs::MarkerArray array;
00179 visualization_msgs::Marker marker;
00180
00181 marker.lifetime = lifetime;
00182 marker.header = this->header;
00183 marker.ns = "gripper_model_" + ns;
00184 marker.type = visualization_msgs::Marker::CUBE;
00185 marker.action = action;
00186
00187 int num_markers = 6;
00188
00189 marker.id = num_markers*id + 0;
00190 tf::poseTFToMsg(this->palm_.frame, marker.pose);
00191 tf::vector3TFToMsg(this->palm_.dims, marker.scale);
00192 marker.color = this->state_.collide_palm?(red):(gray);
00193 array.markers.push_back(marker);
00194
00195 marker.id = num_markers*id + 1;
00196 tf::poseTFToMsg(this->l_finger_.frame, marker.pose);
00197 tf::vector3TFToMsg(this->l_finger_.dims, marker.scale);
00198 marker.color = this->state_.collide_l?(red):(gray);
00199 array.markers.push_back(marker);
00200
00201 marker.id = num_markers*id + 2;
00202 tf::poseTFToMsg(this->r_finger_.frame, marker.pose);
00203 tf::vector3TFToMsg(this->r_finger_.dims, marker.scale);
00204 marker.color = this->state_.collide_r?(red):(gray);
00205 array.markers.push_back(marker);
00206
00207 marker.id =num_markers*id + 3;
00208 tf::poseTFToMsg(this->space_.frame, marker.pose);
00209 tf::vector3TFToMsg(this->space_.dims, marker.scale);
00210 marker.color = this->state_.valid?(green):(gray);
00211 array.markers.push_back(marker);
00212
00213 marker.id = num_markers*id + 4;
00214 tf::poseTFToMsg(this->extended_.frame, marker.pose);
00215 tf::vector3TFToMsg(this->extended_.dims, marker.scale);
00216 marker.color = light_blue;
00217 array.markers.push_back(marker);
00218
00219 marker.id = num_markers*id + 5;
00220 marker.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
00221 tf::Pose text_frame = palm_.frame;
00222 text_frame.setOrigin(text_frame.getOrigin()
00223 - text_frame.getBasis().getColumn(0)*palm_.dims.getX()/1.9
00224 - text_frame.getBasis().getColumn(1)*palm_.dims.getY()/1.8);
00225 tf::poseTFToMsg(text_frame, marker.pose);
00226 marker.scale.z = 0.07;
00227 char text[10];
00228 sprintf(text, "% 2d", id);
00229 marker.text = text;
00230 marker.color = object_manipulator::msg::createColorMsg(0.8, 0.2, 0.2, 0.8);
00231 array.markers.push_back(marker);
00232
00233 pub.publish(array);
00234 }
00235
00245 double GripperModel::evaluateGrasp(const pcl::PointCloud<PointT> &cloud,
00246 FeatureWeights &weights,
00247 tf::Vector3 default_centroid,
00248 bool debug_print,
00249 bool weights_as_output_features)
00250 {
00251 GripperModel* model = this;
00252
00253 pcl::PointCloud<PointT> transformed;
00254 pcl::PointCloud<PointT> filtered;
00255
00256 FeatureWeights features(0, 0, 0, 0, 0, 0);
00257
00258 {
00259
00260 pcl_ros::transformPointCloudWithNormals(cloud, transformed, model->wrist_frame_.inverse());
00261 default_centroid = model->wrist_frame_.inverse()*default_centroid;
00262 }
00263
00264
00265
00266
00267
00268 int collisions = 0;
00269 {
00270
00271 model->state_.reset();
00272
00273 box_filter(transformed, filtered, DEFAULT_GRIPPER.palm_, false, false );
00274 if(filtered.points.size() != 0) model->state_.set(GraspState::COLLIDE_PALM);
00275 collisions += filtered.points.size();
00276
00277 box_filter(transformed, filtered, DEFAULT_GRIPPER.l_finger_, false, false );
00278 if(filtered.points.size() != 0) model->state_.set(GraspState::COLLIDE_L);
00279 collisions += filtered.points.size();
00280
00281 box_filter(transformed, filtered, DEFAULT_GRIPPER.r_finger_, false, false );
00282 if(filtered.points.size() != 0) model->state_.set(GraspState::COLLIDE_R);
00283 collisions += filtered.points.size();
00284
00285 box_filter(transformed, filtered, DEFAULT_GRIPPER.space_, false, false);
00286 }
00287 features.collision = collisions;
00288
00289
00290 int points_enclosed = filtered.points.size();
00291 features.point = pow(points_enclosed, 0.25);
00292
00293
00294
00295 if(!model->state_.inCollision()) {
00296 if(filtered.points.size() < 20)
00297 model->state_.set(GraspState::NO_OBJECT);
00298 else
00299 model->state_.set(GraspState::VALID);
00300 }
00301
00302
00303
00304
00305 box_filter(transformed, filtered, DEFAULT_GRIPPER.extended_, false, true );
00306
00307 double normal_cost = 0;
00308 int count[4] = {0, 0, 0, 0};
00309 double PIby4 = M_PI/4;
00310
00311 tf::Vector3 centroid(0, 0, 0);
00312 double fraction = 0;
00313
00314 double Iyz = 0;
00315
00316 if(filtered.points.size() > 0)
00317 {
00318
00319 for(unsigned int i = 0; i < filtered.points.size(); i++ )
00320 {
00321 PointT point = filtered.points[i];
00322
00323 tf::Vector3 norm = tf::Vector3(point.normal[0], point.normal[1], point.normal[2]);
00324 double this_dot = norm.dot(tf::Vector3(1,0,0));
00325 normal_cost += 1-pow(cos(2*(acos(this_dot) - PIby4)),2);
00326
00327
00328 centroid += tf::Vector3(point.x, point.y, point.z);
00329
00330
00331 if( fabs(this_dot) > 0.707 )
00332 {
00333 if(point.z > 0 && point.y > 0) count[0] += 1;
00334 if(point.z < 0 && point.y > 0) count[1] += 1;
00335 if(point.z < 0 && point.y < 0) count[2] += 1;
00336 if(point.z > 0 && point.y < 0) count[3] += 1;
00337 Iyz += point.y * point.z;
00338 }
00339 }
00340
00341 int max_count = 1;
00342 int min_count = 100000;
00343 for(int i = 0; i < 4; i++)
00344 {
00345 min_count = std::min(min_count, count[i]);
00346 max_count = std::max(max_count, count[i]);
00347 }
00348
00349 fraction = (min_count / (double)max_count );
00350 centroid /= filtered.points.size();
00351 features.normal = normal_cost/(filtered.points.size() + 1);
00352 features.symmetry = (min_count / (double)max_count ) * ((points_enclosed > 20)?(1):(points_enclosed/20.0));
00353 Iyz *=100;
00354 features.Iyz = fabs(Iyz);
00355 if(debug_print)
00356 {
00357 ROS_INFO("Counts: % 4d % 4d % 4d % 4d, frac %.3f, Iyz %f", count[0], count[1], count[2], count[3], fraction, Iyz);
00358 }
00359 }
00360 else{
00361 centroid = default_centroid;
00362 }
00363
00364 tf::Vector3 palm_center = DEFAULT_GRIPPER.palm_.frame.getOrigin() + tf::Vector3(DEFAULT_GRIPPER.palm_.dims.getX()/2 + 0.005, 0, 0);
00365 features.centroid = (centroid - palm_center).length();
00366
00367 double quality = 0.0;
00368 if( weights_as_output_features )
00369 {
00370 weights = features;
00371 }
00372 else
00373 {
00374
00375 quality = weights.symmetry * features.symmetry
00376 + weights.Iyz * features.Iyz
00377 + weights.normal * features.normal
00378 + weights.point * features.point
00379 + weights.centroid * features.centroid
00380 + weights.collision * features.collision;
00381 }
00382
00383 double max_quality = weights.normal + weights.symmetry;
00384 double min_quality = 0;
00385 double score = std::max(std::min(quality, max_quality), min_quality)/max_quality;
00386
00387 if(debug_print)
00388 {
00389
00390 geometry_msgs::Transform msg;
00391 tf::transformTFToMsg(model->wrist_frame_, msg);
00392
00393 geometry_msgs::Vector3 msg2;
00394 geometry_msgs::Vector3 msg3;
00395 tf::vector3TFToMsg(centroid, msg2);
00396 tf::vector3TFToMsg(palm_center, msg3);
00397
00398
00399
00400 ROS_INFO( "Quality = sym % 7.3f + iyz % 7.3f + nor % 7.3f + pnt % 7.3f + cen % 7.3f + col % 7.3f = % 7.3f -> score= % 6.4f",
00401 weights.symmetry * features.symmetry
00402 , weights.Iyz * features.Iyz
00403 , weights.normal * features.normal
00404 , weights.point * features.point
00405 , weights.centroid * features.centroid
00406 , weights.collision * features.collision
00407 , quality
00408 , score);
00409
00410
00411 }
00412
00413 model->score_ = score;
00414 return score;
00415 }
00416