1 #ifndef TRAJECTORY_UTILS_H
2 #define TRAJECTORY_UTILS_H
4 #include <mav_trajectory_generation/polynomial_optimization_nonlinear.h>
5 #include <mav_trajectory_generation/segment.h>
6 #include <mav_trajectory_generation/trajectory.h>
7 #include <mav_trajectory_generation/vertex.h>
35 template <
int DerivativeToOptimize>
36 std::optional<Segment::Vector>
optimize_path(
const std::vector<Eigen::VectorXd>& waypoints,
37 const Eigen::VectorXd& start_vel,
double v_max,
double a_max) {
38 const int dimension = start_vel.size();
39 constexpr
int N = 2 * (DerivativeToOptimize + 1);
41 Vertex::Vector vertices;
42 for (
size_t i = 0; i < waypoints.size(); ++i) {
43 Vertex vertex(dimension);
45 vertex.makeStartOrEnd(waypoints[i], DerivativeToOptimize);
46 vertex.addConstraint(derivative_order::VELOCITY, start_vel);
47 }
else if (i == waypoints.size() - 1) {
48 vertex.makeStartOrEnd(waypoints[i], DerivativeToOptimize);
50 vertex.addConstraint(derivative_order::POSITION, waypoints[i]);
52 vertices.push_back(vertex);
55 std::vector<double> segment_times = estimateSegmentTimes(vertices, v_max, a_max);
57 NonlinearOptimizationParameters parameters;
58 PolynomialOptimizationNonLinear<N> opt(dimension, parameters);
59 if (!opt.setupFromVertices(vertices, segment_times, DerivativeToOptimize)) {
64 opt.addMaximumMagnitudeConstraint(derivative_order::VELOCITY, v_max);
65 opt.addMaximumMagnitudeConstraint(derivative_order::ACCELERATION, a_max);
67 int result = opt.optimize();
68 if (result < 0 && result != nlopt::ROUNDOFF_LIMITED) {
70 nlopt::returnValueToString(result).c_str());
79 Trajectory trajectory;
80 opt.getTrajectory(&trajectory);
82 if (!trajectory.scaleSegmentTimesToMeetConstraints(v_max, a_max)) {
87 Segment::Vector segments;
88 trajectory.getSegments(&segments);
102 template <
int DerivativeToOptimize>
104 constexpr
int N = 2 * (DerivativeToOptimize + 1);
105 const int dimension = value.size();
107 Segment seg(N, dimension);
108 seg.setTime(duration);
110 for (
int d = 0; d < dimension; ++d) {
111 Eigen::VectorXd coeffs = Eigen::VectorXd::Zero(N);
112 coeffs(0) = value(d);
113 seg[d].setCoefficients(coeffs);
136 template <
int DerivativeToOptimize>
138 const Eigen::VectorXd& start_vel,
double v_max,
double a_max,
139 double min_segment_time) {
140 if (waypoints.size() < 2) {
144 const int dimension = start_vel.size();
145 Segment::Vector all_segments;
147 Eigen::VectorXd current_vel = start_vel;
150 while (i < waypoints.size() - 1) {
151 if (waypoints[i] == waypoints[i + 1]) {
152 all_segments.push_back(get_constant_segment<DerivativeToOptimize>(waypoints[i], min_segment_time));
153 current_vel = Eigen::VectorXd::Zero(dimension);
156 std::vector<Eigen::VectorXd> path;
157 path.push_back(waypoints[i]);
158 while (i < waypoints.size() - 1 && waypoints[i] != waypoints[i + 1]) {
159 path.push_back(waypoints[i + 1]);
163 auto segments = optimize_path<DerivativeToOptimize>(path, current_vel, v_max, a_max);
168 all_segments.insert(all_segments.end(), segments->begin(), segments->end());
169 current_vel = Eigen::VectorXd::Zero(dimension);
173 if (all_segments.empty()) {
177 Trajectory trajectory;
178 trajectory.setSegments(all_segments);
216 template <
int DerivativeToOptimize>
218 const Eigen::VectorXd& start_vel,
219 const std::vector<DimensionGroup>& groups,
220 double min_segment_time) {
221 if (waypoints.size() < 2 || groups.empty()) {
225 std::optional<Trajectory> combined;
227 for (
const auto& group : groups) {
228 std::vector<Eigen::VectorXd> sub_waypoints;
229 sub_waypoints.reserve(waypoints.size());
230 for (
const auto& wp : waypoints) {
231 sub_waypoints.push_back(wp.segment(group.start, group.size));
234 Eigen::VectorXd sub_vel = start_vel.segment(group.start, group.size);
236 auto traj = calculate_trajectory<DerivativeToOptimize>(sub_waypoints, sub_vel, group.v_max, group.a_max,
246 if (!combined->getTrajectoryWithAppendedDimension(*traj, &appended)) {
static rclcpp::Logger get_logger()
Returns the ROS logger associated with the shared node.
Definition: NodeUtils.h:58
Definition: TrajectoryUtils.h:15
std::optional< Trajectory > calculate_trajectory(const std::vector< Eigen::VectorXd > &waypoints, const Eigen::VectorXd &start_vel, double v_max, double a_max, double min_segment_time)
Plans a trajectory through waypoints, inserting constant segments at duplicate points.
Definition: TrajectoryUtils.h:137
std::optional< Trajectory > calculate_trajectory_multidim(const std::vector< Eigen::VectorXd > &waypoints, const Eigen::VectorXd &start_vel, const std::vector< DimensionGroup > &groups, double min_segment_time)
Plans a multi-DOF trajectory by solving each dimension group independently and concatenating the resu...
Definition: TrajectoryUtils.h:217
std::optional< Segment::Vector > optimize_path(const std::vector< Eigen::VectorXd > &waypoints, const Eigen::VectorXd &start_vel, double v_max, double a_max)
Plans a minimum-derivative polynomial path through a sequence of distinct waypoints.
Definition: TrajectoryUtils.h:36
Segment get_constant_segment(const Eigen::VectorXd &value, double duration)
Creates a zero-velocity constant-position polynomial segment.
Definition: TrajectoryUtils.h:103
Describes a contiguous slice of trajectory dimensions sharing a common velocity/acceleration budget.
Definition: TrajectoryUtils.h:185
int size
Number of dimensions in this group.
Definition: TrajectoryUtils.h:190
double a_max
Maximum acceleration magnitude for this group.
Definition: TrajectoryUtils.h:196
int start
Index of the first dimension in this group.
Definition: TrajectoryUtils.h:187
double v_max
Maximum velocity magnitude for this group.
Definition: TrajectoryUtils.h:193