gtsam
Loading...
Searching...
No Matches
GeneralSFMFactor.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
21
22#pragma once
23
24#include <gtsam/base/Manifold.h>
25#include <gtsam/base/Matrix.h>
27#include <gtsam/base/Testable.h>
28#include <gtsam/base/Vector.h>
30#include <gtsam/base/concepts.h>
31#include <gtsam/base/timing.h>
32#include <gtsam/base/types.h>
41
42#if GTSAM_ENABLE_BOOST_SERIALIZATION
43#include <boost/serialization/nvp.hpp>
44#endif
45#include <iostream>
46#include <stdexcept>
47#include <string>
48#include <type_traits>
49#include <vector>
50
51namespace boost {
52namespace serialization {
53class access;
54} /* namespace serialization */
55} /* namespace boost */
56
57namespace gtsam {
58
64template <class CAMERA, class LANDMARK>
66 : public NoiseModelFactorT<
67 typename traits<typename CAMERA::Measurement>::TangentVector, CAMERA,
68 LANDMARK> {
69 GTSAM_CONCEPT_MANIFOLD_TYPE(CAMERA)
70 GTSAM_CONCEPT_MANIFOLD_TYPE(LANDMARK)
71
72 using Measurement = typename CAMERA::Measurement;
73 using ErrorVector = typename traits<Measurement>::TangentVector;
74 static const int DimC = FixedDimension<CAMERA>::value;
75 static const int DimL = FixedDimension<LANDMARK>::value;
76 static const int ZDim = traits<Measurement>::dimension;
77 typedef Eigen::Matrix<double, ZDim, DimC> JacobianC;
78 typedef Eigen::Matrix<double, ZDim, DimL> JacobianL;
79
80 protected:
81 Measurement measured_;
82
83 public:
87
88 // Provide access to the Matrix& version of evaluateError:
90
91 // shorthand for a smart pointer to a factor
92 typedef std::shared_ptr<This> shared_ptr;
93
101 GeneralSFMFactor(const Measurement& measured, const SharedNoiseModel& model,
102 Key cameraKey, Key landmarkKey)
103 : Base(model, cameraKey, landmarkKey), measured_(measured) {}
104
105 GeneralSFMFactor() : measured_(Measurement()) {}
107 template <
108 typename M = Measurement,
109 typename std::enable_if<std::is_same<M, Point2>::value, int>::type = 0>
110 GeneralSFMFactor(const Point2& p) : measured_(p) {}
112 template <
113 typename M = Measurement,
114 typename std::enable_if<std::is_same<M, Point2>::value, int>::type = 0>
115 GeneralSFMFactor(double x, double y) : measured_(x, y) {}
117 ~GeneralSFMFactor() override {}
118
119 /// @return a deep copy of this factor
120 gtsam::NonlinearFactor::shared_ptr clone() const override {
121 return std::static_pointer_cast<gtsam::NonlinearFactor>(
122 gtsam::NonlinearFactor::shared_ptr(new This(*this)));
123 }
124
129 */
130 void print(
131 const std::string& s = "SFMFactor",
132 const KeyFormatter& keyFormatter = DefaultKeyFormatter) const override {
133 Base::print(s, keyFormatter);
135 }
136
139 */
140 bool equals(const NonlinearFactor& p, double tol = 1e-9) const override {
141 const This* e = dynamic_cast<const This*>(&p);
142 return e && Base::equals(p, tol) &&
143 traits<Measurement>::Equals(this->measured_, e->measured_, tol);
144 }
145
146 /** h(x)-z */
147 ErrorVector evaluateError(const CAMERA& camera, const LANDMARK& point,
149 OptionalMatrixType H2) const override {
150 try {
151 const Measurement predicted = camera.project2(point, H1, H2);
153 !std::is_base_of_v<
156 if (H1 || H2) {
158 const ErrorVector error =
159 traits<Measurement>::Local(measured_, predicted, {}, Hlocal);
160 if (H1) *H1 = Hlocal * *H1;
161 if (H2) *H2 = Hlocal * *H2;
162 return error;
163 }
164 }
165 return traits<Measurement>::Local(measured_, predicted);
166 } catch (CheiralityException& e [[maybe_unused]]) {
167 if (H1) *H1 = JacobianC::Zero();
168 if (H2) *H2 = JacobianL::Zero();
169 // TODO Print the exception via logging
170 return Vector::Zero(ZDim);
171 }
172 }
173
177 */
178 ErrorVector evaluateError(const CAMERA& camera, const LANDMARK& point,
179 Eigen::Ref<Matrix> H1,
180 Eigen::Ref<Matrix> H2) const {
181 try {
182 const Measurement predicted = camera.project2(point, H1, H2);
184 !std::is_base_of_v<
188 const ErrorVector error =
189 traits<Measurement>::Local(measured_, predicted, {}, Hlocal);
190 // Fixed-size temporaries keep this overload allocation-free.
191 const JacobianC Dcamera = Hlocal * H1;
192 const JacobianL Dlandmark = Hlocal * H2;
193 H1 = Dcamera;
194 H2 = Dlandmark;
195 return error;
196 }
197 return traits<Measurement>::Local(measured_, predicted);
198 } catch (CheiralityException& e [[maybe_unused]]) {
199 H1.setZero();
200 H2.setZero();
201 return ErrorVector::Zero();
202 }
203 }
204
205 /** Linearize using fixed-size Jacobians. */
206 std::shared_ptr<GaussianFactor> linearize(
207 const Values& values) const override {
208 if (!this->active(values)) return std::shared_ptr<JacobianFactor>();
209
210 const Key key1 = this->key1(), key2 = this->key2();
211 JacobianC Dcamera;
212 JacobianL Dlandmark;
213 ErrorVector b = -evaluateError(
214 values.at<CAMERA>(key1), values.at<LANDMARK>(key2), Dcamera, Dlandmark);
215
216 const SharedNoiseModel& noiseModel = this->noiseModel();
217 if (noiseModel && static_cast<size_t>(ZDim) != noiseModel->dim()) {
218 throw std::invalid_argument(
219 "NoiseModelFactor: NoiseModel has dimension " +
220 std::to_string(noiseModel->dim()) + " instead of " +
221 std::to_string(ZDim) + ".");
222 }
223
224 if (noiseModel && !noiseModel->isUnit()) {
225 Matrix dynamicCamera = Dcamera, dynamicLandmark = Dlandmark;
226 Vector dynamicB = b;
227 noiseModel->WhitenSystem(dynamicCamera, dynamicLandmark, dynamicB);
228 Dcamera = dynamicCamera;
229 Dlandmark = dynamicLandmark;
230 b = dynamicB;
231 }
232
233 SharedDiagonal linearModel;
234 if (noiseModel && noiseModel->isConstrained()) {
235 const auto constrained =
236 std::static_pointer_cast<noiseModel::Constrained>(noiseModel);
237 linearModel = constrained->unit();
238 }
239
240 return std::make_shared<FixedJacobianFactor<ZDim, DimC, DimL>>(
241 KeyVector{key1, key2}, std::vector<Matrix>{Dcamera, Dlandmark}, b,
242 linearModel);
243 }
244
246 inline const Measurement measured() const { return measured_; }
247
248 private:
249#if GTSAM_ENABLE_BOOST_SERIALIZATION
251 friend class boost::serialization::access;
252 template <class Archive>
253 void serialize(Archive& ar, const unsigned int /*version*/) {
254 // NoiseModelFactor2 instead of NoiseModelFactorN for backward compatibility
255 ar& boost::serialization::make_nvp(
256 "NoiseModelFactor2", boost::serialization::base_object<Base>(*this));
257 ar& BOOST_SERIALIZATION_NVP(measured_);
258 }
259#endif
260};
261
262template <class CAMERA, class LANDMARK>
263struct traits<GeneralSFMFactor<CAMERA, LANDMARK>>
264 : Testable<GeneralSFMFactor<CAMERA, LANDMARK>> {};
265
271template <class CALIBRATION>
273 : public NoiseModelFactorT<Vector2, Pose3, Point3, CALIBRATION> {
274 GTSAM_CONCEPT_MANIFOLD_TYPE(CALIBRATION)
275 static const int DimK = FixedDimension<CALIBRATION>::value;
276
277 protected:
279
280 public:
285
286 // shorthand for a smart pointer to a factor
287 typedef std::shared_ptr<This> shared_ptr;
288
298 Key poseKey, Key landmarkKey, Key calibKey)
299 : Base(model, poseKey, landmarkKey, calibKey), measured_(measured) {}
300 GeneralSFMFactor2() : measured_(0.0, 0.0) {}
301
302 ~GeneralSFMFactor2() override {}
303
305 gtsam::NonlinearFactor::shared_ptr clone() const override {
306 return std::static_pointer_cast<gtsam::NonlinearFactor>(
307 gtsam::NonlinearFactor::shared_ptr(new This(*this)));
308 }
309
315 void print(
316 const std::string& s = "SFMFactor2",
317 const KeyFormatter& keyFormatter = DefaultKeyFormatter) const override {
318 Base::print(s, keyFormatter);
320 }
321
325 bool equals(const NonlinearFactor& p, double tol = 1e-9) const override {
326 const This* e = dynamic_cast<const This*>(&p);
327 return e && Base::equals(p, tol) &&
328 traits<Point2>::Equals(this->measured_, e->measured_, tol);
329 }
330
332 Vector2 evaluateError(const Pose3& pose3, const Point3& point,
333 const CALIBRATION& calib, OptionalMatrixType H1,
335 OptionalMatrixType H3) const override {
336 try {
337 Camera camera(pose3, calib);
338 return camera.project(point, H1, H2, H3) - measured_;
339 } catch (CheiralityException& e) {
340 if (H1) *H1 = Matrix::Zero(2, 6);
341 if (H2) *H2 = Matrix::Zero(2, 3);
342 if (H3) *H3 = Matrix::Zero(2, DimK);
343 std::cout << e.what() << ": Landmark "
344 << DefaultKeyFormatter(this->key2()) << " behind Camera "
345 << DefaultKeyFormatter(this->key1()) << std::endl;
346 }
347 return Z_2x1;
348 }
349
351 inline const Point2 measured() const { return measured_; }
352
353 private:
354#if GTSAM_ENABLE_BOOST_SERIALIZATION
356 friend class boost::serialization::access;
357 template <class Archive>
358 void serialize(Archive& ar, const unsigned int /*version*/) {
359 // NoiseModelFactor3 instead of NoiseModelFactorN for backward compatibility
360 ar& boost::serialization::make_nvp(
361 "NoiseModelFactor3", boost::serialization::base_object<Base>(*this));
362 ar& BOOST_SERIALIZATION_NVP(measured_);
363 }
364#endif
365};
366
367template <class CALIBRATION>
368struct traits<GeneralSFMFactor2<CALIBRATION>>
369 : Testable<GeneralSFMFactor2<CALIBRATION>> {};
370
371} // namespace gtsam
Typedefs for easier changing of types.
Timing utilities.
typedef and functions to augment Eigen's MatrixXd
Macros for Vector constants to avoid excessive template instantiation.
Access to matrices via blocks of pre-defined sizes.
Concept check for values that can be used in unit tests.
Base class and basic functions for Manifold types.
typedef and functions to augment Eigen's VectorXd
3D Point
Base class for all pinhole cameras.
3D Pose manifold SO(3) x R^3 and group SE(3)
2D Point
Arbitrary-arity Jacobian factor with compile-time block dimensions.
Base class for noise model factors with N variables.
Non-linear factor base classes.
Global functions in a separate testing namespace.
Definition chartTesting.h:28
KeyFormatter DefaultKeyFormatter
Assign default key formatter.
Definition Key.cpp:30
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
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
Vector2 Point2
As of GTSAM 4, in order to make GTSAM more lean, it is now possible to just typedef Point2 to Vector2...
Definition Point2.h:32
std::function< std::string(Key)> KeyFormatter
Typedef for a function to format a key, i.e. to convert it to a string.
Definition Key.h:35
noiseModel::Base::shared_ptr SharedNoiseModel
Aliases.
Definition NoiseModel.h:846
std::uint64_t Key
Integer nonlinear key type.
Definition types.h:43
All noise models live in the noiseModel namespace.
Definition LossFunctions.cpp:33
A manifold defines a space in which there is a notion of a linear tangent space that can be centered ...
Definition Group.h:37
Detect whether a traits type provides Local with Jacobians.
Definition Manifold.h:145
A helper that implements the traits interface for GTSAM types.
Definition Testable.h:152
tag to assert a type is a vector space
Definition VectorSpace.h:21
Definition CalibratedCamera.h:35
A pinhole camera class that has a Pose3 and a Calibration.
Definition PinholeCamera.h:34
Point2 project(const Point3 &pw, OptionalJacobian< 2, 6 > Dpose={}, OptionalJacobian< 2, 3 > Dpoint={}, OptionalJacobian< 2, DimK > Dcal={}) const
project a 3D point from world coordinates into the image
Definition PinholePose.h:112
A 3D pose (R,t) : (Rot3,Point3).
Definition Pose3.h:42
virtual void print(const std::string &s="Factor", const KeyFormatter &formatter=DefaultKeyFormatter) const
print
Definition Factor.cpp:29
bool equals(const This &other, double tol=1e-9) const
check equality
Definition Factor.cpp:42
virtual ErrorVector evaluateError(const ValueTypes &... x, OptionalMatrixTypeT< ValueTypes >... H) const=0
Nonlinear factor base class.
Definition NonlinearFactor.h:70
virtual bool active(const Values &c) const
Checks whether a factor should be used based on a set of values.
Definition NonlinearFactor.h:143
double error(const Values &c) const override
Calculate the error of the factor.
Definition NonlinearFactor.cpp:146
A non-templated config holding any types of Manifold-group elements.
Definition Values.h:65
const ValueType at(Key j) const
Retrieve a variable by key j.
Definition Values-inl.h:260
Non-linear factor for a constraint derived from a 2D measurement.
Definition GeneralSFMFactor.h:68
const Measurement measured() const
Definition GeneralSFMFactor.h:245
gtsam::NonlinearFactor::shared_ptr clone() const override
Definition GeneralSFMFactor.h:119
bool equals(const NonlinearFactor &p, double tol=1e-9) const override
equals
Definition GeneralSFMFactor.h:139
GeneralSFMFactor()
default constructor
Definition GeneralSFMFactor.h:105
GeneralSFMFactor< CAMERA, LANDMARK > This
typedef for this object
Definition GeneralSFMFactor.h:84
NoiseModelFactorT< ErrorVector, CAMERA, LANDMARK > Base
typedef for the base class
Definition GeneralSFMFactor.h:86
ErrorVector evaluateError(const CAMERA &camera, const LANDMARK &point, OptionalMatrixType H1, OptionalMatrixType H2) const override
h(x)-z
Definition GeneralSFMFactor.h:146
~GeneralSFMFactor() override
destructor
Definition GeneralSFMFactor.h:116
std::shared_ptr< GaussianFactor > linearize(const Values &values) const override
Linearize using fixed-size Jacobians.
Definition GeneralSFMFactor.h:205
void print(const std::string &s="SFMFactor", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const override
print
Definition GeneralSFMFactor.h:129
GeneralSFMFactor(const Measurement &measured, const SharedNoiseModel &model, Key cameraKey, Key landmarkKey)
Constructor.
Definition GeneralSFMFactor.h:101
Non-linear factor for a constraint derived from a 2D measurement.
Definition GeneralSFMFactor.h:273
Vector2 evaluateError(const Pose3 &pose3, const Point3 &point, const CALIBRATION &calib, OptionalMatrixType H1, OptionalMatrixType H2, OptionalMatrixType H3) const override
h(x)-z
Definition GeneralSFMFactor.h:332
NoiseModelFactorT< Vector2, Pose3, Point3, CALIBRATION > Base
typedef for the base class
Definition GeneralSFMFactor.h:284
GeneralSFMFactor2()
default constructor
Definition GeneralSFMFactor.h:300
~GeneralSFMFactor2() override
destructor
Definition GeneralSFMFactor.h:302
gtsam::NonlinearFactor::shared_ptr clone() const override
Definition GeneralSFMFactor.h:305
void print(const std::string &s="SFMFactor2", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const override
print
Definition GeneralSFMFactor.h:315
Point2 measured_
Definition GeneralSFMFactor.h:278
const Point2 measured() const
Definition GeneralSFMFactor.h:351
PinholeCamera< CALIBRATION > Camera
typedef for camera type
Definition GeneralSFMFactor.h:282
GeneralSFMFactor2(const Point2 &measured, const SharedNoiseModel &model, Key poseKey, Key landmarkKey, Key calibKey)
Constructor.
Definition GeneralSFMFactor.h:297
bool equals(const NonlinearFactor &p, double tol=1e-9) const override
equals
Definition GeneralSFMFactor.h:325