laser_navigation_alg_node.cpp
Go to the documentation of this file.
00001 #include "laser_navigation_alg_node.h"
00002 #include <iostream>
00003 
00004 LaserNavigationAlgNode::LaserNavigationAlgNode(void) :
00005   algorithm_base::IriBaseAlgorithm<LaserNavigationAlgorithm>(),
00006   send_goal_client_("move_base", true)
00007 {
00008   ROS_INFO("Laser Navigation: Warming up..");
00009   //init class attributes if necessary
00010   //this->loop_rroscdate_ = 2;//in [Hz]
00011 
00012   // [init publishers]
00013   this->pose_ref_publisher_ = this->public_node_handle_.advertise<geometry_msgs::Pose>("pose_ref", 100);
00014   this->scans_map_publisher_ = this->public_node_handle_.advertise<sensor_msgs::LaserScan>("scans_map", 100);
00015   this->checkpoints_publisher_ = this->public_node_handle_.advertise<visualization_msgs::Marker>("checkpoints", 100);
00017 
00018   // [init subscribers]
00019   this->scan_subscriber_ = this->public_node_handle_.subscribe("scan", 100, &LaserNavigationAlgNode::scan_callback, this);
00020 
00021   // [init services]
00022 
00023   // [init clients]
00024   estimate_client_ = this->public_node_handle_.serviceClient<iri_laser_localisation::DoEstimation>("/iri_laser_localisation/estimate");
00025   localise_client_ = this->public_node_handle_.serviceClient<iri_laser_localisation::DoLocalisation>("/iri_laser_localisation/localise");
00026 
00027   // [init action servers]
00028 
00029   // [init action clients]
00030 
00031   current_ = 0;
00032   new_scan_ = false;
00033   first_=true;
00034 }
00035 
00036 LaserNavigationAlgNode::~LaserNavigationAlgNode(void)
00037 {
00038   // [free dynamic memory]
00039 }
00040 
00042 
00043 void LaserNavigationAlgNode::mainNodeThread(void)
00044 {
00045 
00046 
00048 
00049   if(first_)
00050   {
00052 
00053     ROS_INFO_PRESS("load bag");
00054     load_path_(alg_.config_.bag_path);
00055     first_=false;
00056 
00058 
00059     ROS_INFO_PRESS("estimate initial position");
00060     estimate_srv_.request.pose_est = pose_path_.front();;
00061     if (estimate_client_.call(estimate_srv_))
00062       ROS_INFO("LaserNavigationAlgNode:: Response: %d", estimate_srv_.response.ok);
00063     else
00064       ROS_INFO("LaserNavigationAlgNode:: Failed to Call Server on topic estimate ");
00065 
00067     for(uint j=current_;j<pose_path_.size();j++)
00068       publish_marker(pose_path_[j],0);
00069 
00070      if(alg_.config_.preview_map)
00071     {
00072 
00074 
00075       ROS_WARN("MAP PREVIEW");
00076 
00077       while(current_<pose_path_.size())
00078       {
00079         //ROS_INFO_PRESS("GET NEXT POSE & SCAN");
00080         tf::Transform T_scan_map;
00081         tf::poseMsgToTF(pose_path_[current_].pose,T_scan_map);
00082 
00083         tfb_.sendTransform(tf::StampedTransform(T_scan_map, ros::Time::now(), "/map", "/scan_path"));
00084         scan_path_[current_].header.stamp = ros::Time::now();
00085         scan_path_[current_].header.frame_id = "/scan_path";
00086 
00087         scans_map_publisher_.publish(scan_path_[current_]);
00088         publish_marker(pose_path_[current_],2);
00089         pose_ref_publisher_.publish(pose_path_[current_]);
00090 
00091 
00092         ROS_INFO("scan path %d published",current_);
00093         ROS_INFO_XYR("pose_ref", pose_path_[current_].pose.position.x,
00094                               pose_path_[current_].pose.position.y,
00095                               pose_path_[current_].pose.orientation);
00096         ROS_INFO_XYR("scan transform",T_scan_map);
00097 
00098         current_++;
00099 
00100         usleep(500000);
00101 
00102       }
00103 
00104     }else{
00105 
00106      // ---- INITIAL LOCALISATION ---- 
00107 
00108       scan_mutex_.enter();
00109         localise_srv_.request.scan_sens = scan_sens_;
00110       scan_mutex_.exit();
00111       scan_path_[current_].header.stamp = ros::Time::now();
00112       localise_srv_.request.scan_ref = scan_path_[current_];
00113       localise_srv_.request.pose_ref = pose_path_[current_].pose;
00114 
00115       scans_map_publisher_.publish(scan_path_[current_]);
00116       pose_ref_publisher_.publish(pose_path_[current_]);
00117       ROS_INFO("scan path %d published",current_);
00118       ROS_INFO_XYR("pose_ref", pose_path_[current_].pose.position.x,
00119                               pose_path_[current_].pose.position.y,
00120                               pose_path_[current_].pose.orientation);
00121 
00122 
00123       ROS_INFO_PRESS("localise");
00124       ROS_DEBUG("Laser Navigation: Sending localisation request");
00125 
00126       if (localise_client_.call(localise_srv_))
00127       {
00129         ROS_DEBUG("Laser Navigation: Localised Pose: x=%f y=%f th=%f",
00130                 localise_srv_.response.pose.pose.pose.position.x ,
00131                 localise_srv_.response.pose.pose.pose.position.y ,
00132                 tf::getYaw(localise_srv_.response.pose.pose.pose.orientation));
00133       }
00134       else
00135       {
00136         ROS_ERROR("Laser Navigation: Failed to Call Server on topic localise ");
00137       }
00138 
00139       current_++;
00140     }
00141 
00142   }
00143 
00144 
00145 
00147 
00149 
00150   if(new_scan_){
00151 
00152     new_scan_ = false;
00153 
00155     ROS_WARN("jump next checkpoint? y/n");
00156     // y = 121 ASCII
00157     if(std::cin.get() != 121)
00158     {
00159       ROS_INFO("Move");
00160 
00163       // [fill action structure and make request to the action server]
00164       if( current_ < scan_path_.size() )
00165       {
00166         send_goalMakeActionRequest(pose_path_[current_]);
00167       }
00168       else
00169       {
00171         ROS_WARN("Laser Navigation: Last goal reached");
00172 
00173        exit(1);
00174       }
00175 
00177 
00178       ROS_INFO_PRESS("get path pose");
00179 
00181       scan_mutex_.enter();
00182         localise_srv_.request.scan_sens = scan_sens_;
00183       scan_mutex_.exit();
00184       scan_path_[current_].header.stamp = ros::Time::now();
00185       localise_srv_.request.scan_ref = scan_path_[current_];
00186       localise_srv_.request.pose_ref = pose_path_[current_].pose;
00187 
00188       scans_map_publisher_.publish(scan_path_[current_]);
00189       pose_ref_publisher_.publish(pose_path_[current_]);
00190       ROS_INFO("scan path %d published",current_);
00191       ROS_INFO_XYR("pose_ref", pose_path_[current_].pose.position.x,
00192                                pose_path_[current_].pose.position.y,
00193                                pose_path_[current_].pose.orientation);
00194 
00195       ROS_INFO_PRESS("localise");
00196 
00197       ROS_DEBUG("Laser Navigation: Sending localisation request");
00198       if (localise_client_.call(localise_srv_))
00199       {
00201         ROS_DEBUG("Laser Navigation: Localised Pose: x=%f y=%f th=%f",
00202                 localise_srv_.response.pose.pose.pose.position.x ,
00203                 localise_srv_.response.pose.pose.pose.position.y ,
00204                 tf::getYaw(localise_srv_.response.pose.pose.pose.orientation));
00205       }
00206       else
00207       {
00208         ROS_ERROR("Laser Navigation: Failed to Call Server on topic localise ");
00209       }
00210     }else{
00211       ROS_INFO("Checkpoint Jumped");
00212     }
00213 
00214     current_++;
00215 
00216   }
00217 
00218 }
00219 
00220 /*  [subscriber callbacks] */
00221 void LaserNavigationAlgNode::scan_callback(const sensor_msgs::LaserScan::ConstPtr& msg)
00222 {
00223   //ROS_INFO("LaserNavigationAlgNode::scan_callback: New Message Received");
00224   //use appropiate mutex to shared variables if necessary
00225   //this->alg_.lock();
00226   this->scan_mutex_.enter();
00227   scan_sens_ = *msg;
00228   new_scan_ = true;
00229   //std::cout << msg->data << std::endl;
00230   //unlock previously blocked shared variables
00231   //this->alg_.unlock();
00232   this->scan_mutex_.exit();
00233 }
00234 
00235 /*  [service callbacks] */
00236 
00237 /*  [action callbacks] */
00238 void LaserNavigationAlgNode::send_goalDone(const actionlib::SimpleClientGoalState& state,  const move_base_msgs::MoveBaseResultConstPtr& result)
00239 {
00240   if( state.toString().compare("SUCCEEDED") == 0 )
00241     ROS_INFO("Laser Navigation: Goal Reached");
00242   else
00243     ROS_INFO("Laser Navigation: %s", state.toString().c_str());
00244 
00245   //copy & work with requested result
00246 }
00247 
00248 void LaserNavigationAlgNode::send_goalActive()
00249 {
00250   //ROS_INFO("LaserNavigationAlgNode::send_goalActive: Goal just went active!");
00251 }
00252 
00253 void LaserNavigationAlgNode::send_goalFeedback(const move_base_msgs::MoveBaseFeedbackConstPtr& feedback)
00254 {
00255   //ROS_INFO("LaserNavigationAlgNode::send_goalFeedback: Got Feedback!");
00256 
00257   bool feedback_is_ok = true;
00258 
00259   //analyze feedback
00260   //my_var = feedback->var;
00261 
00262   //if feedback is not what expected, cancel requested goal
00263   if( !feedback_is_ok )
00264   {
00265     send_goal_client_.cancelGoal();
00266     //ROS_INFO("LaserNavigationAlgNode::send_goalFeedback: Cancelling Action!");
00267   }
00268 }
00269 
00271 
00272 /*  [action requests] */
00273 void LaserNavigationAlgNode::send_goalMakeActionRequest(const geometry_msgs::PoseStamped & new_goal)
00274 {
00275   //ROS_INFO("LaserNavigationAlgNode::send_goalMakeActionRequest: Starting New Request!");
00276 
00277   //wait for the action server to start
00278   //will wait for infinite time
00279   ROS_DEBUG("Laser Navigation: Send Goal: Waiting for Server...");
00280   send_goal_client_.waitForServer();
00281 
00282   move_base_msgs::MoveBaseGoal goal;
00283 
00284   goal.target_pose.header = new_goal.header;
00285   goal.target_pose.header.frame_id = alg_.config_.goal_frame;
00286   goal.target_pose.pose   = new_goal.pose;
00287 
00288   publish_marker(new_goal,1);
00289 
00290   ROS_INFO_XYR("New Goal", goal.target_pose.pose.position.x,
00291                            goal.target_pose.pose.position.y,
00292                            goal.target_pose.pose.orientation);
00293 
00294   //send a goal to the action
00295   send_goal_client_.sendGoal(goal,
00296               boost::bind(&LaserNavigationAlgNode::send_goalDone,     this, _1, _2),
00297               boost::bind(&LaserNavigationAlgNode::send_goalActive,   this),
00298               boost::bind(&LaserNavigationAlgNode::send_goalFeedback, this, _1));
00299   ROS_DEBUG("Laser Navigation: Goal Sent. Wait for Result");
00300 
00301     // wait for the action to return
00302   float server_timeout = 100.f; //in [secs]
00303   bool finished_before_timeout = send_goal_client_.waitForResult(ros::Duration(server_timeout));
00304 
00305   //if server replies in time
00306   if (finished_before_timeout)
00307   {
00308     actionlib::SimpleClientGoalState state = send_goal_client_.getState();
00309     ROS_DEBUG("Laser Navigation: Action Succesfully Accomplished!");
00310     ROS_DEBUG("Laser Navigation: Send Goal: %s", state.toString().c_str());
00311   }
00312   else
00313   {
00314     send_goal_client_.cancelGoal();
00315     ROS_WARN("Laser Navigation: Action did NOT finish before Timeout. Cancelling");
00316   }
00317   publish_marker(new_goal,2);
00318 }
00319 
00320 void LaserNavigationAlgNode::node_config_update(Config &config, uint32_t level)
00321 {
00322   this->alg_.lock();
00323 
00324   this->alg_.unlock();
00325 }
00326 
00327 void LaserNavigationAlgNode::addNodeDiagnostics(void)
00328 {
00329 }
00330 
00331 /* main function */
00332 int main(int argc,char *argv[])
00333 {
00334   return algorithm_base::main<LaserNavigationAlgNode>(argc, argv, "laser_navigation_alg_node");
00335 }
00336 
00337 // -----------------------------------------------------------------------------
00338 
00340 
00341 bool LaserNavigationAlgNode::load_path_(const std::string & bag_path)
00342 {
00343   rosbag::Bag bag;
00344   ROS_INFO("Laser Navigation: Load Path: Opening Bag '%s'",bag_path.c_str());
00345   bag.open(bag_path, rosbag::bagmode::Read);
00346 //
00347   std::vector<std::string> topics;
00348   topics.push_back(std::string(alg_.config_.scan_topic));
00349   topics.push_back(std::string(alg_.config_.pose_topic));
00350   rosbag::View view(bag, rosbag::TopicQuery(topics));
00351   int counter=0;
00352   bool get_pose=false;
00353 
00354   BOOST_FOREACH(rosbag::MessageInstance const m, view)
00355   {
00356     if (m.getTopic() == topics[0])
00357     {
00358         sensor_msgs::LaserScan::ConstPtr las;
00359         las = m.instantiate<sensor_msgs::LaserScan>();
00360         ROS_INFO("Scan: %d %d",counter, las->header.seq);
00361         scan_path_.push_back(*las);
00362         scan_path_.back().header.frame_id = std::string(alg_.config_.scan_path_frame_id);
00363         scan_path_.back().header.stamp = ros::Time::now();
00364         get_pose = true;
00365     }
00366 
00367     if(m.getTopic() == topics[1] && get_pose)
00368     {
00369       nav_msgs::Odometry::ConstPtr pose;
00370       pose = m.instantiate<nav_msgs::Odometry>();
00371       ROS_INFO("Pose: %d %d",counter,pose->header.seq);
00372       geometry_msgs::PoseStamped aux;
00373       aux.header = pose->header;
00374       aux.pose = pose->pose.pose;
00375       pose_path_.push_back(aux);
00376       get_pose = false;
00377     }
00378     counter++;
00379   }
00380   bag.close();
00381 
00382   scan_path_.pop_back();
00383   pose_path_.pop_back();
00384 
00385   ROS_INFO("Laser Navigation: Load Path: Bag loaded and closed");
00386   ROS_INFO("Laser Navigation: Load Path: scans: %d poses: %d",scan_path_.size(),pose_path_.size());
00387 
00388   return true;
00389 }
00390 
00392 
00393 void LaserNavigationAlgNode::publish_marker(const geometry_msgs::PoseStamped & pose, const int & type)
00394 {
00395     visualization_msgs::Marker marker;
00396 
00397     marker.header.frame_id = alg_.config_.goal_frame;
00398     marker.header.stamp    = ros::Time();
00399     marker.ns              = "checkpoints";
00400     marker.id              = pose.header.seq;
00401     marker.type            = visualization_msgs::Marker::ARROW;
00402     marker.action          = visualization_msgs::Marker::ADD;
00403 
00404     marker.scale.x = 1;
00405     marker.scale.y = 1;
00406     marker.scale.z = 1;
00407 
00408     marker.pose.position = pose.pose.position;
00409     marker.pose.orientation = pose.pose.orientation;
00410 
00411     float c[4]={1,1,0,0.7};
00412     switch(type){
00413       case 1:
00414         c[1]=0;
00415         break;
00416       case 2:
00417         c[0]=c[1]=c[2]=0.5;
00418         break;
00419     }
00420     marker.color.r = c[0];
00421     marker.color.g = c[1];
00422     marker.color.b = c[2];
00423     marker.color.a = c[3];
00424 
00425     checkpoints_publisher_.publish(marker);
00426     ROS_DEBUG("Marker x:%f y:%f",marker.pose.position.x,marker.pose.position.y);
00427 }
00428 
00429 void LaserNavigationAlgNode::ROS_INFO_PRESS(const std::string & str)
00430 {
00431     ROS_INFO("\033[36mPress 'intro' to %s\033[0m",str.c_str());
00432     //std::cout << "\033[1A";
00433     std::cin.get();
00434 }
00435 
00436 void LaserNavigationAlgNode::ROS_INFO_XYR(const std::string & str,const float & x,const float & y,const geometry_msgs::Quaternion & r)
00437 {
00438   ROS_INFO("Laser Navigation: %s",str.c_str());
00439   ROS_INFO("\033[31mx:\033[0m%f \033[32my:\033[0m%f \033[34mth:\033[0m%f ",
00440            x,y,tf::getYaw(r));
00441 }
00442 
00443 void LaserNavigationAlgNode::ROS_INFO_XYR(const std::string & str,const tf::Transform & tftrans)
00444 {
00445   geometry_msgs::Transform gtrans;
00446   tf::transformTFToMsg(tftrans,gtrans);
00447   ROS_INFO("Laser Localisation: %s",str.c_str());
00448   ROS_INFO("\033[31mx:\033[0m%f \033[32my:\033[0m%f \033[34mth:\033[0m%f ",
00449            gtrans.translation.x,gtrans.translation.y,tf::getYaw(gtrans.rotation));
00450 }
00451 
00452 


iri_laser_navigation
Author(s): Marti
autogenerated on Fri Dec 6 2013 22:54:20