Go to the documentation of this file.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 #include "pr2_interactive_manipulation/graspable_object_handler.h"
00031
00032 #include <visualization_msgs/InteractiveMarker.h>
00033 #include <visualization_msgs/InteractiveMarkerFeedback.h>
00034
00035 #include "pr2_interactive_manipulation/interactive_marker_node.h"
00036
00037 using namespace visualization_msgs;
00038 using namespace interactive_markers;
00039
00040 namespace pr2_interactive_manipulation
00041 {
00042
00043 GraspableObjectHandler::GraspableObjectHandler( std::string name,
00044 InteractiveMarkerNode *node,
00045 const object_manipulation_msgs::GraspableObject &object,
00046 const arm_navigation_msgs::Shape &mesh,
00047 interactive_markers::InteractiveMarkerServer &marker_server,
00048 pr2_object_manipulation_msgs::IMGUIOptions &options,
00049 tabletop_collision_map_processing::CollisionMapInterface *col ) :
00050 marker_server_(marker_server),
00051 im_gui_action_client_("imgui_action", false),
00052 options_(options),
00053 object_(object),
00054 mesh_(mesh),
00055 use_rec_result_(true),
00056 collision_map_interface_(col),
00057 use_rec_result_h_(0),
00058 name_(name),
00059 interactive_marker_node_(node)
00060 {
00061 makeMenu();
00062 makeMarker();
00063 }
00064
00065 GraspableObjectHandler::~GraspableObjectHandler()
00066 {
00067 marker_server_.erase(name_);
00068 }
00069
00070 void GraspableObjectHandler::makeMenu()
00071 {
00072
00073 MenuHandler::EntryHandle pickup_h = menu_handler_.insert( "Pick Up" );
00074 left_pickup_h_ = menu_handler_.insert( pickup_h, "Using Left Arm",
00075 boost::bind( &GraspableObjectHandler::pickup, this, _1) );
00076 right_pickup_h_ = menu_handler_.insert( pickup_h, "Using Right Arm",
00077 boost::bind( &GraspableObjectHandler::pickup, this, _1) );
00078
00079 add_collision_object_h_ = menu_handler_.insert("Add Collision Object",
00080 boost::bind( &GraspableObjectHandler::addCollisionObject, this, _1));
00081
00082
00083 if ( mesh_.triangles.size() > 0 && object_.cluster.points.size() > 0 )
00084 {
00085 use_rec_result_h_ = menu_handler_.insert( "Use Recognition Result",
00086 boost::bind( &GraspableObjectHandler::switchFlag, this, &use_rec_result_, _1) );
00087 }
00088
00089 menu_handler_.insert( "Advanced options..",
00090 visualization_msgs::MenuEntry::ROSRUN,
00091 "dynamic_reconfigure reconfigure_gui " + ros::this_node::getName() );
00092
00093 updateMenu();
00094 }
00095
00096 void GraspableObjectHandler::updateMenu()
00097 {
00098 if ( use_rec_result_h_ )
00099 {
00100 menu_handler_.setCheckState( use_rec_result_h_, use_rec_result_ ? MenuHandler::CHECKED : MenuHandler::UNCHECKED );
00101 }
00102
00103 menu_handler_.reApply( marker_server_ );
00104 marker_server_.applyChanges();
00105 }
00106
00107 void GraspableObjectHandler::addCollisionObject( const InteractiveMarkerFeedbackConstPtr &feedback )
00108 {
00109 ros::Time start_time = ros::Time::now();
00110 while (!collision_map_interface_->connectionsEstablished(ros::Duration(1.0)) )
00111 {
00112 ROS_INFO("Waiting for collision map services");
00113 if (ros::Time::now() - start_time >= ros::Duration(5.0))
00114 {
00115 ROS_ERROR("collision map services not found");
00116 return;
00117 }
00118 }
00119 try
00120 {
00121 if (!object_.potential_models.empty())
00122 {
00123 collision_map_interface_->processCollisionGeometryForObject(object_.potential_models[0], collision_object_name_);
00124 }
00125 else
00126 {
00127 object_manipulation_msgs::ClusterBoundingBox bbox;
00128 collision_map_interface_->getClusterBoundingBox(object_.cluster, bbox.pose_stamped, bbox.dimensions);
00129 collision_map_interface_->processCollisionGeometryForBoundingBox(bbox, collision_object_name_);
00130 }
00131 }
00132 catch (tabletop_collision_map_processing::CollisionMapException &ex)
00133 {
00134 ROS_ERROR_STREAM("Exception adding object to collision map: " << ex.what());
00135 return;
00136 }
00137 ROS_INFO_STREAM("Object added to collision map as " << collision_object_name_);
00138 object_.collision_name = collision_object_name_;
00139 }
00140
00141 void GraspableObjectHandler::pickup( const InteractiveMarkerFeedbackConstPtr &feedback )
00142 {
00143
00144 MenuHandler::EntryHandle arm_h = feedback->menu_entry_id;
00145 if ( arm_h == left_pickup_h_ ) options_.arm_selection = 1;
00146 else if ( arm_h == right_pickup_h_ ) options_.arm_selection = 0;
00147 else return;
00148
00149
00150 ROS_INFO_STREAM( "Picking up object # " << feedback->marker_name );
00151
00152 object_manipulation_msgs::GraspableObject object = object_;
00153
00154 if ( !use_rec_result_ )
00155 {
00156 object.potential_models.clear();
00157 }
00158
00159 pr2_object_manipulation_msgs::IMGUIGoal goal;
00160 goal.options = options_;
00161 goal.options.grasp_selection = 1;
00162 goal.options.selected_object = object;
00163 goal.options.movable_obstacles = interactive_marker_node_->getMovableObstacles();
00164 goal.command.command = goal.command.PICKUP;
00165
00166 im_gui_action_client_.sendGoal(goal);
00167
00168 marker_server_.clear();
00169 marker_server_.applyChanges();
00170 }
00171
00172
00173 void GraspableObjectHandler::makeMarker()
00174 {
00175 InteractiveMarker int_marker;
00176 int_marker.name = name_;
00177
00178 Marker marker;
00179 marker.color.r = 0.0;
00180 marker.color.g = 1.0;
00181 marker.color.b = 0.0;
00182 marker.color.a = 0.5;
00183 marker.frame_locked = false;
00184
00185 if ( use_rec_result_ && mesh_.type == arm_navigation_msgs::Shape::MESH && mesh_.vertices.size() > 0 )
00186 {
00187 int_marker.pose = object_.potential_models[0].pose.pose;
00188 int_marker.header = object_.potential_models[0].pose.header;
00189
00190 marker.type = Marker::TRIANGLE_LIST;
00191
00192 ROS_INFO_STREAM( "Adding mesh. #triangles=" << mesh_.triangles.size() );
00193
00194 marker.points.reserve( mesh_.triangles.size()*3 );
00195
00196 size_t num_t = mesh_.triangles.size();
00197 for ( size_t t=0; t+2<num_t; t+=3 )
00198 {
00199 if ( (size_t)mesh_.triangles[t] < mesh_.vertices.size() &&
00200 (size_t)mesh_.triangles[t+1] < mesh_.vertices.size() &&
00201 (size_t)mesh_.triangles[t+2] < mesh_.vertices.size() )
00202 {
00203 marker.points.push_back( mesh_.vertices[ mesh_.triangles[t] ] );
00204 marker.points.push_back( mesh_.vertices[ mesh_.triangles[t+1] ] );
00205 marker.points.push_back( mesh_.vertices[ mesh_.triangles[t+2] ] );
00206 }
00207 else
00208 {
00209 ROS_ERROR("Mesh contains invalid triangle!");
00210 break;
00211 }
00212 }
00213 }
00214 else
00215 {
00216 int_marker.header = object_.cluster.header;
00217 marker.scale.x = 0.005;
00218 marker.scale.y = 0.005;
00219 marker.scale.z = 0.005;
00220 marker.type = Marker::CUBE_LIST;
00221
00222 marker.points.resize( object_.cluster.points.size() );
00223 marker.colors.resize( object_.cluster.points.size() );
00224
00225 ROS_INFO_STREAM( "Adding point cluster. #points=" << object_.cluster.points.size() );
00226 bool use_color = false;
00227 if(object_.cluster.channels.size() != 0 && object_.cluster.channels[0].name == "rgb") use_color = true;
00228 for ( size_t i=0; i<object_.cluster.points.size(); i++)
00229 {
00230 marker.points[i].x = object_.cluster.points[i].x;
00231 marker.points[i].y = object_.cluster.points[i].y;
00232 marker.points[i].z = object_.cluster.points[i].z;
00233 if(use_color)
00234 {
00235 uint32_t rgb = *reinterpret_cast<int*>(&object_.cluster.channels[0].values[i]);
00236 marker.colors[i].r = ((rgb >> 16) & 0x0000ff)/255. * 0.5;
00237 marker.colors[i].g = ((rgb >> 8) & 0x0000ff)/255. * 1.5;
00238 marker.colors[i].b = (rgb & 0x0000ff)/255. * 0.5;
00239 marker.colors[i].a = 1.0;
00240 if(marker.colors[i].g > 1.0) marker.colors[i].g = 1.0;
00241 else if(marker.colors[i].g < 0.5) marker.colors[i].g = 0.5;
00242 }
00243 }
00244 }
00245
00246 InteractiveMarkerControl control;
00247 control.always_visible = true;
00248 control.interaction_mode = InteractiveMarkerControl::MENU;
00249 control.orientation_mode = InteractiveMarkerControl::INHERIT;
00250
00251 control.markers.push_back( marker );
00252
00253 int_marker.controls.push_back( control );
00254
00255 marker_server_.insert( int_marker );
00256 menu_handler_.apply( marker_server_, int_marker.name );
00257 marker_server_.applyChanges();
00258 }
00259
00260
00261 void GraspableObjectHandler::switchFlag( bool *value,
00262 const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback )
00263 {
00264 *value = !(bool)(*value);
00265 makeMarker();
00266 updateMenu();
00267 }
00268
00269
00270 }