24#include <gtsam/slam/JacobianFactorQ.h>
25#include <gtsam/slam/JacobianFactorSVD.h>
33#if GTSAM_ENABLE_BOOST_SERIALIZATION
34#include <boost/serialization/optional.hpp>
56 typedef typename CAMERA::Measurement Z;
57 typedef typename CAMERA::MeasurementVector ZVector;
63 typedef Eigen::Matrix<double, ZDim, Dim> MatrixZD;
64 typedef std::vector<MatrixZD, Eigen::aligned_allocator<MatrixZD> > FBlocks;
100 std::optional<Pose3> body_P_sensor = {},
101 size_t expectedNumberCameras = 10)
104 if (!sharedNoiseModel)
105 throw std::runtime_error(
"SmartFactorBase: sharedNoiseModel is required");
107 SharedIsotropic sharedIsotropic = std::dynamic_pointer_cast<
110 if (!sharedIsotropic)
111 throw std::runtime_error(
"SmartFactorBase: needs isotropic");
127 throw std::invalid_argument(
128 "SmartFactorBase::add: adding duplicate measurement for key.");
130 this->measured_.push_back(
measured);
131 this->
keys_.push_back(key);
137 if (measurements.size() != cameraKeys.size()) {
138 throw std::runtime_error(
"Number of measurements and camera keys do not match");
141 for (
size_t i = 0; i < measurements.size(); i++) {
142 this->
add(measurements[i], cameraKeys[i]);
150 template<
class SFM_TRACK>
151 void add(
const SFM_TRACK& trackToAdd) {
152 for (
size_t k = 0; k < trackToAdd.numberMeasurements(); k++) {
153 this->measured_.push_back(trackToAdd.measurements[k].second);
154 this->
keys_.push_back(trackToAdd.measurements[k].first);
159 size_t dim()
const override {
return ZDim * this->measured_.size(); }
180 std::cout << s <<
"SmartFactorBase, z = \n";
181 for (
size_t k = 0; k <
measured_.size(); ++k) {
182 std::cout <<
"measurement " << k<<
", px = \n" <<
measured_[k] <<
"\n";
192 if (
const This* e =
dynamic_cast<const This*
>(&p)) {
194 for (
size_t i = 0; i <
measured_.size(); i++) {
210 template <
class POINT>
213 typename Cameras::FBlocks* Fs =
nullptr,
214 Matrix* E =
nullptr)
const {
224 for (
size_t i = 0; i < Fs->size(); i++) {
225 const Pose3 world_P_body =
cameras[i].pose() * sensor_P_body;
226 Eigen::Matrix<double, camera_dim, camera_dim> J;
228 Eigen::Matrix<double, pose_dim, pose_dim> H;
232 J.template block<pose_dim, pose_dim>(0, 0) = H;
233 Fs->at(i) = Fs->at(i) * J;
249 template<
class POINT,
class ...OptArgs,
typename = std::enable_if_t<
sizeof...(OptArgs)!=0>>
252 OptArgs&&... optArgs)
const {
263 typename Cameras::FBlocks* Fs =
nullptr,
264 Matrix* E =
nullptr)
const {}
272 template<
class ...OptArgs>
275 OptArgs&&... optArgs)
const {
283 template<
class POINT>
299 template<
class POINT>
301 const POINT& point)
const {
303 return 0.5 * error.dot(error);
308 return (E.transpose() * E).inverse();
317 template<
class POINT>
332 template<
class POINT>
339 static const int N = FixedDimension<POINT>::value;
342 Eigen::JacobiSVD<Matrix>
svd(E, Eigen::ComputeFullU);
343 size_t m = this->
keys_.size();
344 Enull =
svd.matrixU().block(0, N,
ZDim * m,
ZDim * m - N);
351 bool diagonalDamping =
false)
const {
360 return std::make_shared<RegularHessianFactor<Dim> >(
keys_,
370 const double lambda,
bool diagonalDamping,
383 for (
size_t i = 0; i < F.size(); i++)
388 std::shared_ptr<RegularImplicitSchurFactor<CAMERA> >
390 double lambda = 0.0,
bool diagonalDamping =
false)
const {
397 return std::make_shared<RegularImplicitSchurFactor<CAMERA> >(
keys_, F, E,
404 bool diagonalDamping =
false)
const {
409 const size_t M = b.size();
412 return std::make_shared<JacobianFactorQ<Dim, ZDim> >(
keys_, F, E, P, b, n);
421 size_t m = this->
keys_.size();
424 const size_t M =
ZDim * m;
429 return std::make_shared<JacobianFactorSVD<Dim, ZDim> >(
keys_, F, E0, b, n);
434 size_t m = Fs.size();
437 for (
size_t i = 0; i < m; ++i)
442 Pose3 body_P_sensor()
const{
451#if GTSAM_ENABLE_BOOST_SERIALIZATION
453 friend class boost::serialization::access;
454 template<
class ARCHIVE>
455 void serialize(ARCHIVE & ar,
const unsigned int ) {
456 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
Base class to create smart factors on poses or cameras.
Specialized HessianFactor class for regular problems (fixed-size blocks).
Non-linear factor base classes.
A subclass of GaussianFactor specialized to structureless SFM.
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
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
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
void svd(const Matrix &A, Matrix &U, Vector &S, Matrix &V)
SVD computes economy SVD A=U*S*V'.
Definition Matrix.cpp:557
noiseModel::Base::shared_ptr SharedNoiseModel
Aliases.
Definition NoiseModel.h:846
std::uint64_t Key
Integer nonlinear key type.
Definition types.h:43
A manifold defines a space in which there is a notion of a linear tangent space that can be centered ...
Definition Group.h:37
This class stores a dense matrix and allows it to be accessed as a collection of blocks.
Definition SymmetricBlockMatrix.h:80
A set of cameras, all with their own calibration.
Definition CameraSet.h:37
static Matrix PointCov(const Matrix &E, const double lambda=0.0, bool diagonalDamping=false)
Computes Point Covariance P, with lambda parameter, dynamic version.
Definition CameraSet.h:360
static void UpdateSchurComplement(const FBlocks &Fs, const Matrix &E, const Eigen::Matrix< double, N, N > &P, const Vector &b, const KeyVector &allKeys, const KeyVector &keys, SymmetricBlockMatrix &augmentedHessian)
Applies Schur complement (exploiting block structure) to get a smart factor on cameras,...
Definition CameraSet.h:398
static SymmetricBlockMatrix SchurComplement(const std::vector< Eigen::Matrix< double, ZDim, ND >, Eigen::aligned_allocator< Eigen::Matrix< double, ZDim, ND > > > &Fs, const Matrix &E, const Eigen::Matrix< double, N, N > &P, const Vector &b)
Do Schur complement, given Jacobian as Fs,E,P, return SymmetricBlockMatrix G = F' * F - F' * E * P * ...
Definition CameraSet.h:175
A 3D pose (R,t) : (Rot3,Point3).
Definition Pose3.h:42
KeyVector keys_
The keys involved in this factor.
Definition Factor.h:88
An isotropic noise model corresponds to a scaled diagonal covariance To construct,...
Definition NoiseModel.h:581
static shared_ptr Sigma(size_t dim, double sigma, bool smart=true)
An isotropic noise model created by specifying a standard deviation sigma.
Definition NoiseModel.cpp:706
virtual bool equals(const NonlinearFactor &f, double tol=1e-9) const
Check if two factors are equal.
Definition NonlinearFactor.cpp:55
NonlinearFactor()
Default constructor for I/O only.
Definition NonlinearFactor.h:86
void print(const std::string &s="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const override
print
Definition NonlinearFactor.cpp:45
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
void computeJacobians(FBlocks &Fs, Matrix &E, Vector &b, const Cameras &cameras, const POINT &point) const
Compute F, E, and b (called below in both vanilla and SVD versions), where F is a vector of derivativ...
Definition SmartFactorBase.h:318
void add(const Z &measured, const Key &key)
Add a new measurement and pose/camera key.
Definition SmartFactorBase.h:125
~SmartFactorBase() override
Virtual destructor, subclasses from NonlinearFactor.
Definition SmartFactorBase.h:117
std::shared_ptr< JacobianFactor > createJacobianSVDFactor(const Cameras &cameras, const Point3 &point, double lambda=0.0) const
Return Jacobians as JacobianFactorSVD.
Definition SmartFactorBase.h:419
void updateAugmentedHessian(const Cameras &cameras, const Point3 &point, const double lambda, bool diagonalDamping, SymmetricBlockMatrix &augmentedHessian, const KeyVector allKeys) const
Add the contribution of the smart factor to a pre-allocated Hessian, using sparse linear algebra.
Definition SmartFactorBase.h:369
std::shared_ptr< RegularImplicitSchurFactor< CAMERA > > createRegularImplicitSchurFactor(const Cameras &cameras, const Point3 &point, double lambda=0.0, bool diagonalDamping=false) const
Return Jacobians as RegularImplicitSchurFactor with raw access.
Definition SmartFactorBase.h:389
SharedIsotropic noiseModel_
Definition SmartFactorBase.h:73
static const int Dim
Definition SmartFactorBase.h:61
Vector whitenedError(const Cameras &cameras, const POINT &point) const
Calculate vector of re-projection errors [h(x)-z] = [cameras.project(p) - z], with the noise model ap...
Definition SmartFactorBase.h:284
std::shared_ptr< JacobianFactorQ< Dim, ZDim > > createJacobianQFactor(const Cameras &cameras, const Point3 &point, double lambda=0.0, bool diagonalDamping=false) const
Return Jacobians as JacobianFactorQ.
Definition SmartFactorBase.h:402
virtual Cameras cameras(const Values &values) const
Collect all cameras: important that in key order.
Definition SmartFactorBase.h:165
Vector unwhitenedError(const Cameras &cameras, const POINT &point, typename Cameras::FBlocks *Fs=nullptr, Matrix *E=nullptr) const
Compute reprojection errors [h(x)-z] = [cameras.project(p)-z] and derivatives.
Definition SmartFactorBase.h:211
static void FillDiagonalF(const FBlocks &Fs, Matrix &F)
Create BIG block-diagonal matrix F from Fblocks.
Definition SmartFactorBase.h:433
std::shared_ptr< This > shared_ptr
shorthand for a smart pointer to a factor.
Definition SmartFactorBase.h:90
double totalReprojectionError(const Cameras &cameras, const POINT &point) const
Calculate the error of the factor.
Definition SmartFactorBase.h:300
void add(const ZVector &measurements, const KeyVector &cameraKeys)
Add a bunch of measurements, together with the camera keys.
Definition SmartFactorBase.h:135
void computeJacobiansSVD(FBlocks &Fs, Matrix &Enull, Vector &b, const Cameras &cameras, const POINT &point) const
SVD version that produces smaller Jacobian matrices by doing an SVD decomposition on E,...
Definition SmartFactorBase.h:333
ZVector measured_
Definition SmartFactorBase.h:80
std::shared_ptr< RegularHessianFactor< Dim > > createHessianFactor(const Cameras &cameras, const Point3 &point, const double lambda=0.0, bool diagonalDamping=false) const
Linearize to a Hessianfactor.
Definition SmartFactorBase.h:349
SmartFactorBase()
Default Constructor, for serialization.
Definition SmartFactorBase.h:96
void whitenJacobians(FBlocks &F, Matrix &E, Vector &b) const
Whiten the Jacobians computed by computeJacobians using noiseModel_.
Definition SmartFactorBase.h:380
Vector unwhitenedError(const Cameras &cameras, const POINT &point, OptArgs &&... optArgs) const
An overload of unwhitenedError.
Definition SmartFactorBase.h:250
void add(const SFM_TRACK &trackToAdd)
Add an entire SfM_track (collection of cameras observing a single point).
Definition SmartFactorBase.h:151
const ZVector & measured() const
Definition SmartFactorBase.h:162
size_t dim() const override
Return the dimension (number of rows!) of the factor.
Definition SmartFactorBase.h:159
void print(const std::string &s="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const override
print
Definition SmartFactorBase.h:178
void correctForMissingMeasurements(const Cameras &cameras, Vector &ue, OptArgs &&... optArgs) const
An overload of correctForMissingMeasurements.
Definition SmartFactorBase.h:273
virtual void correctForMissingMeasurements(const Cameras &cameras, Vector &ue, typename Cameras::FBlocks *Fs=nullptr, Matrix *E=nullptr) const
This corrects the Jacobians for the case in which some 2D measurement is missing (nan).
Definition SmartFactorBase.h:261
SmartFactorBase(const SharedNoiseModel &sharedNoiseModel, std::optional< Pose3 > body_P_sensor={}, size_t expectedNumberCameras=10)
Construct with given noise model and optional arguments.
Definition SmartFactorBase.h:99
static const int ZDim
Definition SmartFactorBase.h:62
static Matrix PointCov(const Matrix &E)
Computes Point Covariance P from the "point Jacobian" E.
Definition SmartFactorBase.h:307
std::optional< Pose3 > body_P_sensor_
Definition SmartFactorBase.h:83
CameraSet< CAMERA > Cameras
The CameraSet data structure is used to refer to a set of cameras.
Definition SmartFactorBase.h:93
bool equals(const NonlinearFactor &p, double tol=1e-9) const override
equals
Definition SmartFactorBase.h:191