gtsam
Loading...
Searching...
No Matches
WahbaFactor.h
Go to the documentation of this file.
1/* ----------------------------------------------------------------------------
2
3 * GTSAM Copyright 2010-2026, 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
19
20#pragma once
21
22#include <gtsam/constrained/QcqpProblem.h>
23#include <gtsam/constrained/QpCost.h>
24#include <gtsam/geometry/Rot3.h>
25#include <gtsam/geometry/Unit3.h>
27
28#include <memory>
29#include <stdexcept>
30#include <vector>
31
32namespace gtsam {
33
51class WahbaFactor : public NoiseModelFactorN<Rot3> {
52 public:
53 using Base = NoiseModelFactorN<Rot3>;
54 using This = WahbaFactor;
55
56 private:
57 Unit3 bDirection_;
58 Unit3 measured_aDirection_;
59
60 public:
62
64 WahbaFactor(Key key, const Unit3& bDirection,
65 const Unit3& measured_aDirection, const SharedNoiseModel& model)
66 : Base(model, key),
67 bDirection_(bDirection),
68 measured_aDirection_(measured_aDirection) {}
69
70 NonlinearFactor::shared_ptr clone() const override {
71 return std::make_shared<This>(*this);
72 }
73
74 bool equals(const NonlinearFactor& expected,
75 double tol = 1e-9) const override {
76 const auto* e = dynamic_cast<const This*>(&expected);
77 return e != nullptr && Base::equals(*e, tol) &&
78 bDirection_.equals(e->bDirection_, tol) &&
79 measured_aDirection_.equals(e->measured_aDirection_, tol);
80 }
81
83 Vector evaluateError(const Rot3& aRb, OptionalMatrixType H) const override {
84 const Point3 predicted_aDirection = aRb.rotate(bDirection_.unitVector(), H);
85 return predicted_aDirection - measured_aDirection_.unitVector();
86 }
87
90 NonlinearEqualityConstraints* constraints,
91 size_t columnDimension = 1) const override {
92 if (columnDimension != 1) {
93 throw std::invalid_argument(
94 "WahbaFactor::qcqpFactors only supports column dimension 1");
95 }
96 if (!costs) {
97 throw std::invalid_argument("WahbaFactor::qcqpFactors costs is null");
98 }
99 if (!this->noiseModel_ ||
100 std::dynamic_pointer_cast<noiseModel::Robust>(this->noiseModel_) ||
101 this->noiseModel_->isConstrained()) {
102 throw std::runtime_error(
103 "WahbaFactor::qcqpFactors requires a non-null, non-robust/non-hard "
104 "quadratic noise model");
105 }
106
107 constexpr int PointDim = 3;
108 constexpr int N = 3;
109 constexpr int LiftedDim = 1 + PointDim * N;
110
111 Matrix B = Matrix::Zero(PointDim, LiftedDim);
112 B.col(0) = -measured_aDirection_.unitVector();
113 const Point3 bDirection = bDirection_.unitVector();
114 for (int column = 0; column < N; ++column) {
115 B.block(0, 1 + column * PointDim, PointDim, PointDim)
116 .diagonal()
117 .setConstant(bDirection(column));
118 }
119
120 const Matrix whitenedB = this->noiseModel_->Whiten(B);
121 const Matrix Q = whitenedB.transpose() * whitenedB;
122
123 InsertQcqpConstraints<Rot3, 1>(this->key(), constraints);
124 const SymmetricBlockMatrix blockQ(std::vector<DenseIndex>{LiftedDim}, Q);
125 costs->push_back(std::make_shared<QpCost>(KeyVector{this->key()}, blockQ));
126 }
127};
128
129} // namespace gtsam
3D rotation represented as a rotation matrix or quaternion
Base class for noise model factors with N variables.
Global functions in a separate testing namespace.
Definition chartTesting.h:28
FastVector< Key > KeyVector
Define collection type once and for all - also used in wrappers.
Definition Key.h:91
Matrix * OptionalMatrixType
This typedef will be used everywhere boost::optional<Matrix&> reference was used previously.
Definition NonlinearFactor.h:57
NoiseModelFactorT< Vector, ValueTypes... > NoiseModelFactorN
Noise model factor with N value types and dynamic-sized error vector.
Definition NoiseModelFactorN.h:561
Vector3 Point3
As of GTSAM 4, in order to make GTSAM more lean, it is now possible to just typedef Point3 to Vector3...
Definition Point3.h:38
noiseModel::Base::shared_ptr SharedNoiseModel
Aliases.
Definition NoiseModel.h:846
std::uint64_t Key
Integer nonlinear key type.
Definition types.h:43
This class stores a dense matrix and allows it to be accessed as a collection of blocks.
Definition SymmetricBlockMatrix.h:80
Rot3 is a 3D rotation represented as a rotation matrix if the preprocessor symbol GTSAM_USE_QUATERNIO...
Definition Rot3.h:65
Point3 rotate(const Point3 &p, OptionalJacobian< 3, 3 > H1={}, OptionalJacobian< 3, 3 > H2={}) const
rotate point from rotated coordinate frame to world
Definition Rot3M.cpp:165
Represents a 3D point on a unit sphere.
Definition Unit3.h:44
IsDerived< DERIVEDFACTOR > push_back(std::shared_ptr< DERIVEDFACTOR > factor)
Add a factor directly using a shared_ptr.
Definition FactorGraph.h:147
bool equals(const This &other, double tol=1e-9) const
check equality
Definition Factor.cpp:42
virtual Vector evaluateError(const ValueTypes &... x, OptionalMatrixTypeT< ValueTypes >... H) const=0
static constexpr auto N
Definition NoiseModelFactorN.h:158
Key key() const
Definition NoiseModelFactorN.h:307
Nonlinear factor base class.
Definition NonlinearFactor.h:70
Definition NonlinearFactorGraph.h:57
Vector evaluateError(const Rot3 &aRb, OptionalMatrixType H) const override
Evaluate the rotated frame-b direction minus measured_aDirection.
Definition WahbaFactor.h:83
WahbaFactor(Key key, const Unit3 &bDirection, const Unit3 &measured_aDirection, const SharedNoiseModel &model)
Construct from a key, two directions, and a three-dimensional noise model.
Definition WahbaFactor.h:64
bool equals(const NonlinearFactor &expected, double tol=1e-9) const override
Check if two factors are equal.
Definition WahbaFactor.h:74
void qcqpFactors(NonlinearFactorGraph *costs, NonlinearEqualityConstraints *constraints, size_t columnDimension=1) const override
Add the exact D=1 chordal Wahba cost to a QCQP.
Definition WahbaFactor.h:89
NonlinearFactor::shared_ptr clone() const override
Creates a shared_ptr clone of the factor - needs to be specialized to allow for subclasses.
Definition WahbaFactor.h:70