gtsam
Loading...
Searching...
No Matches
CumulativeSplineTrajectory.h
Go to the documentation of this file.
1/* ----------------------------------------------------------------------------
2
3 * GTSAM Copyright 2010, Georgia Tech Research Corporation,
4 * Atlanta, Georgia 30332-0415
5 * All Rights Reserved
6 * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7
8 * See LICENSE for the license information
9
10 * -------------------------------------------------------------------------- */
11
17
18#pragma once
19
24
25#include <algorithm>
26#include <cmath>
27#include <functional>
28#include <stdexcept>
29#include <utility>
30#include <vector>
31
32namespace gtsam {
33
55template <class T>
57 public:
62
74 double density = 1.0, const KernelBase& kernel = kernels::IrwinHallCDF2,
75 const std::vector<Expression<T>>& points = {}, bool padFront = false)
76 : density_(density),
77 kernel_(kernel),
78 points_(points),
79 padFront_(padFront),
80 kernelOffset_(padFront ? kernel.getEnd() : kernel.getBeginning()),
81 windowPre_(padFront ? 0
82 : static_cast<int>(std::ceil(kernel.getLength()))),
83 windowPost_(padFront ? static_cast<int>(std::ceil(kernel.getLength()))
84 : 0) {
85 if (density <= 0.0) {
86 throw std::invalid_argument(
87 "CumulativeSplineTrajectory density must be positive");
88 }
89 }
90
93 : CumulativeSplineTrajectory(density, kernels::IrwinHallCDF2, {},
94 padFront) {}
95
97 double density() const { return density_; }
98
100 const KernelBase& kernel() const { return kernel_; }
101
103 bool padFront() const { return padFront_; }
104
106 void addControlPoint(const Expression<T>& point) { points_.push_back(point); }
107
109 void addControlPoint(const T& point) { points_.emplace_back(point); }
110
112 const std::vector<Expression<T>>& getControlPoints() const { return points_; }
113
121 Expression<T> sampleTrajectory(const Double_& timestamp,
122 double windowStart = 0.0,
123 double windowEnd = -1.0) const {
124 const auto [start, end] = controlPointWindow(windowStart, windowEnd);
125 const Double_ kernelTime = density_ * timestamp + Double_(kernelOffset_);
126 return kernelInterpolate(kernel_, kernelTime, points_, start, end);
127 }
128
137 T sampleTrajectory(double timestamp, double windowStart = 0.0,
138 double windowEnd = -1.0) const {
139 return sampleTrajectory(Double_(timestamp), windowStart, windowEnd)
140 .value(Values());
141 }
142
150 double windowStart = 0.0,
151 double windowEnd = -1.0,
152 size_t derivative = 1) const {
153 const auto [start, end] = controlPointWindow(windowStart, windowEnd);
154 const Double_ kernelTime = density_ * timestamp + Double_(kernelOffset_);
155 return Double_(std::pow(density_, derivative)) *
156 kernelInterpolateDerivative(kernel_, kernelTime, points_, start, end,
157 derivative);
158 }
159
167 double windowStart = 0.0,
168 double windowEnd = -1.0,
169 size_t derivative = 1) const {
170 return sampleTrajectoryDerivative(Double_(timestamp), windowStart,
171 windowEnd, derivative)
172 .value(Values());
173 }
174
175 private:
177 std::pair<size_t, size_t> controlPointWindow(double windowStart,
178 double windowEnd) const {
179 if (points_.empty()) {
180 throw std::invalid_argument(
181 "CumulativeSplineTrajectory requires at least one control point");
182 }
183
184 int start =
185 static_cast<int>(std::floor(windowStart * density_)) - windowPre_;
186 int end =
187 windowEnd < 0.0
188 ? static_cast<int>(points_.size())
189 : static_cast<int>(std::ceil(windowEnd * density_)) + windowPost_;
190 start = std::max(0, start);
191 end = std::min(end, static_cast<int>(points_.size()));
192 if (start >= end) {
193 throw std::invalid_argument(
194 "CumulativeSplineTrajectory sample window contains no control "
195 "points");
196 }
197 return {static_cast<size_t>(start), static_cast<size_t>(end)};
198 }
199
201 static Expression<T> kernelInterpolate(
202 const KernelBase& kernel, const Double_& timestamp,
203 const std::vector<Expression<T>>& points, size_t start, size_t end) {
204 const std::vector<Expression<T>> pointRange(points.begin() + start,
205 points.begin() + end);
206 const std::vector<Double_> weights =
207 sampleKernel(kernel, timestamp, start, end, 0);
208 return cumulativePathSum(pointRange, weights);
209 }
210
212 static TangentExpression kernelInterpolateDerivative(
213 const KernelBase& kernel, const Double_& timestamp,
214 const std::vector<Expression<T>>& points, size_t start, size_t end,
215 size_t derivative) {
216 const std::vector<Expression<T>> pointRange(points.begin() + start,
217 points.begin() + end);
218 const std::vector<Double_> weights =
219 sampleKernel(kernel, timestamp, start, end, derivative);
220 return cumulativePathSumDerivative(pointRange, weights);
221 }
222
224 static std::vector<Double_> sampleKernel(const KernelBase& kernel,
225 const Double_& timestamp,
226 size_t start, size_t end,
227 size_t derivative) {
228 std::vector<Double_> samples;
229 samples.reserve(end - start);
230 const std::function<double(const double&, OptionalJacobian<1, 1>)>
231 evaluateKernel =
232 [&kernel, derivative](const double& x, OptionalJacobian<1, 1> H) {
233 return kernel.evaluateDerivative(derivative, x, H);
234 };
235
236 for (size_t index = start; index < end; ++index) {
237 const Double_ kernelTime =
238 timestamp - Double_(static_cast<double>(index));
239 samples.emplace_back(evaluateKernel, kernelTime);
240 }
241 return samples;
242 }
243
245 static Expression<T> cumulativePathSum(
246 const std::vector<Expression<T>>& points,
247 const std::vector<Double_>& cumulativeWeights) {
248 return expmap(points.front(),
249 cumulativePathSumDerivative(points, cumulativeWeights));
250 }
251
253 static TangentExpression cumulativePathSumDerivative(
254 const std::vector<Expression<T>>& points,
255 const std::vector<Double_>& weights) {
256 TangentExpression tangent(TangentVector::Zero());
257 for (size_t index = 1; index < points.size(); ++index) {
258 tangent += weights[index] * logmap(points[index - 1], points[index]);
259 }
260 return tangent;
261 }
262
263 const double density_;
264 const KernelBase& kernel_;
265 std::vector<Expression<T>> points_;
266 const bool padFront_;
267 const double kernelOffset_;
268 const int windowPre_;
269 const int windowPost_;
270};
271
272} // namespace gtsam
Continuous kernels for convolution-based trajectory models.
Piecewise polynomial Irwin-Hall PDF and CDF kernels.
GTSAM_EXPORT const PiecewisePolynomial< 3, 3 > IrwinHallCDF2
Cubic cardinal-spline CDF kernel.
A non-templated config holding any types of Manifold-group elements.
STL namespace.
Global functions in a separate testing namespace.
Definition chartTesting.h:28
gtsam::Expression< typename gtsam::traits< T >::TangentVector > logmap(const gtsam::Expression< T > &x1, const gtsam::Expression< T > &x2)
logmap
Definition expressions.h:197
Expression< T > expmap(const Expression< T > &origin, const Expression< typename traits< T >::TangentVector > &tangent)
Apply an exponential-map increment to a Lie-group expression.
Definition expressions.h:43
A manifold defines a space in which there is a notion of a linear tangent space that can be centered ...
Definition Group.h:37
TangentExpression sampleTrajectoryDerivative(const Double_ &timestamp, double windowStart=0.0, double windowEnd=-1.0, size_t derivative=1) const
Create an expression for a trajectory derivative in the tangent space.
Definition CumulativeSplineTrajectory.h:149
CumulativeSplineTrajectory(double density, bool padFront)
Construct a trajectory with the default cubic kernel and padding mode.
Definition CumulativeSplineTrajectory.h:92
const KernelBase & kernel() const
Kernel used to interpolate the trajectory.
Definition CumulativeSplineTrajectory.h:100
Expression< TangentVector > TangentExpression
Expression whose value is a trajectory tangent vector.
Definition CumulativeSplineTrajectory.h:61
TangentVector sampleTrajectoryDerivative(double timestamp, double windowStart=0.0, double windowEnd=-1.0, size_t derivative=1) const
Evaluate a tangent derivative for constant controls and numeric time.
Definition CumulativeSplineTrajectory.h:166
bool padFront() const
Whether kernel support is padded before each control point.
Definition CumulativeSplineTrajectory.h:103
CumulativeSplineTrajectory(double density=1.0, const KernelBase &kernel=kernels::IrwinHallCDF2, const std::vector< Expression< T > > &points={}, bool padFront=false)
Construct a trajectory model.
Definition CumulativeSplineTrajectory.h:73
void addControlPoint(const Expression< T > &point)
Append a key, constant, or computed expression as a control point.
Definition CumulativeSplineTrajectory.h:106
double density() const
Number of control points per unit sample coordinate.
Definition CumulativeSplineTrajectory.h:97
void addControlPoint(const T &point)
Append a constant value as a control point.
Definition CumulativeSplineTrajectory.h:109
Expression< T > sampleTrajectory(const Double_ &timestamp, double windowStart=0.0, double windowEnd=-1.0) const
Create an expression that samples the trajectory.
Definition CumulativeSplineTrajectory.h:121
const std::vector< Expression< T > > & getControlPoints() const
Read-only access to the control-point expressions.
Definition CumulativeSplineTrajectory.h:112
typename traits< T >::TangentVector TangentVector
Tangent-space value associated with one trajectory sample.
Definition CumulativeSplineTrajectory.h:59
T sampleTrajectory(double timestamp, double windowStart=0.0, double windowEnd=-1.0) const
Sample a constant-control trajectory at a numeric timestamp.
Definition CumulativeSplineTrajectory.h:137
Interface for a compactly supported continuous convolution kernel.
Definition KernelBase.h:27
Expression class that supports automatic differentiation.
Definition Expression.h:49
T value(const Values &values, std::vector< Matrix > *H=nullptr) const
Return value and optional derivatives, reverse AD version Notes: this is not terribly efficient,...
Definition Expression-inl.h:143
A non-templated config holding any types of Manifold-group elements.
Definition Values.h:65
Common expressions for solving geometry/slam/sfm problems.