moveit2
The MoveIt Motion Planning Framework for ROS 2.
time_optimal_trajectory_generation.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2012, Georgia Tech Research Corporation
3  * All rights reserved.
4  *
5  * Author: Tobias Kunz <tobias@gatech.edu>
6  * Date: 05/2012
7  *
8  * Humanoid Robotics Lab Georgia Institute of Technology
9  * Director: Mike Stilman http://www.golems.org
10  *
11  * Algorithm details and publications:
12  * http://www.golems.org/node/1570
13  *
14  * This file is provided under the following "BSD-style" License:
15  * Redistribution and use in source and binary forms, with or
16  * without modification, are permitted provided that the following
17  * conditions are met:
18  * * Redistributions of source code must retain the above copyright
19  * notice, this list of conditions and the following disclaimer.
20  * * Redistributions in binary form must reproduce the above
21  * copyright notice, this list of conditions and the following
22  * disclaimer in the documentation and/or other materials provided
23  * with the distribution.
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
25  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
26  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
27  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
29  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
32  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
33  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 #pragma once
40 
41 #include <Eigen/Core>
42 #include <list>
45 
46 namespace trajectory_processing
47 {
49 {
52 };
53 
54 const std::unordered_map<LimitType, std::string> LIMIT_TYPES = { { VELOCITY, "velocity" },
55  { ACCELERATION, "acceleration" } };
57 {
58 public:
59  PathSegment(double length = 0.0) : length_(length)
60  {
61  }
62  virtual ~PathSegment() // is required for destructing derived classes
63  {
64  }
65  double getLength() const
66  {
67  return length_;
68  }
69  virtual Eigen::VectorXd getConfig(double s) const = 0;
70  virtual Eigen::VectorXd getTangent(double s) const = 0;
71  virtual Eigen::VectorXd getCurvature(double s) const = 0;
72  virtual std::list<double> getSwitchingPoints() const = 0;
73  virtual PathSegment* clone() const = 0;
74 
75  double position_;
76 
77 protected:
78  double length_;
79 };
80 
81 class Path
82 {
83 public:
84  Path(const std::list<Eigen::VectorXd>& path, double max_deviation = 0.0);
85  Path(const Path& path);
86  double getLength() const;
87  Eigen::VectorXd getConfig(double s) const;
88  Eigen::VectorXd getTangent(double s) const;
89  Eigen::VectorXd getCurvature(double s) const;
90 
96  double getNextSwitchingPoint(double s, bool& discontinuity) const;
97 
99  std::list<std::pair<double, bool>> getSwitchingPoints() const;
100 
101 private:
102  PathSegment* getPathSegment(double& s) const;
103  double length_;
104  std::list<std::pair<double, bool>> switching_points_;
105  std::list<std::unique_ptr<PathSegment>> path_segments_;
106 };
107 
109 {
110 public:
112  Trajectory(const Path& path, const Eigen::VectorXd& max_velocity, const Eigen::VectorXd& max_acceleration,
113  double time_step = 0.001);
114 
115  ~Trajectory();
116 
120  bool isValid() const;
121 
123  double getDuration() const;
124 
127  Eigen::VectorXd getPosition(double time) const;
129  Eigen::VectorXd getVelocity(double time) const;
131  Eigen::VectorXd getAcceleration(double time) const;
132 
133 private:
134  struct TrajectoryStep
135  {
136  TrajectoryStep()
137  {
138  }
139  TrajectoryStep(double path_pos, double path_vel) : path_pos_(path_pos), path_vel_(path_vel)
140  {
141  }
142  double path_pos_;
143  double path_vel_;
144  double time_;
145  };
146 
147  bool getNextSwitchingPoint(double path_pos, TrajectoryStep& next_switching_point, double& before_acceleration,
148  double& after_acceleration);
149  bool getNextAccelerationSwitchingPoint(double path_pos, TrajectoryStep& next_switching_point,
150  double& before_acceleration, double& after_acceleration);
151  bool getNextVelocitySwitchingPoint(double path_pos, TrajectoryStep& next_switching_point, double& before_acceleration,
152  double& after_acceleration);
153  bool integrateForward(std::list<TrajectoryStep>& trajectory, double acceleration);
154  void integrateBackward(std::list<TrajectoryStep>& start_trajectory, double path_pos, double path_vel,
155  double acceleration);
156  double getMinMaxPathAcceleration(double path_position, double path_velocity, bool max);
157  double getMinMaxPhaseSlope(double path_position, double path_velocity, bool max);
158  double getAccelerationMaxPathVelocity(double path_pos) const;
159  double getVelocityMaxPathVelocity(double path_pos) const;
160  double getAccelerationMaxPathVelocityDeriv(double path_pos);
161  double getVelocityMaxPathVelocityDeriv(double path_pos);
162 
163  std::list<TrajectoryStep>::const_iterator getTrajectorySegment(double time) const;
164 
165  Path path_;
166  Eigen::VectorXd max_velocity_;
167  Eigen::VectorXd max_acceleration_;
168  unsigned int joint_num_;
169  bool valid_;
170  std::list<TrajectoryStep> trajectory_;
171  std::list<TrajectoryStep> end_trajectory_; // non-empty only if the trajectory generation failed.
172 
173  const double time_step_;
174 
175  mutable double cached_time_;
176  mutable std::list<TrajectoryStep>::const_iterator cached_trajectory_segment_;
177 };
178 
181 {
182 public:
183  TimeOptimalTrajectoryGeneration(const double path_tolerance = 0.1, const double resample_dt = 0.1,
184  const double min_angle_change = 0.001);
185 
186  // clang-format off
199  // clang-format on
200  bool computeTimeStamps(robot_trajectory::RobotTrajectory& trajectory, const double max_velocity_scaling_factor = 1.0,
201  const double max_acceleration_scaling_factor = 1.0) const override;
202 
203  // clang-format off
218  // clang-format on
220  const std::unordered_map<std::string, double>& velocity_limits,
221  const std::unordered_map<std::string, double>& acceleration_limits,
222  const double max_velocity_scaling_factor = 1.0,
223  const double max_acceleration_scaling_factor = 1.0) const override;
224 
225  // clang-format off
239  // clang-format on
241  const std::vector<moveit_msgs::msg::JointLimits>& joint_limits,
242  const double max_velocity_scaling_factor = 1.0,
243  const double max_acceleration_scaling_factor = 1.0) const override;
244 
245 private:
246  bool doTimeParameterizationCalculations(robot_trajectory::RobotTrajectory& trajectory,
247  const Eigen::VectorXd& max_velocity,
248  const Eigen::VectorXd& max_acceleration) const;
249 
255  bool hasMixedJointTypes(const moveit::core::JointModelGroup* group) const;
256 
263  double verifyScalingFactor(const double requested_scaling_factor, const LimitType limit_type) const;
264 
265  const double path_tolerance_;
266  const double resample_dt_;
267  const double min_angle_change_;
268 };
269 
270 // clang-format off
285 // clang-format on
286 bool totgComputeTimeStamps(const size_t num_waypoints, robot_trajectory::RobotTrajectory& trajectory,
287  const double max_velocity_scaling_factor = 1.0,
288  const double max_acceleration_scaling_factor = 1.0);
289 } // namespace trajectory_processing
Maintain a sequence of waypoints and the time durations between these waypoints.
virtual Eigen::VectorXd getConfig(double s) const =0
virtual std::list< double > getSwitchingPoints() const =0
virtual PathSegment * clone() const =0
virtual Eigen::VectorXd getCurvature(double s) const =0
virtual Eigen::VectorXd getTangent(double s) const =0
Eigen::VectorXd getTangent(double s) const
std::list< std::pair< double, bool > > getSwitchingPoints() const
Return a list of all switching points as a pair (arc length to switching point, discontinuity)
Eigen::VectorXd getCurvature(double s) const
double getNextSwitchingPoint(double s, bool &discontinuity) const
Get the next switching point.
Path(const std::list< Eigen::VectorXd > &path, double max_deviation=0.0)
TimeOptimalTrajectoryGeneration(const double path_tolerance=0.1, const double resample_dt=0.1, const double min_angle_change=0.001)
bool computeTimeStamps(robot_trajectory::RobotTrajectory &trajectory, const double max_velocity_scaling_factor=1.0, const double max_acceleration_scaling_factor=1.0) const override
Compute a trajectory with waypoints spaced equally in time (according to resample_dt_)....
Eigen::VectorXd getAcceleration(double time) const
Return the acceleration vector for a given point in time.
bool isValid() const
Call this method after constructing the object to make sure the trajectory generation succeeded witho...
Eigen::VectorXd getPosition(double time) const
Return the position/configuration vector for a given point in time.
Trajectory(const Path &path, const Eigen::VectorXd &max_velocity, const Eigen::VectorXd &max_acceleration, double time_step=0.001)
Generates a time-optimal trajectory.
double getDuration() const
Returns the optimal duration of the trajectory.
Eigen::VectorXd getVelocity(double time) const
Return the velocity vector for a given point in time.
const std::unordered_map< LimitType, std::string > LIMIT_TYPES
MOVEIT_CLASS_FORWARD(TimeOptimalTrajectoryGeneration)
bool totgComputeTimeStamps(const size_t num_waypoints, robot_trajectory::RobotTrajectory &trajectory, const double max_velocity_scaling_factor=1.0, const double max_acceleration_scaling_factor=1.0)
Compute a trajectory with the desired number of waypoints. Resampling the trajectory doesn't change t...