00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <dt_local_planner/dt_planner_ros.h>
00039 #include <dt_local_planner/polyfit.hpp>
00040 #include <cmath>
00041 #include <limits>
00042 #include <ros/console.h>
00043 #include <pluginlib/class_list_macros.h>
00044 #include <base_local_planner/goal_functions.h>
00045 #include <nav_msgs/Path.h>
00046 #include <angles/angles.h>
00047
00048
00049 PLUGINLIB_EXPORT_CLASS(dt_local_planner::DTPlannerROS, nav_core::BaseLocalPlanner)
00050
00051 namespace dt_local_planner {
00052
00053 void DTPlannerROS::reconfigureCB(DTPlannerConfig &config, uint32_t level) {
00054 max_vel_ = config.max_vel;
00055 max_ang_ = config.max_ang;
00056 max_vel_deltaT0_ = config.max_vel_deltaT0;
00057 stepCnt_max_vel_ = config.stepCnt_max_vel;
00058 nPolyGrad_ = config.nPolyGrad;
00059 K_p_ = config.K_p;
00060 K_d_ = config.K_d;
00061 move_ = config.move;
00062 }
00063
00064 DTPlannerROS::DTPlannerROS() : initialized_(false),goal_reached_(false), firstComputeVelocityCommands_(true) {
00065
00066 }
00067
00068 void DTPlannerROS::initialize(
00069 std::string name,
00070 tf::TransformListener* tf,
00071 costmap_2d::Costmap2DROS* costmap_ros) {
00072 if (! isInitialized()) {
00073
00074 ros::NodeHandle private_nh("~/" + name);
00075 tf_ = tf;
00076 costmap_ros_ = costmap_ros;
00077
00078
00079 costmap_2d::Costmap2D* costmap = costmap_ros_->getCostmap();
00080
00081 std::string odom_topic;
00082 private_nh.param<std::string>("odom_topic", odom_topic, "odom");
00083 odom_helper_.setOdomTopic( odom_topic );
00084
00085 initialized_ = true;
00086
00087 dsrv_ = new dynamic_reconfigure::Server<DTPlannerConfig>(private_nh);
00088 dynamic_reconfigure::Server<DTPlannerConfig>::CallbackType cb = boost::bind(&DTPlannerROS::reconfigureCB, this, _1, _2);
00089 dsrv_->setCallback(cb);
00090 }
00091 else{
00092 ROS_WARN("This planner has already been initialized, doing nothing.");
00093 }
00094 }
00095
00096 bool DTPlannerROS::setPlan(const std::vector<geometry_msgs::PoseStamped>& orig_global_plan) {
00097 if (! isInitialized()) {
00098 ROS_ERROR("This planner has not been initialized, please call initialize() before using this planner");
00099 return false;
00100 }
00101
00102
00103 plan_ = orig_global_plan;
00104 planSize_ = plan_.size();
00105 ROS_INFO_NAMED("dt_local_planner", "Got new plan with size: %d",planSize_);
00106
00107
00108 goal_x_ = plan_[planSize_-1].pose.position.x;
00109 goal_y_ = plan_[planSize_-1].pose.position.y;
00110
00111
00112 std::vector<double> p_x (planSize_, 0.);
00113 std::vector<double> p_y (planSize_, 0.);
00114 std::vector<double> p_t (planSize_, 0.);
00115
00116
00117 for(int index = 0;index < planSize_;index++){
00118 p_x[index] = plan_[index].pose.position.x;
00119 p_y[index] = plan_[index].pose.position.y;
00120
00121 }
00122 ROS_INFO_NAMED("dt_local_planner", "p_x,p_y generated!");
00123
00124
00125 double max_vel_deltaT;
00126 double deltaR;
00127 double deltaT;
00128
00129
00130
00131
00132 for(int index = 1;index < planSize_;index++){
00133 deltaR = sqrt( pow(p_x[index] - p_x[index-1], 2.0) + pow(p_y[index] - p_y[index-1], 2.0) );
00134 if(index <= stepCnt_max_vel_){
00135 max_vel_deltaT = max_vel_deltaT0_*index/stepCnt_max_vel_;
00136 }
00137 deltaT = deltaR / max_vel_deltaT;
00138 p_t[index] = p_t[index-1] + deltaT;
00139
00140 }
00141 ROS_INFO_NAMED("dt_local_planner", "p_t generated!");
00142
00143
00144
00145
00146
00147
00148 aCoeff_x_ = polyfit(p_t, p_x, nPolyGrad_);
00149 aCoeff_y_ = polyfit(p_t, p_y, nPolyGrad_);
00150 ROS_INFO_NAMED("dt_local_planner", "Calculated polyfit for x and y with grade %d",
00151 nPolyGrad_);
00152
00153
00154 goal_reached_ = false;
00155
00156 ROS_INFO_NAMED("dt_local_planner", "----------------------");
00157 return true;
00158 }
00159
00160 bool DTPlannerROS::isGoalReached() {
00161 if (! isInitialized()) {
00162 ROS_ERROR("This planner has not been initialized, please call initialize() before using this planner");
00163 return false;
00164 }
00165 return goal_reached_;
00166 }
00167
00168 DTPlannerROS::~DTPlannerROS(){
00169
00170 delete dsrv_;
00171 }
00172
00173 bool DTPlannerROS::computeVelocityCommands(geometry_msgs::Twist& cmd_vel) {
00174
00175 if( plan_.size() < 2) {
00176 return false;
00177 }
00178
00179 if(firstComputeVelocityCommands_){
00180 start_time_ = ros::Time::now().toSec();
00181 lastCall_time_ = start_time_;
00182 }
00183
00184
00185 tf::Stamped<tf::Pose> current_pose;
00186 costmap_ros_->getRobotPose(current_pose);
00187 double pos_cur_x = current_pose.getOrigin().x();
00188 double pos_cur_y = current_pose.getOrigin().y();
00189 double gamma_cur = tf::getYaw(current_pose.getRotation());
00190 ROS_INFO_NAMED("dt_local_planner", "Current position (costmap) is (%f, %f) with Angular (%f)",
00191 pos_cur_x, pos_cur_y, gamma_cur);
00192
00193
00194 double dist_x = fabs(goal_x_ - current_pose.getOrigin().x());
00195 double dist_y = fabs(goal_y_ - current_pose.getOrigin().x());
00196 ROS_INFO_NAMED("dt_local_planner", "Current distance to goal (%f, %f)",dist_x, dist_y);
00197
00198
00199 if(move_){
00200 ROS_INFO_NAMED("dt_local_planner", "preparing to move:");
00201
00202
00203 tf::Stamped<tf::Pose> robot_vel;
00204 odom_helper_.getRobotVel(robot_vel);
00205 double vel_cur_lin = robot_vel.getOrigin().x();
00206 double vel_cur_ang = robot_vel.getOrigin().y();
00207
00208
00209
00210
00211
00212
00213
00214 ROS_INFO_NAMED("dt_local_planner", "Current robot velocity (lin/ang): (%f/%f)", vel_cur_lin,vel_cur_ang);
00215
00216
00217 double current_time = ros::Time::now().toSec() - start_time_;
00218 ROS_INFO_NAMED("dt_local_planner", "time in seconds: %f",current_time);
00219
00220 std::vector<double> time_vec (nPolyGrad_, 0.);
00221
00222 for(int index = 0; index < nPolyGrad_;index++){
00223 time_vec[index] = pow(current_time,index);
00224
00225 }
00226
00227
00228 double temp_x = 0;
00229 double temp_y = 0;
00230 double pos_dest_x = 0;
00231 double pos_dest_y = 0;
00232 double vel_dest_x = 0;
00233 double vel_dest_y = 0;
00234 double acc_dest_x = 0;
00235 double acc_dest_y = 0;
00236
00237 for(int i=0;i<nPolyGrad_;i++)
00238 {
00239 temp_x = aCoeff_x_[i]*time_vec[i];
00240 temp_y = aCoeff_y_[i]*time_vec[i];
00241 pos_dest_x += temp_x;
00242 pos_dest_y += temp_y;
00243 }
00244 ROS_INFO_NAMED("dt_local_planner", "p_x0=%f and p_y0=%f",pos_dest_x,pos_dest_y);
00245 for(int i=1;i<nPolyGrad_-1;i++)
00246 {
00247 temp_x = aCoeff_x_[i]*i*time_vec[i-1];
00248 temp_y = aCoeff_y_[i]*i*time_vec[i-1];
00249 vel_dest_x += temp_x;
00250 vel_dest_y += temp_y;
00251 }
00252 ROS_INFO_NAMED("dt_local_planner", "p_x1=%f and p_y1=%f",vel_dest_x,vel_dest_y);
00253 for(int i=2;i<nPolyGrad_-2;i++)
00254 {
00255 temp_x = aCoeff_x_[i]*i*(i+1)*time_vec[i-2];
00256 temp_y = aCoeff_y_[i]*i*(i+1)*time_vec[i-2];
00257 acc_dest_x += temp_x;
00258 acc_dest_y += temp_y;
00259 }
00260 ROS_INFO_NAMED("dt_local_planner", "p_x2=%f and p_y2=%f",acc_dest_x,acc_dest_y);
00261
00262
00263 if(firstComputeVelocityCommands_){
00264 double vel_dest_x0 = vel_dest_x;
00265 double vel_dest_y0 = vel_dest_y;
00266 vel_dest0_ = sqrt(fabs(vel_dest_x0) + fabs(vel_dest_y0));
00267 ROS_INFO_NAMED("dt_local_planner", "sqrt(vel_dest_x0(%f)+vel_dest_y0(%f))=vel_dest0_(%f)",vel_dest_x0,vel_dest_y0,vel_dest0_);
00268 }
00269
00270
00271 double lambda_x = acc_dest_x + K_d_ * (vel_dest_x - vel_cur_lin * cos(gamma_cur)) + K_p_ * (pos_dest_x - pos_cur_x);
00272 double lambda_y = acc_dest_y + K_d_ * (vel_dest_y - vel_cur_lin * sin(gamma_cur)) + K_p_ * (pos_dest_y - pos_cur_y);
00273 ROS_INFO_NAMED("dt_local_planner", "lambda x, y: (%f, %f)",lambda_x, lambda_y);
00274
00275 double acc_l = cos( gamma_cur ) * lambda_x + sin( gamma_cur ) * lambda_y;
00276
00277
00278 double omega = 0;
00279 if(fabs(vel_cur_lin) > 0.001){
00280 omega = (-sin(gamma_cur) * lambda_x + cos(gamma_cur) * lambda_y) / vel_cur_lin;
00281 }
00282
00283
00284
00285 double delta_time = ros::Time::now().toSec() - lastCall_time_;
00286 ROS_INFO_NAMED("dt_local_planner", "deltaT in seconds: %f",delta_time);
00287
00288 double vel_dest1 = vel_dest0_ + acc_l * delta_time;
00289 ROS_INFO_NAMED("dt_local_planner", "vel_dest0_ + acc_l: (%f, %f)", vel_dest0_, acc_l*delta_time);
00290 double gamma_dest1 = gamma_dest0_ + omega * delta_time;
00291
00292
00293 vel_dest0_ = vel_dest1;
00294 gamma_dest0_ = gamma_dest1;
00295 lastCall_time_ = current_time;
00296
00297
00298 ROS_INFO_NAMED("dt_local_planner", "Trying to set velocity and angular speed: (%f, %f)",
00299 vel_dest1, gamma_dest1);
00300 if(max_vel_ < fabs(vel_dest1)){
00301 ROS_WARN_NAMED("dt_local_planner", "speed exceed: velocity set to: %f m/s",max_vel_);
00302 cmd_vel.linear.x = max_vel_;
00303 }else{
00304 cmd_vel.linear.x = vel_dest1;
00305 }
00306 if(max_ang_ < fabs(gamma_dest1)){
00307 cmd_vel.angular.z = max_ang_;
00308 ROS_WARN_NAMED("dt_local_planner", "speed exceed: angular velocity set to: %f m/s",max_ang_);
00309 }else{
00310 cmd_vel.angular.z = gamma_dest1;
00311 }
00312 }else
00313 {
00314 ROS_INFO_NAMED("dt_local_planner", "goal reached");
00315 if(!goal_reached_) goal_reached_ = true;
00316 cmd_vel.linear.x = 0;
00317 cmd_vel.angular.z = 0;
00318 }
00319
00320
00321 if(firstComputeVelocityCommands_) firstComputeVelocityCommands_ = false;
00322
00323
00324 ROS_INFO_NAMED("dt_local_planner", "----------------------");
00325 return true;
00326
00327
00328 }
00329
00330 };