My Project 1.0
Holistic Fusion: A Generic Framework for Multimodal Sensor Fusion
Loading...
Searching...
No Matches
OptimizerLMFixedLag.hpp
Go to the documentation of this file.
1/*
2Copyright 2024 by Julian Nubert, Robotic Systems Lab, ETH Zurich.
3All rights reserved.
4This file is released under the "BSD-3-Clause License".
5Please see the LICENSE file that has been included as part of this package.
6 */
7
8#ifndef OPTIMIZER_LM_FIXED_LAG_HPP
9#define OPTIMIZER_LM_FIXED_LAG_HPP
10
11// GTSAM
12#include <gtsam/nonlinear/BatchFixedLagSmoother.h>
13
14// Workspace
16
17namespace holistic_fusion {
18
20 public:
21 explicit OptimizerLMFixedLag(const std::shared_ptr<GraphConfig> graphConfigPtr) : OptimizerLM(graphConfigPtr) {
22 // Set Linear Solver Type
23 if (graphConfigPtr_->realTimeSmootherUseCholeskyFactorizationFlag_) {
24 lmParams_.linearSolverType = gtsam::NonlinearOptimizerParams::MULTIFRONTAL_CHOLESKY;
25 REGULAR_COUT << "Using Multifrontal-Cholesky factorization for fixed-lag smoother (LM)." << std::endl;
26 } else {
27 lmParams_.linearSolverType = gtsam::NonlinearOptimizerParams::MULTIFRONTAL_QR;
28 REGULAR_COUT << "Using Multifrontal-QR factorization for fixed-lag smoother (LM)." << std::endl;
29 }
30
31 // Initialize Real-time Smoother -----------------------------------------------
32 fixedLagSmootherPtr_ = std::make_shared<gtsam::BatchFixedLagSmoother>(graphConfigPtr_->realTimeSmootherLag_, lmParams_);
33 // Print
34 fixedLagSmootherPtr_->print("LM FixedLagSmoother initialized with lag: ");
35 }
37
38 bool update() override {
39 fixedLagSmootherPtr_->update();
40 return true;
41 }
42
43 bool update(const gtsam::NonlinearFactorGraph& newGraphFactors, const gtsam::Values& newGraphValues,
44 const std::map<gtsam::Key, double>& newGraphKeysTimeStampMap, const int depth = 0) override {
45 // Try to update
46 try {
47 fixedLagSmootherPtr_->update(newGraphFactors, newGraphValues, newGraphKeysTimeStampMap);
48 } catch (const std::out_of_range& outOfRangeExeception) { // Not specifically catching
49 std::cerr << YELLOW_START << "GMsf-LM-FixedLagSmoother" << RED_START
50 << " OutOfRange-Exception while optimizing graph: " << outOfRangeExeception.what() << COLOR_END << std::endl;
51 std::cout
52 << YELLOW_START << "GMsf-ISAM2" << RED_START
53 << " This usually happens if the measurement delay is larger than the graph-smootherLag, i.e. the optimized graph instances are "
54 "not connected. Increase the lag in this case."
55 << COLOR_END << std::endl;
56 // throw std::out_of_range(outOfRangeExeception.what());
57 return false;
58 } catch (const gtsam::ValuesKeyDoesNotExist& valuesKeyDoesNotExistException) { // Catching, as this can happen in practice (factors
59 // added that are outside the smoother window)
60 std::cout << "----------------------------------------------------------" << std::endl;
61 std::cerr << YELLOW_START << "GMsf-LM-FixedLagSmoother" << RED_START
62 << " Values Key Does Not Exist exeception while optimizing graph: " << valuesKeyDoesNotExistException.what() << COLOR_END
63 << std::endl;
64 std::cout << YELLOW_START << "GMsf-LM-FixedLagSmoother" << RED_START
65 << " This happens if a factor is added to the graph that contains a non-existent state. The most common case is a factor "
66 "containing a graph state that was marginalized out before. To avoid this, increase the factor graph lag or reduce "
67 "the delay of your measurements."
68 << COLOR_END << std::endl;
69 // Filter out the factor that caused the error -------------------------
70 gtsam::NonlinearFactorGraph newGraphFactorsFiltered;
71 gtsam::Key valuesKeyNotExistent = valuesKeyDoesNotExistException.key();
72 for (auto factor : newGraphFactors) {
73 bool factorContainsExistentKeys = true;
74 for (auto key : factor->keys()) {
75 if (key == valuesKeyNotExistent) {
76 std::cout << YELLOW_START << "GMsf-LM-FixedLagSmoother" << RED_START
77 << " Factor contains non-existent key: " << gtsam::Symbol(key) << COLOR_END << std::endl;
78 factorContainsExistentKeys = false;
79 break;
80 }
81 }
82 if (factorContainsExistentKeys) {
83 newGraphFactorsFiltered.add(factor);
84 }
85 }
86 // Filtering the keyTimestampMap
87 std::map<gtsam::Key, double> newGraphKeysTimeStampMapFiltered = newGraphKeysTimeStampMap;
88 newGraphKeysTimeStampMapFiltered.erase(valuesKeyNotExistent);
89 // Try again
90 std::cout << YELLOW_START << "GMsf-LM-FixedLagSmoother" << GREEN_START
91 << " Filtered out the factor that caused the error. Trying to optimize again." << COLOR_END << std::endl;
92 std::cout << "----------------------------------------------------------" << std::endl;
93 return update(newGraphFactorsFiltered, newGraphValues, newGraphKeysTimeStampMapFiltered);
94 } catch (const std::runtime_error& runtimeError) {
95 std::cout << YELLOW_START << "GMsf-ISAM2" << RED_START << " Runtime error while optimizing graph: " << runtimeError.what()
96 << COLOR_END << std::endl;
97 throw std::runtime_error(runtimeError.what());
98 }
99 return true;
100 }
101
102 // Optimize
103 void optimize(int maxIterations) override {
104 // Print
105 std::cout << YELLOW_START << "HolisticFusion: OptimizerLMFixedLag" << GREEN_START << " Optimizing fixed-lag smoother." << COLOR_END
106 << std::endl;
107
108 // Optimize
110 }
111
112 // Get Result
113 const gtsam::Values& getAllOptimizedStates() override { return fixedLagSmootherOptimizedResult_; }
114
115 // Get all keys of optimized states
116 gtsam::KeyVector getAllOptimizedKeys() override { return fixedLagSmootherOptimizedResult_.keys(); }
117
118 // Get nonlinear factor graph
119 const gtsam::NonlinearFactorGraph& getNonlinearFactorGraph() const override { return fixedLagSmootherPtr_->getFactors(); }
120
121 // Get keyTimestampMap
122 const std::map<gtsam::Key, double>& getFullKeyTimestampMap() override { return fixedLagSmootherPtr_->timestamps(); }
123
124 // Calculate State / Covariance
125 // Pose3
126 gtsam::Pose3 calculateEstimatedPose3(const gtsam::Key& key) override {
127 return fixedLagSmootherPtr_->calculateEstimate<gtsam::Pose3>(key);
128 }
129 // Velocity3
130 gtsam::Vector3 calculateEstimatedVelocity3(const gtsam::Key& key) override {
131 return fixedLagSmootherPtr_->calculateEstimate<gtsam::Vector3>(key);
132 }
133 // Bias
134 gtsam::imuBias::ConstantBias calculateEstimatedBias(const gtsam::Key& key) override {
135 return fixedLagSmootherPtr_->calculateEstimate<gtsam::imuBias::ConstantBias>(key);
136 }
137 // Point3
138 gtsam::Point3 calculateEstimatedPoint3(const gtsam::Key& key) override {
139 return fixedLagSmootherPtr_->calculateEstimate<gtsam::Point3>(key);
140 }
141 // Vector
142 gtsam::Vector calculateEstimatedVector(const gtsam::Key& key) override {
143 return fixedLagSmootherPtr_->calculateEstimate<gtsam::Vector>(key);
144 }
145
146 // Marginal Covariance
147 gtsam::Matrix calculateMarginalCovarianceMatrixAtKey(const gtsam::Key& key) override {
148 // Not implemented
149 std::cout << "FixedLagSmoother: Marginal Covariance not implemented yet. Returning Identity of correct size for key type: "
150 << gtsam::symbolChr(key) << std::endl;
151 const unsigned char measurementType = gtsam::symbolChr(key);
152 // Switch case
153 switch (measurementType) {
154 case 'x':
155 return gtsam::Matrix::Identity(6, 6);
156 case 'v':
157 return gtsam::Matrix::Identity(3, 3);
158 case 'b':
159 return gtsam::Matrix::Identity(6, 6);
160 case 't':
161 return gtsam::Matrix::Identity(6, 6);
162 case 'd':
163 return gtsam::Matrix::Identity(3, 3);
164 default:
165 throw std::runtime_error("FixedLagSmoother: Marginal Covariance not implemented for this key type: " + gtsam::symbolChr(key));
166 }
167 }
168
169 private:
170 // Optimizer itself
171 std::shared_ptr<gtsam::BatchFixedLagSmoother> fixedLagSmootherPtr_;
172 // Result
174};
175
176} // namespace holistic_fusion
177
178#endif // OPTIMIZER_LM_FIXED_LAG_HPP
#define COLOR_END
#define GREEN_START
#define RED_START
#define YELLOW_START
std::shared_ptr< GraphConfig > graphConfigPtr_
bool update(const gtsam::NonlinearFactorGraph &newGraphFactors, const gtsam::Values &newGraphValues, const std::map< gtsam::Key, double > &newGraphKeysTimeStampMap, const int depth=0) override
OptimizerLMFixedLag(const std::shared_ptr< GraphConfig > graphConfigPtr)
void optimize(int maxIterations) override
gtsam::Point3 calculateEstimatedPoint3(const gtsam::Key &key) override
gtsam::KeyVector getAllOptimizedKeys() override
gtsam::Pose3 calculateEstimatedPose3(const gtsam::Key &key) override
const gtsam::Values & getAllOptimizedStates() override
const std::map< gtsam::Key, double > & getFullKeyTimestampMap() override
gtsam::Vector3 calculateEstimatedVelocity3(const gtsam::Key &key) override
std::shared_ptr< gtsam::BatchFixedLagSmoother > fixedLagSmootherPtr_
gtsam::imuBias::ConstantBias calculateEstimatedBias(const gtsam::Key &key) override
const gtsam::NonlinearFactorGraph & getNonlinearFactorGraph() const override
gtsam::Matrix calculateMarginalCovarianceMatrixAtKey(const gtsam::Key &key) override
gtsam::Vector calculateEstimatedVector(const gtsam::Key &key) override
gtsam::LevenbergMarquardtParams lmParams_
OptimizerLM(const std::shared_ptr< GraphConfig > graphConfigPtr)