| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * @file    NonlinearFactor.h | 
					
						
							|  |  |  |  * @brief   Non-linear factor class | 
					
						
							|  |  |  |  * @author  Kai Ni | 
					
						
							|  |  |  |  * @author  Carlos Nieto | 
					
						
							|  |  |  |  * @author  Christian Potthast | 
					
						
							|  |  |  |  * @author  Frank Dellaert | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // \callgraph
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <list>
 | 
					
						
							| 
									
										
										
										
											2009-12-31 18:28:43 +08:00
										 |  |  | #include <limits>
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <boost/shared_ptr.hpp>
 | 
					
						
							| 
									
										
										
										
											2009-10-19 01:35:15 +08:00
										 |  |  | #include <boost/serialization/list.hpp>
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "Factor.h"
 | 
					
						
							| 
									
										
										
										
											2009-10-23 01:23:24 +08:00
										 |  |  | #include "Vector.h"
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | #include "Matrix.h"
 | 
					
						
							| 
									
										
										
										
											2009-11-13 00:16:32 +08:00
										 |  |  | #include "GaussianFactor.h"
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Base Class | 
					
						
							|  |  |  |  * Just has the measurement and noise model | 
					
						
							|  |  |  |  */  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace gtsam { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-13 00:16:32 +08:00
										 |  |  | 	// forward declaration of GaussianFactor
 | 
					
						
							|  |  |  | 	//class GaussianFactor;
 | 
					
						
							|  |  |  | 	//typedef boost::shared_ptr<GaussianFactor> shared_ptr;
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							| 
									
										
										
										
											2009-08-31 12:13:57 +08:00
										 |  |  |    * Nonlinear factor which assumes Gaussian noise on a measurement | 
					
						
							|  |  |  |    * predicted by a non-linear function h. | 
					
						
							| 
									
										
										
										
											2009-10-07 02:25:04 +08:00
										 |  |  |    *  | 
					
						
							|  |  |  |    * Templated on a configuration type. The configurations are typically more general | 
					
						
							|  |  |  | 	 * than just vectors, e.g., Rot3 or Pose3, which are objects in non-linear manifolds. | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2009-10-07 02:25:04 +08:00
										 |  |  | 	template <class Config> | 
					
						
							|  |  |  |   class NonlinearFactor : public Factor<Config> | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |   { | 
					
						
							|  |  |  |   protected: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Vector z_;     // measurement
 | 
					
						
							|  |  |  |     double sigma_; // noise standard deviation
 | 
					
						
							|  |  |  |     std::list<std::string> keys_; // keys
 | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  |   public: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-31 10:40:26 +08:00
										 |  |  |     /** Default constructor, with easily identifiable bogus values */ | 
					
						
							|  |  |  |     NonlinearFactor():z_(Vector_(2,888.0,999.0)),sigma_(0.1234567) {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-07 02:25:04 +08:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      *  Constructor | 
					
						
							|  |  |  |      *  @param z the measurement | 
					
						
							|  |  |  |      *  @param sigma the standard deviation | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     NonlinearFactor(const Vector& z, const double sigma) { | 
					
						
							|  |  |  |     	z_ = z; | 
					
						
							|  |  |  |     	sigma_ = sigma; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-23 01:23:24 +08:00
										 |  |  |     /** print */ | 
					
						
							|  |  |  |     void print(const std::string& s = "") const { | 
					
						
							| 
									
										
										
										
											2009-11-13 00:47:12 +08:00
										 |  |  |     	std::cout << "NonlinearFactor " << s << std::endl; | 
					
						
							| 
									
										
										
										
											2009-10-23 01:23:24 +08:00
										 |  |  |     	gtsam::print(z_, "  z = "); | 
					
						
							|  |  |  |     	std::cout << "  sigma = " << sigma_ << std::endl; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** Check if two NonlinearFactor objects are equal */ | 
					
						
							| 
									
										
										
										
											2009-10-25 04:01:47 +08:00
										 |  |  |     bool equals(const Factor<Config>& f, double tol=1e-9) const { | 
					
						
							| 
									
										
										
										
											2009-10-23 01:23:24 +08:00
										 |  |  |     	const NonlinearFactor<Config>* p = dynamic_cast<const NonlinearFactor<Config>*> (&f); | 
					
						
							|  |  |  |     	if (p == NULL) return false; | 
					
						
							|  |  |  |       return equal_with_abs_tol(z_,p->z_,tol) && fabs(sigma_ - p->sigma_)<=tol; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |     /** Vector of errors */ | 
					
						
							| 
									
										
										
										
											2009-10-07 02:25:04 +08:00
										 |  |  |     virtual Vector error_vector(const Config& c) const = 0; | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-13 00:16:32 +08:00
										 |  |  |     /** linearize to a GaussianFactor */ | 
					
						
							|  |  |  |     virtual boost::shared_ptr<GaussianFactor> linearize(const Config& c) const = 0; | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** get functions */ | 
					
						
							| 
									
										
										
										
											2009-09-13 12:13:03 +08:00
										 |  |  |     double sigma() const {return sigma_;} | 
					
						
							|  |  |  |     Vector measurement() const {return z_;} | 
					
						
							|  |  |  |     std::list<std::string> keys() const {return keys_;} | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** calculate the error of the factor */ | 
					
						
							| 
									
										
										
										
											2009-10-07 02:25:04 +08:00
										 |  |  |     double error(const Config& c) const { | 
					
						
							| 
									
										
										
										
											2009-12-31 18:28:43 +08:00
										 |  |  |     	if (sigma_==0.0) { | 
					
						
							|  |  |  |         Vector e = error_vector(c); | 
					
						
							|  |  |  |     		return (inner_prod(e,e)>0) ? std::numeric_limits<double>::infinity() : 0.0; | 
					
						
							|  |  |  |     	} | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |       Vector e = error_vector(c) / sigma_; | 
					
						
							| 
									
										
										
										
											2009-12-18 13:14:34 +08:00
										 |  |  |       return 0.5 * inner_prod(e,e); | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |     }; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  |     /** get the size of the factor */ | 
					
						
							|  |  |  |     std::size_t size() const{return keys_.size();} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-31 12:13:57 +08:00
										 |  |  |   private: | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-31 12:13:57 +08:00
										 |  |  | 		/** Serialization function */ | 
					
						
							|  |  |  | 		friend class boost::serialization::access; | 
					
						
							|  |  |  | 		template<class Archive> | 
					
						
							|  |  |  | 		void serialize(Archive & ar, const unsigned int version) { | 
					
						
							|  |  |  | 			ar & BOOST_SERIALIZATION_NVP(z_); | 
					
						
							|  |  |  | 			ar & BOOST_SERIALIZATION_NVP(sigma_); | 
					
						
							|  |  |  | 			ar & BOOST_SERIALIZATION_NVP(keys_); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-31 12:13:57 +08:00
										 |  |  |   }; // NonlinearFactor
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * a Gaussian nonlinear factor that takes 1 parameter | 
					
						
							|  |  |  |    * Note: cannot be serialized as contains function pointers | 
					
						
							|  |  |  |    * Specialized derived classes could do this | 
					
						
							|  |  |  |   */ | 
					
						
							| 
									
										
										
										
											2009-10-15 04:39:59 +08:00
										 |  |  |   class NonlinearFactor1 : public NonlinearFactor<VectorConfig> { | 
					
						
							| 
									
										
										
										
											2009-09-13 12:13:03 +08:00
										 |  |  |   private: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-25 04:01:47 +08:00
										 |  |  | 		std::string key_; | 
					
						
							| 
									
										
										
										
											2009-09-13 12:13:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |   public: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-13 12:13:03 +08:00
										 |  |  | 		Vector (*h_)(const Vector&); | 
					
						
							|  |  |  | 		Matrix (*H_)(const Vector&); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |     /** Constructor */ | 
					
						
							|  |  |  |     NonlinearFactor1(const Vector& z,		  // measurement
 | 
					
						
							|  |  |  | 		     const double sigma,	  // variance
 | 
					
						
							|  |  |  | 		     Vector (*h)(const Vector&),  // measurement function
 | 
					
						
							|  |  |  | 		     const std::string& key1,     // key of the variable
 | 
					
						
							|  |  |  | 		     Matrix (*H)(const Vector&)); // derivative of the measurement function
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void print(const std::string& s = "") const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-23 01:23:24 +08:00
										 |  |  |     /** Check if two factors are equal */ | 
					
						
							|  |  |  |     bool equals(const Factor<VectorConfig>& f, double tol=1e-9) const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |     /** error function */ | 
					
						
							| 
									
										
										
										
											2009-10-15 04:39:59 +08:00
										 |  |  |     inline Vector error_vector(const VectorConfig& c) const { | 
					
						
							| 
									
										
										
										
											2009-10-25 04:01:47 +08:00
										 |  |  |       return z_ - h_(c[key_]); | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** linearize a non-linearFactor1 to get a linearFactor1 */ | 
					
						
							| 
									
										
										
										
											2009-11-13 00:16:32 +08:00
										 |  |  |     boost::shared_ptr<GaussianFactor> linearize(const VectorConfig& c) const; | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-31 12:13:57 +08:00
										 |  |  | 	/**
 | 
					
						
							|  |  |  | 	 * a Gaussian nonlinear factor that takes 2 parameters | 
					
						
							|  |  |  | 	 * Note: cannot be serialized as contains function pointers | 
					
						
							|  |  |  | 	 * Specialized derived classes could do this | 
					
						
							|  |  |  | 	*/ | 
					
						
							| 
									
										
										
										
											2009-10-15 04:39:59 +08:00
										 |  |  |   class NonlinearFactor2 : public NonlinearFactor<VectorConfig> { | 
					
						
							| 
									
										
										
										
											2009-09-13 12:13:03 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   private: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     std::string key1_; | 
					
						
							|  |  |  |     std::string key2_; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |   public: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-13 12:13:03 +08:00
										 |  |  |   	Vector (*h_)(const Vector&, const Vector&); | 
					
						
							|  |  |  |     Matrix (*H1_)(const Vector&, const Vector&); | 
					
						
							|  |  |  |     Matrix (*H2_)(const Vector&, const Vector&); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |     /** Constructor */ | 
					
						
							| 
									
										
										
										
											2009-10-25 04:01:47 +08:00
										 |  |  |     NonlinearFactor2(const Vector& z,	               // the measurement
 | 
					
						
							|  |  |  | 		     const double sigma,	                       // the variance
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 		     Vector (*h)(const Vector&, const Vector&),  // the measurement function
 | 
					
						
							|  |  |  | 		     const std::string& key1,                    // key of the first variable
 | 
					
						
							|  |  |  | 		     Matrix (*H1)(const Vector&, const Vector&), // derivative of h in first variable
 | 
					
						
							|  |  |  | 		     const std::string& key2,                    // key of the second variable
 | 
					
						
							|  |  |  | 		     Matrix (*H2)(const Vector&, const Vector&));// derivative of h in second variable
 | 
					
						
							|  |  |  | 			 | 
					
						
							| 
									
										
										
										
											2009-10-23 01:23:24 +08:00
										 |  |  |     /** Print */ | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |     void print(const std::string& s = "") const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-23 01:23:24 +08:00
										 |  |  |     /** Check if two factors are equal */ | 
					
						
							|  |  |  |     bool equals(const Factor<VectorConfig>& f, double tol=1e-9) const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |     /** error function */ | 
					
						
							| 
									
										
										
										
											2009-10-15 04:39:59 +08:00
										 |  |  |     inline Vector error_vector(const VectorConfig& c) const { | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |       return z_ - h_(c[key1_], c[key2_]);  | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** Linearize a non-linearFactor2 to get a linearFactor2 */ | 
					
						
							| 
									
										
										
										
											2009-11-13 00:16:32 +08:00
										 |  |  |     boost::shared_ptr<GaussianFactor> linearize(const VectorConfig& c) const; | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  | } |