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 <eband_local_planner/eband_local_planner_ros.h>
00039
00040
00041 #include <pluginlib/class_list_macros.h>
00042
00043
00044 #include <nav_core/base_local_planner.h>
00045
00046
00047
00048
00049 PLUGINLIB_EXPORT_CLASS(eband_local_planner::EBandPlannerROS, nav_core::BaseLocalPlanner)
00050
00051
00052 namespace eband_local_planner{
00053
00054 EBandPlannerROS::EBandPlannerROS() : costmap_ros_(NULL), tf_(NULL), initialized_(false) {}
00055
00056
00057 EBandPlannerROS::EBandPlannerROS(std::string name, tf::TransformListener* tf, costmap_2d::Costmap2DROS* costmap_ros)
00058 : costmap_ros_(NULL), tf_(NULL), initialized_(false)
00059 {
00060
00061 initialize(name, tf, costmap_ros);
00062 }
00063
00064
00065 EBandPlannerROS::~EBandPlannerROS() {}
00066
00067
00068 void EBandPlannerROS::initialize(std::string name, tf::TransformListener* tf, costmap_2d::Costmap2DROS* costmap_ros)
00069 {
00070
00071 if(!initialized_)
00072 {
00073
00074 costmap_ros_ = costmap_ros;
00075 tf_ = tf;
00076
00077
00078
00079 ros::NodeHandle pn("~/" + name);
00080
00081
00082 g_plan_pub_ = pn.advertise<nav_msgs::Path>("global_plan", 1);
00083 l_plan_pub_ = pn.advertise<nav_msgs::Path>("local_plan", 1);
00084
00085
00086
00087 ros::NodeHandle gn;
00088 odom_sub_ = gn.subscribe<nav_msgs::Odometry>("odom", 1, boost::bind(&EBandPlannerROS::odomCallback, this, _1));
00089
00090
00091
00092
00093 eband_ = boost::shared_ptr<EBandPlanner>(new EBandPlanner(name, costmap_ros_));
00094
00095
00096 eband_trj_ctrl_ = boost::shared_ptr<EBandTrajectoryCtrl>(new EBandTrajectoryCtrl(name, costmap_ros_));
00097
00098
00099 eband_visual_ = boost::shared_ptr<EBandVisualization>(new EBandVisualization);
00100
00101
00102 eband_->setVisualization(eband_visual_);
00103
00104
00105 eband_trj_ctrl_->setVisualization(eband_visual_);
00106
00107
00108 eband_visual_->initialize(pn, costmap_ros);
00109
00110
00111 drs_.reset(new drs(pn));
00112 drs::CallbackType cb = boost::bind(&EBandPlannerROS::reconfigureCallback, this, _1, _2);
00113 drs_->setCallback(cb);
00114
00115
00116 initialized_ = true;
00117
00118
00119 ROS_DEBUG("Elastic Band plugin initialized.");
00120 }
00121 else
00122 {
00123 ROS_WARN("This planner has already been initialized, doing nothing.");
00124 }
00125 }
00126
00127
00128 void EBandPlannerROS::reconfigureCallback(EBandPlannerConfig& config,
00129 uint32_t level)
00130 {
00131 xy_goal_tolerance_ = config.xy_goal_tolerance;
00132 yaw_goal_tolerance_ = config.yaw_goal_tolerance;
00133 rot_stopped_vel_ = config.rot_stopped_vel;
00134 trans_stopped_vel_ = config.trans_stopped_vel;
00135
00136 if (eband_)
00137 eband_->reconfigure(config);
00138 else
00139 ROS_ERROR("Reconfigure CB called before eband planner initialization");
00140
00141 if (eband_trj_ctrl_)
00142 eband_trj_ctrl_->reconfigure(config);
00143 else
00144 ROS_ERROR("Reconfigure CB called before trajectory controller initialization!");
00145
00146 if (eband_visual_)
00147 eband_visual_->reconfigure(config);
00148 else
00149 ROS_ERROR("Reconfigure CB called before eband visualizer initialization");
00150 }
00151
00152
00153
00154 bool EBandPlannerROS::setPlan(const std::vector<geometry_msgs::PoseStamped>& orig_global_plan)
00155 {
00156
00157
00158 if(!initialized_)
00159 {
00160 ROS_ERROR("This planner has not been initialized, please call initialize() before using this planner");
00161 return false;
00162 }
00163
00164
00165 global_plan_.clear();
00166 global_plan_ = orig_global_plan;
00167
00168
00169
00170 std::vector<int> start_end_counts (2, (int) global_plan_.size());
00171 if(!eband_local_planner::transformGlobalPlan(*tf_, global_plan_, *costmap_ros_, costmap_ros_->getGlobalFrameID(), transformed_plan_, start_end_counts))
00172 {
00173
00174 ROS_WARN("Could not transform the global plan to the frame of the controller");
00175 return false;
00176 }
00177
00178
00179 if(transformed_plan_.empty())
00180 {
00181
00182 ROS_WARN("Transformed plan is empty. Aborting local planner!");
00183 return false;
00184 }
00185
00186
00187 if(!eband_->setPlan(transformed_plan_))
00188 {
00189
00190
00191 costmap_ros_->resetLayers();
00192 if (!eband_->setPlan(transformed_plan_)) {
00193 ROS_ERROR("Setting plan to Elastic Band method failed!");
00194 return false;
00195 }
00196 }
00197 ROS_DEBUG("Global plan set to elastic band for optimization");
00198
00199
00200 plan_start_end_counter_ = start_end_counts;
00201
00202
00203 eband_->optimizeBand();
00204
00205
00206
00207 std::vector<eband_local_planner::Bubble> current_band;
00208 if(eband_->getBand(current_band))
00209 eband_visual_->publishBand("bubbles", current_band);
00210
00211
00212 goal_reached_ = false;
00213
00214 return true;
00215 }
00216
00217
00218 bool EBandPlannerROS::computeVelocityCommands(geometry_msgs::Twist& cmd_vel)
00219 {
00220
00221 if(!initialized_)
00222 {
00223 ROS_ERROR("This planner has not been initialized, please call initialize() before using this planner");
00224 return false;
00225 }
00226
00227
00228
00229 tf::Stamped<tf::Pose> global_pose;
00230 geometry_msgs::PoseStamped global_pose_msg;
00231 std::vector<geometry_msgs::PoseStamped> tmp_plan;
00232
00233
00234 ROS_DEBUG("Reading current robot Position from costmap and appending it to elastic band.");
00235 if(!costmap_ros_->getRobotPose(global_pose))
00236 {
00237 ROS_WARN("Could not retrieve up to date robot pose from costmap for local planning.");
00238 return false;
00239 }
00240
00241
00242 tf::poseStampedTFToMsg(global_pose, global_pose_msg);
00243 tmp_plan.assign(1, global_pose_msg);
00244 eband_local_planner::AddAtPosition add_frames_at = add_front;
00245
00246
00247 if(!eband_->addFrames(tmp_plan, add_frames_at))
00248 {
00249 ROS_WARN("Could not connect robot pose to existing elastic band.");
00250 return false;
00251 }
00252
00253
00254 ROS_DEBUG("Checking for new path frames in moving window");
00255 std::vector<int> plan_start_end_counter = plan_start_end_counter_;
00256 std::vector<geometry_msgs::PoseStamped> append_transformed_plan;
00257
00258 if(!eband_local_planner::transformGlobalPlan(*tf_, global_plan_, *costmap_ros_, costmap_ros_->getGlobalFrameID(), transformed_plan_, plan_start_end_counter))
00259 {
00260
00261 ROS_WARN("Could not transform the global plan to the frame of the controller");
00262 return false;
00263 }
00264
00265
00266 if(transformed_plan_.empty())
00267 {
00268
00269 ROS_WARN("Transformed plan is empty. Aborting local planner!");
00270 return false;
00271 }
00272
00273 ROS_DEBUG("Retrieved start-end-counts are: (%d, %d)", plan_start_end_counter.at(0), plan_start_end_counter.at(1));
00274 ROS_DEBUG("Current start-end-counts are: (%d, %d)", plan_start_end_counter_.at(0), plan_start_end_counter_.at(1));
00275
00276
00277 append_transformed_plan.clear();
00278
00279 if(plan_start_end_counter_.at(1) > plan_start_end_counter.at(1))
00280 {
00281
00282 if(plan_start_end_counter_.at(1) > plan_start_end_counter.at(0))
00283 {
00284
00285 append_transformed_plan = transformed_plan_;
00286 }
00287 else
00288 {
00289
00290 int discarded_frames = plan_start_end_counter.at(0) - plan_start_end_counter_.at(1);
00291 ROS_ASSERT(transformed_plan_.begin() + discarded_frames + 1 >= transformed_plan_.begin());
00292 ROS_ASSERT(transformed_plan_.begin() + discarded_frames + 1 < transformed_plan_.end());
00293 append_transformed_plan.assign(transformed_plan_.begin() + discarded_frames + 1, transformed_plan_.end());
00294 }
00295
00296
00297 ROS_DEBUG("Adding %d new frames to current band", (int) append_transformed_plan.size());
00298 add_frames_at = add_back;
00299 if(eband_->addFrames(append_transformed_plan, add_back))
00300 {
00301
00302 ROS_DEBUG("Sucessfully added frames to band");
00303 plan_start_end_counter_ = plan_start_end_counter;
00304 }
00305 else {
00306 ROS_WARN("Failed to add frames to existing band");
00307 return false;
00308 }
00309 }
00310 else
00311 ROS_DEBUG("Nothing to add");
00312
00313
00314 ROS_DEBUG("Calling optimization method for elastic band");
00315 std::vector<eband_local_planner::Bubble> current_band;
00316 if(!eband_->optimizeBand())
00317 {
00318 ROS_WARN("Optimization failed - Band invalid - No controls availlable");
00319
00320 if(eband_->getBand(current_band))
00321 eband_visual_->publishBand("bubbles", current_band);
00322 return false;
00323 }
00324
00325
00326 eband_->getBand(current_band);
00327
00328 if(!eband_trj_ctrl_->setBand(current_band))
00329 {
00330 ROS_DEBUG("Failed to to set current band to Trajectory Controller");
00331 return false;
00332 }
00333
00334
00335 if(!eband_trj_ctrl_->setOdometry(base_odom_))
00336 {
00337 ROS_DEBUG("Failed to to set current odometry to Trajectory Controller");
00338 return false;
00339 }
00340
00341
00342 geometry_msgs::Twist cmd_twist;
00343 if(!eband_trj_ctrl_->getTwist(cmd_twist, goal_reached_))
00344 {
00345 ROS_DEBUG("Failed to calculate Twist from band in Trajectory Controller");
00346 return false;
00347 }
00348
00349
00350
00351 ROS_DEBUG("Retrieving velocity command: (%f, %f, %f)", cmd_twist.linear.x, cmd_twist.linear.y, cmd_twist.angular.z);
00352 cmd_vel = cmd_twist;
00353
00354
00355
00356 std::vector<geometry_msgs::PoseStamped> refined_plan;
00357 if(eband_->getPlan(refined_plan))
00358
00359 base_local_planner::publishPlan(refined_plan, g_plan_pub_);
00360
00361
00362
00363 if(eband_->getBand(current_band))
00364 eband_visual_->publishBand("bubbles", current_band);
00365
00366 return true;
00367 }
00368
00369
00370 bool EBandPlannerROS::isGoalReached()
00371 {
00372
00373 if(!initialized_)
00374 {
00375 ROS_ERROR("This planner has not been initialized, please call initialize() before using this planner");
00376 return false;
00377 }
00378
00379 return goal_reached_;
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402 }
00403
00404
00405 void EBandPlannerROS::odomCallback(const nav_msgs::Odometry::ConstPtr& msg)
00406 {
00407
00408 boost::mutex::scoped_lock lock(odom_mutex_);
00409
00410
00411 base_odom_.twist.twist.linear.x = msg->twist.twist.linear.x;
00412 base_odom_.twist.twist.linear.y = msg->twist.twist.linear.y;
00413 base_odom_.twist.twist.angular.z = msg->twist.twist.angular.z;
00414 }
00415
00416
00417 }
00418
00419