jockey.cpp
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   // Initialize the client for the dissimilarity server.
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   // Initialize the clients for the LaserScan getter and setter services (interface to map).
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   // Initialize the client for the Crossing setter services (interface to map).
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       // Stop the subscribers (may be superfluous).
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 // TODO: Discuss with Karel the exact role of onGetVertexDescriptor
00117 // TODO: in particular: should it save something in the database? This jockey
00118 // is not a learning jockey.
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     // set the action state to preempted
00127     server_.setPreempted();
00128     return;
00129   }
00130 
00131   getData();
00132 
00133   // Add the LaserScan to the descriptor list.
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); // DEBUG
00143   result_.descriptor_links.push_back(laserDescriptorLink(vscan_setter.response.id));
00144 
00145   // Add the Crossing to the descriptor list.
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); // DEBUG
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   // Transform the scan into a polygon.
00189   geometry_msgs::Polygon current_polygon = lama_common::scanToPolygon(scan_);
00190 
00191   // Get all scans from database.
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   // Iterate over vertices and get the associated Polygon (from the LaserScan).
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     // Get all LaserScan descriptors associated with the current vertex.
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     // Transform the LaserScan into a Polygon.
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   // Compare them to the current polygon by calling one of the pm_* service.
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 } // namespace lj_laser


lj_laser
Author(s): Gaƫl Ecorchard
autogenerated on Thu Jun 6 2019 17:50:44