11#include "trajopt/geometry/pose2.hpp"
12#include "trajopt/geometry/rotation2.hpp"
13#include "trajopt/geometry/translation2.hpp"
14#include "trajopt/spline/cubic_hermite_pose_spline_holonomic.hpp"
15#include "trajopt/spline/cubic_hermite_spline.hpp"
16#include "trajopt/spline/spline_helper.hpp"
17#include "trajopt/util/trajopt_util.hpp"
23using PoseWithCurvature = std::pair<Pose2d, double>;
25template <
typename Solution>
26inline std::vector<CubicHermitePoseSplineHolonomic> splines_from_waypoints(
27 const std::vector<std::vector<Pose2d>> initial_guess_points) {
28 size_t total_guess_points = 0;
29 for (
const auto& points : initial_guess_points) {
30 total_guess_points += points.size();
32 std::vector<Translation2d> flat_translation_points;
33 std::vector<Rotation2d> flat_headings;
34 flat_translation_points.reserve(total_guess_points);
35 flat_headings.reserve(total_guess_points);
38 for (
const auto& guess_points : initial_guess_points) {
39 for (
const auto& guess_point : guess_points) {
40 flat_translation_points.emplace_back(guess_point.translation().x(),
41 guess_point.translation().y());
42 flat_headings.emplace_back(guess_point.rotation().cos(),
43 guess_point.rotation().sin());
47 std::vector<CubicHermiteSpline> splines_temp;
48 splines_temp.reserve(total_guess_points);
50 if constexpr (std::same_as<Solution, DifferentialSolution>) {
51 for (
size_t i = 1; i < flat_translation_points.size(); ++i) {
52 const auto spline_control_vectors =
54 Pose2d{flat_translation_points.at(i - 1),
55 flat_headings.at(i - 1)},
56 {}, Pose2d{flat_translation_points.at(i), flat_headings.at(i)});
58 spline_control_vectors.front(), {}, spline_control_vectors.back());
59 for (
const auto& _s : s) {
60 splines_temp.push_back(_s);
65 const auto start_spline_angle =
66 (flat_translation_points.at(1) - flat_translation_points.at(0)).angle();
67 const auto end_spline_angle =
68 (flat_translation_points.back() -
69 flat_translation_points.at(flat_translation_points.size() - 2))
71 const Pose2d start{flat_translation_points.front(), start_spline_angle};
72 const Pose2d end{flat_translation_points.back(), end_spline_angle};
75 std::vector<Translation2d> interior_points{
76 flat_translation_points.begin() + 1, flat_translation_points.end() - 1};
78 const auto spline_control_vectors =
80 start, interior_points, end);
82 spline_control_vectors.front(), interior_points,
83 spline_control_vectors.back());
84 for (
const auto& _s : s) {
85 splines_temp.push_back(_s);
89 std::vector<CubicHermitePoseSplineHolonomic> splines;
90 splines.reserve(splines_temp.size());
91 for (
size_t i = 1; i <= splines_temp.size(); ++i) {
92 splines.emplace_back(splines_temp.at(i - 1).get_initial_control_vector().x,
93 splines_temp.at(i - 1).get_final_control_vector().x,
94 splines_temp.at(i - 1).get_initial_control_vector().y,
95 splines_temp.at(i - 1).get_final_control_vector().y,
96 flat_headings.at(i - 1), flat_headings.at(i));
101template <
typename Solution>
102inline Solution generate_spline_initial_guess(
103 const std::vector<std::vector<Pose2d>>& initial_guess_points,
104 const std::vector<size_t> control_interval_counts) {
105 std::vector<CubicHermitePoseSplineHolonomic> splines =
106 splines_from_waypoints<Solution>(initial_guess_points);
107 std::vector<std::vector<PoseWithCurvature>> sgmt_points;
108 for (
size_t i = 0; i < initial_guess_points.size(); ++i) {
109 for ([[maybe_unused]]
111 j < initial_guess_points.at(i).size(); ++j) {
112 sgmt_points.push_back(std::vector<PoseWithCurvature>());
117 if constexpr (std::same_as<Solution, DifferentialSolution>) {
118 sgmt_points.at(0).push_back(
119 splines.at(traj_idx).get_point(0,
true).value());
121 sgmt_points.at(0).push_back(
122 splines.at(traj_idx).get_point(0,
false).value());
124 for (
size_t sgmt_idx = 1; sgmt_idx < initial_guess_points.size();
126 auto guess_points_size = initial_guess_points.at(sgmt_idx).size();
127 auto samples_for_sgmt = control_interval_counts.at(sgmt_idx - 1);
128 size_t samples = samples_for_sgmt / guess_points_size;
129 for (
size_t guessIdx = 0; guessIdx < guess_points_size; ++guessIdx) {
130 if (guessIdx == (guess_points_size - 1)) {
131 samples += (samples_for_sgmt % guess_points_size);
133 for (
size_t sample_idx = 1; sample_idx < samples + 1; ++sample_idx) {
134 auto t =
static_cast<double>(sample_idx) / samples;
136 if constexpr (std::same_as<Solution, DifferentialSolution>) {
137 const auto state = splines.at(traj_idx).get_point(t,
true).value();
138 sgmt_points.at(traj_idx + 1).push_back(state);
140 const auto state = splines.at(traj_idx).get_point(t,
false).value();
141 sgmt_points.at(traj_idx + 1).push_back(state);
148 size_t wpt_cnt = control_interval_counts.size() + 1;
149 size_t samp_tot = get_index(control_interval_counts, wpt_cnt - 1, 0) + 1;
151 Solution initial_guess;
153 initial_guess.x.reserve(samp_tot);
154 initial_guess.y.reserve(samp_tot);
155 if constexpr (std::same_as<Solution, DifferentialSolution>) {
156 initial_guess.heading.reserve(samp_tot);
158 initial_guess.thetacos.reserve(samp_tot);
159 initial_guess.thetasin.reserve(samp_tot);
162 initial_guess.dt.reserve(samp_tot);
163 for (
size_t i = 0; i < samp_tot; ++i) {
164 initial_guess.dt.push_back((wpt_cnt * 5.0) / samp_tot);
167 for (
auto sgmt : sgmt_points) {
168 for (
auto pt : sgmt) {
169 initial_guess.x.push_back(pt.first.x());
170 initial_guess.y.push_back(pt.first.y());
171 if constexpr (std::same_as<Solution, DifferentialSolution>) {
172 initial_guess.heading.push_back(pt.first.rotation().radians());
174 initial_guess.thetacos.push_back(pt.first.rotation().cos());
175 initial_guess.thetasin.push_back(pt.first.rotation().sin());
179 return initial_guess;
static std::vector< CubicHermiteSpline > cubic_splines_from_control_vectors(const Spline< 3 >::ControlVector &start, std::vector< Translation2d > waypoints, const Spline< 3 >::ControlVector &end)
Definition spline_helper.hpp:60
static std::array< Spline< 3 >::ControlVector, 2 > cubic_control_vectors_from_waypoints(const Pose2d &start, const std::vector< Translation2d > &interior_waypoints, const Pose2d &end)
Definition spline_helper.hpp:29
The holonomic trajectory optimization solution.
Definition differential_trajectory_generator.hpp:47