00001 #include "fetch_pbd_interaction/world.h"
00002
00003 namespace fetch_pbd_interaction {
00004
00005 World::World(ros::NodeHandle n, ros::NodeHandle pn,
00006 const std::string grasp_suggestion_service,
00007 const std::string& segmentation_service_name, const std::string& segmented_objects_topic_name,
00008 const std::string& segmented_table_topic_name, const std::string& planning_scene_topic,
00009 const float& obj_similar_distance_threshold, const float& obj_add_distance_threshold,
00010 const float& obj_nearest_distance_threshold,
00011 const float& obj_distance_zero_clamp, const float& text_h,
00012 const float& surface_h, const float& text_off,
00013 const std::string& base_frame_name)
00014 : im_server("/fetch_pbd/world_objects"){
00015
00016 obj_similar_dist_threshold = obj_similar_distance_threshold;
00017
00018
00019
00020 obj_add_dist_threshold = obj_add_distance_threshold;
00021
00022
00023
00024 obj_nearest_dist_threshold = obj_nearest_distance_threshold;
00025
00026
00027 obj_dist_zero_clamp = obj_distance_zero_clamp;
00028
00029
00030 text_height = text_h;
00031 surface_height = surface_h;
00032 text_offset = text_off;
00033
00034
00035 color_obj = std_msgs::ColorRGBA();
00036 color_obj.r = 0.2;
00037 color_obj.g = 0.8;
00038 color_obj.b = 0.0;
00039 color_obj.a = 0.6;
00040 std_msgs::ColorRGBA color_surface = std_msgs::ColorRGBA();
00041 color_surface.r = 0.8;
00042 color_surface.g = 0.0;
00043 color_surface.b = 0.4;
00044 color_surface.a = 0.4;
00045 std_msgs::ColorRGBA color_text = std_msgs::ColorRGBA();
00046 color_text.r = 0.0;
00047 color_text.g = 0.0;
00048 color_text.b = 0.0;
00049 color_text.a = 0.5;
00050
00051 base_frame = base_frame_name;
00052 marker_duration = ros::Duration(0.0);
00053 segmented_objects_topic = segmented_objects_topic_name;
00054
00055 scale_text = geometry_msgs::Vector3();
00056 scale_text.z = text_height;
00057
00058 add_grasp_pub = n.advertise<fetch_pbd_interaction::Landmark>("/fetch_pbd/add_grasp", 100);
00059 world_update_pub = n.advertise<fetch_pbd_interaction::WorldState>("/fetch_pbd/world_updates", 100);
00060 segmentation_service_client = n.serviceClient<std_srvs::Empty>(segmentation_service_name);
00061 nearest_object_service = n.advertiseService("/fetch_pbd/get_nearest_object", &World::getNearestObjectCallback, this);
00062 object_list_service = n.advertiseService("/fetch_pbd/get_object_list", &World::getObjectListCallback, this);
00063 similar_object_service = n.advertiseService("/fetch_pbd/get_most_similar_object", &World::getMostSimilarObjectCallback, this);
00064 object_from_name_service = n.advertiseService("/fetch_pbd/get_object_from_name", &World::getObjectFromNameCallback, this);
00065 clear_world_objects_service = n.advertiseService("/fetch_pbd/clear_world_objects", &World::clearObjectsCallback, this);
00066 update_world_service = n.advertiseService("/fetch_pbd/update_world", &World::updateWorldCallback, this);
00067
00068 table_subscriber = n.subscribe(segmented_table_topic_name, 1, &World::tablePositionUpdateCallback, this);
00069
00070 has_surface = false;
00071 planning_scene_diff_publisher = n.advertise<moveit_msgs::PlanningScene>(planning_scene_topic, 1);
00072 menu_handler = interactive_markers::MenuHandler();
00073 menu_handler.insert("Remove from scene", boost::bind(&World::removeObject, this, _1));
00074 if (grasp_suggestion_service != ""){
00075 menu_handler.insert("Add grasp", boost::bind(&World::addGrasp, this, _1));
00076 }
00077
00078 }
00079
00080 World::~World() {}
00081
00082
00083 void World::update() {
00084 mutex.lock();
00085 if (hasObjects()) {
00086 for (int i = 0; i < objects.size(); i++){
00087 publishTfPose(objects[i].object.pose,
00088 objects[i].getName(),
00089 base_frame);
00090 }
00091 }
00092 mutex.unlock();
00093 }
00094
00095
00096 void World::pc2ToMarker(sensor_msgs::PointCloud2 pc2, int index,
00097 ros::Duration duration, std::string output_frame,
00098 visualization_msgs::Marker* pc2_marker_points, visualization_msgs::Marker* pc2_marker_sphere_list){
00099 pc2_marker_points->type = visualization_msgs::Marker::POINTS;
00100 pc2_marker_points->id = index;
00101 pc2_marker_points->lifetime=duration;
00102 pc2_marker_points->scale.x = 0.005;
00103 pc2_marker_points->scale.y = 0.005;
00104 pc2_marker_points->scale.z = 0.005;
00105 pc2_marker_points->header.frame_id = pc2.header.frame_id;
00106 pc2_marker_points->pose.orientation.w = 1.0;
00107
00108 pc2_marker_sphere_list->type = visualization_msgs::Marker::SPHERE_LIST;
00109 pc2_marker_sphere_list->id = index + 500;
00110 pc2_marker_sphere_list->lifetime=duration;
00111 pc2_marker_sphere_list->scale.x = 0.007;
00112 pc2_marker_sphere_list->scale.y = 0.007;
00113 pc2_marker_sphere_list->scale.z = 0.007;
00114 pc2_marker_sphere_list->header.frame_id = pc2.header.frame_id;
00115 pc2_marker_sphere_list->pose.orientation.w = 1.0;
00116
00117 pcl::PointCloud<pcl::PointXYZRGB> pc;
00118
00119
00120
00121
00122
00123
00124
00125
00126 pcl::fromROSMsg(pc2, pc);
00127 std::vector<geometry_msgs::Point> points_msgs;
00128 std::vector<std_msgs::ColorRGBA> colors_msgs;
00129 std::vector<std_msgs::ColorRGBA> no_colors_msgs;
00130
00131 for (int i=0; i < pc.points.size(); i++){
00132 pcl::PointXYZRGB point = pc.points[i];
00133 geometry_msgs::Point point_msg;
00134 std_msgs::ColorRGBA color_msg;
00135
00136 point_msg.x = point.x;
00137 point_msg.y = point.y;
00138 point_msg.z = point.z;
00139
00140 color_msg.r = point.r/255.0;
00141 color_msg.g = point.g/255.0;
00142 color_msg.b = point.b/255.0;
00143 color_msg.a = 1.0;
00144
00145 points_msgs.push_back(point_msg);
00146 colors_msgs.push_back(color_msg);
00147
00148 color_msg.a = 0.0;
00149 no_colors_msgs.push_back(color_msg);
00150 }
00151
00152 pc2_marker_points->colors = colors_msgs;
00153 pc2_marker_points->points = points_msgs;
00154 pc2_marker_sphere_list->points = points_msgs;
00155 pc2_marker_sphere_list->colors = no_colors_msgs;
00156
00157 return;
00158 }
00159
00160 float World::objectDissimilarity(fetch_pbd_interaction::Landmark obj1, fetch_pbd_interaction::Landmark obj2){
00161 float dis;
00162
00163 geometry_msgs::Vector3 d1 = obj1.dimensions;
00164 geometry_msgs::Vector3 d2 = obj2.dimensions;
00165 dis = sqrt(pow(d1.x - d2.x,2) + pow(d1.y - d2.y,2) + pow(d1.z - d2.z,2));
00166
00167 return dis;
00168 }
00169
00170 float World::poseDistance(geometry_msgs::Pose pose1, geometry_msgs::Pose pose2, bool is_on_table ){
00171 float dist;
00172 geometry_msgs::Point p1 = pose1.position;
00173 geometry_msgs::Point p2 = pose2.position;
00174 if (is_on_table){
00175 dist = sqrt(pow(p1.x - p2.x,2) + pow(p1.y - p2.y,2));
00176 }
00177 else {
00178 dist = sqrt(pow(p1.x - p2.x,2) + pow(p1.y - p2.y,2) + pow(p1.z - p2.z,2));
00179 }
00180 return dist;
00181 }
00182
00183 visualization_msgs::InteractiveMarker World::getSurfaceMarker(geometry_msgs::Pose pose, geometry_msgs::Vector3 dimensions){
00184 visualization_msgs::InteractiveMarker int_marker;
00185 int_marker.name = "surface";
00186 int_marker.header.frame_id = base_frame;
00187 int_marker.pose = pose;
00188 int_marker.scale = 1.0;
00189 visualization_msgs::Marker marker;
00190 marker.type = visualization_msgs::Marker::CUBE;
00191 marker.id = 2000;
00192 marker.lifetime = marker_duration;
00193 marker.scale = dimensions;
00194 marker.color = color_surface;
00195
00196
00197 visualization_msgs::InteractiveMarkerControl button_control;
00198 button_control.interaction_mode = visualization_msgs::InteractiveMarkerControl::NONE;
00199 button_control.always_visible = true;
00200 button_control.markers.push_back(marker);
00201 int_marker.controls.push_back(button_control);
00202 return int_marker;
00203 }
00204
00205
00206 void World::worldChanged(){
00207 fetch_pbd_interaction::WorldState new_state;
00208 new_state.object_list = getObjectList();
00209 update();
00210 world_update_pub.publish(new_state);
00211 }
00212
00213 std::vector<fetch_pbd_interaction::Landmark> World::getObjectList(){
00214 std::vector<fetch_pbd_interaction::Landmark> object_list;
00215 for (int i=0; i < objects.size(); i++){
00216 object_list.push_back(objects[i].object);
00217 }
00218 if (object_list.size() == 0){
00219 ROS_WARN("No objects detected");
00220 }
00221 return object_list;
00222 }
00223
00224 bool World::getMostSimilarObjectCallback(fetch_pbd_interaction::GetMostSimilarObject::Request& req,
00225 fetch_pbd_interaction::GetMostSimilarObject::Response& resp){
00226 mutex.lock();
00227 float best_dist = 10000.0;
00228 fetch_pbd_interaction::Landmark chosen_object;
00229 bool success = false;
00230 std::vector<fetch_pbd_interaction::Landmark> object_list = getObjectList();
00231 for (int i=0; i < object_list.size(); i++){
00232 float dist = World::objectDissimilarity(object_list[i], req.original_object);
00233 if (dist < best_dist){
00234 best_dist = dist;
00235 chosen_object = object_list[i];
00236 success = true;
00237 }
00238 }
00239 if (!success){
00240 ROS_INFO("Did not find a similar object.");
00241 resp.has_similar = false;
00242 }
00243 else{
00244 ROS_INFO("Landmark dissimilarity is --- %f", best_dist);
00245 if (best_dist > obj_similar_dist_threshold){
00246 ROS_INFO("Found an object but it is not similar enough.");
00247 resp.has_similar = false;
00248 }
00249 else {
00250 ROS_INFO("Most similar object is: %s", chosen_object.name.c_str());
00251 resp.has_similar = true;
00252 resp.similar_object = chosen_object;
00253 }
00254 }
00255 mutex.unlock();
00256 return true;
00257 }
00258
00259 bool World::getObjectListCallback(fetch_pbd_interaction::GetObjectList::Request& req,
00260 fetch_pbd_interaction::GetObjectList::Response& resp){
00261 update();
00262 resp.object_list = getObjectList();
00263 return true;
00264 }
00265
00266 bool World::updateWorldCallback(fetch_pbd_interaction::GetObjectList::Request& req,
00267 fetch_pbd_interaction::GetObjectList::Response& resp){
00268 recordObjectPose();
00269 resp.object_list = getObjectList();
00270 return true;
00271 }
00272
00273 bool World::getObjectFromNameCallback(fetch_pbd_interaction::GetObjectFromName::Request& req,
00274 fetch_pbd_interaction::GetObjectFromName::Response& resp){
00275 std::vector<fetch_pbd_interaction::Landmark> object_list = getObjectList();
00276 for (int i=0; i < object_list.size(); i++){
00277 if (object_list[i].name == req.ref_name){
00278 resp.has_object = true;
00279 resp.obj = object_list[i];
00280 return true;
00281 }
00282 }
00283 resp.has_object = false;
00284 return true;
00285 }
00286
00287 bool World::hasObjects(){
00288 if (objects.size() > 0){
00289 return true;
00290 }
00291 else {
00292 return false;
00293 }
00294 }
00295
00296 void World::recordObjectPose(){
00297 ROS_INFO("Waiting for segmentation service");
00298 try
00299 {
00300 std_srvs::Empty srv;
00301 segmentation_service_client.call(srv);
00302 rail_manipulation_msgs::SegmentedObjectListConstPtr msg = ros::topic::waitForMessage<rail_manipulation_msgs::SegmentedObjectList>(segmented_objects_topic);
00303 objectsUpdateCallback(msg);
00304 }
00305 catch ( ros::Exception &e )
00306 {
00307 ROS_ERROR("Error occured: %s ", e.what());
00308 }
00309 }
00310
00311 void World::objectsUpdateCallback(const rail_manipulation_msgs::SegmentedObjectListConstPtr& msg){
00312
00313 for (int i=0; i < objects.size(); i++){
00314 im_server.erase(objects[i].int_marker.name);
00315 im_server.applyChanges();
00316 }
00317 objects.clear();
00318 mutex.lock();
00319 bool added = false;
00320 for (int i=0; i < msg->objects.size(); i++){
00321 if (msg->objects[i].point_cloud.height == 0 || msg->objects[i].point_cloud.width == 0){
00322 ROS_WARN("Empty point cloud");
00323 }
00324 sensor_msgs::PointCloud2 pc2 = msg->objects[i].point_cloud;
00325 geometry_msgs::Vector3 dimensions;
00326 geometry_msgs::Pose pose;
00327 getBoundingBox(pc2, &dimensions, &pose);
00328 added = addNewObject(pose, dimensions, pc2);
00329 }
00330 if (!added){
00331 ROS_WARN("Failed to add object");
00332 }
00333
00334 mutex.unlock();
00335 worldChanged();
00336 }
00337
00338 void World::getBoundingBox(sensor_msgs::PointCloud2 pc2, geometry_msgs::Vector3* dimensions, geometry_msgs::Pose* pose){
00339 pcl::PointCloud<pcl::PointXYZRGB> cloud;
00340
00341
00342
00343
00344
00345
00346
00347 bool switched = false;
00348 pcl::fromROSMsg(pc2, cloud);
00349
00350 pcl::PointCloud<pcl::PointXYZRGB>::Ptr projected(new pcl::PointCloud<pcl::PointXYZRGB>(cloud));
00351 for (size_t i = 0; i < projected->points.size(); ++i) {
00352 pcl::PointXYZRGB& point = projected->at(i);
00353 point.z = 0;
00354 }
00355
00356 pcl::PCA<pcl::PointXYZRGB> pca(true);
00357 pca.setInputCloud(projected);
00358
00359 Eigen::Matrix3f eigenvectors = pca.getEigenVectors();
00360
00361
00362 eigenvectors.col(2) = eigenvectors.col(0).cross(eigenvectors.col(1));
00363 if(eigenvectors.col(2)(2) < 0.0){
00364
00365 switched = true;
00366 Eigen::Matrix3f eigenvectors_temp;
00367 eigenvectors_temp.col(0) = eigenvectors.col(1);
00368 eigenvectors_temp.col(1) = eigenvectors.col(0);
00369 eigenvectors_temp.col(2) = eigenvectors_temp.col(0).cross(eigenvectors_temp.col(1));
00370 eigenvectors = eigenvectors_temp;
00371 }
00372
00373 Eigen::Quaternionf q1(eigenvectors);
00374
00375 pcl::PointCloud<pcl::PointXYZRGB>::Ptr eigen_projected(
00376 new pcl::PointCloud<pcl::PointXYZRGB>(cloud));
00377 pca.project(cloud, *eigen_projected);
00378 pcl::PointXYZRGB eigen_min;
00379 pcl::PointXYZRGB eigen_max;
00380 pcl::getMinMax3D(*eigen_projected, eigen_min, eigen_max);
00381 double x_length = eigen_max.x - eigen_min.x;
00382 double y_length = eigen_max.y - eigen_min.y;
00383
00384
00385 pcl::PointXYZRGB cloud_min;
00386 pcl::PointXYZRGB cloud_max;
00387 pcl::getMinMax3D(cloud, cloud_min, cloud_max);
00388 double z_length = cloud_max.z - cloud_min.z;
00389
00390
00391
00392
00393 pcl::PointXYZRGB eigen_center;
00394 eigen_center.x = eigen_min.x + x_length / 2;
00395 eigen_center.y = eigen_min.y + y_length / 2;
00396 eigen_center.z = 0;
00397 pcl::PointXYZRGB center;
00398 pca.reconstruct(eigen_center, center);
00399 center.z = z_length / 2 + cloud_min.z;
00400
00401 pose->position.x = center.x;
00402 pose->position.y = center.y;
00403 pose->position.z = center.z;
00404 pose->orientation.w = q1.w();
00405 pose->orientation.x = q1.x();
00406 pose->orientation.y = q1.y();
00407 pose->orientation.z = q1.z();
00408
00409 if (!switched){
00410 dimensions->x = x_length;
00411 dimensions->y = y_length;
00412 dimensions->z = z_length;
00413 }
00414 else {
00415 dimensions->x = y_length;
00416 dimensions->y = x_length;
00417 dimensions->z = z_length;
00418 }
00419 }
00420
00421 void World::tablePositionUpdateCallback(const rail_manipulation_msgs::SegmentedObjectPtr& msg){
00422
00423 removeSurfaceMarker();
00424
00425 if (msg->point_cloud.height == 0 || msg->point_cloud.width == 0){
00426 ROS_WARN("No table detected");
00427 has_surface = false;
00428 return;
00429 }
00430 ROS_INFO("Table detected");
00431 has_surface = true;
00432 sensor_msgs::PointCloud2 pc2 = msg->point_cloud;
00433 geometry_msgs::Vector3 dimensions;
00434 geometry_msgs::Pose pose;
00435 pose.position.x = msg->center.x;
00436 pose.position.y = msg->center.y;
00437 pose.position.z = msg->center.z;
00438 pose.orientation.w = 1.0;
00439 dimensions.x = msg->depth;
00440 dimensions.y = msg->width;
00441 dimensions.z = msg->height;
00442
00443 ROS_INFO("Adding table marker");
00444 visualization_msgs::InteractiveMarker surface = getSurfaceMarker(pose, dimensions);
00445 im_server.insert(surface);
00446 im_server.setCallback(surface.name, boost::bind(&World::markerFeedbackCallback, this, _1));
00447 im_server.applyChanges();
00448 ROS_INFO("Adding surface to planning scene");
00449 addSurfaceToPlanningScene(pose, dimensions);
00450 ROS_INFO("Added surface to planning scene");
00451 }
00452
00453 bool World::clearObjectsCallback(std_srvs::Empty::Request& req,
00454 std_srvs::Empty::Response& resp){
00455 clearObjects();
00456 return true;
00457 }
00458
00459 void World::clearObjects(){
00460 ROS_INFO("Clearing objects");
00461 resetObjects();
00462 removeSurfaceMarker();
00463 worldChanged();
00464 removeSurfaceFromPlanningScene();
00465 }
00466
00467 bool World::getNearestObjectCallback(fetch_pbd_interaction::GetNearestObject::Request& req,
00468 fetch_pbd_interaction::GetNearestObject::Response& resp){
00469 geometry_msgs::PoseStamped arm_pose;
00470 ROS_INFO("Transform from frame: %s to %s", base_frame.c_str(), req.pose.header.frame_id.c_str());
00471 tf_listener.waitForTransform(base_frame, req.pose.header.frame_id,
00472 ros::Time::now(), ros::Duration(5.0));
00473 tf_listener.transformPose(base_frame, req.pose, arm_pose);
00474 std::vector<float> distances;
00475 for (int i=0; i < objects.size(); i++){
00476 float dist = poseDistance(objects[i].object.pose, arm_pose.pose);
00477 distances.push_back(dist);
00478 }
00479
00480 if (distances.size() > 0){
00481 float min = *std::min_element(distances.begin(), distances.end());
00482 if (min < obj_nearest_dist_threshold){
00483 for (int i=0; i < distances.size(); i++){
00484 if (distances[i] == min) {
00485 resp.has_nearest = true;
00486 resp.nearest_object = objects[i].object;
00487 return true;
00488 }
00489 }
00490 }
00491 }
00492 else {
00493 ROS_INFO("No objects");
00494 }
00495 resp.has_nearest = false;
00496 return true;
00497 }
00498
00499 void World::markerFeedbackCallback(const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback){
00500 ;
00501
00502 }
00503
00504 void World::resetObjects(){
00505 mutex.lock();
00506 ROS_INFO("Resetting objects");
00507 for (int i=0; i < objects.size(); i++){
00508 im_server.erase(objects[i].int_marker.name);
00509 im_server.applyChanges();
00510 }
00511 if (has_surface){
00512 removeSurfaceMarker();
00513 }
00514 im_server.clear();
00515 im_server.applyChanges();
00516 objects.clear();
00517 mutex.unlock();
00518 worldChanged();
00519 }
00520
00521 bool World::addNewObject(geometry_msgs::Pose pose, geometry_msgs::Vector3 dimensions,
00522 sensor_msgs::PointCloud2 point_cloud){
00523 for (int i=0; i < objects.size(); i++){
00524 if (World::poseDistance(objects[i].object.pose, pose) < obj_add_dist_threshold){
00525 ROS_INFO("Previously detected object at the same location. Will not add this object.");
00526 return false;
00527 }
00528 }
00529 int n_objects = objects.size();
00530 objects.push_back(fetch_pbd_interaction::WorldLandmark(
00531 pose, n_objects, dimensions, point_cloud));
00532
00533
00534
00535
00536 visualization_msgs::InteractiveMarker int_marker = getObjectMarker(n_objects);
00537 objects[n_objects].int_marker = int_marker;
00538
00539 im_server.insert(int_marker);
00540 im_server.setCallback(int_marker.name, boost::bind(&World::markerFeedbackCallback, this, _1));
00541 im_server.applyChanges();
00542 menu_handler.apply(im_server, int_marker.name);
00543 im_server.applyChanges();
00544
00545 return true;
00546 }
00547
00548
00549 void World::removeSurfaceMarker(){
00550 ROS_INFO("Removing surface marker");
00551 im_server.erase("surface");
00552 im_server.applyChanges();
00553 has_surface = false;
00554 }
00555
00556 visualization_msgs::InteractiveMarker World::getObjectMarker(int index){
00557 visualization_msgs::InteractiveMarker int_marker;
00558 int_marker.name = objects[index].getName();
00559 int_marker.header.frame_id = objects[index].object.point_cloud.header.frame_id;
00560 int_marker.pose.position = objects[index].object.pose.position;
00561 int_marker.pose.orientation.w = 1.0;
00562 int_marker.scale = 1.0;
00563 sensor_msgs::PointCloud2 pc2 = objects[index].object.point_cloud;
00564 visualization_msgs::Marker marker_points;
00565 visualization_msgs::Marker marker_sphere_list;
00566 World::pc2ToMarker(pc2, index, marker_duration, base_frame, &marker_points, &marker_sphere_list);
00567
00568 visualization_msgs::InteractiveMarkerControl button_control;
00569 button_control.interaction_mode = visualization_msgs::InteractiveMarkerControl::BUTTON;
00570 button_control.always_visible = true;
00571 button_control.markers.push_back(marker_sphere_list);
00572 button_control.markers.push_back(marker_points);
00573 visualization_msgs::Marker text_marker;
00574 text_marker.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
00575 text_marker.id = index;
00576 text_marker.scale = scale_text;
00577 text_marker.text = int_marker.name;
00578 text_marker.color.a = 0.5;
00579
00580 geometry_msgs::Point text_pos;
00581
00582
00583 text_pos.z = objects[index].object.dimensions.z / 2.0 + text_offset;
00584
00585
00586 text_marker.pose.position = text_pos;
00587 text_marker.pose.orientation.w = 1.0;
00588 button_control.markers.push_back(text_marker);
00589 int_marker.controls.push_back(button_control);
00590
00591 return int_marker;
00592 }
00593
00594 void World::addSurfaceToPlanningScene(geometry_msgs::Pose pose, geometry_msgs::Vector3 dimensions){
00595 moveit_msgs::CollisionObject collision_object;
00596
00597 collision_object.header.frame_id = base_frame;
00598
00599 collision_object.id = "surface";
00600
00601
00602 shape_msgs::SolidPrimitive primitive;
00603 primitive.type = primitive.BOX;
00604 primitive.dimensions.resize(3);
00605 primitive.dimensions[0] = dimensions.x;
00606 primitive.dimensions[1] = dimensions.y;
00607 primitive.dimensions[2] = dimensions.z;
00608
00609 collision_object.primitives.push_back(primitive);
00610 collision_object.primitive_poses.push_back(pose);
00611 collision_object.operation = moveit_msgs::CollisionObject::ADD;
00612 moveit_msgs::PlanningScene planning_scene_msg;
00613 planning_scene_msg.world.collision_objects.push_back(collision_object);
00614 planning_scene_msg.is_diff = true;
00615
00616 planning_scene_diff_publisher.publish(planning_scene_msg);
00617
00618
00619 }
00620
00621 void World::removeSurfaceFromPlanningScene(){
00622 ROS_INFO("Removing the object from the world.");
00623 moveit_msgs::PlanningScene planning_scene_msg;
00624 moveit_msgs::CollisionObject remove_object;
00625 remove_object.id = "surface";
00626 remove_object.header.frame_id = base_frame;
00627 remove_object.operation = moveit_msgs::CollisionObject::REMOVE;
00628 planning_scene_msg.world.collision_objects.push_back(remove_object);
00629 planning_scene_msg.is_diff = true;
00630
00631 planning_scene_diff_publisher.publish(planning_scene_msg);
00632
00633
00634 }
00635
00636 void World::publishTfPose(geometry_msgs::Pose pose, std::string name, std::string parent){
00637 tf::Transform transform;
00638 transform.setOrigin( tf::Vector3(pose.position.x, pose.position.y, pose.position.z));
00639 tf::Quaternion q;
00640 tf::quaternionMsgToTF(pose.orientation, q);
00641
00642 transform.setRotation(q);
00643
00644 if (name == ""){
00645 ROS_INFO("No name");
00646 }
00647 if (parent == ""){
00648 ROS_INFO("No parent");
00649 }
00650 tf_broadcaster.sendTransform(tf::StampedTransform(transform, ros::Time::now(), parent, name));
00651 }
00652
00653 void World::removeObject(const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback){
00654 std::string to_remove = feedback->marker_name;
00655 fetch_pbd_interaction::GetObjectFromNameRequest req;
00656 req.ref_name = to_remove;
00657 fetch_pbd_interaction::GetObjectFromNameResponse resp;
00658 getObjectFromNameCallback(req, resp);
00659 for (int i=0; i < objects.size(); i ++){
00660 if (objects[i].object.name == resp.obj.name){
00661 im_server.erase(objects[i].int_marker.name);
00662 objects.erase(objects.begin() + i );
00663 im_server.applyChanges();
00664 break;
00665 }
00666 }
00667 worldChanged();
00668 }
00669
00670 void World::addGrasp(const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback){
00671 ROS_INFO("Marker menu feedback: Grasp object");
00672 std::string to_grasp = feedback->marker_name;
00673 fetch_pbd_interaction::GetObjectFromNameRequest req;
00674 req.ref_name = to_grasp;
00675 fetch_pbd_interaction::GetObjectFromNameResponse resp;
00676 getObjectFromNameCallback(req, resp);
00677 if (resp.has_object){
00678 add_grasp_pub.publish(resp.obj);
00679 }
00680 else {
00681 ROS_WARN("Cannot generate grasp. No object matching that name.");
00682 }
00683 }
00684
00685 }