RecognizedObjectsListener.cpp
Go to the documentation of this file.
00001 #include <spatial_world_model/RecognizedObjectsListener.h>
00002 
00003 #include <interactive_world_msgs/StoreObservation.h>
00004 #include <interactive_world_msgs/FindSurface.h>
00005 #include <interactive_world_msgs/FindObservations.h>
00006 #include <interactive_world_msgs/SetObservationsRemoved.h>
00007 #include <interactive_world_msgs/TransformToSurfaceFrame.h>
00008 
00009 using namespace std;
00010 using namespace rail::interactive_world;
00011 
00012 RecognizedObjectsListener::RecognizedObjectsListener()
00013 {
00014   incoming_cleared_objects_ = false;
00015   store_observation_srv_ = node_.serviceClient<interactive_world_msgs::StoreObservation>(
00016       "/spatial_world_model_server/store_observation"
00017   );
00018   find_surface_srv_ = node_.serviceClient<interactive_world_msgs::FindSurface>(
00019       "/high_level_action_server/find_surface"
00020   );
00021   transform_to_surface_frame_srv_ = node_.serviceClient<interactive_world_msgs::TransformToSurfaceFrame>(
00022       "/high_level_action_server/transform_to_surface_frame"
00023   );
00024   find_observations_srv_ = node_.serviceClient<interactive_world_msgs::FindObservations>(
00025       "/spatial_world_model_server/find_observations"
00026   );
00027   recognized_objects_sub_ = node_.subscribe("/object_recognition_listener/recognized_objects", 1,
00028                                             &RecognizedObjectsListener::recognizedObjectsCallback, this);
00029   set_observations_removed_srv_ = node_.serviceClient<interactive_world_msgs::SetObservationsRemoved>(
00030       "/spatial_world_model_server/set_observations_removed"
00031   );
00032   ROS_INFO("Recognized Objects Listener Initialized");
00033 }
00034 
00035 void RecognizedObjectsListener::recognizedObjectsCallback(const rail_manipulation_msgs::SegmentedObjectList &objects)
00036 {
00037   // ignore cleared objects
00038   incoming_cleared_objects_ = !incoming_cleared_objects_;
00039   if (objects.objects.empty() && incoming_cleared_objects_)
00040   {
00041     return;
00042   }
00043 
00044   ROS_INFO("Attmpting to store %ld objects in the spatial world model...", objects.objects.size());
00045 
00046   // list of objects seen
00047   vector<string> seen_objects;
00048   // list of placement surfaces found
00049   map<string, vector<string> > seen_surfaces;
00050 
00051   // go through each recognized object
00052   uint32_t count = 0;
00053   for (size_t i = 0; i < objects.objects.size(); i++)
00054   {
00055     const rail_manipulation_msgs::SegmentedObject &object = objects.objects[i];
00056     if (object.recognized)
00057     {
00058       // determine the surface
00059       interactive_world_msgs::FindSurface surface;
00060       surface.request.pose.header.frame_id = object.point_cloud.header.frame_id;
00061       surface.request.pose.pose.position.x = object.centroid.x;
00062       surface.request.pose.pose.position.y = object.centroid.y;
00063       surface.request.pose.pose.position.z = object.centroid.z - (object.height / 2.0);
00064       surface.request.pose.pose.orientation = object.orientation;
00065 
00066       if (find_surface_srv_.call(surface))
00067       {
00068         // check if the surface was found
00069         if (!surface.response.surface.empty())
00070         {
00071           seen_objects.push_back(object.name);
00072 
00073           // fill the request
00074           interactive_world_msgs::StoreObservation store;
00075           store.request.surface = surface.response.surface;
00076           store.request.surface_frame_id = surface.response.surface_frame_id;
00077           store.request.placement_surface_frame_id = surface.response.placement_surface_frame_id;
00078           store.request.item = object.name;
00079           store.request.item_conf = object.confidence;
00080 
00081           // store the surface
00082           seen_surfaces[surface.response.surface_frame_id].push_back(surface.response.placement_surface_frame_id);
00083 
00084           // transform the position to the surface frame
00085           interactive_world_msgs::TransformToSurfaceFrame transform_to_surface_frame;
00086           transform_to_surface_frame.request.pose = surface.request.pose;
00087           transform_to_surface_frame.request.surface = surface.response.surface;
00088           if (transform_to_surface_frame_srv_.call(transform_to_surface_frame))
00089           {
00090             store.request.x = transform_to_surface_frame.response.pose.pose.position.x;
00091             store.request.y = transform_to_surface_frame.response.pose.pose.position.y;
00092             store.request.z = transform_to_surface_frame.response.pose.pose.position.z;
00093             tf2::Quaternion q(transform_to_surface_frame.response.pose.pose.orientation.x,
00094                               transform_to_surface_frame.response.pose.pose.orientation.y,
00095                               transform_to_surface_frame.response.pose.pose.orientation.z,
00096                               transform_to_surface_frame.response.pose.pose.orientation.w);
00097             store.request.theta = q.getAngle();
00098 
00099             // attempt to store the result
00100             if (store_observation_srv_.call(store))
00101             {
00102               count++;
00103             } else
00104             {
00105               ROS_WARN("Failed to store current observation of object '%s'.", object.name.c_str());
00106             }
00107           } else
00108           {
00109             ROS_WARN("Failed to transform pose to surface frame for '%s'.", object.name.c_str());
00110           }
00111         } else
00112         {
00113           ROS_WARN("Failed to find surface for object '%s'.", object.name.c_str());
00114         }
00115       } else
00116       {
00117         ROS_WARN("Failed to call surface finder.");
00118       }
00119     }
00120   }
00121 
00122   ROS_INFO("Stored %d item observations.", count);
00123 
00124   // now remove things that are gone
00125   interactive_world_msgs::SetObservationsRemoved remove;
00126   for (map<string, vector<string> >::iterator iter = seen_surfaces.begin(); iter != seen_surfaces.end(); ++iter)
00127   {
00128     // unique placement surfaces
00129     vector<string> &placement_surfaces = iter->second;
00130     sort(placement_surfaces.begin(), placement_surfaces.end());
00131     vector<string>::iterator last = unique(iter->second.begin(), iter->second.end());
00132     placement_surfaces.erase(last, placement_surfaces.end());
00133     for (size_t i = 0; i < placement_surfaces.size(); i++)
00134     {
00135       // grab anything that should have been on the table
00136       interactive_world_msgs::FindObservations find;
00137       find.request.surface_frame_id = iter->first;
00138       find.request.placement_surface_frame_id = placement_surfaces[i];
00139       find.request.removed = false;
00140       find_observations_srv_.call(find);
00141       // go through and remove objects we did not see
00142       for (size_t j = 0; j < find.response.items.size(); j++)
00143       {
00144         if (std::find(seen_objects.begin(), seen_objects.end(), find.response.items[j]) == seen_objects.end())
00145         {
00146           remove.request.ids.push_back(find.response.ids[j]);
00147         }
00148       }
00149     }
00150   }
00151 
00152   if (!remove.request.ids.empty())
00153   {
00154     ROS_INFO("Setting %ld old observations as removed.", remove.request.ids.size());
00155     set_observations_removed_srv_.call(remove);
00156   }
00157 }


spatial_world_model
Author(s): Russell Toris
autogenerated on Thu Jun 6 2019 21:34:31