23 #include <gtsam/slam/JacobianFactorQ.h> 24 #include <gtsam/slam/JacobianFactorSVD.h> 31 #include <boost/optional.hpp> 32 #include <boost/serialization/optional.hpp> 33 #include <boost/make_shared.hpp> 46 template<
class CAMERA>
52 typedef typename CAMERA::Measurement Z;
58 typedef Eigen::Matrix<double, ZDim, Dim> MatrixZD;
81 mutable std::vector<MatrixZD> Fblocks;
85 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
98 boost::optional<Pose3> body_P_sensor = boost::none,
99 size_t expectedNumberCameras = 10)
100 : body_P_sensor_(body_P_sensor), Fblocks(expectedNumberCameras) {
102 if (!sharedNoiseModel)
103 throw std::runtime_error(
"SmartFactorBase: sharedNoiseModel is required");
105 SharedIsotropic sharedIsotropic = boost::dynamic_pointer_cast<
108 if (!sharedIsotropic)
109 throw std::runtime_error(
"SmartFactorBase: needs isotropic");
111 noiseModel_ = sharedIsotropic;
124 void add(
const Z& measured_i,
const Key& cameraKey_i) {
125 this->measured_.push_back(measured_i);
126 this->
keys_.push_back(cameraKey_i);
132 void add(std::vector<Z>& measurements, std::vector<Key>& cameraKeys) {
133 for (
size_t i = 0; i < measurements.size(); i++) {
134 this->measured_.push_back(measurements.at(i));
135 this->
keys_.push_back(cameraKeys.at(i));
143 template<
class SFM_TRACK>
144 void add(
const SFM_TRACK& trackToAdd) {
145 for (
size_t k = 0; k < trackToAdd.number_measurements(); k++) {
146 this->measured_.push_back(trackToAdd.measurements[k].second);
147 this->
keys_.push_back(trackToAdd.measurements[k].first);
152 virtual size_t dim()
const {
153 return ZDim * this->measured_.size();
165 cameras.push_back(values.
at<CAMERA>(k));
175 DefaultKeyFormatter)
const {
176 std::cout << s <<
"SmartFactorBase, z = \n";
177 for (
size_t k = 0; k < measured_.size(); ++k) {
178 std::cout <<
"measurement, p = " << measured_[k] <<
"\t";
179 noiseModel_->print(
"noise model = ");
182 body_P_sensor_->print(
"body_P_sensor_:\n");
188 const This *e =
dynamic_cast<const This*
>(&p);
190 bool areMeasurementsEqual =
true;
191 for (
size_t i = 0; i < measured_.size(); i++) {
193 areMeasurementsEqual =
false;
196 return e &&
Base::equals(p, tol) && areMeasurementsEqual;
200 template<
class POINT>
202 boost::optional<typename Cameras::FBlocks&> Fs = boost::none,
203 boost::optional<Matrix&> E = boost::none)
const {
206 for(
size_t i=0; i < Fs->size(); i++){
207 Pose3 w_Pose_body = (cameras[i].pose()).compose(body_P_sensor_->inverse());
209 Pose3 world_P_body = w_Pose_body.compose(*body_P_sensor_, J);
210 Fs->at(i) = Fs->at(i) * J;
220 template<
class POINT>
224 noiseModel_->whitenInPlace(e);
234 template<
class POINT>
236 const POINT& point)
const {
238 return 0.5 * e.dot(e);
243 return (E.transpose() * E).inverse();
252 template<
class POINT>
254 const Cameras&
cameras,
const POINT& point)
const {
263 template<
class POINT>
265 Vector& b,
const Cameras&
cameras,
const POINT& point)
const {
273 Eigen::JacobiSVD<Matrix>
svd(E, Eigen::ComputeFullU);
274 Vector s = svd.singularValues();
275 size_t m = this->
keys_.size();
276 Enull = svd.matrixU().block(0, N, ZDim * m, ZDim * m - N);
281 const Cameras&
cameras,
const Point3& point,
const double lambda = 0.0,
282 bool diagonalDamping =
false)
const {
291 return boost::make_shared<RegularHessianFactor<Dim> >(
keys_,
301 const double lambda,
bool diagonalDamping,
312 noiseModel_->WhitenSystem(E, b);
314 for (
size_t i = 0; i < F.size(); i++)
315 F[i] = noiseModel_->Whiten(F[i]);
319 boost::shared_ptr<RegularImplicitSchurFactor<CAMERA> >
321 double lambda = 0.0,
bool diagonalDamping =
false)
const {
324 std::vector<MatrixZD> F;
328 return boost::make_shared<RegularImplicitSchurFactor<CAMERA> >(
keys_, F, E,
336 const Cameras&
cameras,
const Point3& point,
double lambda = 0.0,
337 bool diagonalDamping =
false)
const {
340 std::vector<MatrixZD> F;
342 const size_t M = b.size();
345 return boost::make_shared<JacobianFactorQ<Dim, ZDim> >(
keys_, F, E, P, b, n);
353 const Cameras&
cameras,
const Point3& point,
double lambda = 0.0)
const {
354 size_t m = this->
keys_.size();
355 std::vector<MatrixZD> F;
357 const size_t M = ZDim * m;
361 noiseModel_->sigma());
362 return boost::make_shared<JacobianFactorSVD<Dim, ZDim> >(
keys_, F, E0, b, n);
366 static void FillDiagonalF(
const std::vector<MatrixZD>& Fblocks, Matrix& F) {
367 size_t m = Fblocks.size();
368 F.resize(ZDim * m, Dim * m);
370 for (
size_t i = 0; i < m; ++i)
371 F.block<ZDim, Dim>(ZDim * i, Dim * i) = Fblocks.at(i);
375 Pose3 body_P_sensor()
const{
385 friend class boost::serialization::access;
386 template<
class ARCHIVE>
387 void serialize(ARCHIVE & ar,
const unsigned int ) {
388 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
389 ar & BOOST_SERIALIZATION_NVP(noiseModel_);
390 ar & BOOST_SERIALIZATION_NVP(measured_);
391 ar & BOOST_SERIALIZATION_NVP(body_P_sensor_);
void print(const std::string &s="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const
print
Definition: SmartFactorBase.h:174
Nonlinear factor base class.
Definition: NonlinearFactor.h:52
Base class to create smart factors on poses or cameras.
void svd(const Matrix &A, Matrix &U, Vector &S, Matrix &V)
SVD computes economy SVD A=U*S*V'.
Definition: Matrix.cpp:554
This is the base class for all factor types.
Definition: Factor.h:51
virtual Cameras cameras(const Values &values) const
Collect all cameras: important that in key order.
Definition: SmartFactorBase.h:162
noiseModel::Base::shared_ptr SharedNoiseModel
Note, deliberately not in noiseModel namespace.
Definition: NoiseModel.h:1072
void computeJacobiansSVD(std::vector< MatrixZD > &Fblocks, Matrix &Enull, Vector &b, const Cameras &cameras, const POINT &point) const
SVD version.
Definition: SmartFactorBase.h:264
static SymmetricBlockMatrix SchurComplement(const FBlocks &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:143
Vector reprojectionError(const POINT &point, const std::vector< Z > &measured, boost::optional< FBlocks & > Fs=boost::none, boost::optional< Matrix & > E=boost::none) const
Calculate vector [project2(point)-z] of re-projection errors.
Definition: CameraSet.h:130
An isotropic noise model corresponds to a scaled diagonal covariance To construct, use one of the static methods.
Definition: NoiseModel.h:519
static shared_ptr Sigma(size_t dim, double sigma, bool smart=true)
An isotropic noise model created by specifying a standard devation sigma.
Definition: NoiseModel.cpp:561
boost::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:280
HessianFactor class with constant sized blocks.
double totalReprojectionError(const Cameras &cameras, const POINT &point) const
Calculate the error of the factor.
Definition: SmartFactorBase.h:235
Base class for smart factors This base class has no internal point, but it has a measurement, noise model and an optional sensor pose.
Definition: SmartFactorBase.h:47
boost::optional< Pose3 > body_P_sensor_
Pose of the camera in the body frame.
Definition: SmartFactorBase.h:77
A non-templated config holding any types of Manifold-group elements.
Definition: Values.h:70
Definition: SymmetricBlockMatrix.h:51
void add(const Z &measured_i, const Key &cameraKey_i)
Add a new measurement and pose key.
Definition: SmartFactorBase.h:124
void computeJacobians(std::vector< MatrixZD > &Fblocks, 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:253
boost::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:335
static Matrix PointCov(Matrix &E)
Computes Point Covariance P from E.
Definition: SmartFactorBase.h:242
std::vector< Z > measured_
2D measurement and noise model for each of the m views We keep a copy of measurements for I/O and com...
Definition: SmartFactorBase.h:74
Vector unwhitenedError(const Cameras &cameras, const POINT &point, boost::optional< typename Cameras::FBlocks & > Fs=boost::none, boost::optional< Matrix & > E=boost::none) const
Compute reprojection errors [h(x)-z] = [cameras.project(p)-z] and derivatives.
Definition: SmartFactorBase.h:201
virtual ~SmartFactorBase()
Virtual destructor, subclasses from NonlinearFactor.
Definition: SmartFactorBase.h:115
boost::shared_ptr< JacobianFactor > createJacobianSVDFactor(const Cameras &cameras, const Point3 &point, double lambda=0.0) const
Return Jacobians as JacobianFactorSVD TODO lambda is currently ignored.
Definition: SmartFactorBase.h:352
void add(std::vector< Z > &measurements, std::vector< Key > &cameraKeys)
Add a bunch of measurements, together with the camera keys.
Definition: SmartFactorBase.h:132
Vector whitenedError(const Cameras &cameras, const POINT &point) const
Calculate vector of re-projection errors [h(x)-z] = [cameras.project(p) - z] Noise model applied...
Definition: SmartFactorBase.h:221
void updateAugmentedHessian(const Cameras &cameras, const Point3 &point, const double lambda, bool diagonalDamping, SymmetricBlockMatrix &augmentedHessian, const FastVector< Key > allKeys) const
Add the contribution of the smart factor to a pre-allocated Hessian, using sparse linear algebra...
Definition: SmartFactorBase.h:300
virtual bool equals(const NonlinearFactor &p, double tol=1e-9) const
equals
Definition: SmartFactorBase.h:187
SmartFactorBase(const SharedNoiseModel &sharedNoiseModel, boost::optional< Pose3 > body_P_sensor=boost::none, size_t expectedNumberCameras=10)
Constructor.
Definition: SmartFactorBase.h:97
virtual void print(const std::string &s="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const
print
Definition: NonlinearFactor.cpp:26
virtual size_t dim() const
get the dimension (number of rows!) of the factor
Definition: SmartFactorBase.h:152
A set of cameras, all with their own calibration.
Definition: CameraSet.h:34
void whitenJacobians(std::vector< MatrixZD > &F, Matrix &E, Vector &b) const
Whiten the Jacobians computed by computeJacobians using noiseModel_.
Definition: SmartFactorBase.h:311
static void FillDiagonalF(const std::vector< MatrixZD > &Fblocks, Matrix &F)
Create BIG block-diagonal matrix F from Fblocks.
Definition: SmartFactorBase.h:366
FastVector< Key > keys_
The keys involved in this factor.
Definition: Factor.h:69
SharedIsotropic noiseModel_
As of Feb 22, 2015, the noise model is the same for all measurements and is isotropic.
Definition: SmartFactorBase.h:67
static void UpdateSchurComplement(const FBlocks &Fs, const Matrix &E, const Eigen::Matrix< double, N, N > &P, const Vector &b, const FastVector< Key > &allKeys, const FastVector< Key > &keys, SymmetricBlockMatrix &augmentedHessian)
Applies Schur complement (exploiting block structure) to get a smart factor on cameras, and adds the contribution of the smart factor to a pre-allocated augmented Hessian.
Definition: CameraSet.h:240
ValueType at(Key j) const
Retrieve a variable by key j.
Definition: Values-inl.h:343
EIGEN_MAKE_ALIGNED_OPERATOR_NEW typedef boost::shared_ptr< This > shared_ptr
shorthand for a smart pointer to a factor
Definition: SmartFactorBase.h:88
virtual bool equals(const NonlinearFactor &f, double tol=1e-9) const
Check if two factors are equal.
Definition: NonlinearFactor.cpp:36
A manifold defines a space in which there is a notion of a linear tangent space that can be centered ...
Definition: concepts.h:30
void add(const SFM_TRACK &trackToAdd)
Adds an entire SfM_track (collection of cameras observing a single point).
Definition: SmartFactorBase.h:144
Give fixed size dimension of a type, fails at compile time if dynamic.
Definition: Manifold.h:164
SmartFactorBase()
Default Constructor, for serialization.
Definition: SmartFactorBase.h:94
static const int ZDim
Measurement dimension.
Definition: SmartFactorBase.h:57
static const int Dim
Camera dimension.
Definition: SmartFactorBase.h:56
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:204
Non-linear factor base classes.
const std::vector< Z > & measured() const
return the measurements
Definition: SmartFactorBase.h:157
boost::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:320
std::uint64_t Key
Integer nonlinear key type.
Definition: types.h:57
A new type of linear factor (GaussianFactor), which is subclass of GaussianFactor.
CameraSet< CAMERA > Cameras
We use the new CameraSte data structure to refer to a set of cameras.
Definition: SmartFactorBase.h:91
Global functions in a separate testing namespace.
Definition: chartTesting.h:28
boost::function< std::string(Key)> KeyFormatter
Typedef for a function to format a key, i.e. to convert it to a string.
Definition: Key.h:33