Go to the documentation of this file.00001 #include <nlj_laser/nj_laser.h>
00002 #include <nlj_laser/hist.h>
00003 NJLaser::NJLaser(const std::string& name, const std::string& get_service_name) :
00004 lama_jockeys::NavigatingJockey(name),
00005 get_service_name_(get_service_name),
00006 mean_traversing_time_(2.0),
00007 max_traversing_delta_(0.5)
00008 {
00009 }
00010
00011 void NJLaser::onStop()
00012 {
00013 ROS_DEBUG("NJLaser STOP");
00014 laser_scan_subscriber_.shutdown();
00015 result_.final_state = lama_jockeys::NavigateResult::STOPPED;
00016 result_.completion_time = ros::Duration(0);
00017 server_.setSucceeded(result_);
00018 }
00019
00020
00021
00022 void NJLaser::onTraverse()
00023 {
00024 ROS_DEBUG("NJLaser TRAVERSING");
00025 ros::Time start_time = ros::Time::now();
00026 nlj_laser::GetLaserDescriptor dg;
00027 assigned_ = false;
00028 completed_ = false;
00029 dg.request.id = goal_.descriptor_link.descriptor_id;
00030 ROS_INFO("goal.descriptor: %d", goal_.descriptor_link.descriptor_id);
00031 ros::service::call(get_service_name_, dg);
00032 actual_trajectory_descriptor_ = dg.response.descriptor;
00033 laser_scan_subscriber_ = nh_.subscribe<sensor_msgs::LaserScan> ("base_scan",50,&NJLaser::handleLaser,this);
00034 cmd_vel_publisher_ = nh_.advertise<geometry_msgs::Twist> ("nav_cmd",1,false);
00035
00036
00037 ros::Rate r(10);
00038 while (ros::ok())
00039 {
00040 if (server_.isPreemptRequested() && !ros::ok())
00041 {
00042 ROS_INFO_STREAM(jockey_name_ << ": Preempted");
00043 break;
00044 }
00045 ros::spinOnce();
00046 r.sleep();
00047 ros::Time current_time = ros::Time::now();
00048 ros::Duration real_time_elapsed = current_time - start_time;
00049 ros::Duration time_elapsed_for_task;
00050 if (isInterrupted())
00051 {
00052
00053 time_elapsed_for_task = getInterruptionTime() - start_time - getInterruptionsDuration();
00054 }
00055 else
00056 {
00057
00058 time_elapsed_for_task = real_time_elapsed - getInterruptionsDuration();
00059 }
00060 feedback_.current_state = lama_jockeys::NavigateFeedback::TRAVERSING;
00061 feedback_.time_elapsed = time_elapsed_for_task;
00062 feedback_.completion = completion();
00063 server_.publishFeedback(feedback_);
00064
00065
00066 if (completed_)
00067 {
00068 result_.final_state = lama_jockeys::NavigateResult::DONE;
00069 result_.completion_time = real_time_elapsed;
00070 server_.setSucceeded(result_);
00071 break;
00072 }
00073 }
00074 laser_scan_subscriber_.shutdown();
00075 ROS_DEBUG("NAVIGATION completed");
00076 }
00077
00078
00079 void NJLaser::onInterrupt()
00080 {
00081 laser_scan_subscriber_.shutdown();
00082 }
00083
00084 void NJLaser::onContinue()
00085 {
00086 ROS_DEBUG_STREAM(jockey_name_ << ": continue");
00087 laser_scan_subscriber_ = nh_.subscribe<sensor_msgs::LaserScan> ("base_scan",50,&NJLaser::handleLaser,this);
00088 }
00089
00090 void NJLaser::handleLaser(sensor_msgs::LaserScan msg) {
00091 if (!assigned_)
00092 {
00093 completed_ = false;
00094 navigation_index_ = 0;
00095 reference_laser_scan_ = actual_trajectory_descriptor_.scans[navigation_index_++];
00096 assigned_ = true;
00097 }
00098 int angle_histogram_bin_number = 100;
00099 float min_distance = 0.05;
00100
00101 geometry_msgs::Pose2D goal = localize(msg, reference_laser_scan_, angle_histogram_bin_number);
00102 geometry_msgs::Pose2D fix;
00103 fix.x= fix.y=fix.theta = 0;
00104
00105 float distance = sqrt (goal.x*goal.x+goal.y*goal.y) ;
00106
00107 if (distance < min_distance)
00108 {
00109 ROS_DEBUG_STREAM(jockey_name_<< "distance shorter than min nav index" << navigation_index_ <<" from "<< actual_trajectory_descriptor_.scans.size());
00110 if (navigation_index_ < actual_trajectory_descriptor_.scans.size())
00111 {
00112 reference_laser_scan_ = actual_trajectory_descriptor_.scans[navigation_index_++];
00113 }
00114 else
00115 {
00116 completed_ = true;
00117 ROS_DEBUG("completed");
00118 }
00119 }
00120 if (!completed_)
00121 {
00122
00123 float deviation = atan2(goal.y, goal.x)*0.5;
00124 if (deviation > 0.8)
00125 deviation = 0.8;
00126 if (deviation < -0.8)
00127 deviation = -0.8;
00128 float speed = 2*distance *(0.8-fabs(deviation)) ;
00129 if (speed < -0.05)
00130 speed = -0.05;
00131
00132
00133 geometry_msgs::Twist pub_msg;
00134 pub_msg.linear.x = 0.9*speed;
00135 pub_msg. angular.z = 1.1*deviation;
00136 ROS_DEBUG("speed x %f, y %f",pub_msg.linear.x, pub_msg.angular.z);
00137 cmd_vel_publisher_.publish(pub_msg);
00138 }
00139 else
00140 {
00141 geometry_msgs::Twist pub_msg;
00142 pub_msg.linear.x = 0;
00143 pub_msg. angular.z = 0 ;
00144 cmd_vel_publisher_.publish(pub_msg);
00145 }
00146 }
00147
00148 double NJLaser::completion()
00149 {
00150 return (1.0*navigation_index_-1)/actual_trajectory_descriptor_.scans.size();
00151 }
00152