Go to the documentation of this file.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 #ifndef TRAJECTORY_TRACKER_PATH2D_H
00031 #define TRAJECTORY_TRACKER_PATH2D_H
00032
00033 #include <vector>
00034 #include <limits>
00035
00036 #include <Eigen/Core>
00037 #include <Eigen/Geometry>
00038
00039 #include <geometry_msgs/Pose.h>
00040 #include <tf2/utils.h>
00041
00042 #include <trajectory_tracker/eigen_line.h>
00043 #include <trajectory_tracker/average.h>
00044
00045 namespace trajectory_tracker
00046 {
00047 class Pose2D
00048 {
00049 public:
00050 Eigen::Vector2d pos_;
00051 float yaw_;
00052 float velocity_;
00053
00054 inline Pose2D()
00055 : pos_(0, 0)
00056 , yaw_(0)
00057 , velocity_(0)
00058 {
00059 }
00060 inline Pose2D(const Eigen::Vector2d& p, float y, float velocity)
00061 : pos_(p)
00062 , yaw_(y)
00063 , velocity_(velocity)
00064 {
00065 }
00066 inline explicit Pose2D(const geometry_msgs::Pose& pose, float velocity)
00067 : pos_(Eigen::Vector2d(pose.position.x, pose.position.y))
00068 , yaw_(tf2::getYaw(pose.orientation))
00069 , velocity_(velocity)
00070 {
00071 }
00072 };
00073 class Path2D : public std::vector<Pose2D>
00074 {
00075 private:
00076 using Super = std::vector<Pose2D>;
00077
00078 public:
00079 using Iterator = std::vector<Pose2D>::iterator;
00080 using ConstIterator = std::vector<Pose2D>::const_iterator;
00081
00082 inline float length() const
00083 {
00084 double l = 0;
00085 for (size_t i = 1; i < size(); i++)
00086 l += ((*this)[i - 1].pos_ - (*this)[i].pos_).norm();
00087 return l;
00088 }
00089 inline ConstIterator findLocalGoal(
00090 const ConstIterator& begin,
00091 const ConstIterator& end,
00092 const bool allow_backward_motion) const
00093 {
00094 float sign_vel_prev = 0;
00095 ConstIterator it_prev = begin;
00096 for (ConstIterator it = begin + 1; it < end; ++it)
00097 {
00098 const Eigen::Vector2d inc = it->pos_ - it_prev->pos_;
00099
00100
00101 const float angle = atan2(inc[1], inc[0]);
00102 const float angle_pose = allow_backward_motion ? it->yaw_ : angle;
00103 const float sign_vel_req = std::cos(angle) * std::cos(angle_pose) + std::sin(angle) * std::sin(angle_pose);
00104 if (sign_vel_prev * sign_vel_req < 0)
00105 return it;
00106 sign_vel_prev = sign_vel_req;
00107 it_prev = it;
00108 }
00109 return end;
00110 }
00111 inline ConstIterator findNearest(
00112 const ConstIterator& begin,
00113 const ConstIterator& end,
00114 const Eigen::Vector2d& target,
00115 const float max_search_range = 0) const
00116 {
00117 float distance_path_search = 0;
00118 float min_dist = std::numeric_limits<float>::max();
00119 ConstIterator it_nearest = Super::end();
00120
00121 ConstIterator it_prev = begin;
00122 for (ConstIterator it = begin + 1; it < end; ++it)
00123 {
00124 const Eigen::Vector2d inc = it->pos_ - it_prev->pos_;
00125 distance_path_search += inc.norm();
00126 if (max_search_range > 0 && distance_path_search > max_search_range)
00127 break;
00128
00129 const float d =
00130 trajectory_tracker::lineStripDistance(it_prev->pos_, it->pos_, target);
00131 if (d <= min_dist)
00132 {
00133 min_dist = d;
00134 it_nearest = it;
00135 }
00136 it_prev = it;
00137 }
00138 return it_nearest;
00139 }
00140 inline double remainedDistance(
00141 const ConstIterator& begin,
00142 const ConstIterator& nearest,
00143 const ConstIterator& end,
00144 const Eigen::Vector2d& target_on_line) const
00145 {
00146 double remain = (nearest->pos_ - target_on_line).norm();
00147 if (nearest + 1 >= end)
00148 {
00149 const ConstIterator last = end - 1;
00150 const ConstIterator last_pre = end - 2;
00151 if (last_pre < begin || last < begin)
00152 {
00153
00154 return 0;
00155 }
00156 const Eigen::Vector2d vec_path = last->pos_ - last_pre->pos_;
00157 const Eigen::Vector2d vec_remain = last->pos_ - target_on_line;
00158 if (vec_path.dot(vec_remain) >= 0)
00159 {
00160
00161 return remain;
00162 }
00163
00164 return -remain;
00165 }
00166 ConstIterator it_prev = nearest;
00167 for (ConstIterator it = nearest + 1; it < end; ++it)
00168 {
00169 remain += (it_prev->pos_ - it->pos_).norm();
00170 it_prev = it;
00171 }
00172 return remain;
00173 }
00174 inline float getCurvature(
00175 const ConstIterator& begin,
00176 const ConstIterator& end,
00177 const Eigen::Vector2d& target_on_line,
00178 const float max_search_range) const
00179 {
00180 const float max_search_range_sq = max_search_range * max_search_range;
00181 trajectory_tracker::Average<float> curv;
00182 ConstIterator it_prev2 = begin;
00183 ConstIterator it_prev1 = begin + 1;
00184 for (ConstIterator it = begin + 2; it < end; ++it)
00185 {
00186 curv += trajectory_tracker::curv3p(it_prev2->pos_, it_prev1->pos_, it->pos_);
00187 if ((it->pos_ - target_on_line).squaredNorm() > max_search_range_sq)
00188 break;
00189 it_prev2 = it_prev1;
00190 it_prev1 = it;
00191 }
00192 return curv;
00193 }
00194 };
00195 }
00196
00197 #endif // TRAJECTORY_TRACKER_PATH2D_H