jockey.cpp
Go to the documentation of this file.
00001 #include <place_matcher_mcc/jockey.h>
00002 
00003 namespace place_matcher_mcc
00004 {
00005 
00006 Jockey::Jockey(const std::string& name) :
00007   lama_jockeys::LocalizingJockey(name),
00008   place_profile_interface_name_defined_(false)
00009 {
00010   place_profile_interface_name_defined_ = private_nh_.getParam("place_profile_interface_name", place_profile_interface_name_);
00011   if (!place_profile_interface_name_defined_)
00012   {
00013     ROS_WARN_STREAM(private_nh_.getNamespace() << "/place_profile_interface_name parameter not defined");
00014   }
00015 
00016   initMapPlaceProfileInterface();
00017 }
00018 
00021 void Jockey::initMapPlaceProfileInterface()
00022 {
00023   ros::ServiceClient client = nh_.serviceClient<lama_interfaces::AddInterface>("interface_factory");
00024   while (ros::ok() && !client.waitForExistence(ros::Duration(5)))
00025   {
00026     ROS_WARN("Waiting for service /interface_factory");
00027   }
00028   lama_interfaces::AddInterface srv;
00029   srv.request.interface_name = place_profile_interface_name_;
00030   srv.request.interface_type = lama_interfaces::AddInterfaceRequest::SERIALIZED;
00031   srv.request.get_service_message = "lama_msgs/GetPlaceProfile";
00032   srv.request.set_service_message = "lama_msgs/SetPlaceProfile";
00033   if (!client.call(srv))
00034   {
00035     ROS_ERROR_STREAM("Failed to create the LaMa interface " << place_profile_interface_name_);
00036     return;
00037   }
00038   place_profile_getter_service_name_ = srv.response.get_service_name;
00039 }
00040 
00041 void Jockey::onGetDissimilarity()
00042 {
00043   if (!place_profile_interface_name_defined_)
00044   {
00045     ROS_ERROR_STREAM(private_nh_.getNamespace() << "/place_profile_interface_name parameter not defined, aborting");
00046     server_.setAborted();
00047     return;
00048   }
00049 
00050   // Initialize the clients for the getter service (interface to map).
00051   ros::ServiceClient place_profile_getter;
00052   place_profile_getter = nh_.serviceClient<lama_msgs::GetPlaceProfile>(place_profile_getter_service_name_);
00053   while (ros::ok() && !place_profile_getter.waitForExistence(ros::Duration(5)))
00054   {
00055     ROS_WARN_STREAM("Waiting for service " << place_profile_getter.getService());
00056   }
00057 
00058   getData();
00059 
00060   // Get all scans from database.
00061   lama_interfaces::ActOnMap srv;
00062   srv.request.action = lama_interfaces::ActOnMapRequest::GET_VERTEX_LIST;
00063   if (!map_agent_.call(srv))
00064   {
00065     ROS_ERROR_STREAM("Failed to call map agent \"" << map_agent_.getService() << "\"");
00066     server_.setAborted();
00067     return;
00068   }
00069   
00070   // Iterate over vertices and get the associated Polygon (from the PlaceProfile).
00071   std::vector<int32_t> vertices;
00072   vertices.reserve(srv.response.objects.size());
00073   std::vector<geometry_msgs::Polygon> polygons;
00074   polygons.reserve(srv.response.objects.size());
00075   for (size_t i = 0; i < srv.response.objects.size(); ++i)
00076   {
00077     // Get all PlaceProfile descriptors associated with the current vertex.
00078     lama_interfaces::ActOnMap desc_srv;
00079     desc_srv.request.action = lama_interfaces::ActOnMapRequest::GET_DESCRIPTOR_LINKS;
00080     desc_srv.request.object.id = srv.response.objects[i].id;
00081     desc_srv.request.interface_name = place_profile_interface_name_;
00082     if (!map_agent_.call(desc_srv))
00083     {
00084       ROS_ERROR_STREAM("Failed to call map agent \"" << map_agent_.getService() << "\"");
00085       server_.setAborted();
00086       return;
00087     }
00088     if (desc_srv.response.descriptor_links.empty())
00089     {
00090       continue;
00091     }
00092     if (desc_srv.response.descriptor_links.size() > 1)
00093     {
00094       ROS_WARN_STREAM("More than one descriptor with interface " <<
00095           place_profile_interface_name_ << " for vertex " <<
00096           desc_srv.request.object.id << ", taking the first one");
00097     }
00098     // Get the first linked PlaceProfile.
00099     lama_msgs::GetPlaceProfile profile_srv;
00100     profile_srv.request.id = desc_srv.response.descriptor_links[0].descriptor_id;
00101     if (!place_profile_getter.call(profile_srv))
00102     {
00103       ROS_ERROR_STREAM(jockey_name_ << ": failed to call service \"" <<
00104           place_profile_interface_name_ << "\"");
00105       server_.setAborted();
00106       return;
00107     }
00108     vertices.push_back(desc_srv.request.object.id);
00109     polygons.push_back(profile_srv.response.descriptor.polygon);
00110   }
00111   
00112   // Compare them to the current polygon.
00113   result_.idata.clear();
00114   result_.fdata.clear();
00115   result_.idata.reserve(vertices.size());
00116   result_.fdata.reserve(vertices.size());
00117   for (size_t i = 0; i < vertices.size(); ++i)
00118   {
00119     result_.idata.push_back(vertices[i]);
00120     result_.fdata.push_back(dissimilarity_getter_.getDissimilarity(current_polygon_, polygons[i]));
00121   }
00122 
00123   ROS_INFO_STREAM(jockey_name_ << ": computed " << result_.idata.size() << " dissimilarities");
00124   result_.state = lama_jockeys::LocalizeResult::DONE;
00125   result_.completion_time = getCompletionDuration();
00126   server_.setSucceeded(result_);
00127 }
00128 
00134 void Jockey::getData()
00135 {
00136   ros::Subscriber polygon_handler;
00137   polygon_handler = private_nh_.subscribe<geometry_msgs::Polygon>("polyoon", 1, &Jockey::handlePolygon, this);
00138 
00139   /* Wait a bit to avoid the first throttled message. */
00140   // TODO: simplify with ROS_INFO_STREAM_DELAYED_THROTTLE, when available.
00141   ros::Duration(0.2).sleep();
00142   ros::spinOnce();
00143   while (ros::ok())
00144   {
00145     ros::spinOnce();
00146     if (has_polygon_data_)
00147     {
00148       has_polygon_data_ = false;
00149       break;
00150     }
00151     ROS_INFO_STREAM_THROTTLE(5, "Did not received any polygon on " << polygon_handler.getTopic());
00152     ros::Duration(0.01).sleep();
00153   }
00154 }
00155 
00158 void Jockey::handlePolygon(const geometry_msgs::PolygonConstPtr& msg)
00159 {
00160   if (!has_polygon_data_)
00161   {
00162     current_polygon_ = *msg;
00163     has_polygon_data_ = true;
00164   }
00165 }
00166 
00167 } /* namespace place_matcher_mcc */
00168 


place_matcher_mcc
Author(s): Gaël Ecorchard , Karel Košnar
autogenerated on Sat Jun 8 2019 19:53:05