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
00039 #ifndef TIMED_ELASTIC_BAND_H_
00040 #define TIMED_ELASTIC_BAND_H_
00041
00042 #include <ros/ros.h>
00043 #include <ros/assert.h>
00044
00045 #include <geometry_msgs/PoseStamped.h>
00046 #include <geometry_msgs/PoseArray.h>
00047 #include <tf/tf.h>
00048
00049 #include <complex>
00050 #include <iterator>
00051
00052 #include <teb_local_planner/obstacles.h>
00053
00054
00055 #include <teb_local_planner/g2o_types/vertex_pose.h>
00056 #include <teb_local_planner/g2o_types/vertex_timediff.h>
00057
00058
00059 namespace teb_local_planner
00060 {
00061
00063 typedef std::vector<VertexPose*> PoseSequence;
00065 typedef std::vector<VertexTimeDiff*> TimeDiffSequence;
00066
00067
00086 class TimedElasticBand
00087 {
00088 public:
00089
00093 TimedElasticBand();
00094
00098 virtual ~TimedElasticBand();
00099
00100
00101
00104
00109 PoseSequence& poses() {return pose_vec_;};
00110
00115 const PoseSequence& poses() const {return pose_vec_;};
00116
00121 TimeDiffSequence& timediffs() {return timediff_vec_;};
00122
00127 const TimeDiffSequence& timediffs() const {return timediff_vec_;};
00128
00134 double& TimeDiff(unsigned int index)
00135 {
00136 ROS_ASSERT(index<sizeTimeDiffs());
00137 return timediff_vec_.at(index)->dt();
00138 }
00139
00145 const double& TimeDiff(unsigned int index) const
00146 {
00147 ROS_ASSERT(index<sizeTimeDiffs());
00148 return timediff_vec_.at(index)->dt();
00149 }
00150
00156 PoseSE2& Pose(unsigned int index)
00157 {
00158 ROS_ASSERT(index<sizePoses());
00159 return pose_vec_.at(index)->pose();
00160 }
00161
00167 const PoseSE2& Pose(unsigned int index) const
00168 {
00169 ROS_ASSERT(index<sizePoses());
00170 return pose_vec_.at(index)->pose();
00171 }
00172
00176 PoseSE2& BackPose() {return pose_vec_.back()->pose(); }
00177
00181 const PoseSE2& BackPose() const {return pose_vec_.back()->pose();}
00182
00186 double& BackTimeDiff() {return timediff_vec_.back()->dt(); }
00187
00191 const double& BackTimeDiff() const {return timediff_vec_.back()->dt(); }
00192
00198 VertexPose* PoseVertex(unsigned int index)
00199 {
00200 ROS_ASSERT(index<sizePoses());
00201 return pose_vec_.at(index);
00202 }
00203
00209 VertexTimeDiff* TimeDiffVertex(unsigned int index)
00210 {
00211 ROS_ASSERT(index<sizeTimeDiffs());
00212 return timediff_vec_.at(index);
00213 }
00214
00216
00217
00218
00221
00227 void addPose(const PoseSE2& pose, bool fixed=false);
00228
00235 void addPose(const Eigen::Ref<const Eigen::Vector2d>& position, double theta, bool fixed=false);
00236
00244 void addPose(double x, double y, double theta, bool fixed=false);
00245
00251 void addTimeDiff(double dt, bool fixed=false);
00252
00261 void addPoseAndTimeDiff(const PoseSE2& pose, double dt);
00262
00270 void addPoseAndTimeDiff(const Eigen::Ref<const Eigen::Vector2d>& position, double theta, double dt);
00271
00280 void addPoseAndTimeDiff(double x, double y, double theta, double dt);
00281
00283
00284
00287
00293 void insertPose(unsigned int index, const PoseSE2& pose);
00294
00301 void insertPose(unsigned int index, const Eigen::Ref<const Eigen::Vector2d>& position, double theta);
00302
00310 void insertPose(unsigned int index, double x, double y, double theta);
00311
00317 void insertTimeDiff(unsigned int index, double dt);
00318
00323 void deletePose(unsigned int index);
00324
00330 void deletePoses(unsigned int index, unsigned int number);
00331
00336 void deleteTimeDiff(unsigned int index);
00337
00343 void deleteTimeDiffs(unsigned int index, unsigned int number);
00344
00346
00347
00350
00368 bool initTEBtoGoal(const PoseSE2& start, const PoseSE2& goal, double diststep=0, double timestep=1, int min_samples = 3);
00369
00370
00404 template<typename BidirIter, typename Fun>
00405 bool initTEBtoGoal(BidirIter path_start, BidirIter path_end, Fun fun_position, double max_vel_x, double max_vel_theta,
00406 boost::optional<double> max_acc_x, boost::optional<double> max_acc_theta,
00407 boost::optional<double> start_orientation, boost::optional<double> goal_orientation, int min_samples = 3);
00408
00423 bool initTEBtoGoal(const std::vector<geometry_msgs::PoseStamped>& plan, double dt, bool estimate_orient=false, int min_samples = 3);
00424
00426
00429
00430
00446 void updateAndPruneTEB(boost::optional<const PoseSE2&> new_start, boost::optional<const PoseSE2&> new_goal, int min_samples = 3);
00447
00448
00475 void autoResize(double dt_ref, double dt_hysteresis, int min_samples = 3);
00476
00477
00483 void setPoseVertexFixed(unsigned int index, bool status);
00484
00490 void setTimeDiffVertexFixed(unsigned int index, bool status);
00491
00496 void clearTimedElasticBand();
00497
00499
00500
00503
00518 int findClosestTrajectoryPose(const Eigen::Ref<const Eigen::Vector2d>& ref_point, double* distance = NULL, int begin_idx=0) const;
00519
00534 int findClosestTrajectoryPose(const Eigen::Ref<const Eigen::Vector2d>& ref_line_start, const Eigen::Ref<const Eigen::Vector2d>& ref_line_end, double* distance = NULL) const;
00535
00549 int findClosestTrajectoryPose(const Point2dContainer& vertices, double* distance = NULL) const;
00550
00562 int findClosestTrajectoryPose(const Obstacle& obstacle, double* distance = NULL) const;
00563
00564
00568 std::size_t sizePoses() const {return pose_vec_.size();};
00569
00573 std::size_t sizeTimeDiffs() const {return timediff_vec_.size();};
00574
00578 bool isInit() const {return !timediff_vec_.empty() && !pose_vec_.empty();}
00579
00583 double getSumOfAllTimeDiffs() const;
00584
00588 double getAccumulatedDistance() const;
00589
00604 bool detectDetoursBackwards(double threshold=0) const;
00605
00606
00608
00609 protected:
00610 PoseSequence pose_vec_;
00611 TimeDiffSequence timediff_vec_;
00612
00613 public:
00614 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00615 };
00616
00617 }
00618
00619
00620
00621 #include <teb_local_planner/timed_elastic_band.hpp>
00622
00623
00624 #endif