22 template <
class TScalar>
25 static Eigen::Matrix<TScalar, 3, 4>
c() {
26 Eigen::Matrix<TScalar, 3, 4>
c;
30 c << TScalar(5./6), TScalar(3./6), -TScalar(3./6), TScalar(1./6),
31 TScalar(1./6), TScalar(3./6), TScalar(3./6), -TScalar(2./6),
32 o, o, o, TScalar(1./6);
37 static Eigen::Vector3<TScalar>
b(TScalar
const& u) {
40 TScalar u_square(u * u);
41 return c() * Eigen::Vector4<TScalar>(TScalar(1), u, u_square, u * u_square);
44 static Eigen::Vector3<TScalar>
dtB(TScalar
const& u, TScalar
const& delta_t) {
47 return (TScalar(1) / delta_t) *
c() *
48 Eigen::Vector4<TScalar>(
49 TScalar(0), TScalar(1), TScalar(2) * u, TScalar(3) * u * u);
52 static Eigen::Vector3<TScalar>
dt2B(
53 TScalar
const& u, TScalar
const& delta_t) {
56 return (TScalar(1) / (delta_t * delta_t)) *
c() *
57 Eigen::Vector4<TScalar>(
58 TScalar(0), TScalar(0), TScalar(2), TScalar(6) * u);
62 template <concepts::LieGroup TGroup>
66 using Scalar =
typename LieGroup::Scalar;
68 Eigen::Matrix<Scalar, TGroup::kAmbientDim, TGroup::kAmbientDim>;
72 LieGroup const& parent_ts_control_point,
73 std::tuple<Tangent, Tangent, Tangent>
const& control_tagent_vectors,
75 auto aa = a(control_tagent_vectors, u);
76 return parent_ts_control_point * std::get<0>(aa) * std::get<1>(aa) *
81 LieGroup const& parent_ts_control_point,
82 std::tuple<Tangent, Tangent, Tangent>
const& control_tagent_vectors,
85 auto aa = a(control_tagent_vectors, u);
86 auto dt_aa = dtA(aa, control_tagent_vectors, u, delta_t);
87 return parent_ts_control_point.matrix() *
88 ((std::get<0>(dt_aa) * std::get<1>(aa).matrix() *
89 std::get<2>(aa).matrix()) +
90 (std::get<0>(aa).matrix() * std::get<1>(dt_aa) *
91 std::get<2>(aa).matrix()) +
92 (std::get<0>(aa).matrix() * std::get<1>(aa).matrix() *
97 LieGroup const& parent_ts_control_point,
98 std::tuple<Tangent, Tangent, Tangent>
const& control_tagent_vectors,
101 using TScalar =
typename LieGroup::Scalar;
102 auto aa = a(control_tagent_vectors, u);
103 auto dt_aa = dtA(aa, control_tagent_vectors, u, delta_t);
104 auto dt2_aa = dt2A(aa, dt_aa, control_tagent_vectors, u, delta_t);
106 return parent_ts_control_point.matrix() *
107 ((std::get<0>(dt2_aa) * std::get<1>(aa).matrix() *
108 std::get<2>(aa).matrix()) +
109 (std::get<0>(aa).matrix() * std::get<1>(dt2_aa) *
110 std::get<2>(aa).matrix()) +
111 (std::get<0>(aa).matrix() * std::get<1>(aa).matrix() *
112 std::get<2>(dt2_aa)) +
113 TScalar(2) * ((std::get<0>(dt_aa) * std::get<1>(dt_aa) *
114 std::get<2>(aa).matrix()) +
115 (std::get<0>(dt_aa) * std::get<1>(aa).matrix() *
116 std::get<2>(dt_aa)) +
117 (std::get<0>(aa).matrix() * std::get<1>(dt_aa) *
118 std::get<2>(dt_aa))));
122 static std::tuple<LieGroup, LieGroup, LieGroup> a(
123 std::tuple<Tangent, Tangent, Tangent>
const& control_tagent_vectors,
126 return std::make_tuple(
127 LieGroup::exp(b[0] * std::get<0>(control_tagent_vectors)),
128 LieGroup::exp(b[1] * std::get<1>(control_tagent_vectors)),
129 LieGroup::exp(b[2] * std::get<2>(control_tagent_vectors)));
132 static std::tuple<Transformation, Transformation, Transformation> dtA(
133 std::tuple<LieGroup, LieGroup, LieGroup>
const& aa,
134 std::tuple<Tangent, Tangent, Tangent>
const& control_tagent_vectors,
138 return std::make_tuple(
139 dt_b[0] * std::get<0>(aa).matrix() *
140 LieGroup::hat(std::get<0>(control_tagent_vectors)),
141 dt_b[1] * std::get<1>(aa).matrix() *
142 LieGroup::hat(std::get<1>(control_tagent_vectors)),
143 dt_b[2] * std::get<2>(aa).matrix() *
144 LieGroup::hat(std::get<2>(control_tagent_vectors)));
147 static std::tuple<Transformation, Transformation, Transformation> dt2A(
148 std::tuple<LieGroup, LieGroup, LieGroup>
const& aa,
149 std::tuple<Transformation, Transformation, Transformation>
const& dt_aa,
150 std::tuple<Tangent, Tangent, Tangent>
const& control_tagent_vectors,
156 return std::make_tuple(
157 (dt_b[0] * std::get<0>(dt_aa).matrix() +
158 dt2_b[0] * std::get<0>(aa).matrix()) *
159 LieGroup::hat(std::get<0>(control_tagent_vectors)),
160 (dt_b[1] * std::get<1>(dt_aa).matrix() +
161 dt2_b[1] * std::get<1>(aa).matrix()) *
162 LieGroup::hat(std::get<1>(control_tagent_vectors)),
163 (dt_b[2] * std::get<2>(dt_aa).matrix() +
164 dt2_b[2] * std::get<2>(aa).matrix()) *
165 LieGroup::hat(std::get<2>(control_tagent_vectors)));
171 template <concepts::LieGroup TGroup>
177 Eigen::Matrix<Scalar, TGroup::kAmbientDim, TGroup::kAmbientDim>;
186 : segment_case_(segment_case),
199 return TGroup::fromParams(params0_);
202 return TGroup::fromParams(params1_);
206 return TGroup::fromParams(params2_);
210 return TGroup::fromParams(params3_);
213 switch (segment_case_) {
243 switch (segment_case_) {
276 switch (segment_case_) {
316 template <concepts::LieGroup TGroup>
320 using Scalar =
typename LieGroup::Scalar;
322 Eigen::Matrix<Scalar, TGroup::kAmbientDim, TGroup::kAmbientDim>;
326 std::vector<LieGroup>
const& parent_ts_control_point,
double delta_t)
327 : parent_from_control_point_transforms_(parent_ts_control_point),
328 delta_transform_(delta_t) {
330 parent_from_control_point_transforms_.size() >= 2u,
332 parent_from_control_point_transforms_.size());
339 "i = {}; this->getNumSegments() = {}; "
340 "parent_from_control_point_transforms_.size() = {}",
343 parent_from_control_point_transforms_.size());
354 i + 2,
int(this->parent_from_control_point_transforms_.size()) - 1);
358 parent_from_control_point_transforms_[idx_prev].params(),
359 parent_from_control_point_transforms_[idx_0].params(),
360 parent_from_control_point_transforms_[idx_1].params(),
361 parent_from_control_point_transforms_[idx_2].params())
369 "i = {}; this->getNumSegments() = {}; "
370 "parent_from_control_point_transforms_.size() = {}",
373 parent_from_control_point_transforms_.size());
384 i + 2,
int(this->parent_from_control_point_transforms_.size()) - 1);
388 parent_from_control_point_transforms_[idx_prev].params(),
389 parent_from_control_point_transforms_[idx_0].params(),
390 parent_from_control_point_transforms_[idx_1].params(),
391 parent_from_control_point_transforms_[idx_2].params())
399 "i = {}; this->getNumSegments() = {}; "
400 "parent_from_control_point_transforms_.size() = {}",
403 parent_from_control_point_transforms_.size());
414 i + 2,
int(this->parent_from_control_point_transforms_.size()) - 1);
418 parent_from_control_point_transforms_[idx_prev].params(),
419 parent_from_control_point_transforms_[idx_0].params(),
420 parent_from_control_point_transforms_[idx_1].params(),
421 parent_from_control_point_transforms_[idx_2].params())
426 return parent_from_control_point_transforms_;
430 return parent_from_control_point_transforms_;
434 return int(parent_from_control_point_transforms_.size()) - 1;
437 [[nodiscard]]
double deltaT()
const {
return delta_transform_; }
440 std::vector<LieGroup> parent_from_control_point_transforms_;
441 double delta_transform_;
449 template <concepts::LieGroup TGroup>
453 using Scalar =
typename LieGroup::Scalar;
455 Eigen::Matrix<Scalar, TGroup::kAmbientDim, TGroup::kAmbientDim>;
459 std::vector<LieGroup> parent_ts_control_point,
double t0,
double delta_t)
460 : impl_(std::move(parent_ts_control_point), delta_t), t0_(
t0) {}
478 [[nodiscard]]
double t0()
const {
return t0_; }
480 [[nodiscard]]
double tmax()
const {
494 [[nodiscard]]
double s(
double t)
const {
return (t - t0_) / impl_.
deltaT(); }
502 double s = this->
s(t);
505 index_and_u.
u = std::modf(
s, &i);
506 index_and_u.
i = int(i);
507 if (index_and_u.
u > sophus::kEpsilonF64) {
512 if (t < 0.5 * this->
tmax()) {
518 index_and_u.
u += 1.0;