timed_elastic_band.hpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  *
00003  * Software License Agreement (BSD License)
00004  *
00005  *  Copyright (c) 2016,
00006  *  TU Dortmund - Institute of Control Theory and Systems Engineering.
00007  *  All rights reserved.
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *
00013  *   * Redistributions of source code must retain the above copyright
00014  *     notice, this list of conditions and the following disclaimer.
00015  *   * Redistributions in binary form must reproduce the above
00016  *     copyright notice, this list of conditions and the following
00017  *     disclaimer in the documentation and/or other materials provided
00018  *     with the distribution.
00019  *   * Neither the name of the institute nor the names of its
00020  *     contributors may be used to endorse or promote products derived
00021  *     from this software without specific prior written permission.
00022  *
00023  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00026  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00027  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00028  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00029  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00033  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00034  *  POSSIBILITY OF SUCH DAMAGE.
00035  *
00036  * Author: Christoph Rösmann
00037  *********************************************************************/
00038 
00039 #include <teb_local_planner/timed_elastic_band.h>
00040 
00041 namespace teb_local_planner
00042 {
00043 
00044   
00045 
00046 template<typename BidirIter, typename Fun>
00047 bool TimedElasticBand::initTEBtoGoal(BidirIter path_start, BidirIter path_end, Fun fun_position, double max_vel_x, double max_vel_theta,
00048                       boost::optional<double> max_acc_x, boost::optional<double> max_acc_theta,
00049                       boost::optional<double> start_orientation, boost::optional<double> goal_orientation, int min_samples) 
00050 {
00051     Eigen::Vector2d start_position = fun_position( *path_start );
00052     Eigen::Vector2d goal_position = fun_position( *boost::prior(path_end) );
00053     
00054     double start_orient, goal_orient;
00055     if (start_orientation)
00056     {
00057       start_orient = *start_orientation;
00058     }
00059     else
00060     {
00061       Eigen::Vector2d start2goal =  goal_position - start_position;
00062       start_orient = atan2(start2goal[1],start2goal[0]);
00063     }
00064     double timestep = 1; // TODO: time
00065     
00066     
00067     if (goal_orientation)
00068     {
00069       goal_orient = *goal_orientation;
00070     }
00071     else
00072     {
00073       goal_orient = start_orient;
00074     }
00075     
00076     if (!isInit())
00077     {   
00078       addPose(start_position, start_orient, true); // add starting point and mark it as fixed for optimization          
00079 
00080       // we insert middle points now (increase start by 1 and decrease goal by 1)
00081       std::advance(path_start,1);
00082       std::advance(path_end,-1);
00083       unsigned int idx=0;
00084       for (; path_start != path_end; ++path_start) // insert middle-points
00085       {
00086         //Eigen::Vector2d point_to_goal = path.back()-*it;
00087         //double dir_to_goal = atan2(point_to_goal[1],point_to_goal[0]); // direction to goal
00088         // Alternative: Direction from last path
00089         Eigen::Vector2d curr_point = fun_position(*path_start);
00090         Eigen::Vector2d diff_last = curr_point - Pose(idx).position(); // we do not use boost::prior(*path_start) for those cases,
00091                                                                        // where fun_position() does not return a reference or is expensive.
00092         double diff_norm = diff_last.norm();
00093         
00094         double timestep_vel = diff_norm/max_vel_x; // constant velocity
00095         double timestep_acc;
00096         if (max_acc_x)
00097         {
00098                 timestep_acc = sqrt(2*diff_norm/(*max_acc_x)); // constant acceleration
00099                 if (timestep_vel < timestep_acc && max_acc_x) timestep = timestep_acc;
00100                 else timestep = timestep_vel;
00101         }
00102         else timestep = timestep_vel;
00103         
00104         if (timestep<0) timestep=0.2; // TODO: this is an assumption
00105         
00106         addPoseAndTimeDiff(curr_point, atan2(diff_last[1],diff_last[0]) ,timestep);
00107         
00108         Eigen::Vector2d diff_next = fun_position(*boost::next(path_start))-curr_point; // TODO maybe store the boost::next for the following iteration
00109         double ang_diff = std::abs( g2o::normalize_theta( atan2(diff_next[1],diff_next[0])
00110                                                          -atan2(diff_last[1],diff_last[0]) ) );
00111         
00112         timestep_vel = ang_diff/max_vel_theta; // constant velocity
00113         if (max_acc_theta)
00114         {
00115                 timestep_acc = sqrt(2*ang_diff/(*max_acc_theta)); // constant acceleration
00116                 if (timestep_vel < timestep_acc) timestep = timestep_acc;
00117                 else timestep = timestep_vel;
00118         }
00119         else timestep = timestep_vel;
00120         
00121         if (timestep<0) timestep=0.2; // TODO: this is an assumption
00122         
00123         addPoseAndTimeDiff(curr_point, atan2(diff_last[1],diff_last[0]) ,timestep);
00124         
00125         ++idx;
00126       }
00127       Eigen::Vector2d diff = goal_position-Pose(idx).position();
00128       double diff_norm = diff.norm();
00129       double timestep_vel = diff_norm/max_vel_x; // constant velocity
00130       if (max_acc_x)
00131       {
00132         double timestep_acc = sqrt(2*diff_norm/(*max_acc_x)); // constant acceleration
00133         if (timestep_vel < timestep_acc) timestep = timestep_acc;
00134         else timestep = timestep_vel;
00135       }
00136       else timestep = timestep_vel;
00137 
00138       
00139       PoseSE2 goal(goal_position, goal_orient);
00140       
00141       // if number of samples is not larger than min_samples, insert manually
00142       if ( (int)sizePoses() < min_samples-1 )
00143       {
00144         ROS_DEBUG("initTEBtoGoal(): number of generated samples is less than specified by min_samples. Forcing the insertion of more samples...");
00145         while ((int)sizePoses() < min_samples-1) // subtract goal point that will be added later
00146         {
00147           // simple strategy: interpolate between the current pose and the goal
00148           addPoseAndTimeDiff( PoseSE2::average(BackPose(), goal), timestep ); // let the optimier correct the timestep (TODO: better initialization     
00149         }
00150       }
00151       
00152       // now add goal
00153       addPoseAndTimeDiff(goal, timestep); // add goal point
00154       setPoseVertexFixed(sizePoses()-1,true); // GoalConf is a fixed constraint during optimization
00155     }
00156     else // size!=0
00157     {
00158       ROS_WARN("Cannot init TEB between given configuration and goal, because TEB vectors are not empty or TEB is already initialized (call this function before adding states yourself)!");
00159       ROS_WARN("Number of TEB configurations: %d, Number of TEB timediffs: %d",(unsigned int) sizePoses(),(unsigned int) sizeTimeDiffs());
00160       return false;
00161     }
00162     return true;
00163 }  
00164   
00165 
00166 } // namespace teb_local_planner
00167 
00168 
00169 


teb_local_planner
Author(s): Christoph Rösmann
autogenerated on Mon Oct 24 2016 05:31:15