COPP C++ API
C++ interface for COPP trajectory optimization
Loading...
Searching...
No Matches
path.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cmath>
4#include <functional>
5#include <initializer_list>
6#include <memory>
7#include <optional>
8#include <utility>
9#include <vector>
10
11#include "copp/core.hpp"
12
13namespace copp
14{
15
16 class Path;
17
18 namespace detail
19 {
25 COPP_API const void *path_handle(const Path &path) noexcept;
26 } // namespace detail
27
43 struct Jet3
44 {
45 double v = 0.0;
46 double d1 = 0.0;
47 double d2 = 0.0;
48 double d3 = 0.0;
49
50 static constexpr Jet3 constant(double value) noexcept
51 {
52 return Jet3{value, 0.0, 0.0, 0.0};
53 }
54
55 static constexpr Jet3 seed(double value) noexcept
56 {
57 return Jet3{value, 1.0, 0.0, 0.0};
58 }
59 };
60
61 inline constexpr Jet3 operator+(Jet3 lhs, Jet3 rhs) noexcept
62 {
63 return Jet3{
64 lhs.v + rhs.v,
65 lhs.d1 + rhs.d1,
66 lhs.d2 + rhs.d2,
67 lhs.d3 + rhs.d3,
68 };
69 }
70
71 inline constexpr Jet3 operator+(Jet3 lhs, double rhs) noexcept
72 {
73 return Jet3{lhs.v + rhs, lhs.d1, lhs.d2, lhs.d3};
74 }
75
76 inline constexpr Jet3 operator+(double lhs, Jet3 rhs) noexcept
77 {
78 return rhs + lhs;
79 }
80
81 inline constexpr Jet3 operator-(Jet3 lhs, Jet3 rhs) noexcept
82 {
83 return Jet3{
84 lhs.v - rhs.v,
85 lhs.d1 - rhs.d1,
86 lhs.d2 - rhs.d2,
87 lhs.d3 - rhs.d3,
88 };
89 }
90
91 inline constexpr Jet3 operator-(Jet3 lhs, double rhs) noexcept
92 {
93 return Jet3{lhs.v - rhs, lhs.d1, lhs.d2, lhs.d3};
94 }
95
96 inline constexpr Jet3 operator-(double lhs, Jet3 rhs) noexcept
97 {
98 return Jet3{lhs - rhs.v, -rhs.d1, -rhs.d2, -rhs.d3};
99 }
100
101 inline constexpr Jet3 operator-(Jet3 value) noexcept
102 {
103 return Jet3{-value.v, -value.d1, -value.d2, -value.d3};
104 }
105
106 inline constexpr Jet3 operator*(Jet3 lhs, Jet3 rhs) noexcept
107 {
108 return Jet3{
109 lhs.v * rhs.v,
110 lhs.d1 * rhs.v + lhs.v * rhs.d1,
111 lhs.d2 * rhs.v + 2.0 * lhs.d1 * rhs.d1 + lhs.v * rhs.d2,
112 lhs.d3 * rhs.v + 3.0 * (lhs.d2 * rhs.d1 + lhs.d1 * rhs.d2) + lhs.v * rhs.d3,
113 };
114 }
115
116 inline constexpr Jet3 operator*(Jet3 lhs, double rhs) noexcept
117 {
118 return Jet3{
119 lhs.v * rhs,
120 lhs.d1 * rhs,
121 lhs.d2 * rhs,
122 lhs.d3 * rhs,
123 };
124 }
125
126 inline constexpr Jet3 operator*(double lhs, Jet3 rhs) noexcept
127 {
128 return rhs * lhs;
129 }
130
131 inline Jet3 operator/(double lhs, Jet3 rhs) noexcept
132 {
133 const double inv = 1.0 / rhs.v;
134 const double inv2 = inv * inv;
135 const double inv3 = inv2 * inv;
136 const double inv4 = inv3 * inv;
137 const double d1sq = rhs.d1 * rhs.d1;
138 return Jet3{
139 lhs * inv,
140 -lhs * inv2 * rhs.d1,
141 lhs * (2.0 * inv3 * d1sq - inv2 * rhs.d2),
142 lhs * (-6.0 * inv4 * d1sq * rhs.d1 + 6.0 * inv3 * rhs.d1 * rhs.d2 - inv2 * rhs.d3),
143 };
144 }
145
146 inline constexpr Jet3 operator/(Jet3 lhs, double rhs) noexcept
147 {
148 return lhs * (1.0 / rhs);
149 }
150
151 inline Jet3 operator/(Jet3 lhs, Jet3 rhs) noexcept
152 {
153 return lhs * (1.0 / rhs);
154 }
155
156 inline Jet3 sin(Jet3 x) noexcept
157 {
158 const double sv = std::sin(x.v);
159 const double cv = std::cos(x.v);
160 const double d1sq = x.d1 * x.d1;
161 return Jet3{
162 sv,
163 cv * x.d1,
164 -sv * d1sq + cv * x.d2,
165 -cv * d1sq * x.d1 - 3.0 * sv * x.d1 * x.d2 + cv * x.d3,
166 };
167 }
168
169 inline Jet3 cos(Jet3 x) noexcept
170 {
171 const double sv = std::sin(x.v);
172 const double cv = std::cos(x.v);
173 const double d1sq = x.d1 * x.d1;
174 return Jet3{
175 cv,
176 -sv * x.d1,
177 -cv * d1sq - sv * x.d2,
178 sv * d1sq * x.d1 - 3.0 * cv * x.d1 * x.d2 - sv * x.d3,
179 };
180 }
181
182 inline Jet3 exp(Jet3 x) noexcept
183 {
184 const double ev = std::exp(x.v);
185 const double d1sq = x.d1 * x.d1;
186 return Jet3{
187 ev,
188 ev * x.d1,
189 ev * (d1sq + x.d2),
190 ev * (d1sq * x.d1 + 3.0 * x.d1 * x.d2 + x.d3),
191 };
192 }
193
194 inline Jet3 log(Jet3 x) noexcept
195 {
196 const double inv = 1.0 / x.v;
197 const double inv2 = inv * inv;
198 const double inv3 = inv2 * inv;
199 const double d1sq = x.d1 * x.d1;
200 return Jet3{
201 std::log(x.v),
202 inv * x.d1,
203 -inv2 * d1sq + inv * x.d2,
204 2.0 * inv3 * d1sq * x.d1 - 3.0 * inv2 * x.d1 * x.d2 + inv * x.d3,
205 };
206 }
207
208 inline Jet3 ln(Jet3 x) noexcept
209 {
210 return log(x);
211 }
212
213 inline Jet3 sqrt(Jet3 x) noexcept
214 {
215 const double sqrtv = std::sqrt(x.v);
216 const double inv_sqrt = 1.0 / sqrtv;
217 const double inv_v_sqrt = inv_sqrt / x.v;
218 const double inv_v2_sqrt = inv_v_sqrt / x.v;
219 const double d1sq = x.d1 * x.d1;
220 return Jet3{
221 sqrtv,
222 0.5 * inv_sqrt * x.d1,
223 -0.25 * inv_v_sqrt * d1sq + 0.5 * inv_sqrt * x.d2,
224 0.375 * inv_v2_sqrt * d1sq * x.d1 - 0.75 * inv_v_sqrt * x.d1 * x.d2 +
225 0.5 * inv_sqrt * x.d3,
226 };
227 }
228
229 inline Jet3 powi(Jet3 x, int n) noexcept
230 {
231 if (n == 0)
232 {
233 return Jet3::constant(1.0);
234 }
235
236 const double nf = static_cast<double>(n);
237 const double coeff2 = nf * (nf - 1.0);
238 const double coeff3 = coeff2 * (nf - 2.0);
239 const double dv = nf * std::pow(x.v, nf - 1.0);
240 const double ddv = coeff2 == 0.0 ? 0.0 : coeff2 * std::pow(x.v, nf - 2.0);
241 const double dddv = coeff3 == 0.0 ? 0.0 : coeff3 * std::pow(x.v, nf - 3.0);
242 const double d1sq = x.d1 * x.d1;
243 return Jet3{
244 std::pow(x.v, nf),
245 dv * x.d1,
246 ddv * d1sq + dv * x.d2,
247 dddv * d1sq * x.d1 + 3.0 * ddv * x.d1 * x.d2 + dv * x.d3,
248 };
249 }
250
257 using PathParametric = std::function<std::vector<Jet3>(Jet3 s)>;
258
264 using PathParametricWriter = std::function<void(Jet3 s, Span<Jet3> q)>;
265
272 using PathEvaluator2nd = std::function<void(
274 MatrixRef q,
275 MatrixRef dq,
276 MatrixRef ddq)>;
277
284 using PathEvaluator3rd = std::function<void(
286 MatrixRef q,
287 MatrixRef dq,
288 MatrixRef ddq,
289 MatrixRef dddq)>;
290
296 enum class OutOfRangeMode
297 {
302 };
303
315 {
316 std::size_t order = 5;
317 double s_min = 0.0;
318 double s_max = 1.0;
325 std::optional<Matrix> start_state;
328 std::optional<Matrix> end_state;
329 };
330
340 {
342 std::optional<Matrix> dq;
343 std::optional<Matrix> ddq;
344 std::optional<Matrix> dddq;
345 };
346
353 {
354 public:
381 static Path from_waypoints(MatrixView waypoints, SplineConfig config = {});
382 static Expected<Path> from_waypoints(MatrixView waypoints, SplineConfig config, NoThrowTag);
383 static Expected<Path> from_waypoints(MatrixView waypoints, NoThrowTag);
384
403 std::initializer_list<std::initializer_list<double>> waypoints,
404 SplineConfig config = {});
405 static Expected<Path> from_waypoints(
406 std::initializer_list<std::initializer_list<double>> waypoints,
407 SplineConfig config,
408 NoThrowTag);
409 static Expected<Path> from_waypoints(
410 std::initializer_list<std::initializer_list<double>> waypoints,
411 NoThrowTag);
412
428 PathParametric parametric,
429 double s_min,
430 double s_max);
432 PathParametric parametric,
433 double s_min,
434 double s_max,
435 NoThrowTag);
436
447 std::size_t dim,
448 double s_min,
449 double s_max,
450 PathParametricWriter parametric);
452 std::size_t dim,
453 double s_min,
454 double s_max,
455 PathParametricWriter parametric,
456 NoThrowTag);
457
471 std::size_t dim,
472 double s_min,
473 double s_max,
474 PathEvaluator2nd evaluator);
476 std::size_t dim,
477 double s_min,
478 double s_max,
479 PathEvaluator2nd evaluator,
480 NoThrowTag);
481
491 std::size_t dim,
492 double s_min,
493 double s_max,
494 PathEvaluator3rd evaluator);
496 std::size_t dim,
497 double s_min,
498 double s_max,
499 PathEvaluator3rd evaluator,
500 NoThrowTag);
501
502 Path(Path &&) noexcept;
503 Path &operator=(Path &&) noexcept;
505
506 Path(const Path &) = delete;
507 Path &operator=(const Path &) = delete;
508
512 std::size_t dim() const;
513
517 std::pair<double, double> s_range() const;
518
527 PathDerivatives evaluate_q(Span<const double> s) const;
528 Expected<PathDerivatives> evaluate_q(Span<const double> s, NoThrowTag) const;
529
538
547
548 private:
549 struct Impl;
550
551 explicit Path(std::unique_ptr<Impl> impl);
552
553 std::unique_ptr<Impl> impl_;
554
555 friend const void *detail::path_handle(const Path &path) noexcept;
556 };
557
559 MatrixView waypoints,
560 SplineConfig config,
562 {
563 return detail::expected_from([&] { return from_waypoints(waypoints, config); });
564 }
565
567 {
568 return from_waypoints(waypoints, SplineConfig{}, tag);
569 }
570
572 std::initializer_list<std::initializer_list<double>> waypoints,
573 SplineConfig config,
575 {
576 return detail::expected_from([&] { return from_waypoints(waypoints, config); });
577 }
578
580 std::initializer_list<std::initializer_list<double>> waypoints,
581 NoThrowTag tag)
582 {
583 return from_waypoints(waypoints, SplineConfig{}, tag);
584 }
585
587 PathParametric parametric,
588 double s_min,
589 double s_max,
591 {
593 [&] { return from_parametric(std::move(parametric), s_min, s_max); });
594 }
595
597 std::size_t dim,
598 double s_min,
599 double s_max,
600 PathParametricWriter parametric,
602 {
604 [&] { return from_parametric(dim, s_min, s_max, std::move(parametric)); });
605 }
606
608 std::size_t dim,
609 double s_min,
610 double s_max,
611 PathEvaluator2nd evaluator,
613 {
615 [&] { return from_evaluator_2nd(dim, s_min, s_max, std::move(evaluator)); });
616 }
617
619 std::size_t dim,
620 double s_min,
621 double s_max,
622 PathEvaluator3rd evaluator,
624 {
626 [&] { return from_evaluator_3rd(dim, s_min, s_max, std::move(evaluator)); });
627 }
628
633
638
643
644} // namespace copp
Exception type thrown by the default C++ API.
Definition core.hpp:100
Small C++17 expected-like result used by no-throw overloads.
Definition core.hpp:527
Lightweight owned column-major matrix.
Definition core.hpp:352
Mutable column-major matrix view used by callback APIs.
Definition core.hpp:288
Non-owning view of a two-dimensional double matrix.
Definition core.hpp:205
Geometric path wrapper backed by Rust Path.
Definition path.hpp:353
static Path from_parametric(PathParametric parametric, double s_min, double s_max)
Build a path from a scalar-parametric formula.
std::size_t dim() const
Return the path dimension.
static Path from_evaluator_3rd(std::size_t dim, double s_min, double s_max, PathEvaluator3rd evaluator)
Build a path from a batch evaluator with explicit derivatives up to third order.
PathDerivatives evaluate_q(Span< const double > s) const
Evaluate position samples only.
static Path from_parametric(std::size_t dim, double s_min, double s_max, PathParametricWriter parametric)
Build a path from a scalar-parametric formula that writes into a buffer.
static Path from_waypoints(std::initializer_list< std::initializer_list< double > > waypoints, SplineConfig config={})
Build a spline path from waypoint-list notation.
static Path from_waypoints(MatrixView waypoints, SplineConfig config={})
Build a spline path from waypoint positions.
PathDerivatives evaluate_up_to_3rd(Span< const double > s) const
Evaluate position, first derivative, second derivative, and third derivative.
Path(Path &&) noexcept
friend const void * detail::path_handle(const Path &path) noexcept
static Path from_evaluator_2nd(std::size_t dim, double s_min, double s_max, PathEvaluator2nd evaluator)
Build a path from a batch evaluator with explicit derivatives up to second order.
std::pair< double, double > s_range() const
Return the valid path-parameter interval (s_min, s_max).
PathDerivatives evaluate_up_to_2nd(Span< const double > s) const
Evaluate position, first derivative, and second derivative.
Non-owning view of a contiguous one-dimensional array.
Definition core.hpp:139
#define COPP_API
Definition core.hpp:23
Internal helpers for error conversion, no-throw overloads, and small implementation utilities used by...
auto expected_from(Fn &&fn) -> Expected< typename std::decay< decltype(fn())>::type >
Definition core.hpp:580
COPP_API const void * path_handle(const Path &path) noexcept
Return the private bridge handle stored by Path.
Root namespace for the C++ facade: paths, robots, constraints, matrices, profiles,...
Jet3 sin(Jet3 x) noexcept
Definition path.hpp:156
Jet3 powi(Jet3 x, int n) noexcept
Definition path.hpp:229
std::function< void( Span< const double > s, MatrixRef q, MatrixRef dq, MatrixRef ddq, MatrixRef dddq)> PathEvaluator3rd
Batch third-order evaluator callback.
Definition path.hpp:284
constexpr Jet3 operator-(Jet3 lhs, Jet3 rhs) noexcept
Definition path.hpp:81
Jet3 sqrt(Jet3 x) noexcept
Definition path.hpp:213
std::function< std::vector< Jet3 >(Jet3 s)> PathParametric
Scalar-parametric path callback that returns one Jet3 per dimension.
Definition path.hpp:257
Jet3 log(Jet3 x) noexcept
Definition path.hpp:194
std::function< void( Span< const double > s, MatrixRef q, MatrixRef dq, MatrixRef ddq)> PathEvaluator2nd
Batch second-order evaluator callback.
Definition path.hpp:272
constexpr Jet3 operator+(Jet3 lhs, Jet3 rhs) noexcept
Definition path.hpp:61
OutOfRangeMode
Policy for evaluating a path outside its configured s range.
Definition path.hpp:297
@ Clamp
Clamp out-of-range query samples to the nearest endpoint.
Definition path.hpp:301
@ Error
Throw copp::Error when any query sample is outside [s_min, s_max].
Definition path.hpp:299
Jet3 exp(Jet3 x) noexcept
Definition path.hpp:182
Jet3 cos(Jet3 x) noexcept
Definition path.hpp:169
Jet3 operator/(double lhs, Jet3 rhs) noexcept
Definition path.hpp:131
std::function< void(Jet3 s, Span< Jet3 > q)> PathParametricWriter
Allocation-free scalar-parametric path callback that writes one Jet3 per dimension.
Definition path.hpp:264
Jet3 ln(Jet3 x) noexcept
Definition path.hpp:208
constexpr Jet3 operator*(Jet3 lhs, Jet3 rhs) noexcept
Definition path.hpp:106
Third-order forward-mode automatic-differentiation scalar.
Definition path.hpp:44
static constexpr Jet3 seed(double value) noexcept
Definition path.hpp:55
double d3
Definition path.hpp:48
static constexpr Jet3 constant(double value) noexcept
Definition path.hpp:50
double v
Definition path.hpp:45
double d2
Definition path.hpp:47
double d1
Definition path.hpp:46
Tag object selecting no-throw overloads.
Definition core.hpp:608
Result of path evaluation.
Definition path.hpp:340
std::optional< Matrix > dq
Definition path.hpp:342
std::optional< Matrix > ddq
Definition path.hpp:343
std::optional< Matrix > dddq
Definition path.hpp:344
Configuration for waypoint spline construction.
Definition path.hpp:315
std::size_t order
Definition path.hpp:316
std::optional< Matrix > end_state
Optional boundary derivatives at s_max; same shape convention as start_state.
Definition path.hpp:328
OutOfRangeMode out_of_range
Definition path.hpp:319
std::optional< Matrix > start_state
Optional boundary derivatives at s_min.
Definition path.hpp:325