24 #include <gtsam/slam/JacobianFactorQ.h> 25 #include <gtsam/slam/JacobianFactorSVD.h> 33 #ifdef GTSAM_ENABLE_BOOST_SERIALIZATION 34 #include <boost/serialization/optional.hpp> 50 template<
class CAMERA>
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;
102 std::optional<Pose3> body_P_sensor = {},
103 size_t expectedNumberCameras = 10)
106 if (!sharedNoiseModel)
107 throw std::runtime_error(
"SmartFactorBase: sharedNoiseModel is required");
109 SharedIsotropic sharedIsotropic = std::dynamic_pointer_cast<
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));
176 DefaultKeyFormatter)
const override {
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>
209 const Cameras&
cameras,
const POINT& point,
210 typename Cameras::FBlocks* Fs =
nullptr,
211 Matrix* E =
nullptr)
const {
221 for (
size_t i = 0; i < Fs->size(); i++) {
222 const Pose3 world_P_body = cameras[i].pose() * sensor_P_body;
223 Eigen::Matrix<double, camera_dim, camera_dim> J;
225 Eigen::Matrix<double, pose_dim, pose_dim> H;
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>>
248 const Cameras&
cameras,
const POINT& point,
249 OptArgs&&... optArgs)
const {
259 const Cameras& cameras, Vector& ue,
260 typename Cameras::FBlocks* Fs =
nullptr,
261 Matrix* E =
nullptr)
const {}
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 {
339 Eigen::JacobiSVD<Matrix>
svd(E, Eigen::ComputeFullU);
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);
439 Pose3 body_P_sensor()
const{
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_);
virtual Cameras cameras(const Values &values) const
Collect all cameras: important that in key order.
Definition: SmartFactorBase.h:163
void computeJacobians(FBlocks &Fs, Matrix &E, Vector &b, const Cameras &cameras, const POINT &point) const
Definition: SmartFactorBase.h:315
typename std::enable_if< B, T >::type enable_if_t
An shorthand alias for accessing the ::type inside std::enable_if that can be used in a template dire...
Definition: make_shared.h:30
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:352
void add(const SFM_TRACK &trackToAdd)
Definition: SmartFactorBase.h:149
double totalReprojectionError(const Cameras &cameras, const POINT &point) const
Definition: SmartFactorBase.h:297
GTSAM_MAKE_ALIGNED_OPERATOR_NEW typedef std::shared_ptr< This > shared_ptr
shorthand for a smart pointer to a factor.
Definition: SmartFactorBase.h:92
std::string serialize(const T &input)
serializes to a string
Definition: serialization.h:113
bool equals(const NonlinearFactor &p, double tol=1e-9) const override
equals
Definition: SmartFactorBase.h:188
const ValueType at(Key j) const
Definition: Values-inl.h:204
Base class to create smart factors on poses or cameras.
Give fixed size dimension of a type, fails at compile time if dynamic.
Definition: Manifold.h:161
Vector reprojectionError(const POINT &point, const ZVector &measured, FBlocks *Fs=nullptr, Matrix *E=nullptr) const
Calculate vector [project2(point)-z] of re-projection errors.
Definition: CameraSet.h:146
virtual bool equals(const NonlinearFactor &f, double tol=1e-9) const
Definition: NonlinearFactor.h:68
SmartFactorBase()
Default Constructor, for serialization.
Definition: SmartFactorBase.h:98
CameraSet< CAMERA > Cameras
The CameraSet data structure is used to refer to a set of cameras.
Definition: SmartFactorBase.h:95
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:346
virtual void correctForMissingMeasurements(const Cameras &cameras, Vector &ue, typename Cameras::FBlocks *Fs=nullptr, Matrix *E=nullptr) const
Definition: SmartFactorBase.h:258
KeyVector keys_
The keys involved in this factor.
Definition: Factor.h:87
void print(const std::string &s="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const override
SharedIsotropic noiseModel_
Definition: SmartFactorBase.h:73
void print(const std::string &s="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const override
Definition: SmartFactorBase.h:175
~SmartFactorBase() override
Virtual destructor, subclasses from NonlinearFactor.
Definition: SmartFactorBase.h:119
A set of cameras, all with their own calibration.
Definition: CameraSet.h:36
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)
Definition: CameraSet.h:171
Vector unwhitenedError(const Cameras &cameras, const POINT &point, OptArgs &&... optArgs) const
Definition: SmartFactorBase.h:247
Definition: SymmetricBlockMatrix.h:53
Base class for smart factors. This base class has no internal point, but it has a measurement...
Definition: SmartFactorBase.h:51
ZVector measured_
Definition: SmartFactorBase.h:80
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:386
void computeJacobiansSVD(FBlocks &Fs, Matrix &Enull, Vector &b, const Cameras &cameras, const POINT &point) const
Definition: SmartFactorBase.h:330
static void FillDiagonalF(const FBlocks &Fs, Matrix &F)
Create BIG block-diagonal matrix F from Fblocks.
Definition: SmartFactorBase.h:430
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:101
HessianFactor class with constant sized blocks.
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
Vector whitenedError(const Cameras &cameras, const POINT &point) const
Definition: SmartFactorBase.h:281
void add(const ZVector &measurements, const KeyVector &cameraKeys)
Add a bunch of measurements, together with the camera keys.
Definition: SmartFactorBase.h:137
std::shared_ptr< JacobianFactor > createJacobianSVDFactor(const Cameras &cameras, const Point3 &point, double lambda=0.0) const
Definition: SmartFactorBase.h:416
const ZVector & measured() const
Return the 2D measurements (ZDim, in general).
Definition: SmartFactorBase.h:160
Definition: chartTesting.h:28
FastVector< Key > KeyVector
Define collection type once and for all - also used in wrappers.
Definition: Key.h:86
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.
Definition: SmartFactorBase.h:157
void add(const Z &measured, const Key &key)
Definition: SmartFactorBase.h:127
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:399
void correctForMissingMeasurements(const Cameras &cameras, Vector &ue, OptArgs &&... optArgs) const
Definition: SmartFactorBase.h:270
GTSAM_EXPORT void svd(const Matrix &A, Matrix &U, Vector &S, Matrix &V)
static const int Dim
Camera dimension.
Definition: SmartFactorBase.h:61
void updateAugmentedHessian(const Cameras &cameras, const Point3 &point, const double lambda, bool diagonalDamping, SymmetricBlockMatrix &augmentedHessian, const KeyVector allKeys) const
Definition: SmartFactorBase.h:366
#define GTSAM_MAKE_ALIGNED_OPERATOR_NEW
Definition: types.h:284
Vector3 Point3
Definition: Point3.h:38
static Matrix PointCov(const Matrix &E)
Computes Point Covariance P from the "point Jacobian" E.
Definition: SmartFactorBase.h:304
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)
Definition: CameraSet.h:390
void whitenJacobians(FBlocks &F, Matrix &E, Vector &b) const
Whiten the Jacobians computed by computeJacobians using noiseModel_.
Definition: SmartFactorBase.h:377
Definition: NoiseModel.h:527
std::optional< Pose3 > body_P_sensor_
Pose of the camera in the body frame.
Definition: SmartFactorBase.h:83
std::uint64_t Key
Integer nonlinear key type.
Definition: types.h:102
static const int ZDim
Measurement dimension.
Definition: SmartFactorBase.h:62
noiseModel::Base::shared_ptr SharedNoiseModel
Definition: NoiseModel.h:741
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
Definition: SmartFactorBase.h:208