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