ObjectSearcher.cpp
Go to the documentation of this file.
00001 
00012 #include <boost/algorithm/string.hpp>
00013 #include <informed_object_search/ObjectSearcher.h>
00014 #include <interactive_world_msgs/LoadModels.h>
00015 #include <interactive_world_msgs/FindObservations.h>
00016 #include <interactive_world_msgs/GetSurfaces.h>
00017 #include <informed_object_search/ObjectOnSurfaceModel.h>
00018 
00019 using namespace std;
00020 using namespace rail::interactive_world;
00021 
00022 ObjectSearcher::ObjectSearcher()
00023     : private_node_("~"), search_ac_("/high_level_action_server/drive_and_search", true), ac_wait_time_(AC_WAIT_TIME),
00024       as_(private_node_, "object_search", boost::bind(&ObjectSearcher::objectSearch, this, _1), false)
00025 {
00026   // setup any services/topics we need
00027   model_fetcher_srv_ = node_.serviceClient<interactive_world_msgs::LoadModels>(
00028       "/interactive_world_model_fetcher/load_models"
00029   );
00030   find_observations_srv_ = node_.serviceClient<interactive_world_msgs::FindObservations>(
00031       "/spatial_world_model_server/find_observations"
00032   );
00033   get_surfaces_srv_ = node_.serviceClient<interactive_world_msgs::GetSurfaces>(
00034       "/high_level_action_server/get_surfaces"
00035   );
00036 
00037   // start the action server
00038   as_.start();
00039 
00040   // wait for the action server
00041   search_ac_.waitForServer(ac_wait_time_);
00042 
00043   ROS_INFO("Object Searcher Successfully Initialized");
00044 }
00045 
00046 
00047 void ObjectSearcher::objectSearch(const interactive_world_msgs::ObjectSearchGoalConstPtr &goal)
00048 {
00049   // final list based on confidence
00050   map<string, double> confidences;
00051 
00052   // seed every surface
00053   interactive_world_msgs::GetSurfaces surfaces_req;
00054   get_surfaces_srv_.call(surfaces_req);
00055   for (size_t i = 0; i < surfaces_req.response.surfaces.size(); i++)
00056   {
00057     cout << surfaces_req.response.surfaces[i] << endl;
00058     confidences[surfaces_req.response.surfaces[i]] = 0.001;
00059   }
00060 
00061   // ignore case
00062   string item = boost::to_upper_copy(goal->item);
00063   ROS_INFO("Searching for '%s'...", item.c_str());
00064 
00065   interactive_world_msgs::ObjectSearchFeedback feedback;
00066   interactive_world_msgs::ObjectSearchResult result;
00067   // default to false
00068   result.success = false;
00069 
00070   // check the world model
00071   feedback.message = "Requesting world model history...";
00072   as_.publishFeedback(feedback);
00073 
00074   interactive_world_msgs::FindObservations find_observations;
00075   find_observations.request.item = item;
00076   find_observations_srv_.call(find_observations);
00077 
00078   // each surface has an exponential distribution
00079   map<string, map<string, ObjectOnSurfaceModel> > distributions;
00080   ros::Time now = ros::Time::now();
00081   for (size_t i = 0; i < find_observations.response.surfaces.size(); i++)
00082   {
00083     ObjectOnSurfaceModel &model = distributions[find_observations.response.surfaces[i]][item];
00084     model.setObject(item);
00085     model.setSurface(find_observations.response.surfaces[i]);
00086     model.addObservation(find_observations.response.times[i].sec, find_observations.response.removals[i].sec);
00087   }
00088 
00089   for (map<string, map<string, ObjectOnSurfaceModel> >::iterator iter = distributions.begin();
00090        iter != distributions.end(); ++iter)
00091   {
00092     double p = iter->second[item].getCurrentProbability();
00093     cout << "P(" << item << " on " << iter->first << ")=" << p << endl;
00094     confidences[iter->first] = p;
00095   }
00096 
00097 //  // request models
00098 //  feedback.message = "Requesting trainied models...";
00099 //  as_.publishFeedback(feedback);
00100 //
00101 //  // grab each model from the database
00102 //  vector<interactive_world_msgs::Model> models;
00103 //  for (size_t i = 0; i < goal->models.size(); i++)
00104 //  {
00105 //    // create and send a request
00106 //    interactive_world_msgs::LoadModels loader;
00107 //    loader.request.condition_id = goal->models[i];
00108 //    if (model_fetcher_srv_.call(loader))
00109 //    {
00110 //      // search for the object we are looking for
00111 //      vector<interactive_world_msgs::Model> &cur = loader.response.models.models;
00112 //      for (size_t j = 0; j < cur.size(); j++)
00113 //      {
00114 //        // check if the names match and restrict search to surfaces
00115 //        string placement_item = boost::to_upper_copy(cur[j].placement.item.name);
00116 //        string placement_reference = boost::to_upper_copy(cur[j].placement.reference_frame_id);
00117 //        if (cur[j].placement.surface.name.size() > 0 && (placement_item == item || placement_reference == item))
00118 //        {
00119 //          models.push_back(cur[j]);
00120 //        }
00121 //      }
00122 //    } else
00123 //    {
00124 //      ROS_WARN("Could not load model %i.", goal->models[i]);
00125 //      as_.setSucceeded(result, "Could not load all models from the RMS database.");
00126 //      return;
00127 //    }
00128 //  }
00129 //
00130 //  // tally up confidences for each surface
00131 //  for (size_t i = 0; i < models.size(); i++)
00132 //  {
00133 //    // get the current surface name
00134 //    const interactive_world_msgs::Model &m = models[i];
00135 //    string surface_name = m.placement.surface.name;
00136 //    if (confidences.find(surface_name) == confidences.end())
00137 //    {
00138 //      confidences[surface_name] = 0.0;
00139 //    }
00140 //
00141 //    // add to the confidence
00142 //    confidences[surface_name] += m.decision_value;
00143 //  }
00144 
00145   while (!confidences.empty())
00146   {
00147     // check for the current best
00148     //double lowest = numeric_limits<double>::infinity();
00149     double highest = -numeric_limits<double>::infinity();
00150     string best_surface;
00151     for (map<string, double>::iterator iter = confidences.begin(); iter != confidences.end(); ++iter)
00152     {
00153       string key = iter->first;
00154       double value = iter->second;
00155       if (value > highest)
00156       {
00157         best_surface = key;
00158         highest = value;
00159       }
00160     }
00161 
00162     // search for the highest confidence
00163     feedback.message = "Searching " + best_surface;
00164     cout << feedback.message << endl;
00165     as_.publishFeedback(feedback);
00166 
00167     // perform a higher level search request
00168     interactive_world_msgs::DriveAndSearchGoal search_goal;
00169     search_goal.item = item;
00170     search_goal.surface = best_surface;
00171     search_ac_.sendGoal(search_goal);
00172     bool completed = search_ac_.waitForResult(ac_wait_time_);
00173     bool succeeded = (search_ac_.getState() == actionlib::SimpleClientGoalState::SUCCEEDED);
00174     bool success = search_ac_.getResult()->success;
00175     if (!completed || !succeeded || !success)
00176     {
00177       feedback.message = "Object not found on " + search_goal.surface;
00178       cout << feedback.message << endl;
00179       as_.publishFeedback(feedback);
00180     } else
00181     {
00182       // TODO object found
00183       cout << "FOUND THE OBJECT" << endl;
00184     }
00185 
00186     confidences.erase(best_surface);
00187   }
00188 
00189   // success
00190   as_.setSucceeded(result, "Object search failed.");
00191 }


informed_object_search
Author(s): Russell Toris
autogenerated on Thu Jun 6 2019 21:34:20