33 #ifdef GTSAM_ENABLE_BOOST_SERIALIZATION 34 #include <boost/serialization/optional.hpp> 50 template<
class CAMERA>
57 typedef typename CAMERA::MeasurementVector
ZVector;
64 typedef std::vector<MatrixZD, Eigen::aligned_allocator<MatrixZD> >
FBlocks;
103 size_t expectedNumberCameras = 10)
106 if (!sharedNoiseModel)
107 throw std::runtime_error(
"SmartFactorBase: sharedNoiseModel is required");
112 if (!sharedIsotropic)
113 throw std::runtime_error(
"SmartFactorBase: needs isotropic");
115 noiseModel_ = sharedIsotropic;
129 throw std::invalid_argument(
130 "SmartFactorBase::add: adding duplicate measurement for key.");
132 this->measured_.push_back(measured);
133 this->
keys_.push_back(key);
138 assert(measurements.size() == cameraKeys.size());
139 for (
size_t i = 0;
i < measurements.size();
i++) {
140 this->
add(measurements[
i], cameraKeys[i]);
148 template<
class SFM_TRACK>
149 void add(
const SFM_TRACK& trackToAdd) {
150 for (
size_t k = 0; k < trackToAdd.numberMeasurements(); k++) {
151 this->measured_.push_back(trackToAdd.measurements[k].second);
152 this->
keys_.push_back(trackToAdd.measurements[k].first);
157 size_t dim()
const override {
return ZDim * this->measured_.size(); }
166 cameras.push_back(values.
at<CAMERA>(k));
177 std::cout <<
s <<
"SmartFactorBase, z = \n";
178 for (
size_t k = 0; k < measured_.size(); ++k) {
179 std::cout <<
"measurement " << k<<
", px = \n" << measured_[k] <<
"\n";
180 noiseModel_->print(
"noise model = ");
189 if (
const This*
e = dynamic_cast<const This*>(&p)) {
191 for (
size_t i = 0;
i < measured_.size();
i++) {
207 template <
class POINT>
221 for (
size_t i = 0;
i < Fs->size();
i++) {
222 const Pose3 world_P_body = cameras[
i].pose() * sensor_P_body;
229 J.template block<pose_dim, pose_dim>(0, 0) = H;
230 Fs->at(
i) = Fs->at(
i) *
J;
246 template<
class POINT,
class ...OptArgs,
typename =
std::enable_if_t<
sizeof...(OptArgs)!=0>>
249 OptArgs&&... optArgs)
const {
259 const Cameras& cameras,
Vector& ue,
269 template<
class ...OptArgs>
271 const Cameras& cameras,
Vector& ue,
272 OptArgs&&... optArgs)
const {
280 template<
class POINT>
284 noiseModel_->whitenInPlace(error);
296 template<
class POINT>
298 const POINT& point)
const {
300 return 0.5 * error.dot(error);
305 return (E.transpose() *
E).
inverse();
314 template<
class POINT>
316 const Cameras& cameras,
const POINT& point)
const {
329 template<
class POINT>
331 Vector&
b,
const Cameras& cameras,
const POINT& point)
const {
340 size_t m = this->
keys_.size();
341 Enull = svd.
matrixU().block(0, N, ZDim * m, ZDim * m - N);
347 const Cameras& cameras,
const Point3& point,
const double lambda = 0.0,
348 bool diagonalDamping =
false)
const {
357 return std::make_shared<RegularHessianFactor<Dim> >(
keys_,
367 const double lambda,
bool diagonalDamping,
378 noiseModel_->WhitenSystem(E, b);
380 for (
size_t i = 0;
i < F.size();
i++)
381 F[
i] = noiseModel_->Whiten(F[
i]);
385 std::shared_ptr<RegularImplicitSchurFactor<CAMERA> >
387 double lambda = 0.0,
bool diagonalDamping =
false)
const {
394 return std::make_shared<RegularImplicitSchurFactor<CAMERA> >(
keys_,
F,
E,
400 const Cameras& cameras,
const Point3& point,
double lambda = 0.0,
401 bool diagonalDamping =
false)
const {
406 const size_t M = b.size();
409 return std::make_shared<JacobianFactorQ<Dim, ZDim> >(
keys_,
F,
E,
P,
b,
n);
417 const Cameras& cameras,
const Point3& point,
double lambda = 0.0)
const {
418 size_t m = this->
keys_.size();
421 const size_t M = ZDim *
m;
425 noiseModel_->sigma());
426 return std::make_shared<JacobianFactorSVD<Dim, ZDim> >(
keys_,
F, E0,
b,
n);
431 size_t m = Fs.size();
432 F.resize(ZDim * m, Dim * m);
434 for (
size_t i = 0;
i <
m; ++
i)
435 F.block<ZDim, Dim>(ZDim *
i, Dim * i) = Fs.at(i);
448 #ifdef GTSAM_ENABLE_BOOST_SERIALIZATION 449 friend class boost::serialization::access; 451 template<
class ARCHIVE>
452 void serialize(ARCHIVE & ar,
const unsigned int ) {
453 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
454 ar & BOOST_SERIALIZATION_NVP(noiseModel_);
455 ar & BOOST_SERIALIZATION_NVP(measured_);
const gtsam::Symbol key('X', 0)
virtual Cameras cameras(const Values &values) const
Collect all cameras: important that in key order.
void computeJacobians(FBlocks &Fs, Matrix &E, Vector &b, const Cameras &cameras, const POINT &point) const
virtual double error(const Values &c) const
static Matrix PointCov(const Matrix &E, const double lambda=0.0, bool diagonalDamping=false)
Computes Point Covariance P, with lambda parameter, dynamic version.
void add(const SFM_TRACK &trackToAdd)
Matrix< RealScalar, Dynamic, Dynamic > M
EIGEN_DEVICE_FUNC Matrix< _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols > & setZero(Index size)
Pose3 body_P_sensor() const
double totalReprojectionError(const Cameras &cameras, const POINT &point) const
GTSAM_MAKE_ALIGNED_OPERATOR_NEW typedef std::shared_ptr< This > shared_ptr
shorthand for a smart pointer to a factor.
std::string serialize(const T &input)
serializes to a string
bool equals(const NonlinearFactor &p, double tol=1e-9) const override
equals
const ValueType at(Key j) const
Base class to create smart factors on poses or cameras.
const MatrixUType & matrixU() const
Give fixed size dimension of a type, fails at compile time if dynamic.
Vector reprojectionError(const POINT &point, const ZVector &measured, FBlocks *Fs=nullptr, Matrix *E=nullptr) const
Calculate vector [project2(point)-z] of re-projection errors.
std::vector< MatrixZD, Eigen::aligned_allocator< MatrixZD > > FBlocks
SmartFactorBase()
Default Constructor, for serialization.
CameraSet< CAMERA > Cameras
The CameraSet data structure is used to refer to a set of cameras.
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.
virtual void correctForMissingMeasurements(const Cameras &cameras, Vector &ue, typename Cameras::FBlocks *Fs=nullptr, Matrix *E=nullptr) const
KeyVector keys_
The keys involved in this factor.
noiseModel::Isotropic::shared_ptr SharedIsotropic
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy y set format x g set format y g set format x2 g set format y2 g set format z g set angles radians set nogrid set key title set key left top Right noreverse box linetype linewidth samplen spacing width set nolabel set noarrow set nologscale set logscale x set set pointsize set encoding default set nopolar set noparametric set set set set surface set nocontour set clabel set mapping cartesian set nohidden3d set cntrparam order set cntrparam linear set cntrparam levels auto set cntrparam points set size set set xzeroaxis lt lw set x2zeroaxis lt lw set yzeroaxis lt lw set y2zeroaxis lt lw set tics in set ticslevel set tics set mxtics default set mytics default set mx2tics default set my2tics default set xtics border mirror norotate autofreq set ytics border mirror norotate autofreq set ztics border nomirror norotate autofreq set nox2tics set noy2tics set timestamp bottom norotate set rrange [*:*] noreverse nowriteback set trange [*:*] noreverse nowriteback set urange [*:*] noreverse nowriteback set vrange [*:*] noreverse nowriteback set xlabel matrix size set x2label set timefmt d m y n H
SharedIsotropic noiseModel_
void print(const std::string &s="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const override
CAMERA::MeasurementVector ZVector
void print(const std::string &s="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const override
~SmartFactorBase() override
Virtual destructor, subclasses from NonlinearFactor.
A set of cameras, all with their own calibration.
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)
static const KeyFormatter DefaultKeyFormatter
EIGEN_DEVICE_FUNC const InverseReturnType inverse() const
Vector unwhitenedError(const Cameras &cameras, const POINT &point, OptArgs &&... optArgs) const
virtual bool equals(const NonlinearFactor &f, double tol=1e-9) const
Base class for smart factors. This base class has no internal point, but it has a measurement...
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.
void computeJacobiansSVD(FBlocks &Fs, Matrix &Enull, Vector &b, const Cameras &cameras, const POINT &point) const
static void FillDiagonalF(const FBlocks &Fs, Matrix &F)
Create BIG block-diagonal matrix F from Fblocks.
GenericMeasurement< Point2, Point2 > Measurement
SmartFactorBase(const SharedNoiseModel &sharedNoiseModel, std::optional< Pose3 > body_P_sensor={}, size_t expectedNumberCameras=10)
Construct with given noise model and optional arguments.
Array< double, 1, 3 > e(1./3., 0.5, 2.)
HessianFactor class with constant sized blocks.
std::vector< MatrixZD, Eigen::aligned_allocator< MatrixZD > > FBlocks
JacobiRotation< float > J
void svd(const Matrix &A, Matrix &U, Vector &S, Matrix &V)
Class compose(const Class &g) const
std::function< std::string(Key)> KeyFormatter
Typedef for a function to format a key, i.e. to convert it to a string.
Vector whitenedError(const Cameras &cameras, const POINT &point) const
void add(const ZVector &measurements, const KeyVector &cameraKeys)
Add a bunch of measurements, together with the camera keys.
std::shared_ptr< JacobianFactor > createJacobianSVDFactor(const Cameras &cameras, const Point3 &point, double lambda=0.0) const
cout<< "The eigenvalues of A are:"<< endl<< ces.eigenvalues()<< endl;cout<< "The matrix of eigenvectors, V, is:"<< endl<< ces.eigenvectors()<< endl<< endl;complex< float > lambda
const ZVector & measured() const
Return the 2D measurements (ZDim, in general).
A subclass of GaussianFactor specialized to structureless SFM.
Non-linear factor base classes.
size_t dim() const override
Return the dimension (number of rows!) of the factor.
void add(const Z &measured, const Key &key)
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.
void correctForMissingMeasurements(const Cameras &cameras, Vector &ue, OptArgs &&... optArgs) const
static const int Dim
Camera dimension.
void updateAugmentedHessian(const Cameras &cameras, const Point3 &point, const double lambda, bool diagonalDamping, SymmetricBlockMatrix &augmentedHessian, const KeyVector allKeys) const
Two-sided Jacobi SVD decomposition of a rectangular matrix.
typename std::enable_if< B, T >::type enable_if_t
from cpp_future import (convenient aliases from C++14/17)
SmartFactorBase< CAMERA > This
#define GTSAM_MAKE_ALIGNED_OPERATOR_NEW
Eigen::Matrix< double, ZDim, Dim > MatrixZD
static Matrix PointCov(const Matrix &E)
Computes Point Covariance P from the "point Jacobian" E.
FastVector< Key > KeyVector
Define collection type once and for all - also used in wrappers.
The matrix class, also used for vectors and row-vectors.
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)
void whitenJacobians(FBlocks &F, Matrix &E, Vector &b) const
Whiten the Jacobians computed by computeJacobians using noiseModel_.
std::optional< Pose3 > body_P_sensor_
Pose of the camera in the body frame.
std::uint64_t Key
Integer nonlinear key type.
static const int ZDim
Measurement dimension.
noiseModel::Base::shared_ptr SharedNoiseModel
static shared_ptr Sigma(size_t dim, double sigma, bool smart=true)
Vector unwhitenedError(const Cameras &cameras, const POINT &point, typename Cameras::FBlocks *Fs=nullptr, Matrix *E=nullptr) const