gtsam  3.2.1
gtsam
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SmartProjectionFactor.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 
20 #pragma once
21 
22 #include "SmartFactorBase.h"
23 
25 #include <gtsam/geometry/Pose3.h>
26 #include <gtsam/inference/Symbol.h>
27 #include <gtsam/slam/dataset.h>
28 
29 #include <boost/optional.hpp>
30 #include <boost/make_shared.hpp>
31 #include <vector>
32 
33 namespace gtsam {
34 
40 
41 protected:
42 
43 public:
44 
46  }
47  // Hessian representation (after Schur complement)
48  bool calculatedHessian;
49  Matrix H;
50  Vector gs_vector;
51  std::vector<Matrix> Gs;
52  std::vector<Vector> gs;
53  double f;
54 };
55 
56 enum LinearizationMode {
57  HESSIAN, JACOBIAN_SVD, JACOBIAN_Q
58 };
59 
64 template<class POSE, class LANDMARK, class CALIBRATION, size_t D>
65 class SmartProjectionFactor: public SmartFactorBase<POSE, CALIBRATION, D> {
66 protected:
67 
68  // Some triangulation parameters
69  const double rankTolerance_;
71  mutable std::vector<Pose3> cameraPosesTriangulation_;
72 
73  const bool manageDegeneracy_;
74 
75  const bool enableEPI_;
76 
77  const double linearizationThreshold_;
78  mutable std::vector<Pose3> cameraPosesLinearization_;
79 
80  mutable Point3 point_;
81 
82  mutable bool degenerate_;
83  mutable bool cheiralityException_;
84 
85  // verbosity handling for Cheirality Exceptions
86  const bool throwCheirality_;
87  const bool verboseCheirality_;
88 
89  boost::shared_ptr<SmartProjectionFactorState> state_;
90 
92  typedef boost::shared_ptr<SmartProjectionFactorState> SmartFactorStatePtr;
93 
96 
97  double landmarkDistanceThreshold_; // if the landmark is triangulated at a
98  // distance larger than that the factor is considered degenerate
99 
100  double dynamicOutlierRejectionThreshold_; // if this is nonnegative the factor will check if the
101  // average reprojection error is smaller than this threshold after triangulation,
102  // and the factor is disregarded if the error is large
103 
106 
107 public:
108 
110  typedef boost::shared_ptr<This> shared_ptr;
111 
114  typedef std::vector<Camera> Cameras;
115 
125  SmartProjectionFactor(const double rankTol, const double linThreshold,
126  const bool manageDegeneracy, const bool enableEPI,
127  boost::optional<POSE> body_P_sensor = boost::none,
128  double landmarkDistanceThreshold = 1e10,
129  double dynamicOutlierRejectionThreshold = -1,
131  Base(body_P_sensor), rankTolerance_(rankTol), retriangulationThreshold_(
132  1e-5), manageDegeneracy_(manageDegeneracy), enableEPI_(enableEPI), linearizationThreshold_(
133  linThreshold), degenerate_(false), cheiralityException_(false), throwCheirality_(
134  false), verboseCheirality_(false), state_(state),
135  landmarkDistanceThreshold_(landmarkDistanceThreshold),
136  dynamicOutlierRejectionThreshold_(dynamicOutlierRejectionThreshold) {
137  }
138 
141  }
142 
148  void print(const std::string& s = "", const KeyFormatter& keyFormatter =
149  DefaultKeyFormatter) const {
150  std::cout << s << "SmartProjectionFactor, z = \n";
151  std::cout << "rankTolerance_ = " << rankTolerance_ << std::endl;
152  std::cout << "degenerate_ = " << degenerate_ << std::endl;
153  std::cout << "cheiralityException_ = " << cheiralityException_ << std::endl;
154  Base::print("", keyFormatter);
155  }
156 
158  bool decideIfTriangulate(const Cameras& cameras) const {
159  // several calls to linearize will be done from the same linearization point_, hence it is not needed to re-triangulate
160  // Note that this is not yet "selecting linearization", that will come later, and we only check if the
161  // current linearization is the "same" (up to tolerance) w.r.t. the last time we triangulated the point_
162 
163  size_t m = cameras.size();
164 
165  bool retriangulate = false;
166 
167  // if we do not have a previous linearization point_ or the new linearization point_ includes more poses
168  if (cameraPosesTriangulation_.empty()
169  || cameras.size() != cameraPosesTriangulation_.size())
170  retriangulate = true;
171 
172  if (!retriangulate) {
173  for (size_t i = 0; i < cameras.size(); i++) {
174  if (!cameras[i].pose().equals(cameraPosesTriangulation_[i],
176  retriangulate = true; // at least two poses are different, hence we retriangulate
177  break;
178  }
179  }
180  }
181 
182  if (retriangulate) { // we store the current poses used for triangulation
184  cameraPosesTriangulation_.reserve(m);
185  for (size_t i = 0; i < m; i++)
186  // cameraPosesTriangulation_[i] = cameras[i].pose();
187  cameraPosesTriangulation_.push_back(cameras[i].pose());
188  }
189 
190  return retriangulate; // if we arrive to this point_ all poses are the same and we don't need re-triangulation
191  }
192 
194  bool decideIfLinearize(const Cameras& cameras) const {
195  // "selective linearization"
196  // The function evaluates how close are the old and the new poses, transformed in the ref frame of the first pose
197  // (we only care about the "rigidity" of the poses, not about their absolute pose)
198 
199  if (this->linearizationThreshold_ < 0) //by convention if linearizationThreshold is negative we always relinearize
200  return true;
201 
202  // if we do not have a previous linearization point_ or the new linearization point_ includes more poses
203  if (cameraPosesLinearization_.empty()
204  || (cameras.size() != cameraPosesLinearization_.size()))
205  return true;
206 
207  Pose3 firstCameraPose, firstCameraPoseOld;
208  for (size_t i = 0; i < cameras.size(); i++) {
209 
210  if (i == 0) { // we store the initial pose, this is useful for selective re-linearization
211  firstCameraPose = cameras[i].pose();
212  firstCameraPoseOld = cameraPosesLinearization_[i];
213  continue;
214  }
215 
216  // we compare the poses in the frame of the first pose
217  Pose3 localCameraPose = firstCameraPose.between(cameras[i].pose());
218  Pose3 localCameraPoseOld = firstCameraPoseOld.between(
220  if (!localCameraPose.equals(localCameraPoseOld,
221  this->linearizationThreshold_))
222  return true; // at least two "relative" poses are different, hence we re-linearize
223  }
224  return false; // if we arrive to this point_ all poses are the same and we don't need re-linearize
225  }
226 
228  size_t triangulateSafe(const Values& values) const {
229  return triangulateSafe(this->cameras(values));
230  }
231 
233  size_t triangulateSafe(const Cameras& cameras) const {
234 
235  size_t m = cameras.size();
236  if (m < 2) { // if we have a single pose the corresponding factor is uninformative
237  degenerate_ = true;
238  return m;
239  }
240  bool retriangulate = decideIfTriangulate(cameras);
241 
242  if (retriangulate) {
243  // We triangulate the 3D position of the landmark
244  try {
245  // std::cout << "triangulatePoint3 i \n" << rankTolerance << std::endl;
246  point_ = triangulatePoint3<CALIBRATION>(cameras, this->measured_,
248  degenerate_ = false;
249  cheiralityException_ = false;
250 
251  // Check landmark distance and reprojection errors to avoid outliers
252  double totalReprojError = 0.0;
253  size_t i=0;
254  BOOST_FOREACH(const Camera& camera, cameras) {
255  Point3 cameraTranslation = camera.pose().translation();
256  // we discard smart factors corresponding to points that are far away
257  if(cameraTranslation.distance(point_) > landmarkDistanceThreshold_){
258  degenerate_ = true;
259  break;
260  }
261  const Point2& zi = this->measured_.at(i);
262  try {
263  Point2 reprojectionError(camera.project(point_) - zi);
264  totalReprojError += reprojectionError.vector().norm();
265  } catch (CheiralityException) {
266  cheiralityException_ = true;
267  }
268  i += 1;
269  }
270  // we discard smart factors that have large reprojection error
271  if(dynamicOutlierRejectionThreshold_ > 0 &&
272  totalReprojError/m > dynamicOutlierRejectionThreshold_)
273  degenerate_ = true;
274 
276  // if TriangulationUnderconstrainedException can be
277  // 1) There is a single pose for triangulation - this should not happen because we checked the number of poses before
278  // 2) The rank of the matrix used for triangulation is < 3: rotation-only, parallel cameras (or motion towards the landmark)
279  // in the second case we want to use a rotation-only smart factor
280  degenerate_ = true;
281  cheiralityException_ = false;
283  // point is behind one of the cameras: can be the case of close-to-parallel cameras or may depend on outliers
284  // we manage this case by either discarding the smart factor, or imposing a rotation-only constraint
285  cheiralityException_ = true;
286  }
287  }
288  return m;
289  }
290 
292  bool triangulateForLinearize(const Cameras& cameras) const {
293 
294  bool isDebug = false;
295  size_t nrCameras = this->triangulateSafe(cameras);
296 
297  if (nrCameras < 2
298  || (!this->manageDegeneracy_
299  && (this->cheiralityException_ || this->degenerate_))) {
300  if (isDebug) {
301  std::cout << "createImplicitSchurFactor: degenerate configuration"
302  << std::endl;
303  }
304  return false;
305  } else {
306 
307  // instead, if we want to manage the exception..
308  if (this->cheiralityException_ || this->degenerate_) { // if we want to manage the exceptions with rotation-only factors
309  this->degenerate_ = true;
310  }
311  return true;
312  }
313  }
314 
316  boost::shared_ptr<RegularHessianFactor<D> > createHessianFactor(
317  const Cameras& cameras, const double lambda = 0.0) const {
318 
319  bool isDebug = false;
320  size_t numKeys = this->keys_.size();
321  // Create structures for Hessian Factors
322  std::vector < Key > js;
323  std::vector < Matrix > Gs(numKeys * (numKeys + 1) / 2);
324  std::vector < Vector > gs(numKeys);
325 
326  if (this->measured_.size() != cameras.size()) {
327  std::cout
328  << "SmartProjectionHessianFactor: this->measured_.size() inconsistent with input"
329  << std::endl;
330  exit(1);
331  }
332 
333  this->triangulateSafe(cameras);
334 
335  if (numKeys < 2
336  || (!this->manageDegeneracy_
337  && (this->cheiralityException_ || this->degenerate_))) {
338  // std::cout << "In linearize: exception" << std::endl;
339  BOOST_FOREACH(gtsam::Matrix& m, Gs)
340  m = zeros(D, D);
341  BOOST_FOREACH(Vector& v, gs)
342  v = zero(D);
343  return boost::make_shared<RegularHessianFactor<D> >(this->keys_, Gs, gs,
344  0.0);
345  }
346 
347  // instead, if we want to manage the exception..
348  if (this->cheiralityException_ || this->degenerate_) { // if we want to manage the exceptions with rotation-only factors
349  this->degenerate_ = true;
350  }
351 
352  bool doLinearize = this->decideIfLinearize(cameras);
353 
354  if (this->linearizationThreshold_ >= 0 && doLinearize) // if we apply selective relinearization and we need to relinearize
355  for (size_t i = 0; i < cameras.size(); i++)
356  this->cameraPosesLinearization_[i] = cameras[i].pose();
357 
358  if (!doLinearize) { // return the previous Hessian factor
359  std::cout << "=============================" << std::endl;
360  std::cout << "doLinearize " << doLinearize << std::endl;
361  std::cout << "this->linearizationThreshold_ "
362  << this->linearizationThreshold_ << std::endl;
363  std::cout << "this->degenerate_ " << this->degenerate_ << std::endl;
364  std::cout
365  << "something wrong in SmartProjectionHessianFactor: selective relinearization should be disabled"
366  << std::endl;
367  exit(1);
368  return boost::make_shared<RegularHessianFactor<D> >(this->keys_,
369  this->state_->Gs, this->state_->gs, this->state_->f);
370  }
371 
372  // ==================================================================
373  Matrix F, E;
374  Matrix3 PointCov;
375  Vector b;
376  double f = computeJacobians(F, E, PointCov, b, cameras, lambda);
377 
378  // Schur complement trick
379  // Frank says: should be possible to do this more efficiently?
380  // And we care, as in grouped factors this is called repeatedly
381  Matrix H(D * numKeys, D * numKeys);
382  Vector gs_vector;
383 
384  H.noalias() = F.transpose() * (F - (E * (PointCov * (E.transpose() * F))));
385  gs_vector.noalias() = F.transpose()
386  * (b - (E * (PointCov * (E.transpose() * b))));
387  if (isDebug)
388  std::cout << "gs_vector size " << gs_vector.size() << std::endl;
389 
390  // Populate Gs and gs
391  int GsCount2 = 0;
392  for (DenseIndex i1 = 0; i1 < (DenseIndex)numKeys; i1++) { // for each camera
393  DenseIndex i1D = i1 * D;
394  gs.at(i1) = gs_vector.segment < D > (i1D);
395  for (DenseIndex i2 = 0; i2 < (DenseIndex)numKeys; i2++) {
396  if (i2 >= i1) {
397  Gs.at(GsCount2) = H.block < D, D > (i1D, i2 * D);
398  GsCount2++;
399  }
400  }
401  }
402  // ==================================================================
403  if (this->linearizationThreshold_ >= 0) { // if we do not use selective relinearization we don't need to store these variables
404  this->state_->Gs = Gs;
405  this->state_->gs = gs;
406  this->state_->f = f;
407  }
408  return boost::make_shared<RegularHessianFactor<D> >(this->keys_, Gs, gs, f);
409  }
410 
411  // create factor
412  boost::shared_ptr<ImplicitSchurFactor<D> > createImplicitSchurFactor(
413  const Cameras& cameras, double lambda) const {
414  if (triangulateForLinearize(cameras))
415  return Base::createImplicitSchurFactor(cameras, point_, lambda);
416  else
417  return boost::shared_ptr<ImplicitSchurFactor<D> >();
418  }
419 
421  boost::shared_ptr<JacobianFactorQ<D> > createJacobianQFactor(
422  const Cameras& cameras, double lambda) const {
423  if (triangulateForLinearize(cameras))
424  return Base::createJacobianQFactor(cameras, point_, lambda);
425  else
426  return boost::make_shared< JacobianFactorQ<D> >(this->keys_);
427  }
428 
430  boost::shared_ptr<JacobianFactorQ<D> > createJacobianQFactor(
431  const Values& values, double lambda) const {
432  Cameras myCameras;
433  // TODO triangulate twice ??
434  bool nonDegenerate = computeCamerasAndTriangulate(values, myCameras);
435  if (nonDegenerate)
436  return createJacobianQFactor(myCameras, lambda);
437  else
438  return boost::make_shared< JacobianFactorQ<D> >(this->keys_);
439  }
440 
442  boost::shared_ptr< JacobianFactor > createJacobianSVDFactor(const Cameras& cameras,
443  double lambda) const {
444  if (triangulateForLinearize(cameras))
445  return Base::createJacobianSVDFactor(cameras, point_, lambda);
446  else
447  return boost::make_shared< JacobianFactorSVD<D> >(this->keys_);
448  }
449 
452  Cameras& myCameras) const {
453  Values valuesFactor;
454 
455  // Select only the cameras
456  BOOST_FOREACH(const Key key, this->keys_)
457  valuesFactor.insert(key, values.at(key));
458 
459  myCameras = this->cameras(valuesFactor);
460  size_t nrCameras = this->triangulateSafe(myCameras);
461 
462  if (nrCameras < 2
463  || (!this->manageDegeneracy_
464  && (this->cheiralityException_ || this->degenerate_)))
465  return false;
466 
467  // instead, if we want to manage the exception..
468  if (this->cheiralityException_ || this->degenerate_) // if we want to manage the exceptions with rotation-only factors
469  this->degenerate_ = true;
470 
471  if (this->degenerate_) {
472  std::cout << "SmartProjectionFactor: this is not ready" << std::endl;
473  std::cout << "this->cheiralityException_ " << this->cheiralityException_
474  << std::endl;
475  std::cout << "this->degenerate_ " << this->degenerate_ << std::endl;
476  }
477  return true;
478  }
479 
481  bool computeEP(Matrix& E, Matrix& PointCov, const Values& values) const {
482  Cameras myCameras;
483  bool nonDegenerate = computeCamerasAndTriangulate(values, myCameras);
484  if (nonDegenerate)
485  computeEP(E, PointCov, myCameras);
486  return nonDegenerate;
487  }
488 
490  void computeEP(Matrix& E, Matrix& PointCov, const Cameras& cameras) const {
491  return Base::computeEP(E, PointCov, cameras, point_);
492  }
493 
495  bool computeJacobians(std::vector<typename Base::KeyMatrix2D>& Fblocks,
496  Matrix& E, Matrix& PointCov, Vector& b, const Values& values) const {
497  Cameras myCameras;
498  bool nonDegenerate = computeCamerasAndTriangulate(values, myCameras);
499  if (nonDegenerate)
500  computeJacobians(Fblocks, E, PointCov, b, myCameras, 0.0);
501  return nonDegenerate;
502  }
503 
507  double computeJacobians(std::vector<typename Base::KeyMatrix2D>& Fblocks,
508  Matrix& E, Vector& b, const Cameras& cameras) const {
509 
510  if (this->degenerate_) {
511  std::cout << "manage degeneracy " << manageDegeneracy_ << std::endl;
512  std::cout << "point " << point_ << std::endl;
513  std::cout
514  << "SmartProjectionFactor: Management of degeneracy is disabled - not ready to be used"
515  << std::endl;
516  if (D > 6) {
517  std::cout
518  << "Management of degeneracy is not yet ready when one also optimizes for the calibration "
519  << std::endl;
520  }
521 
522  int numKeys = this->keys_.size();
523  E = zeros(2 * numKeys, 2);
524  b = zero(2 * numKeys);
525  double f = 0;
526  for (size_t i = 0; i < this->measured_.size(); i++) {
527  if (i == 0) { // first pose
528  this->point_ = cameras[i].backprojectPointAtInfinity(
529  this->measured_.at(i));
530  // 3D parametrization of point at infinity: [px py 1]
531  }
532  Matrix Fi, Ei;
533  Vector bi = -(cameras[i].projectPointAtInfinity(this->point_, Fi, Ei)
534  - this->measured_.at(i)).vector();
535 
536  this->noise_.at(i)->WhitenSystem(Fi, Ei, bi);
537  f += bi.squaredNorm();
538  Fblocks.push_back(typename Base::KeyMatrix2D(this->keys_[i], Fi));
539  E.block < 2, 2 > (2 * i, 0) = Ei;
540  subInsert(b, bi, 2 * i);
541  }
542  return f;
543  } else {
544  // nondegenerate: just return Base version
545  return Base::computeJacobians(Fblocks, E, b, cameras, point_);
546  } // end else
547  }
548 
550  double computeJacobians(std::vector<typename Base::KeyMatrix2D>& Fblocks,
551  Matrix& E, Matrix& PointCov, Vector& b, const Cameras& cameras,
552  const double lambda = 0.0) const {
553 
554  double f = computeJacobians(Fblocks, E, b, cameras);
555 
556  // Point covariance inv(E'*E)
557  PointCov.noalias() = (E.transpose() * E + lambda * eye(E.cols())).inverse();
558 
559  return f;
560  }
561 
563  bool computeJacobiansSVD(std::vector<typename Base::KeyMatrix2D>& Fblocks,
564  Matrix& Enull, Vector& b, const Values& values) const {
565  typename Base::Cameras myCameras;
566  double good = computeCamerasAndTriangulate(values, myCameras);
567  if (good)
568  computeJacobiansSVD(Fblocks, Enull, b, myCameras);
569  return true;
570  }
571 
573  double computeJacobiansSVD(std::vector<typename Base::KeyMatrix2D>& Fblocks,
574  Matrix& Enull, Vector& b, const Cameras& cameras) const {
575  return Base::computeJacobiansSVD(Fblocks, Enull, b, cameras, point_);
576  }
577 
579  // TODO should there be a lambda?
580  double computeJacobiansSVD(Matrix& F, Matrix& Enull, Vector& b,
581  const Cameras& cameras) const {
582  return Base::computeJacobiansSVD(F, Enull, b, cameras, point_);
583  }
584 
586  double computeJacobians(Matrix& F, Matrix& E, Matrix3& PointCov, Vector& b,
587  const Cameras& cameras, const double lambda) const {
588  return Base::computeJacobians(F, E, PointCov, b, cameras, point_, lambda);
589  }
590 
593  Vector reprojectionError(const Cameras& cameras) const {
594  return Base::reprojectionError(cameras, point_);
595  }
596 
598  Vector reprojectionError(const Values& values) const {
599  Cameras myCameras;
600  bool nonDegenerate = computeCamerasAndTriangulate(values, myCameras);
601  if (nonDegenerate)
602  return reprojectionError(myCameras);
603  else
604  return zero(myCameras.size() * 2);
605  }
606 
613  double totalReprojectionError(const Cameras& cameras,
614  boost::optional<Point3> externalPoint = boost::none) const {
615 
616  size_t nrCameras;
617  if (externalPoint) {
618  nrCameras = this->keys_.size();
619  point_ = *externalPoint;
620  degenerate_ = false;
621  cheiralityException_ = false;
622  } else {
623  nrCameras = this->triangulateSafe(cameras);
624  }
625 
626  if (nrCameras < 2
627  || (!this->manageDegeneracy_
628  && (this->cheiralityException_ || this->degenerate_))) {
629  // if we don't want to manage the exceptions we discard the factor
630  // std::cout << "In error evaluation: exception" << std::endl;
631  return 0.0;
632  }
633 
634  if (this->cheiralityException_) { // if we want to manage the exceptions with rotation-only factors
635  std::cout
636  << "SmartProjectionHessianFactor: cheirality exception (this should not happen if CheiralityException is disabled)!"
637  << std::endl;
638  this->degenerate_ = true;
639  }
640 
641  if (this->degenerate_) {
642  // return 0.0; // TODO: this maybe should be zero?
643  std::cout
644  << "SmartProjectionHessianFactor: trying to manage degeneracy (this should not happen is manageDegeneracy is disabled)!"
645  << std::endl;
646  size_t i = 0;
647  double overallError = 0;
648  BOOST_FOREACH(const Camera& camera, cameras) {
649  const Point2& zi = this->measured_.at(i);
650  if (i == 0) // first pose
651  this->point_ = camera.backprojectPointAtInfinity(zi); // 3D parametrization of point at infinity
653  camera.projectPointAtInfinity(this->point_) - zi);
654  overallError += 0.5
655  * this->noise_.at(i)->distance(reprojectionError.vector());
656  i += 1;
657  }
658  return overallError;
659  } else {
660  // Just use version in base class
661  return Base::totalReprojectionError(cameras, point_);
662  }
663  }
664 
666  virtual Cameras cameras(const Values& values) const = 0;
667 
669  boost::optional<Point3> point() const {
670  return point_;
671  }
672 
674  boost::optional<Point3> point(const Values& values) const {
675  triangulateSafe(values);
676  return point_;
677  }
678 
680  inline bool isDegenerate() const {
681  return (cheiralityException_ || degenerate_);
682  }
683 
685  inline bool isPointBehindCamera() const {
686  return cheiralityException_;
687  }
689  inline bool verboseCheirality() const {
690  return verboseCheirality_;
691  }
692 
694  inline bool throwCheirality() const {
695  return throwCheirality_;
696  }
697 
698 private:
699 
701  friend class boost::serialization::access;
702  template<class ARCHIVE>
703  void serialize(ARCHIVE & ar, const unsigned int version) {
704  ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
705  ar & BOOST_SERIALIZATION_NVP(throwCheirality_);
706  ar & BOOST_SERIALIZATION_NVP(verboseCheirality_);
707  }
708 };
709 
710 } // \ namespace gtsam
const double rankTolerance_
threshold to decide whether triangulation is degenerate_
Definition: SmartProjectionFactor.h:69
void computeEP(Matrix &E, Matrix &PointCov, const Cameras &cameras, const Point3 &point) const
Assumes non-degenerate !
Definition: SmartFactorBase.h:235
bool decideIfTriangulate(const Cameras &cameras) const
Check if the new linearization point_ is the same as the one used for previous triangulation.
Definition: SmartProjectionFactor.h:158
boost::shared_ptr< RegularHessianFactor< D > > createHessianFactor(const Cameras &cameras, const double lambda=0.0) const
linearize returns a Hessianfactor that is an approximation of error(p)
Definition: SmartProjectionFactor.h:316
const double retriangulationThreshold_
threshold to decide whether to re-triangulate
Definition: SmartProjectionFactor.h:70
bool triangulateForLinearize(const Cameras &cameras) const
triangulate
Definition: SmartProjectionFactor.h:292
bool throwCheirality() const
return flag for throwing cheirality exceptions
Definition: SmartProjectionFactor.h:694
double computeJacobiansSVD(std::vector< KeyMatrix2D > &Fblocks, Matrix &Enull, Vector &b, const Cameras &cameras, const Point3 &point, double lambda=0.0, bool diagonalDamping=false) const
SVD version.
Definition: SmartFactorBase.h:342
void insert(Key j, const Value &val)
Add a variable with the given j, throws KeyAlreadyExists<J> if j is already present.
Definition: Values.cpp:127
SmartProjectionFactor: triangulates point TODO: why LANDMARK parameter?
Definition: SmartProjectionFactor.h:65
boost::shared_ptr< JacobianFactorQ< D > > createJacobianQFactor(const Values &values, double lambda) const
Create a factor, takes values.
Definition: SmartProjectionFactor.h:430
PinholeCamera< CALIBRATION > Camera
shorthand for a pinhole camera
Definition: SmartProjectionFactor.h:113
const double linearizationThreshold_
threshold to decide whether to re-linearize
Definition: SmartProjectionFactor.h:77
Matrix eye(size_t m, size_t n)
Creates an identity matrix, with matlab-like syntax.
Definition: Matrix.cpp:50
std::vector< Pose3 > cameraPosesLinearization_
current linearization poses
Definition: SmartProjectionFactor.h:78
const Point3 & translation() const
get translation
Definition: Pose3.h:264
Point3 backprojectPointAtInfinity(const Point2 &p) const
backproject a 2-dimensional point to a 3-dimensional point at infinity
Definition: PinholeCamera.h:417
Definition: Point2.h:35
FastVector< Key > keys_
The keys involved in this factor.
Definition: Factor.h:69
double computeJacobians(std::vector< typename Base::KeyMatrix2D > &Fblocks, Matrix &E, Matrix &PointCov, Vector &b, const Cameras &cameras, const double lambda=0.0) const
Version that computes PointCov, with optional lambda parameter.
Definition: SmartProjectionFactor.h:550
Exception thrown by triangulateDLT when SVD returns rank < 3.
Definition: triangulation.h:32
double distance(const Point3 &p2) const
distance between two points
Definition: Point3.h:167
bool computeJacobians(std::vector< typename Base::KeyMatrix2D > &Fblocks, Matrix &E, Matrix &PointCov, Vector &b, const Values &values) const
Version that takes values, and creates the point.
Definition: SmartProjectionFactor.h:495
Point2 project(const Point3 &pw, boost::optional< Matrix & > Dpose=boost::none, boost::optional< Matrix & > Dpoint=boost::none, boost::optional< Matrix & > Dcal=boost::none) const
project a point from world coordinate to the image
Definition: PinholeCamera.h:299
std::vector< Pose3 > cameraPosesTriangulation_
current triangulation poses
Definition: SmartProjectionFactor.h:71
Definition: Pose3.h:42
This is the base class for all factor types.
Definition: Factor.h:51
const bool enableEPI_
if set to true, will refine triangulation using LM
Definition: SmartProjectionFactor.h:75
std::vector< Point2 > measured_
2D measurement for each of the m views
Definition: SmartFactorBase.h:44
bool decideIfLinearize(const Cameras &cameras) const
This function checks if the new linearization point_ is 'close' to the previous one used for lineariz...
Definition: SmartProjectionFactor.h:194
Point3 point_
Current estimate of the 3D point.
Definition: SmartProjectionFactor.h:80
Vector reprojectionError(const Cameras &cameras) const
Calculate vector of re-projection errors, before applying noise model Assumes triangulation was done ...
Definition: SmartProjectionFactor.h:593
A non-templated config holding any types of Manifold-group elements.
Definition: Values.h:75
bool zero(const Vector &v)
check if all zero
Definition: Vector.cpp:39
utility functions for loading datasets
bool computeEP(Matrix &E, Matrix &PointCov, const Values &values) const
Takes values.
Definition: SmartProjectionFactor.h:481
SmartProjectionFactor(const double rankTol, const double linThreshold, const bool manageDegeneracy, const bool enableEPI, boost::optional< POSE > body_P_sensor=boost::none, double landmarkDistanceThreshold=1e10, double dynamicOutlierRejectionThreshold=-1, SmartFactorStatePtr state=SmartFactorStatePtr(new SmartProjectionFactorState()))
Constructor.
Definition: SmartProjectionFactor.h:125
void subInsert(Vector &fullVector, const Vector &subVector, size_t i)
Inserts a subvector into a vector IN PLACE.
Definition: Vector.cpp:180
bool isDegenerate() const
return the degenerate state
Definition: SmartProjectionFactor.h:680
Definition: PinholeCamera.h:40
boost::optional< Point3 > point(const Values &values) const
COMPUTE the landmark.
Definition: SmartProjectionFactor.h:674
Functions for triangulation.
double totalReprojectionError(const Cameras &cameras, boost::optional< Point3 > externalPoint=boost::none) const
Calculate the error of the factor.
Definition: SmartProjectionFactor.h:613
bool equals(const Pose3 &pose, double tol=1e-9) const
assert equality up to a tolerance
Definition: Pose3.cpp:124
Base class with no internal point, completely functional.
Definition: SmartFactorBase.h:40
size_t triangulateSafe(const Values &values) const
triangulateSafe
Definition: SmartProjectionFactor.h:228
const ValueType & at(Key j) const
Retrieve a variable by key j.
Definition: Values-inl.h:219
Definition: CalibratedCamera.h:27
bool isPointBehindCamera() const
return the cheirality status flag
Definition: SmartProjectionFactor.h:685
void computeEP(Matrix &E, Matrix &PointCov, const Cameras &cameras) const
Assumes non-degenerate !
Definition: SmartProjectionFactor.h:490
std::vector< SharedNoiseModel > noise_
noise model used
Definition: SmartFactorBase.h:45
virtual ~SmartProjectionFactor()
Virtual destructor.
Definition: SmartProjectionFactor.h:140
size_t Key
Integer nonlinear key type.
Definition: types.h:59
double computeJacobiansSVD(std::vector< typename Base::KeyMatrix2D > &Fblocks, Matrix &Enull, Vector &b, const Cameras &cameras) const
SVD version.
Definition: SmartProjectionFactor.h:573
bool computeJacobiansSVD(std::vector< typename Base::KeyMatrix2D > &Fblocks, Matrix &Enull, Vector &b, const Values &values) const
takes values
Definition: SmartProjectionFactor.h:563
boost::shared_ptr< SmartProjectionFactorState > SmartFactorStatePtr
shorthand for smart projection factor state variable
Definition: SmartProjectionFactor.h:92
ptrdiff_t DenseIndex
The index type for Eigen objects.
Definition: types.h:74
Point2 projectPointAtInfinity(const Point3 &pw, boost::optional< Matrix & > Dpose=boost::none, boost::optional< Matrix & > Dpoint=boost::none, boost::optional< Matrix & > Dcal=boost::none) const
project a point at infinity from world coordinate to the image
Definition: PinholeCamera.h:338
const bool verboseCheirality_
If true, prints text for Cheirality exceptions (default: false)
Definition: SmartProjectionFactor.h:87
3D Pose
bool verboseCheirality() const
return chirality verbosity
Definition: SmartProjectionFactor.h:689
Pose3 between(const Pose3 &p2, boost::optional< Matrix & > H1=boost::none, boost::optional< Matrix & > H2=boost::none) const
Return relative pose between p1 and p2, in p1 coordinate frame as well as optionally the derivatives...
Definition: Pose3.cpp:291
double computeJacobians(Matrix &F, Matrix &E, Matrix3 &PointCov, Vector &b, const Cameras &cameras, const double lambda) const
Returns Matrix, TODO: maybe should not exist -> not sparse !
Definition: SmartProjectionFactor.h:586
void print(const std::string &s="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const
print
Definition: SmartFactorBase.h:153
Vector reprojectionError(const Values &values) const
Calculate vector of re-projection errors, before applying noise model.
Definition: SmartProjectionFactor.h:598
const bool manageDegeneracy_
if set to true will use the rotation-only version for degenerate cases
Definition: SmartProjectionFactor.h:73
void print(const std::string &s="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const
print
Definition: SmartProjectionFactor.h:148
Definition: SmartProjectionFactor.h:39
double totalReprojectionError(const Cameras &cameras, const Point3 &point) const
Calculate the error of the factor.
Definition: SmartFactorBase.h:212
Exception thrown by triangulateDLT when landmark is behind one or more of the cameras.
Definition: triangulation.h:40
Vector reprojectionError(const Cameras &cameras, const Point3 &point) const
Calculate vector of re-projection errors, before applying noise model.
Definition: SmartFactorBase.h:183
boost::optional< Point3 > point() const
return the landmark
Definition: SmartProjectionFactor.h:669
double computeJacobians(std::vector< KeyMatrix2D > &Fblocks, Matrix &E, Vector &b, const Cameras &cameras, const Point3 &point) const
Compute F, E only (called below in both vanilla and SVD versions) Given a Point3, assumes dimensional...
Definition: SmartFactorBase.h:261
boost::shared_ptr< JacobianFactorQ< D > > createJacobianQFactor(const Cameras &cameras, double lambda) const
create factor
Definition: SmartProjectionFactor.h:421
SmartFactorBase< POSE, CALIBRATION, D > Base
shorthand for base class type
Definition: SmartProjectionFactor.h:95
size_t triangulateSafe(const Cameras &cameras) const
triangulateSafe
Definition: SmartProjectionFactor.h:233
const bool throwCheirality_
If true, rethrows Cheirality exceptions (default: false)
Definition: SmartProjectionFactor.h:86
boost::shared_ptr< This > shared_ptr
shorthand for a smart pointer to a factor
Definition: SmartProjectionFactor.h:110
Pose3 & pose()
return pose
Definition: PinholeCamera.h:149
double computeJacobians(std::vector< typename Base::KeyMatrix2D > &Fblocks, Matrix &E, Vector &b, const Cameras &cameras) const
Compute F, E only (called below in both vanilla and SVD versions) Assumes the point has been computed...
Definition: SmartProjectionFactor.h:507
Definition: Point3.h:39
boost::shared_ptr< JacobianFactor > createJacobianSVDFactor(const Cameras &cameras, double lambda) const
different (faster) way to compute Jacobian factor
Definition: SmartProjectionFactor.h:442
Matrix zeros(size_t m, size_t n)
Creates an zeros matrix, with matlab-like syntax.
Definition: Matrix.cpp:40
bool computeCamerasAndTriangulate(const Values &values, Cameras &myCameras) const
Returns true if nonDegenerate.
Definition: SmartProjectionFactor.h:451
boost::function< std::string(Key)> KeyFormatter
Typedef for a function to format a key, i.e. to convert it to a string.
Definition: types.h:62
double computeJacobiansSVD(Matrix &F, Matrix &Enull, Vector &b, const Cameras &cameras) const
Returns Matrix, TODO: maybe should not exist -> not sparse !
Definition: SmartProjectionFactor.h:580
Base class to create smart factors on poses or cameras.
SmartProjectionFactor< POSE, LANDMARK, CALIBRATION, D > This
shorthand for this class
Definition: SmartProjectionFactor.h:105
virtual Cameras cameras(const Values &values) const =0
Cameras are computed in derived class.