My Project 1.0
Holistic Fusion: A Generic Framework for Multimodal Sensor Fusion
Loading...
Searching...
No Matches
unaryYawFactor.h
Go to the documentation of this file.
1/*
2Copyright 2022 by Julian Nubert, Timo Schoenegg, 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 HOLISTIC_FUSION_HEADING_FACTOR_H
9#define HOLISTIC_FUSION_HEADING_FACTOR_H
10
11// C++
12#include <cmath>
13
14// GTSAM
15#include <gtsam/base/OptionalJacobian.h>
16#include <gtsam/base/Vector.h>
17#include <gtsam/geometry/Pose3.h>
18#include <gtsam/geometry/Rot3.h>
19#include <gtsam/inference/Key.h>
20#include <gtsam/linear/NoiseModel.h>
21#include <gtsam/nonlinear/NoiseModelFactorN.h>
22
23namespace holistic_fusion {
24
29class YawFactor : public gtsam::NoiseModelFactorN<gtsam::Pose3> {
30 public:
31 using Base = gtsam::NoiseModelFactorN<gtsam::Pose3>;
32 // Bring the convenience overloads (without Jacobian, with Jacobian by reference) into scope
33 using Base::evaluateError;
34
42 YawFactor(gtsam::Key j, double yaw_W_S, const gtsam::SharedNoiseModel& model, const gtsam::Rot3& R_I_S = gtsam::Rot3())
43 : Base(model, j), yaw_W_S_(yaw_W_S), R_I_S_(R_I_S) {}
44
45 // Destructor
46 ~YawFactor() override = default;
47
52 gtsam::Vector evaluateError(const gtsam::Pose3& T_W_I, gtsam::OptionalMatrixType H_Ptr = OptionalNone) const override {
53 gtsam::Matrix33 H_compose;
54 const gtsam::Rot3 R_W_S = H_Ptr ? T_W_I.rotation().compose(R_I_S_, H_compose) : T_W_I.rotation().compose(R_I_S_);
55
56 // Yaw is singular only at gimbal lock of frame S, so do not add the measurement there
57 if (std::abs(R_W_S.pitch()) >= M_PI / 2.0 - 0.1) {
58 if (H_Ptr) {
59 (*H_Ptr) = gtsam::Matrix::Zero(1, 6);
60 }
61 return gtsam::Vector1::Zero();
62 }
63
64 // Measurement function (with Jacobian w.r.t. the rotation of S only if requested)
65 gtsam::Matrix13 H_yaw;
66 const double estimatedYaw = H_Ptr ? R_W_S.yaw(H_yaw) : R_W_S.yaw();
67
68 // Calculate error
69 double yawError = estimatedYaw - yaw_W_S_;
70
71 // Smaller half circle
72 while (yawError < -M_PI) yawError += 2 * M_PI;
73 while (yawError > M_PI) yawError -= 2 * M_PI;
74
75 // Jacobian: Pose3 tangent space is [rotation (3), translation (3)] --> [rad] [m]
76 if (H_Ptr) {
77 (*H_Ptr) = gtsam::Matrix::Zero(1, 6);
78 H_Ptr->block<1, 3>(0, 0) = H_yaw * H_compose;
79 }
80
81 return gtsam::Vector1(yawError);
82 }
83
84 private:
85 double yaw_W_S_; // yaw measurement of frame S
86 gtsam::Rot3 R_I_S_; // rotation of frame S in the IMU frame
87};
88
89} // namespace holistic_fusion
90
91#endif // HOLISTIC_FUSION_HEADING_FACTOR_H
~YawFactor() override=default
gtsam::Vector evaluateError(const gtsam::Pose3 &T_W_I, gtsam::OptionalMatrixType H_Ptr=OptionalNone) const override
vector of errors
YawFactor(gtsam::Key j, double yaw_W_S, const gtsam::SharedNoiseModel &model, const gtsam::Rot3 &R_I_S=gtsam::Rot3())
gtsam::NoiseModelFactorN< gtsam::Pose3 > Base