gtsam
Loading...
Searching...
No Matches
WnoaFactorGraph.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
26
27#include <array>
28#include <memory>
29#include <unordered_map>
30#include <unordered_set>
31
32namespace gtsam {
33
50template <typename PoseType>
51class GTSAM_EXPORT WnoaFactorGraph : public ExpressionFactorGraph {
52 private:
53 using This = WnoaFactorGraph<PoseType>;
54 using Base = ExpressionFactorGraph;
55 using VelocityType = typename gtsam::traits<PoseType>::TangentVector;
56 static constexpr int dim = traits<PoseType>::dimension;
57
58 // Convenient matrices
59 using Matrix2N = Eigen::Matrix<double, 2 * dim, 2 * dim>;
60 using MatrixN = Eigen::Matrix<double, dim, dim>;
61 using VectorN = Eigen::Matrix<double, dim, 1>;
62
63 // Interpolator class
64 const Interpolator<PoseType> interpolator_;
65
66 using LambdaPsiMats = typename Interpolator<PoseType>::LambdaPsiMats;
67 using LocalStateVecs = typename Interpolator<PoseType>::LocalStateVecs;
68 using StateJacobians = typename Interpolator<PoseType>::StateJacobians;
69
70 // map interpolated state to border states
71 std::unordered_map<StateData, std::pair<StateData, StateData>>
72 interp_to_borders_map_;
73 std::vector<std::pair<StateData, std::pair<StateData, StateData>>>
74 interp_to_borders_vec_;
75 std::vector<std::pair<StateData, std::shared_ptr<const LambdaPsiMats>>>
76 interp_to_LambdaPsi_vec_;
77
78 // Precomputed batches of borders -> indices in interp_to_borders_vec_
79 // Each entry contains the border pair and the list of interp indices that
80 // share those borders.
81 std::vector<std::pair<std::pair<StateData, StateData>, std::vector<size_t>>>
82 border_batches_;
83
84 bool fixed_noise_model_ = false;
85
86 std::unordered_set<Key> border_pose_keys_;
87 std::unordered_set<Key> border_vel_keys_;
88
89 // Efficient storage for indices of WnoaInterpFactors
90 std::unordered_set<size_t> wnoa_interp_factor_indices_;
91
108 Values getInterpolatedValues(
109 const Values& values,
110 std::unordered_map<Key, std::array<Matrix, 4>>* InterpJacobians,
111 std::unordered_map<StateData, Matrix2N>* InterpCondCovs = nullptr) const;
112
113 public:
126 std::shared_ptr<GaussianFactorGraph> linearize(
127 const Values& linearizationPoint) const override;
128
140 double error(const Values& values) const override;
141
143 std::shared_ptr<const NonlinearFactorGraph> cloneShared() const override {
144 return std::make_shared<WnoaFactorGraph<PoseType>>(*this);
145 }
146
164 std::unordered_map<StateData, std::pair<StateData, StateData>> interp_map,
165 const VectorN q_psd_diag, bool fixed_noise_model = false);
166};
167
170
200template <class PoseType, class FactorGraphType = NonlinearFactorGraph>
202 const NonlinearFactorGraph& graph,
203 const std::set<StateData>& estimated_states,
204 const std::set<StateData>& interp_states, Vector q_psd_diag,
205 bool fixed_noise = false) {
206 // assert that the pose is the right kind of variable
207 static_assert(
208 std::is_same_v<typename traits<PoseType>::structure_category,
209 lie_group_tag> ||
210 std::is_same_v<typename traits<PoseType>::structure_category,
212 "Pose type must be either a Lie group or vector space");
213 // check dimension on the power spectral density matrix
214 assert(traits<PoseType>::dimension == q_psd_diag.size());
215 // Get map from keys to interpolated state, and interpolated state to
216 // estimated state.
217 std::unordered_map<Key, StateData> key_to_interp_;
218 std::unordered_map<StateData, std::pair<StateData, StateData>>
219 interp_to_borders_;
220 for (const StateData& state : interp_states) {
221 // search for estimated state that upper bound current interpolated state
222 auto iter_est_state = estimated_states.lower_bound(state);
223 if (iter_est_state == estimated_states.begin()) {
224 throw std::runtime_error(
225 "Interpolated state time is before all estimated state times");
226 } else if (iter_est_state == estimated_states.end()) {
227 throw std::runtime_error(
228 "Interpolated state time is after all estimated state times");
229 } else {
230 // decrement iterator (point to left border)
231 iter_est_state--;
232 // map interp to left border index
233 interp_to_borders_[state] =
234 std::pair(*iter_est_state, *std::next(iter_est_state));
235 // map keys to interp state
236 key_to_interp_[state.pose] = state;
237 key_to_interp_[state.velocity] = state;
238 }
239 }
240 // Create new factor graph (we use a lambda to handle the case where we need
241 // to pass additional info to the constructor, e.g. for WnoaFactorGraph)
242 FactorGraphType new_graph = [&]() {
243 if constexpr (std::is_same_v<FactorGraphType, WnoaFactorGraph<PoseType>>) {
244 return FactorGraphType(interp_to_borders_, q_psd_diag, fixed_noise);
245 } else {
246 return FactorGraphType();
247 }
248 }();
249 // Add WNOA prior between all estimated states
250 auto iter_state = estimated_states.begin();
251 while (std::next(iter_state) != estimated_states.end()) {
252 StateData state_k = *iter_state;
253 StateData state_kp1 = *std::next(iter_state);
254 // get time diff
255 double delta_t = state_kp1.time - state_k.time;
256 // add factor
257 auto motion_factor = std::make_shared<WnoaMotionFactor<PoseType>>(
258 state_k.pose, state_k.velocity, state_kp1.pose, state_kp1.velocity,
259 delta_t, q_psd_diag);
260 new_graph.add(motion_factor);
261 iter_state++;
262 }
263 // loop through factors and wrap factors on interpolated states
264 for (auto& factor : graph) {
265 // handle null factor
266 if (!factor) continue;
267 // if the factor is a WNOA motion factor, do not add it
268 if (std::dynamic_pointer_cast<WnoaMotionFactor<PoseType>>(factor)) continue;
269 // get ordered sets of interpolated and estimated states
270 std::set<StateData> factor_interp_states;
271 std::set<StateData> factor_estimated_states;
272 for (Key& key : factor->keys()) {
273 // check if key is an interpolated value
274 if (key_to_interp_.count(key) > 0) {
275 // add indices
276 StateData interp_state = key_to_interp_[key];
277 factor_interp_states.insert(interp_state);
278 auto [left, right] = interp_to_borders_.at(interp_state);
279 factor_estimated_states.insert(left);
280 factor_estimated_states.insert(right);
281 }
282 }
283 // add factor to new graph
284 if (factor_interp_states.size() == 0) {
285 // factor does not require interpolation, just add factor as is
286 new_graph.add(factor);
287 } else {
288 // Downcast the NonlinearFactor to a NoiseModelFactor
289 auto nmfactor = std::dynamic_pointer_cast<NoiseModelFactor>(factor);
290 assert(nmfactor &&
291 "Defined factors must be NoiseModelFactor or derivative class");
292
293 // Define and add factor to new graph
294 const auto wrapped_factor = std::make_shared<WnoaInterpFactor<PoseType>>(
295 nmfactor, factor_estimated_states, factor_interp_states, q_psd_diag,
296 fixed_noise);
297 new_graph.add(wrapped_factor);
298 }
299 }
300
301 return new_graph;
302}
303
334template <class PoseType>
336 const NonlinearFactorGraph& graph,
337 const std::set<StateData>& estimated_states,
338 const std::set<StateData>& interp_states, Vector q_psd_diag,
339 bool fixed_noise = false) {
341 graph, estimated_states, interp_states, q_psd_diag, fixed_noise);
342}
343
364template <class PoseType>
366 const NonlinearFactorGraph& interp_graph, const Values& values,
367 const std::set<StateData>& estim_states,
368 const std::set<StateData>& interp_states, const Vector q_psd_diag,
369 std::shared_ptr<InterpCovarianceMap> covarianceMapOut = nullptr) {
370 // assert that the pose is the right kind of variable
371 static_assert(
372 std::is_same_v<typename traits<PoseType>::structure_category,
373 lie_group_tag> ||
374 std::is_same_v<typename traits<PoseType>::structure_category,
376 "Pose type must be either a Lie group or vector space");
377 // check dimension on the power spectral density matrix
378 assert(traits<PoseType>::dimension == q_psd_diag.size());
379 // Define interpolator
380 Interpolator<PoseType> interpolator(q_psd_diag);
381 // get interpolated values
382 Values interp_vals = interpolator.interpolatePosesAndVelocities(
383 interp_graph, values, estim_states, interp_states, covarianceMapOut);
384 // update values
385 Values values_updated(values);
386 values_updated.insert(interp_vals);
387 return values_updated;
388}
389
407template <class PoseType>
408std::pair<Values, InterpCovarianceMap> updateInterpValuesWithCovariance(
409 const NonlinearFactorGraph& interp_graph, const Values& values,
410 const std::set<StateData>& estim_states,
411 const std::set<StateData>& interp_states, const Vector q_psd_diag) {
412 auto covariance_map = std::make_shared<InterpCovarianceMap>();
413 Values values_updated =
414 updateInterpValues<PoseType>(interp_graph, values, estim_states,
415 interp_states, q_psd_diag, covariance_map);
416 return std::make_pair(values_updated, std::move(*covariance_map));
417}
418
419} // namespace gtsam
Linear Factor Graph where all factors are Gaussians.
Interpolator class implementation for interpolating poses and velocities between two bordering states...
Introduces a lightweight struct for identifying states in continuous-time estimation and interpolatio...
Factor Graph consisting of non-linear factors.
White-Noise-On-Acceleration (WNOA) continuous time interpolation wrapper factor and functions to auto...
Factor graph that supports adding ExpressionFactors directly.
Global functions in a separate testing namespace.
Definition chartTesting.h:28
WnoaFactorGraph< PoseType > interpolateWnoaFactorGraph(const NonlinearFactorGraph &graph, const std::set< StateData > &estimated_states, const std::set< StateData > &interp_states, Vector q_psd_diag, bool fixed_noise=false)
WnoaFactorGraph specialization of interpolateFactorGraph for use in Python bindings.
Definition WnoaFactorGraph.h:335
Values updateInterpValues(const NonlinearFactorGraph &interp_graph, const Values &values, const std::set< StateData > &estim_states, const std::set< StateData > &interp_states, const Vector q_psd_diag, std::shared_ptr< InterpCovarianceMap > covarianceMapOut=nullptr)
Update a Values with interpolated pose and velocity entries.
Definition WnoaFactorGraph.h:365
std::pair< Values, InterpCovarianceMap > updateInterpValuesWithCovariance(const NonlinearFactorGraph &interp_graph, const Values &values, const std::set< StateData > &estim_states, const std::set< StateData > &interp_states, const Vector q_psd_diag)
Update Values with interpolated states and return covariances.
Definition WnoaFactorGraph.h:408
FactorGraphType interpolateFactorGraph(const NonlinearFactorGraph &graph, const std::set< StateData > &estimated_states, const std::set< StateData > &interp_states, Vector q_psd_diag, bool fixed_noise=false)
Utility functions for working with Factor Graphs containing interpolated variables.
Definition WnoaFactorGraph.h:201
std::uint64_t Key
Integer nonlinear key type.
Definition types.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
tag to assert a type is a Lie group
Definition Lie.h:271
tag to assert a type is a vector space
Definition VectorSpace.h:21
Factor graph that supports adding ExpressionFactors directly.
Definition ExpressionFactorGraph.h:29
Definition NonlinearFactorGraph.h:57
A non-templated config holding any types of Manifold-group elements.
Definition Values.h:65
void insert(Key j, const Value &val)
Add a variable with the given j, throws KeyAlreadyExists<J> if j is already present.
Definition Values.cpp:170
WNOA (White Noise on Acceleration) motion prior factor.
Definition WnoaFactor.h:56
Factor graph specialized for WNOA interpolation-aware computation.
Definition WnoaFactorGraph.h:51
double error(const Values &values) const override
Compute the unnormalized graph error (sum of factor losses).
Definition WnoaFactorGraph.cpp:216
WnoaFactorGraph(std::unordered_map< StateData, std::pair< StateData, StateData > > interp_map, const VectorN q_psd_diag, bool fixed_noise_model=false)
Construct a WnoaFactorGraph with interpolation metadata.
Definition WnoaFactorGraph.cpp:86
std::shared_ptr< GaussianFactorGraph > linearize(const Values &linearizationPoint) const override
Linearize the graph into a GaussianFactorGraph.
Definition WnoaFactorGraph.cpp:141
std::shared_ptr< const NonlinearFactorGraph > cloneShared() const override
Clone into a shared pointer while preserving WnoaFactorGraph behavior.
Definition WnoaFactorGraph.h:143
Interpolator for poses and velocities under a motion prior.
Definition WnoaInterpolator.h:106
Values interpolatePosesAndVelocities(const NonlinearFactorGraph &mainSolveGraph, const Values &mainSolveSolution, const StateDataSet &mainSolveStates, const StateDataSet &interpolatedStates, std::shared_ptr< InterpCovarianceMap > covarianceMapOut=nullptr) const
Interpolate multiple poses and velocities given a solved factor graph.
Definition WnoaInterpolator.cpp:488
Definition WnoaInterpolator.h:138
Lightweight container for states used for continuous-time estimation and interpolation.
Definition WnoaStateData.h:39
double time
Timestamp (seconds) associated with this state.
Definition WnoaStateData.h:42
Key pose
Key of the pose variable.
Definition WnoaStateData.h:40
Key velocity
Key of the velocity variable.
Definition WnoaStateData.h:41