path2d.h
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2018, the neonavigation authors
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of the copyright holder nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
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       // stop reading forward if the path is switching back
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         // no enough points: orientation control mode
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         // ongoing
00161         return remain;
00162       }
00163       // overshoot
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 }  // namespace trajectory_tracker
00196 
00197 #endif  // TRAJECTORY_TRACKER_PATH2D_H


trajectory_tracker
Author(s): Atsushi Watanabe
autogenerated on Sat Jun 22 2019 20:07:25