moveit2
The MoveIt Motion Planning Framework for ROS 2.
Loading...
Searching...
No Matches
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
47{
48
49// The intermediate waypoints of the input path need to be blended so that the entire path is diffentiable.
50// This constant defines the maximum deviation allowed at those intermediate waypoints, in radians for revolute joints,
51// or meters for prismatic joints.
52constexpr double DEFAULT_PATH_TOLERANCE = 0.1;
53
59
60const std::unordered_map<LimitType, std::string> LIMIT_TYPES = { { VELOCITY, "velocity" },
61 { ACCELERATION, "acceleration" } };
63{
64public:
65 PathSegment(double length = 0.0) : length_(length)
66 {
67 }
68 virtual ~PathSegment() // is required for destructing derived classes
69 {
70 }
71 double getLength() const
72 {
73 return length_;
74 }
75 virtual Eigen::VectorXd getConfig(double s) const = 0;
76 virtual Eigen::VectorXd getTangent(double s) const = 0;
77 virtual Eigen::VectorXd getCurvature(double s) const = 0;
78 virtual std::list<double> getSwitchingPoints() const = 0;
79 virtual PathSegment* clone() const = 0;
80
81 double position_;
82
83protected:
84 double length_;
85};
86
87class Path
88{
89public:
90 // Create a Path from a vector of waypoints and a maximum deviation to tolerate at the intermediate waypoints.
91 // The algorithm needs max_deviation to be greater than zero so that the path is differentiable.
92 static std::optional<Path> create(const std::vector<Eigen::VectorXd>& waypoint,
93 double max_deviation = DEFAULT_PATH_TOLERANCE);
94
95 // Copy constructor.
96 Path(const Path& path);
97
98 double getLength() const;
99 Eigen::VectorXd getConfig(double s) const;
100 Eigen::VectorXd getTangent(double s) const;
101 Eigen::VectorXd getCurvature(double s) const;
102
108 double getNextSwitchingPoint(double s, bool& discontinuity) const;
109
111 std::list<std::pair<double, bool>> getSwitchingPoints() const;
112
113private:
114 // Default constructor private to prevent misuse. Use `create` instead to create a Path object.
115 Path() = default;
116
117 PathSegment* getPathSegment(double& s) const;
118
119 double length_ = 0.0;
120 std::list<std::pair<double, bool>> switching_points_;
121 std::list<std::unique_ptr<PathSegment>> path_segments_;
122};
123
125{
126public:
129 static std::optional<Trajectory> create(const Path& path, const Eigen::VectorXd& max_velocity,
130 const Eigen::VectorXd& max_acceleration, double time_step = 0.001);
131
133 double getDuration() const;
134
137 Eigen::VectorXd getPosition(double time) const;
139 Eigen::VectorXd getVelocity(double time) const;
141 Eigen::VectorXd getAcceleration(double time) const;
142
143private:
144 Trajectory(const Path& path, const Eigen::VectorXd& max_velocity, const Eigen::VectorXd& max_acceleration,
145 double time_step);
146
147 struct TrajectoryStep
148 {
149 TrajectoryStep()
150 {
151 }
152 TrajectoryStep(double path_pos, double path_vel) : path_pos_(path_pos), path_vel_(path_vel)
153 {
154 }
155 double path_pos_;
156 double path_vel_;
157 double time_;
158 };
159
160 bool getNextSwitchingPoint(double path_pos, TrajectoryStep& next_switching_point, double& before_acceleration,
161 double& after_acceleration);
162 bool getNextAccelerationSwitchingPoint(double path_pos, TrajectoryStep& next_switching_point,
163 double& before_acceleration, double& after_acceleration);
164 bool getNextVelocitySwitchingPoint(double path_pos, TrajectoryStep& next_switching_point, double& before_acceleration,
165 double& after_acceleration);
166 bool integrateForward(std::list<TrajectoryStep>& trajectory, double acceleration);
167 void integrateBackward(std::list<TrajectoryStep>& start_trajectory, double path_pos, double path_vel,
168 double acceleration);
169 double getMinMaxPathAcceleration(double path_position, double path_velocity, bool max);
170 double getMinMaxPhaseSlope(double path_position, double path_velocity, bool max);
171 double getAccelerationMaxPathVelocity(double path_pos) const;
172 double getVelocityMaxPathVelocity(double path_pos) const;
173 double getAccelerationMaxPathVelocityDeriv(double path_pos);
174 double getVelocityMaxPathVelocityDeriv(double path_pos);
175
176 std::list<TrajectoryStep>::const_iterator getTrajectorySegment(double time) const;
177
178 Path path_;
179 Eigen::VectorXd max_velocity_;
180 Eigen::VectorXd max_acceleration_;
181 unsigned int joint_num_ = 0.0;
182 bool valid_ = true;
183 std::list<TrajectoryStep> trajectory_;
184 std::list<TrajectoryStep> end_trajectory_; // non-empty only if the trajectory generation failed.
185
186 double time_step_ = 0.0;
187
188 mutable double cached_time_ = std::numeric_limits<double>::max();
189 mutable std::list<TrajectoryStep>::const_iterator cached_trajectory_segment_;
190};
191
194{
195public:
196 TimeOptimalTrajectoryGeneration(const double path_tolerance = DEFAULT_PATH_TOLERANCE, const double resample_dt = 0.1,
197 const double min_angle_change = 0.001);
198
199 // clang-format off
212 // clang-format on
213 bool computeTimeStamps(robot_trajectory::RobotTrajectory& trajectory, const double max_velocity_scaling_factor = 1.0,
214 const double max_acceleration_scaling_factor = 1.0) const override;
215
216 // clang-format off
231 // clang-format on
233 const std::unordered_map<std::string, double>& velocity_limits,
234 const std::unordered_map<std::string, double>& acceleration_limits,
235 const double max_velocity_scaling_factor = 1.0,
236 const double max_acceleration_scaling_factor = 1.0) const override;
237
238 // clang-format off
252 // clang-format on
254 const std::vector<moveit_msgs::msg::JointLimits>& joint_limits,
255 const double max_velocity_scaling_factor = 1.0,
256 const double max_acceleration_scaling_factor = 1.0) const override;
257
258private:
259 bool doTimeParameterizationCalculations(robot_trajectory::RobotTrajectory& trajectory,
260 const Eigen::VectorXd& max_velocity,
261 const Eigen::VectorXd& max_acceleration) const;
262
268 bool hasMixedJointTypes(const moveit::core::JointModelGroup* group) const;
269
276 double verifyScalingFactor(const double requested_scaling_factor, const LimitType limit_type) const;
277
278 const double path_tolerance_;
279 const double resample_dt_;
280 const double min_angle_change_;
281};
282
283// clang-format off
298// clang-format on
299bool totgComputeTimeStamps(const size_t num_waypoints, robot_trajectory::RobotTrajectory& trajectory,
300 const double max_velocity_scaling_factor = 1.0,
301 const double max_acceleration_scaling_factor = 1.0);
302} // namespace trajectory_processing
#define MOVEIT_CLASS_FORWARD(C)
Maintain a sequence of waypoints and the time durations between these waypoints.
virtual Eigen::VectorXd getConfig(double s) const =0
virtual PathSegment * clone() const =0
virtual std::list< double > getSwitchingPoints() const =0
virtual Eigen::VectorXd getCurvature(double s) const =0
virtual Eigen::VectorXd getTangent(double s) const =0
std::list< std::pair< double, bool > > getSwitchingPoints() const
Return a list of all switching points as a pair (arc length to switching point, discontinuity)
static std::optional< Path > create(const std::vector< Eigen::VectorXd > &waypoint, double max_deviation=DEFAULT_PATH_TOLERANCE)
double getNextSwitchingPoint(double s, bool &discontinuity) const
Get the next switching point.
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.
Eigen::VectorXd getPosition(double time) const
Return the position/configuration vector for a given point in time.
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.
static std::optional< Trajectory > create(const Path &path, const Eigen::VectorXd &max_velocity, const Eigen::VectorXd &max_acceleration, double time_step=0.001)
Generates a time-optimal trajectory.
const std::unordered_map< LimitType, std::string > LIMIT_TYPES
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...