| 
									
										
										
										
											2012-08-03 03:27:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * @file InvDepthFactor3.h | 
					
						
							| 
									
										
										
										
											2012-11-30 02:19:28 +08:00
										 |  |  |  * @brief Inverse Depth Factor based on Civera09tro, Montiel06rss. | 
					
						
							|  |  |  |  * Landmarks are initialized from the first camera observation with | 
					
						
							|  |  |  |  * (x,y,z,theta,phi,inv_depth), where x,y,z are the coordinates of | 
					
						
							|  |  |  |  * the camera. InvDepthCamera provides methods to initialize inverse | 
					
						
							|  |  |  |  * depth landmarks (backproject), and to convert inverse depth | 
					
						
							|  |  |  |  * landmarks to cartesian coordinates (Point3) for visualization, etc. | 
					
						
							|  |  |  |  * The inverse depth parameterization is split into (x,y,z,theta,phi), | 
					
						
							|  |  |  |  * (inv_depth) to make it easy to add a prior on inverse depth alone | 
					
						
							| 
									
										
										
										
											2012-08-03 03:27:36 +08:00
										 |  |  |  * @author Chris Beall | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <gtsam/geometry/Cal3_S2.h>
 | 
					
						
							|  |  |  | #include <gtsam/nonlinear/NonlinearFactor.h>
 | 
					
						
							| 
									
										
										
										
											2012-08-03 04:47:16 +08:00
										 |  |  | #include <gtsam_unstable/geometry/InvDepthCamera3.h>
 | 
					
						
							| 
									
										
										
										
											2012-08-03 03:27:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace gtsam { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-03 04:47:16 +08:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Ternary factor representing a visual measurement that includes inverse depth | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | template<class POSE, class LANDMARK, class INVDEPTH> | 
					
						
							| 
									
										
										
										
											2016-06-06 15:37:49 +08:00
										 |  |  | class InvDepthFactor3: public NoiseModelFactor3<POSE, LANDMARK, INVDEPTH> { | 
					
						
							| 
									
										
										
										
											2012-08-03 04:47:16 +08:00
										 |  |  | protected: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   // Keep a copy of measurement and calibration for I/O
 | 
					
						
							| 
									
										
										
										
											2016-06-06 15:37:49 +08:00
										 |  |  |   Point2 measured_;                ///< 2D measurement
 | 
					
						
							|  |  |  |   boost::shared_ptr<Cal3_S2> K_;  ///< shared pointer to calibration object
 | 
					
						
							| 
									
										
										
										
											2012-08-03 04:47:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   /// shorthand for base class type
 | 
					
						
							| 
									
										
										
										
											2016-06-06 15:37:49 +08:00
										 |  |  |   typedef NoiseModelFactor3<POSE, LANDMARK, INVDEPTH> Base; | 
					
						
							| 
									
										
										
										
											2012-08-03 04:47:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   /// shorthand for this class
 | 
					
						
							|  |  |  |   typedef InvDepthFactor3<POSE, LANDMARK, INVDEPTH> This; | 
					
						
							| 
									
										
										
										
											2012-08-03 04:47:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   /// shorthand for a smart pointer to a factor
 | 
					
						
							|  |  |  |   typedef boost::shared_ptr<This> shared_ptr; | 
					
						
							| 
									
										
										
										
											2012-08-03 04:47:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   /// Default constructor
 | 
					
						
							| 
									
										
										
										
											2016-06-06 15:37:49 +08:00
										 |  |  |   InvDepthFactor3() : | 
					
						
							|  |  |  |       measured_(0.0, 0.0), K_(new Cal3_S2(444, 555, 666, 777, 888)) { | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-08-03 04:47:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * Constructor | 
					
						
							|  |  |  |    * TODO: Mark argument order standard (keys, measurement, parameters) | 
					
						
							|  |  |  |    * @param measured is the 2 dimensional location of point in image (the measurement) | 
					
						
							|  |  |  |    * @param model is the standard deviation | 
					
						
							|  |  |  |    * @param poseKey is the index of the camera pose | 
					
						
							|  |  |  |    * @param pointKey is the index of the landmark | 
					
						
							| 
									
										
										
										
											2012-09-08 02:54:12 +08:00
										 |  |  |    * @param invDepthKey is the index of inverse depth | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |    * @param K shared pointer to the constant calibration | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2016-06-06 15:37:49 +08:00
										 |  |  |   InvDepthFactor3(const Point2& measured, const SharedNoiseModel& model, | 
					
						
							|  |  |  |       const Key poseKey, Key pointKey, Key invDepthKey, const Cal3_S2::shared_ptr& K) : | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |         Base(model, poseKey, pointKey, invDepthKey), measured_(measured), K_(K) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** Virtual destructor */ | 
					
						
							|  |  |  |   virtual ~InvDepthFactor3() {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * print | 
					
						
							|  |  |  |    * @param s optional string naming the factor | 
					
						
							|  |  |  |    * @param keyFormatter optional formatter useful for printing Symbols | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   void print(const std::string& s = "InvDepthFactor3", | 
					
						
							| 
									
										
										
										
											2016-06-06 15:37:49 +08:00
										 |  |  |       const KeyFormatter& keyFormatter = DefaultKeyFormatter) const { | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |     Base::print(s, keyFormatter); | 
					
						
							| 
									
										
										
										
											2016-06-07 12:57:52 +08:00
										 |  |  |     traits<Point2>::Print(measured_, s + ".z"); | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// equals
 | 
					
						
							| 
									
										
										
										
											2016-06-06 15:37:49 +08:00
										 |  |  |   virtual bool equals(const NonlinearFactor& p, double tol = 1e-9) const { | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |     const This *e = dynamic_cast<const This*>(&p); | 
					
						
							| 
									
										
										
										
											2016-06-07 12:57:52 +08:00
										 |  |  |     return e && Base::equals(p, tol) && traits<Point2>::Equals(this->measured_, e->measured_, tol) && this->K_->equals(*e->K_, tol); | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Evaluate error h(x)-z and optionally derivatives
 | 
					
						
							| 
									
										
										
										
											2016-06-06 15:37:49 +08:00
										 |  |  |   Vector evaluateError(const POSE& pose, const Vector5& point, const INVDEPTH& invDepth, | 
					
						
							|  |  |  |       boost::optional<Matrix&> H1=boost::none, | 
					
						
							|  |  |  |       boost::optional<Matrix&> H2=boost::none, | 
					
						
							|  |  |  |       boost::optional<Matrix&> H3=boost::none) const { | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |     try { | 
					
						
							| 
									
										
										
										
											2016-06-06 15:37:49 +08:00
										 |  |  |       InvDepthCamera3<Cal3_S2> camera(pose, K_); | 
					
						
							|  |  |  |       return camera.project(point, invDepth, H1, H2, H3) - measured_; | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |     } catch( CheiralityException& e) { | 
					
						
							| 
									
										
										
										
											2016-04-12 03:11:29 +08:00
										 |  |  |       if (H1) *H1 = Matrix::Zero(2,6); | 
					
						
							|  |  |  |       if (H2) *H2 = Matrix::Zero(2,5); | 
					
						
							|  |  |  |       if (H3) *H2 = Matrix::Zero(2,1); | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |       std::cout << e.what() << ": Landmark "<< DefaultKeyFormatter(this->key2()) << | 
					
						
							|  |  |  |           " moved behind camera " << DefaultKeyFormatter(this->key1()) << std::endl; | 
					
						
							| 
									
										
										
										
											2016-06-06 15:37:49 +08:00
										 |  |  |       return Vector::Ones(2) * 2.0 * K_->fx(); | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-06-06 15:37:49 +08:00
										 |  |  |     return (Vector(1) << 0.0).finished(); | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** return the measurement */ | 
					
						
							| 
									
										
										
										
											2016-06-06 15:37:49 +08:00
										 |  |  |   const Point2& imagePoint() const { | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |     return measured_; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** return the calibration object */ | 
					
						
							| 
									
										
										
										
											2016-06-06 15:37:49 +08:00
										 |  |  |   inline const Cal3_S2::shared_ptr calibration() const { | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |     return K_; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-08-03 04:47:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   /// Serialization function
 | 
					
						
							|  |  |  |   friend class boost::serialization::access; | 
					
						
							|  |  |  |   template<class ARCHIVE> | 
					
						
							| 
									
										
										
										
											2015-03-06 23:12:09 +08:00
										 |  |  |   void serialize(ARCHIVE & ar, const unsigned int /*version*/) { | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |     ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base); | 
					
						
							|  |  |  |     ar & BOOST_SERIALIZATION_NVP(measured_); | 
					
						
							|  |  |  |     ar & BOOST_SERIALIZATION_NVP(K_); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-08-03 04:47:16 +08:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2012-08-03 03:27:36 +08:00
										 |  |  | } // \ namespace gtsam
 |