My Project 1.0
Holistic Fusion: A Generic Framework for Multimodal Sensor Fusion
Loading...
Searching...
No Matches
HolisticFusionHolistic.cpp
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// Implementation
10
11// Workspace
14
15// Unary Expression Factors
22
23// Landmark Expression Factors
25
26// Binary Expression Factors
27// TODO: add binary factors
28
29namespace holistic_fusion {
30
31// Constructor
33 REGULAR_COUT << GREEN_START << " HolisticFusionHolistic-Constructor called." << COLOR_END << std::endl;
34}
35
36// The alignment keyframe of a fixed frame is only created by a measurement with a position
38 const std::string& worldFrame = measurement.worldFrameName();
39 const std::string& fixedFrame = measurement.fixedFrameName();
40 if (graphConfigPtr_->optimizeReferenceFramePosesWrtWorldFlag_ && fixedFrame != worldFrame &&
41 !graphMgrPtr_->hasReferenceFrameKeyframe(worldFrame, fixedFrame)) {
42 REGULAR_COUT << YELLOW_START << " Skipping measurement " << measurement.measurementName() << ": frame " << fixedFrame
43 << " has no alignment keyframe yet. A position or pose measurement of this frame creates it." << COLOR_END << std::endl;
44 return false;
45 }
46 return true;
47}
48
49// Unary Measurements: In reference frame --> systematic drift ---------------------------------------------------------
50
51// Pose3
53 const bool addToOnlineSmootherFlag) {
54 // Valid measurement received
57 }
58
59 // Only take actions if graph has been initialized
60 if (!initedGraphFlag_) { // Graph not yet initialized
61 return;
62 } else { // Graph initialized
63 // Check for covariance violation
64 bool covarianceViolatedFlag = isCovarianceViolated_<6>(R_T_R_S.unaryMeasurementNoiseDensity(), R_T_R_S.covarianceViolationThreshold());
65 if (checkAndPrintCovarianceViolation_(R_T_R_S.measurementName(), covarianceViolatedFlag)) {
66 return;
67 }
68
69 // Create GMSF expression
70 auto gmsfUnaryExpressionPose3Ptr = std::make_shared<GmsfUnaryExpressionAbsolutePose3>(
71 std::make_shared<UnaryMeasurementXDAbsolute<Eigen::Isometry3d, 6>>(R_T_R_S), staticTransformsPtr_->getImuFrame(),
72 staticTransformsPtr_->rv_T_frame1_frame2(staticTransformsPtr_->getImuFrame(), R_T_R_S.sensorFrameName()),
73 graphConfigPtr_->createReferenceAlignmentKeyframeEveryNSeconds_);
74
75 // Add factor to graph
76 graphMgrPtr_->addUnaryHolisticFactor<GmsfUnaryExpressionAbsolutePose3>(gmsfUnaryExpressionPose3Ptr, addToOnlineSmootherFlag);
77
78 // Optimize ---------------------------------------------------------------
79 {
80 // Mutex for optimizeGraph Flag
81 const std::lock_guard<std::mutex> optimizeGraphLock(optimizeGraphMutex_);
82 optimizeGraphFlag_ = true;
83 }
84 }
85}
86
87// Position3
89 UnaryMeasurementXDAbsolute<Eigen::Vector3d, 3>& fixedFrame_t_fixedFrame_sensorFrame) {
90 // Valid measurement received
93 }
94
95 // Only take actions if graph has been initialized
96 if (!initedGraphFlag_) { // Case 1: Graph not yet initialized
97 return;
98 } else { // Case 2: Graph Initialized
99 // Check for covariance violation
100 bool covarianceViolatedFlag = isCovarianceViolated_<3>(fixedFrame_t_fixedFrame_sensorFrame.unaryMeasurementNoiseDensity(),
101 fixedFrame_t_fixedFrame_sensorFrame.covarianceViolationThreshold());
102 if (checkAndPrintCovarianceViolation_(fixedFrame_t_fixedFrame_sensorFrame.measurementName(), covarianceViolatedFlag)) {
103 return;
104 }
105
106 // Create GMSF expression
107 auto gmsfUnaryExpressionPosition3Ptr = std::make_shared<GmsfUnaryExpressionAbsolutePosition3>(
108 std::make_shared<UnaryMeasurementXDAbsolute<Eigen::Vector3d, 3>>(fixedFrame_t_fixedFrame_sensorFrame),
109 staticTransformsPtr_->getImuFrame(),
110 staticTransformsPtr_->rv_T_frame1_frame2(staticTransformsPtr_->getImuFrame(),
111 fixedFrame_t_fixedFrame_sensorFrame.sensorFrameName()),
112 graphConfigPtr_->createReferenceAlignmentKeyframeEveryNSeconds_);
113
114 // Add factor to graph
115 graphMgrPtr_->addUnaryHolisticFactor<GmsfUnaryExpressionAbsolutePosition3>(gmsfUnaryExpressionPosition3Ptr);
116
117 // Optimize ---------------------------------------------------------------
118 {
119 // Mutex for optimizeGraph Flag
120 const std::lock_guard<std::mutex> optimizeGraphLock(optimizeGraphMutex_);
121 optimizeGraphFlag_ = true;
122 }
123 }
124}
125
128 // Valid measurement received
131 }
132
133 // Only take actions if graph has been initialized
134 if (!initedGraphFlag_) {
135 return;
136 }
137
138 // Check for covariance violation
139 bool covarianceViolatedFlag = isCovarianceViolated_<1>(R_M_S.unaryMeasurementNoiseDensity(),
141 if (checkAndPrintCovarianceViolation_(R_M_S.measurementName(), covarianceViolatedFlag)) {
142 return;
143 }
144
146 return;
147 }
148
149 // Create GMSF expression
150 auto gmsfUnaryExpressionHeadingPtr = std::make_shared<GmsfUnaryExpressionAbsoluteHeading>(
151 std::make_shared<UnaryMeasurementXDAbsolute<Eigen::Matrix3d, 1>>(R_M_S),
152 staticTransformsPtr_->getImuFrame(),
153 staticTransformsPtr_->rv_T_frame1_frame2(staticTransformsPtr_->getImuFrame(), R_M_S.sensorFrameName()),
154 graphConfigPtr_->createReferenceAlignmentKeyframeEveryNSeconds_);
155
156 // Add factor to graph
157 graphMgrPtr_->addUnaryHolisticFactor<GmsfUnaryExpressionAbsoluteHeading>(gmsfUnaryExpressionHeadingPtr);
158
159 // Optimize ---------------------------------------------------------------
160 {
161 // Mutex for optimizeGraph Flag
162 const std::lock_guard<std::mutex> optimizeGraphLock(optimizeGraphMutex_);
163 optimizeGraphFlag_ = true;
164 }
165}
166
167// Velocity3 in Fixed Frame
169 throw std::runtime_error("Velocity measurements in fixed frame are not yet supported.");
170}
171
172// Local Measurements: Fully Local ---------------------------------------------------------
173// Velocity3 in Body Frame
175 // Valid measurement received
178 }
179
180 // Only take actions if graph has been initialized
181 if (!initedGraphFlag_) { // Case 1: Graph not yet initialized
182 return;
183 } else { // Case 2: Graph Initialized
184 // Check for covariance violation
185 bool covarianceViolatedFlag = isCovarianceViolated_<3>(S_v_F_S.unaryMeasurementNoiseDensity(), S_v_F_S.covarianceViolationThreshold());
186 if (checkAndPrintCovarianceViolation_(S_v_F_S.measurementName(), covarianceViolatedFlag)) {
187 return;
188 }
189
190 // Create GMSF expression
191 auto gmsfUnaryExpressionVelocity3SensorFramePtr = std::make_shared<GmsfUnaryExpressionLocalVelocity3>(
192 std::make_shared<UnaryMeasurementXD<Eigen::Vector3d, 3>>(S_v_F_S), staticTransformsPtr_->getImuFrame(),
193 staticTransformsPtr_->rv_T_frame1_frame2(staticTransformsPtr_->getImuFrame(), S_v_F_S.sensorFrameName()), coreImuBufferPtr_);
194
195 // Add factor to graph
196 graphMgrPtr_->addUnaryHolisticFactor<GmsfUnaryExpressionLocalVelocity3>(gmsfUnaryExpressionVelocity3SensorFramePtr);
197
198 // Optimize ---------------------------------------------------------------
199 {
200 // Mutex for optimizeGraph Flag
201 const std::lock_guard<std::mutex> optimizeGraphLock(optimizeGraphMutex_);
202 optimizeGraphFlag_ = true;
203 }
204 }
205}
206
207// Velocity3 in Body Frame, sensor frame not rigidly attached to the IMU
209 const Eigen::Isometry3d& T_I_sensorFrame,
210 const Eigen::Vector3d& I_w_W_I) {
211 // Valid measurement received
214 }
215
216 // Only take actions if graph has been initialized
217 if (!initedGraphFlag_) { // Case 1: Graph not yet initialized
218 return;
219 } else { // Case 2: Graph Initialized
220 // Check for covariance violation
221 bool covarianceViolatedFlag = isCovarianceViolated_<3>(S_v_F_S.unaryMeasurementNoiseDensity(), S_v_F_S.covarianceViolationThreshold());
222 if (checkAndPrintCovarianceViolation_(S_v_F_S.measurementName(), covarianceViolatedFlag)) {
223 return;
224 }
225
226 // Create GMSF expression, with the caller-supplied extrinsics and angular velocity
227 auto gmsfUnaryExpressionVelocity3SensorFramePtr = std::make_shared<GmsfUnaryExpressionLocalVelocity3>(
228 std::make_shared<UnaryMeasurementXD<Eigen::Vector3d, 3>>(S_v_F_S), staticTransformsPtr_->getImuFrame(), T_I_sensorFrame, I_w_W_I);
229
230 // Add factor to graph
231 graphMgrPtr_->addUnaryHolisticFactor<GmsfUnaryExpressionLocalVelocity3>(gmsfUnaryExpressionVelocity3SensorFramePtr);
232
233 // Optimize ---------------------------------------------------------------
234 {
235 // Mutex for optimizeGraph Flag
236 const std::lock_guard<std::mutex> optimizeGraphLock(optimizeGraphMutex_);
237 optimizeGraphFlag_ = true;
238 }
239 }
240}
241
242// Landmark Measurements: No systematic drift ------------------------------------------------------
243// Position3
245 const int landmarkCreationCounter) {
246 // Valid measurement received
249 }
250
251 // Only take actions if graph has been initialized
252 if (!initedGraphFlag_) { // Case 1: Graph not yet initialized
253 return;
254 } else { // Case 2: Graph Initialized
255 // Check for covariance violation
256 bool covarianceViolatedFlag = isCovarianceViolated_<3>(S_t_S_L.unaryMeasurementNoiseDensity(), S_t_S_L.covarianceViolationThreshold());
257 if (checkAndPrintCovarianceViolation_(S_t_S_L.measurementName(), covarianceViolatedFlag)) {
258 return;
259 }
260
261 // TODO: Change this to more explicit handling of counter
262 // S_t_S_L.setMeasurementName(S_t_S_L.measurementName() + "_" + std::to_string(landmarkCreationCounter));
263
264 // Create GMSF expression
265 auto gmsfUnaryExpressionPosition3LandmarkPtr = std::make_shared<GmsfUnaryExpressionLandmarkPosition3>(
266 std::make_shared<UnaryMeasurementXDLandmark<Eigen::Vector3d, 3>>(S_t_S_L), staticTransformsPtr_->getImuFrame(),
267 staticTransformsPtr_->rv_T_frame1_frame2(staticTransformsPtr_->getImuFrame(), S_t_S_L.sensorFrameName()), landmarkCreationCounter);
268
269 // Add factor to graph
270 graphMgrPtr_->addUnaryHolisticFactor<GmsfUnaryExpressionLandmarkPosition3>(gmsfUnaryExpressionPosition3LandmarkPtr);
271
272 // Optimize ---------------------------------------------------------------
273 {
274 // Mutex for optimizeGraph Flag
275 const std::lock_guard<std::mutex> optimizeGraphLock(optimizeGraphMutex_);
276 optimizeGraphFlag_ = true;
277 }
278 }
279}
280
281// Bearing3
283 throw std::runtime_error("Landmark measurements are not yet supported for the holistic MSF.");
284}
285
286// Binary Measurements: Purely relative --------------------------------------------------------
287
288} // namespace holistic_fusion
#define REGULAR_COUT
#define COLOR_END
#define GREEN_START
#define YELLOW_START
void addUnaryPosition3AbsoluteMeasurement(UnaryMeasurementXDAbsolute< Eigen::Vector3d, 3 > &R_t_R_S) override
void addUnaryVelocity3AbsoluteMeasurement(UnaryMeasurementXDAbsolute< Eigen::Vector3d, 3 > &R_v_R_S) override
void addUnaryPose3AbsoluteMeasurement(const UnaryMeasurementXDAbsolute< Eigen::Isometry3d, 6 > &R_T_R_S, const bool addToOnlineSmootherFlag=true) override
Unary Measurements / Absolute Measurements: In reference frame --> systematic drift.
void addUnaryBearing3LandmarkMeasurement(UnaryMeasurementXDLandmark< Eigen::Vector3d, 3 > &S_bearing_S_L) override
void addUnaryVelocity3LocalMeasurement(UnaryMeasurementXD< Eigen::Vector3d, 3 > &S_v_F_S) override
void addUnaryPosition3LandmarkMeasurement(UnaryMeasurementXDLandmark< Eigen::Vector3d, 3 > &S_t_S_L, const int landmarkCreationCounter) override
Landmark Measurements: No systematic drift.
bool hasAlignmentKeyframeForMeasurementWithoutPosition_(const UnaryMeasurementAbsolute &measurement) const
Binary Measurements: Purely relative.
void addUnaryHeadingAbsoluteMeasurement(const UnaryMeasurementXDAbsolute< Eigen::Matrix3d, 1 > &R_M_S)
void addUnaryVelocity3LocalMovingFrameMeasurement(UnaryMeasurementXD< Eigen::Vector3d, 3 > &S_v_F_S, const Eigen::Isometry3d &T_I_sensorFrame, const Eigen::Vector3d &I_w_W_I)
std::shared_ptr< GraphConfig > graphConfigPtr_
std::shared_ptr< holistic_fusion::ImuBuffer > coreImuBufferPtr_
std::shared_ptr< GraphManager > graphMgrPtr_
std::shared_ptr< StaticTransforms > staticTransformsPtr_
bool checkAndPrintCovarianceViolation_(const std::string &measurementName, const bool violatedFlag)
bool isCovarianceViolated_(const Eigen::Matrix< double, DIM, 1 > &covariance, const double covarianceViolationThreshold)
Convenience functions.
const std::string & sensorFrameName() const
Definition Measurement.h:83
const std::string & measurementName() const
Names.
Definition Measurement.h:82
Class to represent an absolute unary measurement in the graph. Exact dimension is not known.
Class to represent x-dimensional absolute unary measurement in the graph.
Class to represent x-dimensional landmark unary measurement in the graph.
Class to represent x-dimensional unary measurement in the graph.
const Eigen::Matrix< double, DIM, 1 > & unaryMeasurementNoiseDensity() const