30 #ifndef TRAJECTORY_TRACKER_PATH2D_H
31 #define TRAJECTORY_TRACKER_PATH2D_H
38 #include <Eigen/Geometry>
40 #include <geometry_msgs/Pose.h>
41 #include <nav_msgs/Path.h>
43 #include <trajectory_tracker_msgs/PathWithVelocity.h>
65 inline Pose2D(
const Eigen::Vector2d& p,
float y,
float velocity)
71 inline Pose2D(
const geometry_msgs::Pose& pose,
float velocity)
72 :
pos_(Eigen::Vector2d(pose.position.x, pose.position.y))
77 inline explicit Pose2D(
const geometry_msgs::PoseStamped& pose)
78 :
pos_(Eigen::Vector2d(pose.pose.position.x, pose.pose.position.y))
83 inline explicit Pose2D(
const trajectory_tracker_msgs::PoseStampedWithVelocity& pose)
84 :
pos_(Eigen::Vector2d(pose.pose.position.x, pose.pose.position.y))
91 const float org_x =
pos_.x();
92 const float org_y =
pos_.y();
93 const float cos_v = std::cos(ang);
94 const float sin_v = std::sin(ang);
96 pos_.x() = cos_v * org_x - sin_v * org_y;
97 pos_.y() = sin_v * org_x + cos_v * org_y;
101 while (
yaw_ > 2 * M_PI)
104 void toMsg(geometry_msgs::PoseStamped& pose)
const
106 pose.pose.position.x =
pos_.x();
107 pose.pose.position.y =
pos_.y();
110 void toMsg(trajectory_tracker_msgs::PoseStampedWithVelocity& pose)
const
112 pose.pose.position.x =
pos_.x();
113 pose.pose.position.y =
pos_.y();
118 class Path2D :
public std::vector<Pose2D>
130 for (
size_t i = 1; i < size(); i++)
131 l += ((*
this)[i - 1].pos_ - (*this)[i].pos_).norm();
137 const bool allow_switch_back,
138 const bool allow_in_place_turn =
true,
139 const double epsilon = 1e-6)
const
141 float sign_vel_prev = 0;
145 if ((it->pos_ - it_prev->pos_).squaredNorm() <
epsilon)
147 if (allow_in_place_turn)
154 else if (allow_switch_back)
156 const Eigen::Vector2d inc = it->pos_ - it_prev->pos_;
157 const float angle = atan2(inc[1], inc[0]);
158 const float angle_pose = it->yaw_;
159 const float sign_vel_req = std::cos(
angle) * std::cos(angle_pose) + std::sin(
angle) * std::sin(angle_pose);
160 if (sign_vel_prev * sign_vel_req < 0)
165 sign_vel_prev = sign_vel_req;
174 const Eigen::Vector2d& target,
175 const float max_search_range = 0,
176 const float epsilon = 1e-6)
const
183 const Eigen::Vector2d& target,
184 const float max_search_range = 0,
185 const float epsilon = 1e-6)
const
189 if (end == this->end())
191 return std::make_pair(end, std::numeric_limits<double>::max());
193 return std::make_pair(end, (end->pos_ - target).norm());
195 float distance_path_search = 0;
197 float min_dist = (begin->pos_ - target).norm() +
epsilon;
202 const Eigen::Vector2d inc = it->pos_ - it_prev->pos_;
203 distance_path_search += inc.norm();
204 if (max_search_range > 0 && distance_path_search > max_search_range)
212 const float d_compare = (
d > 0) ?
d : (-
d -
epsilon);
213 const float d_abs = std::abs(
d);
217 if (d_compare <= min_dist || (it + 1 == end && d_abs <= min_dist +
epsilon))
224 return std::make_pair(it_nearest, min_dist);
230 const Eigen::Vector2d& target_on_line)
const
232 double remain = (nearest->pos_ - target_on_line).norm();
233 if (nearest + 1 >= end)
237 if (last_pre < begin || last < begin)
242 const Eigen::Vector2d vec_path = last->pos_ - last_pre->pos_;
243 const Eigen::Vector2d vec_remain = last->pos_ - target_on_line;
244 if (vec_path.dot(vec_remain) >= 0)
255 remain += (it_prev->pos_ - it->pos_).norm();
263 const Eigen::Vector2d& target_on_line,
264 const float max_search_range)
const
266 if (end - begin <= 1)
270 else if (end - begin == 2)
275 Pose2D rel(it->pos_ - it_prev->pos_, it->yaw_, 0.0f);
276 rel.
rotate(-it_prev->yaw_);
277 const float sin_v = std::sin(rel.
yaw_);
278 static const float EPS = 1.0e-6
f;
279 if (std::abs(sin_v) < EPS)
283 const float cos_v = std::cos(rel.
yaw_);
284 const float r1 = rel.
pos_.y() + rel.
pos_.x() * cos_v / sin_v;
285 const float r2 = std::copysign(
286 std::sqrt(std::pow(rel.
pos_.x(), 2) + std::pow(rel.
pos_.x() * cos_v / sin_v, 2)),
287 rel.
pos_.x() * sin_v);
288 return 1.0f / ((r1 + r2) / 2);
290 const float max_search_range_sq = max_search_range * max_search_range;
297 if ((it->pos_ - target_on_line).squaredNorm() > max_search_range_sq)
305 template <
typename PATH_TYPE>
306 inline void fromMsg(
const PATH_TYPE& path,
const double in_place_turn_eps = 1.0e-6)
309 bool in_place_turning =
false;
311 for (
const auto& pose : path.poses)
319 if ((back().pos_ - next.
pos_).squaredNorm() >= std::pow(in_place_turn_eps, 2))
321 if (in_place_turning)
323 push_back(in_place_turn_end);
324 in_place_turning =
false;
332 in_place_turning =
true;
335 if (in_place_turning)
337 push_back(in_place_turn_end);
341 template <
typename PATH_TYPE>
342 inline void toMsg(PATH_TYPE& path)
const
345 path.poses.resize(size());
346 for (
size_t i = 0; i < size(); ++i)
348 path.poses[i].header = path.header;
349 at(i).toMsg(path.poses[i]);
356 const bool allow_switch_back,
357 const bool allow_in_place_turn =
true,
358 const double epsilon = 1e-6)
const
361 std::vector<ConstIterator> results;
366 if (it_local_goal == end)
368 results.push_back(it_local_goal);
369 it_search_begin = it_local_goal;
377 const double linear_speed,
378 const double angular_speed,
379 const double initial_eta_sec = 0.0)
const
383 return std::vector<double>();
385 std::vector<double> results(1, initial_eta_sec);
386 double elapsed_sec = initial_eta_sec;
390 const double dist = (it_prev->pos_ - it->pos_).norm();
393 elapsed_sec += dist / linear_speed;
397 double ang_diff = std::abs(it_prev->yaw_ - it->yaw_);
400 ang_diff = 2 * M_PI - ang_diff;
402 elapsed_sec += ang_diff / angular_speed;
404 results.push_back(elapsed_sec);
412 #endif // TRAJECTORY_TRACKER_PATH2D_H