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
00010
00011
00012
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
00019 this->scan_subscriber_ = this->public_node_handle_.subscribe("scan", 100, &LaserNavigationAlgNode::scan_callback, this);
00020
00021
00022
00023
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
00028
00029
00030
00031 current_ = 0;
00032 new_scan_ = false;
00033 first_=true;
00034 }
00035
00036 LaserNavigationAlgNode::~LaserNavigationAlgNode(void)
00037 {
00038
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
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
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
00157 if(std::cin.get() != 121)
00158 {
00159 ROS_INFO("Move");
00160
00163
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
00221 void LaserNavigationAlgNode::scan_callback(const sensor_msgs::LaserScan::ConstPtr& msg)
00222 {
00223
00224
00225
00226 this->scan_mutex_.enter();
00227 scan_sens_ = *msg;
00228 new_scan_ = true;
00229
00230
00231
00232 this->scan_mutex_.exit();
00233 }
00234
00235
00236
00237
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
00246 }
00247
00248 void LaserNavigationAlgNode::send_goalActive()
00249 {
00250
00251 }
00252
00253 void LaserNavigationAlgNode::send_goalFeedback(const move_base_msgs::MoveBaseFeedbackConstPtr& feedback)
00254 {
00255
00256
00257 bool feedback_is_ok = true;
00258
00259
00260
00261
00262
00263 if( !feedback_is_ok )
00264 {
00265 send_goal_client_.cancelGoal();
00266
00267 }
00268 }
00269
00271
00272
00273 void LaserNavigationAlgNode::send_goalMakeActionRequest(const geometry_msgs::PoseStamped & new_goal)
00274 {
00275
00276
00277
00278
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
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
00302 float server_timeout = 100.f;
00303 bool finished_before_timeout = send_goal_client_.waitForResult(ros::Duration(server_timeout));
00304
00305
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
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
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