Go to the documentation of this file.00001 #include <lj_laser/jockey.h>
00002
00003 namespace lj_laser {
00004
00005 Jockey::Jockey(std::string name, const double frontier_width, const double max_frontier_angle) :
00006 LocalizingJockey(name),
00007 data_received_(false),
00008 scan_reception_time_(ros::Time(0)),
00009 laser_interface_name_(name + "_laser"),
00010 crossing_interface_name_(name + "_crossing"),
00011 dissimilarity_server_name_("compute_dissimilarity"),
00012 crossing_detector_(frontier_width, max_frontier_angle)
00013 {
00014 private_nh_.getParam("laser_interface_name", laser_interface_name_);
00015 private_nh_.getParam("crossing_interface_name", crossing_interface_name_);
00016 private_nh_.getParam("dissimilarity_server_name", dissimilarity_server_name_);
00017
00018 if (!initMapLaserInterface())
00019 {
00020 throw ros::Exception("Initialization error");
00021 }
00022
00023 if (!initMapCrossingInterface())
00024 {
00025 throw ros::Exception("Initialization error");
00026 }
00027
00028
00029 dissimilarity_server_ = nh_.serviceClient<place_matcher_msgs::PolygonDissimilarity>(dissimilarity_server_name_);
00030 }
00031
00036 bool Jockey::initMapLaserInterface()
00037 {
00038 ros::ServiceClient client = nh_.serviceClient<lama_interfaces::AddInterface>("interface_factory");
00039 client.waitForExistence();
00040 lama_interfaces::AddInterface srv;
00041 srv.request.interface_name = laser_interface_name_;
00042 srv.request.interface_type = lama_interfaces::AddInterfaceRequest::SERIALIZED;
00043 srv.request.get_service_message = "lama_interfaces/GetVectorLaserScan";
00044 srv.request.set_service_message = "lama_interfaces/SetVectorLaserScan";
00045 if (!client.call(srv))
00046 {
00047 ROS_ERROR("Failed to create the LaMa interface %s", srv.request.interface_name.c_str());
00048 return false;
00049 }
00050
00051 laser_descriptor_getter_ = nh_.serviceClient<lama_interfaces::GetVectorLaserScan>(srv.response.get_service_name);
00052 laser_descriptor_getter_.waitForExistence();
00053 laser_descriptor_setter_ = nh_.serviceClient<lama_interfaces::SetVectorLaserScan>(srv.response.set_service_name);
00054 laser_descriptor_setter_.waitForExistence();
00055 return true;
00056 }
00057
00062 bool Jockey::initMapCrossingInterface()
00063 {
00064 ros::ServiceClient client = nh_.serviceClient<lama_interfaces::AddInterface>("interface_factory");
00065 client.waitForExistence();
00066 lama_interfaces::AddInterface srv;
00067 srv.request.interface_name = crossing_interface_name_;
00068 srv.request.interface_type = lama_interfaces::AddInterfaceRequest::SERIALIZED;
00069 srv.request.get_service_message = "lama_msgs/GetCrossing";
00070 srv.request.set_service_message = "lama_msgs/SetCrossing";
00071 if (!client.call(srv))
00072 {
00073 ROS_ERROR("Failed to create the Lama interface %s", crossing_interface_name_.c_str());
00074 return false;
00075 }
00076
00077 crossing_descriptor_setter_ = nh_.serviceClient<lama_msgs::SetCrossing>(srv.response.set_service_name);
00078 crossing_descriptor_setter_.waitForExistence();
00079 return true;
00080 }
00081
00084 void Jockey::getData()
00085 {
00086 laserHandler_ = nh_.subscribe<sensor_msgs::LaserScan>("base_scan", 1, &Jockey::handleLaser, this);
00087
00088 ros::Rate r(100);
00089 while (ros::ok())
00090 {
00091 if (data_received_)
00092 {
00093
00094 laserHandler_.shutdown();
00095 data_received_ = false;
00096 break;
00097 }
00098 ros::spinOnce();
00099 r.sleep();
00100 }
00101 }
00102
00105 void Jockey::handleLaser(const sensor_msgs::LaserScanConstPtr& msg)
00106 {
00107 scan_ = *msg;
00108 scan_reception_time_ = msg->header.stamp;
00109 data_received_ = true;
00110 }
00111
00116
00117
00118
00119 void Jockey::onGetVertexDescriptor()
00120 {
00121 ROS_INFO("Received action GET_VERTEX_DESCRIPTOR");
00122
00123 if (server_.isPreemptRequested() && !ros::ok())
00124 {
00125 ROS_INFO("%s: Preempted", jockey_name_.c_str());
00126
00127 server_.setPreempted();
00128 return;
00129 }
00130
00131 getData();
00132
00133
00134 lama_interfaces::SetVectorLaserScan vscan_setter;
00135 vscan_setter.request.descriptor.push_back(scan_);
00136 if (!laser_descriptor_setter_.call(vscan_setter))
00137 {
00138 ROS_ERROR("Failed to add LaserScan[] to the map");
00139 server_.setAborted();
00140 return;
00141 }
00142 ROS_INFO("Added LaserScan[] with id %d", vscan_setter.response.id);
00143 result_.descriptor_links.push_back(laserDescriptorLink(vscan_setter.response.id));
00144
00145
00146 lama_msgs::SetCrossing crossing_setter;
00147 lama_msgs::Crossing crossing = crossing_detector_.crossingDescriptor(scan_, true);
00148 crossing_setter.request.descriptor = crossing;
00149 if (!crossing_descriptor_setter_.call(crossing_setter))
00150 {
00151 ROS_ERROR("Failed to add Crossing to the map");
00152 server_.setAborted();
00153 return;
00154 }
00155 ROS_INFO("Added Crossing with id %d", crossing_setter.response.id);
00156 result_.descriptor_links.push_back(crossingDescriptorLink(crossing_setter.response.id));
00157
00158 result_.state = lama_jockeys::LocalizeResult::DONE;
00159 result_.completion_time = getCompletionDuration();
00160 server_.setSucceeded(result_);
00161 }
00162
00163 void Jockey::onGetEdgesDescriptors()
00164 {
00165 result_.state = lama_jockeys::LocalizeResult::NOT_SUPPORTED;
00166 result_.completion_time = ros::Duration(0.0);
00167 server_.setSucceeded(result_);
00168 }
00169
00170 void Jockey::onLocalizeInVertex()
00171 {
00172 result_.state = lama_jockeys::LocalizeResult::NOT_SUPPORTED;
00173 result_.completion_time = ros::Duration(0.0);
00174 server_.setSucceeded(result_);
00175 }
00176
00177 void Jockey::onLocalizeEdge()
00178 {
00179 result_.state = lama_jockeys::LocalizeResult::NOT_SUPPORTED;
00180 result_.completion_time = ros::Duration(0.0);
00181 server_.setSucceeded(result_);
00182 }
00183
00184 void Jockey::onGetDissimilarity()
00185 {
00186 getData();
00187
00188
00189 geometry_msgs::Polygon current_polygon = lama_common::scanToPolygon(scan_);
00190
00191
00192 lama_interfaces::ActOnMap srv;
00193 srv.request.action = lama_interfaces::ActOnMapRequest::GET_VERTEX_LIST;
00194 ROS_DEBUG("Calling action GET_VERTEX_LIST");
00195 if (!map_agent_.call(srv))
00196 {
00197 ROS_ERROR("Failed to call map agent");
00198 server_.setAborted();
00199 return;
00200 }
00201 ROS_DEBUG("Received response GET_VERTEX_LIST");
00202
00203
00204 std::vector<int32_t> vertices;
00205 vertices.reserve(srv.response.objects.size());
00206 std::vector<geometry_msgs::Polygon> polygons;
00207 polygons.reserve(srv.response.objects.size());
00208 for (size_t i = 0; i < srv.response.objects.size(); ++i)
00209 {
00210
00211 lama_interfaces::ActOnMap desc_srv;
00212 desc_srv.request.action = lama_interfaces::ActOnMapRequest::GET_DESCRIPTOR_LINKS;
00213 desc_srv.request.object.id = srv.response.objects[i].id;
00214 desc_srv.request.interface_name = laser_interface_name_;
00215 map_agent_.call(desc_srv);
00216 if (desc_srv.response.descriptor_links.empty())
00217 {
00218 continue;
00219 }
00220 if (desc_srv.response.descriptor_links.size() > 1)
00221 {
00222 ROS_WARN("More than one descriptor with interface %s for vertex %d, taking the first one",
00223 laser_interface_name_.c_str(), desc_srv.request.object.id);
00224 }
00225
00226 lama_interfaces::GetVectorLaserScan scan_srv;
00227 scan_srv.request.id = desc_srv.response.descriptor_links[0].descriptor_id;
00228 if (!laser_descriptor_getter_.call(scan_srv))
00229 {
00230 ROS_ERROR("Failed to call %s service", laser_interface_name_.c_str());
00231 server_.setAborted();
00232 return;
00233 }
00234 geometry_msgs::Polygon polygon = lama_common::scanToPolygon(scan_srv.response.descriptor[0]);
00235 vertices.push_back(desc_srv.request.object.id);
00236 polygons.push_back(polygon);
00237 }
00238
00239
00240 place_matcher_msgs::PolygonDissimilarity dissimi_srv;
00241 dissimi_srv.request.polygon1 = current_polygon;
00242 result_.idata.clear();
00243 result_.fdata.clear();
00244 result_.idata.reserve(vertices.size());
00245 result_.fdata.reserve(vertices.size());
00246 for (size_t i = 0; i < vertices.size(); ++i)
00247 {
00248 dissimi_srv.request.polygon2 = polygons[i];
00249 if (!dissimilarity_server_.call(dissimi_srv))
00250 {
00251 ROS_ERROR_STREAM("Failed to call " << dissimilarity_server_name_);
00252 server_.setAborted();
00253 return;
00254 }
00255 result_.idata.push_back(vertices[i]);
00256 result_.fdata.push_back(dissimi_srv.response.raw_dissimilarity);
00257 }
00258
00259 ROS_INFO("Computed %zu dissimilarities", result_.idata.size());
00260 result_.state = lama_jockeys::LocalizeResult::DONE;
00261 result_.completion_time = getCompletionDuration();
00262 server_.setSucceeded(result_);
00263 }
00264
00269 lama_msgs::DescriptorLink Jockey::laserDescriptorLink(const int32_t id)
00270 {
00271 lama_msgs::DescriptorLink descriptor_link;
00272 descriptor_link.descriptor_id = id;
00273 descriptor_link.interface_name = laser_interface_name_;
00274 return descriptor_link;
00275 }
00276
00281 lama_msgs::DescriptorLink Jockey::crossingDescriptorLink(const int32_t id)
00282 {
00283 lama_msgs::DescriptorLink descriptor_link;
00284 descriptor_link.descriptor_id = id;
00285 descriptor_link.interface_name = crossing_interface_name_;
00286 return descriptor_link;
00287 }
00288
00289 }