Selective relinearization
							parent
							
								
									9f68c04792
								
							
						
					
					
						commit
						73e72a98bd
					
				| 
						 | 
					@ -264,7 +264,7 @@ int main(int argc, char** argv) {
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (useSmartProjectionFactor) {
 | 
					      if (useSmartProjectionFactor) {
 | 
				
			||||||
        SmartFactor::shared_ptr smartFactor(new SmartFactor(measurements, pixel_sigma, views, K));
 | 
					        SmartFactor::shared_ptr smartFactor(new SmartFactor(views, measurements, pixel_sigma, K));
 | 
				
			||||||
        graph.push_back(smartFactor);
 | 
					        graph.push_back(smartFactor);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -290,7 +290,7 @@ int main(int argc, char** argv) {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  // Add last measurements
 | 
					  // Add last measurements
 | 
				
			||||||
  if (useSmartProjectionFactor) {
 | 
					  if (useSmartProjectionFactor) {
 | 
				
			||||||
    SmartFactor::shared_ptr smartFactor(new SmartFactor(measurements, pixel_sigma, views, K));
 | 
					    SmartFactor::shared_ptr smartFactor(new SmartFactor(views, measurements, pixel_sigma, K));
 | 
				
			||||||
    graph.push_back(smartFactor);
 | 
					    graph.push_back(smartFactor);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -437,7 +437,7 @@ int main(int argc, char** argv) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // This is a new landmark, create a new factor and add to mapping
 | 
					        // This is a new landmark, create a new factor and add to mapping
 | 
				
			||||||
        boost::shared_ptr<SmartProjectionFactorState> smartFactorState(new SmartProjectionFactorState());
 | 
					        boost::shared_ptr<SmartProjectionFactorState> smartFactorState(new SmartProjectionFactorState());
 | 
				
			||||||
        SmartFactor::shared_ptr smartFactor(new SmartFactor(measurements, pixel_sigma, views, K));
 | 
					        SmartFactor::shared_ptr smartFactor(new SmartFactor(views, measurements, pixel_sigma,  K));
 | 
				
			||||||
        smartFactorStates.insert( make_pair(L(l), smartFactorState) );
 | 
					        smartFactorStates.insert( make_pair(L(l), smartFactorState) );
 | 
				
			||||||
        smartFactors.insert( make_pair(L(l), smartFactor) );
 | 
					        smartFactors.insert( make_pair(L(l), smartFactor) );
 | 
				
			||||||
        graph.push_back(smartFactor);
 | 
					        graph.push_back(smartFactor);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -59,28 +59,24 @@ namespace gtsam {
 | 
				
			||||||
    double overallError;
 | 
					    double overallError;
 | 
				
			||||||
    std::vector<Pose3> cameraPosesError;
 | 
					    std::vector<Pose3> cameraPosesError;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Hessian
 | 
					    // Hessian representation (after Schur complement)
 | 
				
			||||||
    bool calculatedHessian;
 | 
					    bool calculatedHessian;
 | 
				
			||||||
    Matrix H;
 | 
					    Matrix H;
 | 
				
			||||||
    Vector gs_vector;
 | 
					    Vector gs_vector;
 | 
				
			||||||
    double f;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    std::vector<Matrix> Gs;
 | 
					    std::vector<Matrix> Gs;
 | 
				
			||||||
    std::vector<Vector> gs;
 | 
					    std::vector<Vector> gs;
 | 
				
			||||||
 | 
					    double f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Jacobian representation (before Schur complement)
 | 
				
			||||||
    Matrix Hx;
 | 
					    Matrix Hx;
 | 
				
			||||||
    Matrix Hl;
 | 
					    Matrix Hl;
 | 
				
			||||||
    Vector b;
 | 
					    Vector b;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // C = Hl'Hl
 | 
					    // C = Hl'Hl
 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Cinv = inv(Hl'Hl)
 | 
					    // Cinv = inv(Hl'Hl)
 | 
				
			||||||
    // Matrix3 Cinv;
 | 
					    // Matrix3 Cinv;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    // E = Hx'Hl
 | 
					    // E = Hx'Hl
 | 
				
			||||||
 | 
					 | 
				
			||||||
    // w = Hl'b
 | 
					    // w = Hl'b
 | 
				
			||||||
 | 
					 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int SmartProjectionFactorState::lastID = 0;
 | 
					  int SmartProjectionFactorState::lastID = 0;
 | 
				
			||||||
| 
						 | 
					@ -105,6 +101,7 @@ namespace gtsam {
 | 
				
			||||||
    bool throwCheirality_; ///< If true, rethrows Cheirality exceptions (default: false)
 | 
					    bool throwCheirality_; ///< If true, rethrows Cheirality exceptions (default: false)
 | 
				
			||||||
    bool verboseCheirality_; ///< If true, prints text for Cheirality exceptions (default: false)
 | 
					    bool verboseCheirality_; ///< If true, prints text for Cheirality exceptions (default: false)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public:
 | 
					  public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// shorthand for base class type
 | 
					    /// shorthand for base class type
 | 
				
			||||||
| 
						 | 
					@ -124,15 +121,16 @@ namespace gtsam {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Constructor
 | 
					     * Constructor
 | 
				
			||||||
     * TODO: Mark argument order standard (keys, measurement, parameters)
 | 
					     * @param poseKeys is the set of indices corresponding to the cameras observing the same landmark
 | 
				
			||||||
     * @param measured is the 2m dimensional location of the projection of a single landmark in the m views (the measurements)
 | 
					     * @param measured is the 2m dimensional location of the projection of a single landmark in the m views (the measurements)
 | 
				
			||||||
     * @param model is the standard deviation (current version assumes that the uncertainty is the same for all views)
 | 
					     * @param model is the standard deviation (current version assumes that the uncertainty is the same for all views)
 | 
				
			||||||
     * @param poseKeys is the set of indices corresponding to the cameras observing the same landmark
 | 
					 | 
				
			||||||
     * @param K shared pointer to the constant calibration
 | 
					     * @param K shared pointer to the constant calibration
 | 
				
			||||||
     * @param body_P_sensor is the transform from body to sensor frame (default identity)
 | 
					     * @param body_P_sensor is the transform from body to sensor frame (default identity)
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    SmartProjectionFactor(const std::vector<Point2> measured, const SharedNoiseModel& model,
 | 
					    SmartProjectionFactor(std::vector<Key> poseKeys, // camera poses
 | 
				
			||||||
        std::vector<Key> poseKeys, const boost::shared_ptr<CALIBRATION>& K,
 | 
					        const std::vector<Point2> measured,          // pixel measurements
 | 
				
			||||||
 | 
					        const SharedNoiseModel& model,               // noise model (same for all measurements)
 | 
				
			||||||
 | 
					        const boost::shared_ptr<CALIBRATION>& K,     // calibration matrix (same for all measurements)
 | 
				
			||||||
        boost::optional<POSE> body_P_sensor = boost::none,
 | 
					        boost::optional<POSE> body_P_sensor = boost::none,
 | 
				
			||||||
        SmartFactorStatePtr state = SmartFactorStatePtr(new SmartProjectionFactorState())) :
 | 
					        SmartFactorStatePtr state = SmartFactorStatePtr(new SmartProjectionFactorState())) :
 | 
				
			||||||
          measured_(measured), noise_(model), K_(K), body_P_sensor_(body_P_sensor),
 | 
					          measured_(measured), noise_(model), K_(K), body_P_sensor_(body_P_sensor),
 | 
				
			||||||
| 
						 | 
					@ -151,14 +149,15 @@ namespace gtsam {
 | 
				
			||||||
     * @param verboseCheirality determines whether exceptions are printed for Cheirality
 | 
					     * @param verboseCheirality determines whether exceptions are printed for Cheirality
 | 
				
			||||||
     * @param body_P_sensor is the transform from body to sensor frame  (default identity)
 | 
					     * @param body_P_sensor is the transform from body to sensor frame  (default identity)
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    SmartProjectionFactor(const std::vector<Point2> measured, const SharedNoiseModel& model,
 | 
					    SmartProjectionFactor(std::vector<Key> poseKeys,
 | 
				
			||||||
        std::vector<Key> poseKeys, const boost::shared_ptr<CALIBRATION>& K,
 | 
					        const std::vector<Point2> measured,
 | 
				
			||||||
 | 
					        const SharedNoiseModel& model,
 | 
				
			||||||
 | 
					        const boost::shared_ptr<CALIBRATION>& K,
 | 
				
			||||||
        bool throwCheirality, bool verboseCheirality,
 | 
					        bool throwCheirality, bool verboseCheirality,
 | 
				
			||||||
        boost::optional<POSE> body_P_sensor = boost::none,
 | 
					        boost::optional<POSE> body_P_sensor = boost::none,
 | 
				
			||||||
        SmartFactorStatePtr state = SmartFactorStatePtr(new SmartProjectionFactorState())) :
 | 
					        SmartFactorStatePtr state = SmartFactorStatePtr(new SmartProjectionFactorState())) :
 | 
				
			||||||
          measured_(measured), noise_(model), K_(K), body_P_sensor_(body_P_sensor),
 | 
					          measured_(measured), noise_(model), K_(K), body_P_sensor_(body_P_sensor),
 | 
				
			||||||
          state_(state), throwCheirality_(throwCheirality), verboseCheirality_(verboseCheirality) {
 | 
					          state_(state), throwCheirality_(throwCheirality), verboseCheirality_(verboseCheirality) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
| 
						 | 
					@ -185,6 +184,83 @@ namespace gtsam {
 | 
				
			||||||
      keys_.push_back(poseKey);
 | 
					      keys_.push_back(poseKey);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // This function decides whether a new triangulation is needed
 | 
				
			||||||
 | 
					    inline bool decideIfTriangulate(std::vector<Pose3> cameraPoses, const Values& values) const {
 | 
				
			||||||
 | 
					      // several calls to linearize will be done from the same linearization point, hence it is not needed to re-triangulate
 | 
				
			||||||
 | 
					      // Note that this is not yet "selecting linearization", that will come later, and we only check if the
 | 
				
			||||||
 | 
					      // current linearization is the "same" (up to tolerance) w.r.t. the last time we triangulated the point
 | 
				
			||||||
 | 
					      bool retriangulate = true;
 | 
				
			||||||
 | 
					      bool valuesEqualRetriangulation = true;
 | 
				
			||||||
 | 
					      double retriangulationThreshold = 1e-9;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      int poseCount = 0;
 | 
				
			||||||
 | 
					      BOOST_FOREACH(const Key& k, keys_) {
 | 
				
			||||||
 | 
					        Pose3 cameraPose;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(body_P_sensor_)
 | 
				
			||||||
 | 
					          cameraPose = values.at<Pose3>(k).compose(*body_P_sensor_);
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					          cameraPose = values.at<Pose3>(k);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!state_->cameraPosesTriangulation.empty()) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          // TODO: are you sure that when using "add" the number of poses will be ok? (old linearization point will contain 1 pose less)
 | 
				
			||||||
 | 
					          if (!cameraPose.equals(state_->cameraPosesTriangulation[poseCount], retriangulationThreshold)) {
 | 
				
			||||||
 | 
					            valuesEqualRetriangulation = false;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          valuesEqualRetriangulation = false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cameraPoses.push_back(cameraPose);
 | 
				
			||||||
 | 
					        poseCount++;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (valuesEqualRetriangulation) {
 | 
				
			||||||
 | 
					        retriangulate = false;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return retriangulate;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // This function decides whether a new triangulation is needed
 | 
				
			||||||
 | 
					    //    bool decideIfLinearize(std::vector<Pose3> cameraPoses) const {
 | 
				
			||||||
 | 
					    //      // "selecting linearization"
 | 
				
			||||||
 | 
					    //      bool doLinearize = true;
 | 
				
			||||||
 | 
					    //      double linearizationThreshold = 1e-2;
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    //      Pose3 firstCameraPose;
 | 
				
			||||||
 | 
					    //      Pose3 firstCameraPoseOld;
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    //      for(size_t i = 0; i < cameraPoses.size(); i++) {
 | 
				
			||||||
 | 
					    //        Pose3 cameraPose = cameraPoses.at(i);
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    //        if (!state_->cameraPosesLinearization.empty()) { // if we have a previous linearization point
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    //          if(i==0){ // we store the initial pose, this is useful for selective re-linearization
 | 
				
			||||||
 | 
					    //            firstCameraPose = cameraPose;
 | 
				
			||||||
 | 
					    //            firstCameraPoseOld = state_->cameraPosesLinearization[i];
 | 
				
			||||||
 | 
					    //            continue;
 | 
				
			||||||
 | 
					    //          }
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    //          // we compare the poses in the frame of the first pose
 | 
				
			||||||
 | 
					    //          Pose3 localCameraPose = firstCameraPose.between(cameraPose);
 | 
				
			||||||
 | 
					    //          Pose3 localCameraPoseOld = firstCameraPoseOld.between(state_->cameraPosesLinearization[i]);
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    //          if (!localCameraPose.equals(localCameraPoseOld, linearizationThreshold)) {
 | 
				
			||||||
 | 
					    //            doLinearize = false;
 | 
				
			||||||
 | 
					    //          }
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    //        } else {
 | 
				
			||||||
 | 
					    //          doLinearize = false;
 | 
				
			||||||
 | 
					    //        }
 | 
				
			||||||
 | 
					    //      }
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    //      return doLinearize;
 | 
				
			||||||
 | 
					    //    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * print
 | 
					     * print
 | 
				
			||||||
     * @param s optional string naming the factor
 | 
					     * @param s optional string naming the factor
 | 
				
			||||||
| 
						 | 
					@ -226,25 +302,21 @@ namespace gtsam {
 | 
				
			||||||
    /// linearize returns a Hessianfactor that is an approximation of error(p)
 | 
					    /// linearize returns a Hessianfactor that is an approximation of error(p)
 | 
				
			||||||
    virtual boost::shared_ptr<GaussianFactor> linearize(const Values& values) const {
 | 
					    virtual boost::shared_ptr<GaussianFactor> linearize(const Values& values) const {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      bool blockwise = false;
 | 
					      bool blockwise = false;                  // the full matrix version in faster
 | 
				
			||||||
      double retriangulationThreshold = 1e-9;
 | 
					      int dim_landmark = 3;                    // for degenerate instances this will become 2 (direction-only information)
 | 
				
			||||||
 | 
					 | 
				
			||||||
      int dim_landmark = 3;
 | 
					 | 
				
			||||||
      bool retriangulate = true;
 | 
					 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
 | 
					      // Create structures for Hessian Factors
 | 
				
			||||||
      unsigned int numKeys = keys_.size();
 | 
					      unsigned int numKeys = keys_.size();
 | 
				
			||||||
      std::vector<Index> js;
 | 
					      std::vector<Index> js;
 | 
				
			||||||
      std::vector<Matrix> Gs(numKeys*(numKeys+1)/2);
 | 
					      std::vector<Matrix> Gs(numKeys*(numKeys+1)/2);
 | 
				
			||||||
      std::vector<Vector> gs(numKeys);
 | 
					      std::vector<Vector> gs(numKeys);
 | 
				
			||||||
      double f=0;
 | 
					      double f=0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      Vector changeLinPoses(numKeys*6);
 | 
					 | 
				
			||||||
      Point3 changeLinPoint;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // Collect all poses (Cameras)
 | 
					      // Collect all poses (Cameras)
 | 
				
			||||||
      bool valuesEqualRetriangulation = true;
 | 
					 | 
				
			||||||
      std::vector<Pose3> cameraPoses;
 | 
					      std::vector<Pose3> cameraPoses;
 | 
				
			||||||
      int poseCount = 0;
 | 
					
 | 
				
			||||||
 | 
					      bool retriangulate = true; // decideIfTriangulate(cameraPoses, values);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      BOOST_FOREACH(const Key& k, keys_) {
 | 
					      BOOST_FOREACH(const Key& k, keys_) {
 | 
				
			||||||
        Pose3 cameraPose;
 | 
					        Pose3 cameraPose;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -253,27 +325,10 @@ namespace gtsam {
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
          cameraPose = values.at<Pose3>(k);
 | 
					          cameraPose = values.at<Pose3>(k);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!state_->cameraPosesTriangulation.empty()) {
 | 
					 | 
				
			||||||
          // TODO: are you sure that when using "add" the number of poses will be ok? (old linearization point will contain 1 pose less)
 | 
					 | 
				
			||||||
          if (!cameraPose.equals(state_->cameraPosesTriangulation[poseCount], retriangulationThreshold)) {
 | 
					 | 
				
			||||||
            valuesEqualRetriangulation = false;
 | 
					 | 
				
			||||||
            subInsert(changeLinPoses, Vector::Zero(6), 6*poseCount);
 | 
					 | 
				
			||||||
          }else{
 | 
					 | 
				
			||||||
            Vector changeLinPoses_i = Pose3::Logmap(state_->cameraPosesTriangulation[poseCount].between(cameraPose));
 | 
					 | 
				
			||||||
            subInsert(changeLinPoses, changeLinPoses_i, 6*poseCount);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
          valuesEqualRetriangulation = false;
 | 
					 | 
				
			||||||
          subInsert(changeLinPoses, Vector::Zero(6), 6*poseCount);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        cameraPoses.push_back(cameraPose);
 | 
					        cameraPoses.push_back(cameraPose);
 | 
				
			||||||
        poseCount++;
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (valuesEqualRetriangulation) {
 | 
					      if(retriangulate) {
 | 
				
			||||||
        retriangulate = false;
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        state_->cameraPosesTriangulation = cameraPoses;
 | 
					        state_->cameraPosesTriangulation = cameraPoses;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -281,7 +336,7 @@ namespace gtsam {
 | 
				
			||||||
        // We triangulate the 3D position of the landmark
 | 
					        // We triangulate the 3D position of the landmark
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
          Point3 newPoint = triangulatePoint3(cameraPoses, measured_, *K_);
 | 
					          Point3 newPoint = triangulatePoint3(cameraPoses, measured_, *K_);
 | 
				
			||||||
          changeLinPoint = newPoint - state_->point;  // TODO: implement this check for the degenerate case
 | 
					          // changeLinPoint = newPoint - state_->point;  // TODO: implement this check for the degenerate case
 | 
				
			||||||
          state_->point = newPoint;
 | 
					          state_->point = newPoint;
 | 
				
			||||||
          state_->degenerate = false;
 | 
					          state_->degenerate = false;
 | 
				
			||||||
          state_->cheiralityException = false;
 | 
					          state_->cheiralityException = false;
 | 
				
			||||||
| 
						 | 
					@ -313,6 +368,17 @@ namespace gtsam {
 | 
				
			||||||
        dim_landmark = 2;
 | 
					        dim_landmark = 2;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      bool doLinearize = true; //= decideIfLinearize(cameraPoses);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (doLinearize) {
 | 
				
			||||||
 | 
					        state_->cameraPosesLinearization = cameraPoses;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if(!doLinearize){ // return the previous Hessian factor
 | 
				
			||||||
 | 
					        return HessianFactor::shared_ptr(new HessianFactor(keys_, state_->Gs, state_->gs, state_->f));
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      //otherwise redo linearization
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (blockwise){
 | 
					      if (blockwise){
 | 
				
			||||||
        // ==========================================================================================================
 | 
					        // ==========================================================================================================
 | 
				
			||||||
        std::cout << "Deprecated use of blockwise version. This is slower and no longer supported" << std::endl;
 | 
					        std::cout << "Deprecated use of blockwise version. This is slower and no longer supported" << std::endl;
 | 
				
			||||||
| 
						 | 
					@ -401,40 +467,11 @@ namespace gtsam {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else{
 | 
					        else{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
          for(size_t i = 0; i < measured_.size(); i++) {
 | 
					          for(size_t i = 0; i < measured_.size(); i++) {
 | 
				
			||||||
            Pose3 pose = cameraPoses.at(i);
 | 
					            Pose3 pose = cameraPoses.at(i);
 | 
				
			||||||
            PinholeCamera<CALIBRATION> camera(pose, *K_);
 | 
					            PinholeCamera<CALIBRATION> camera(pose, *K_);
 | 
				
			||||||
            Matrix Hxi, Hli;
 | 
					            Matrix Hxi, Hli;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Selective relinearization (check if new linearization is needed)
 | 
					 | 
				
			||||||
            Vector repErr_i;
 | 
					 | 
				
			||||||
            try {
 | 
					 | 
				
			||||||
              repErr_i = - ( camera.project(state_->point) - measured_.at(i) ).vector();
 | 
					 | 
				
			||||||
            } catch ( CheiralityException& e) {
 | 
					 | 
				
			||||||
              std::cout << "Cheirality exception " << state_->ID << std::endl;
 | 
					 | 
				
			||||||
              exit(EXIT_FAILURE);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            noise_-> whitenInPlace(repErr_i);
 | 
					 | 
				
			||||||
            f += repErr_i.squaredNorm();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            Vector linRepErr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            linRepErr = state_->Hx * changeLinPoses + state_->Hl * changeLinPoint.vector() - state_->b;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            double f_lin = linRepErr.squaredNorm();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Relinearization check
 | 
					 | 
				
			||||||
            if (state_->f - f_lin > 1e-7){
 | 
					 | 
				
			||||||
              double rho = (state_->f - f) / (state_->f - f_lin);
 | 
					 | 
				
			||||||
              if( fabs(rho) > 0.75 ){
 | 
					 | 
				
			||||||
                return HessianFactor::shared_ptr(new HessianFactor(keys_, state_->Gs, state_->gs, state_->f));
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else{
 | 
					 | 
				
			||||||
              return HessianFactor::shared_ptr(new HessianFactor(keys_, state_->Gs, state_->gs, state_->f));
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            Vector bi;
 | 
					            Vector bi;
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
              bi = -( camera.project(state_->point,Hxi,Hli) - measured_.at(i) ).vector();
 | 
					              bi = -( camera.project(state_->point,Hxi,Hli) - measured_.at(i) ).vector();
 | 
				
			||||||
| 
						 | 
					@ -494,15 +531,15 @@ namespace gtsam {
 | 
				
			||||||
     * to transform it to \f$ (h(x)-z)^2/\sigma^2 \f$, and then multiply by 0.5.
 | 
					     * to transform it to \f$ (h(x)-z)^2/\sigma^2 \f$, and then multiply by 0.5.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    virtual double error(const Values& values) const {
 | 
					    virtual double error(const Values& values) const {
 | 
				
			||||||
      double retriangulationThreshold = 1e-9;
 | 
					 | 
				
			||||||
      if (this->active(values)) {
 | 
					      if (this->active(values)) {
 | 
				
			||||||
        double overallError=0;
 | 
					        double overallError=0;
 | 
				
			||||||
        bool retriangulate = true;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Collect all poses (Cameras)
 | 
					        // Collect all poses (Cameras)
 | 
				
			||||||
        bool valuesEqualRetriangulation = true;
 | 
					 | 
				
			||||||
        std::vector<Pose3> cameraPoses;
 | 
					        std::vector<Pose3> cameraPoses;
 | 
				
			||||||
        int poseCount = 0;
 | 
					
 | 
				
			||||||
 | 
					        // check if triangulation and linearization are actually needed
 | 
				
			||||||
 | 
					        bool retriangulate = true; //decideIfTriangulate(cameraPoses, values);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        BOOST_FOREACH(const Key& k, keys_) {
 | 
					        BOOST_FOREACH(const Key& k, keys_) {
 | 
				
			||||||
          Pose3 cameraPose;
 | 
					          Pose3 cameraPose;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -511,21 +548,10 @@ namespace gtsam {
 | 
				
			||||||
          else
 | 
					          else
 | 
				
			||||||
            cameraPose = values.at<Pose3>(k);
 | 
					            cameraPose = values.at<Pose3>(k);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          if (!state_->cameraPosesTriangulation.empty()) {
 | 
					 | 
				
			||||||
            if (!cameraPose.equals(state_->cameraPosesTriangulation[poseCount], retriangulationThreshold)) {
 | 
					 | 
				
			||||||
              valuesEqualRetriangulation = false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            valuesEqualRetriangulation = false;
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          cameraPoses.push_back(cameraPose);
 | 
					          cameraPoses.push_back(cameraPose);
 | 
				
			||||||
          poseCount++;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (valuesEqualRetriangulation) {
 | 
					        if(retriangulate) {
 | 
				
			||||||
          retriangulate = false;
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
          state_->cameraPosesTriangulation = cameraPoses;
 | 
					          state_->cameraPosesTriangulation = cameraPoses;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -629,3 +655,80 @@ namespace gtsam {
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // \ namespace gtsam
 | 
					} // \ namespace gtsam
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					// Discarded version of decideIfTriangulate and decideIfLinearize
 | 
				
			||||||
 | 
					 *  This function decides whether a new triangulation and linearization is needed
 | 
				
			||||||
 | 
					bool decideIfLinearize(std::vector<Pose3> cameraPoses) {
 | 
				
			||||||
 | 
					  // Selective relinearization (check if new linearization is needed)
 | 
				
			||||||
 | 
					        Vector repErr_i;
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					          repErr_i = - ( camera.project(state_->point) - measured_.at(i) ).vector();
 | 
				
			||||||
 | 
					        } catch ( CheiralityException& e) {
 | 
				
			||||||
 | 
					          std::cout << "Cheirality exception " << state_->ID << std::endl;
 | 
				
			||||||
 | 
					          exit(EXIT_FAILURE);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        noise_-> whitenInPlace(repErr_i);
 | 
				
			||||||
 | 
					        f += repErr_i.squaredNorm();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Vector linRepErr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        linRepErr = state_->Hx * changeLinPoses + state_->Hl * changeLinPoint.vector() - state_->b;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        double f_lin = linRepErr.squaredNorm();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Relinearization check
 | 
				
			||||||
 | 
					        if (state_->f - f_lin > 1e-7){
 | 
				
			||||||
 | 
					          double rho = (state_->f - f) / (state_->f - f_lin);
 | 
				
			||||||
 | 
					          if( fabs(rho) > 0.75 ){
 | 
				
			||||||
 | 
					            return HessianFactor::shared_ptr(new HessianFactor(keys_, state_->Gs, state_->gs, state_->f));
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else{
 | 
				
			||||||
 | 
					          return HessianFactor::shared_ptr(new HessianFactor(keys_, state_->Gs, state_->gs, state_->f));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool decideIfTriangulateAndLinearize(std::vector<Pose3> cameraPoses) {
 | 
				
			||||||
 | 
					      //      Vector changeLinPoses(numKeys*6);
 | 
				
			||||||
 | 
					      //      Point3 changeLinPoint;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Pose3 firstCameraPose;
 | 
				
			||||||
 | 
					      Pose3 firstCameraPoseOld;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      int poseCount = 0;
 | 
				
			||||||
 | 
					      BOOST_FOREACH(const Key& k, keys_) {
 | 
				
			||||||
 | 
					        Pose3 cameraPose;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(body_P_sensor_)
 | 
				
			||||||
 | 
					          cameraPose = values.at<Pose3>(k).compose(*body_P_sensor_);
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					          cameraPose = values.at<Pose3>(k);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!state_->cameraPosesTriangulation.empty()) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          if(poseCount==0){ // we store the initial pose, this is useful for selective re-linearization
 | 
				
			||||||
 | 
					            firstCameraPose = cameraPose;
 | 
				
			||||||
 | 
					            firstCameraPoseOld = state_->cameraPosesTriangulation[poseCount];
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          // TODO: are you sure that when using "add" the number of poses will be ok? (old linearization point will contain 1 pose less)
 | 
				
			||||||
 | 
					          if (!cameraPose.equals(state_->cameraPosesTriangulation[poseCount], retriangulationThreshold)) {
 | 
				
			||||||
 | 
					            valuesEqualRetriangulation = false;
 | 
				
			||||||
 | 
					            subInsert(changeLinPoses, Vector::Zero(6), 6*poseCount);
 | 
				
			||||||
 | 
					          }else{
 | 
				
			||||||
 | 
					            Vector changeLinPoses_i = Pose3::Logmap(state_->cameraPosesTriangulation[poseCount].between(cameraPose));
 | 
				
			||||||
 | 
					            subInsert(changeLinPoses, changeLinPoses_i, 6*poseCount);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          valuesEqualRetriangulation = false;
 | 
				
			||||||
 | 
					          subInsert(changeLinPoses, Vector::Zero(6), 6*poseCount);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cameraPoses.push_back(cameraPose);
 | 
				
			||||||
 | 
					        poseCount++;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -73,7 +73,7 @@ TEST( SmartProjectionFactor, Constructor) {
 | 
				
			||||||
  std::vector<Point2> measurements;
 | 
					  std::vector<Point2> measurements;
 | 
				
			||||||
  measurements.push_back(Point2(323.0, 240.0));
 | 
					  measurements.push_back(Point2(323.0, 240.0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TestSmartProjectionFactor factor(measurements, model, views, K);
 | 
					  TestSmartProjectionFactor factor(views, measurements, model, K);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ************************************************************************* */
 | 
					/* ************************************************************************* */
 | 
				
			||||||
| 
						 | 
					@ -87,7 +87,7 @@ TEST( SmartProjectionFactor, ConstructorWithTransform) {
 | 
				
			||||||
  measurements.push_back(Point2(323.0, 240.0));
 | 
					  measurements.push_back(Point2(323.0, 240.0));
 | 
				
			||||||
  Pose3 body_P_sensor(Rot3::RzRyRx(-M_PI_2, 0.0, -M_PI_2), Point3(0.25, -0.10, 1.0));
 | 
					  Pose3 body_P_sensor(Rot3::RzRyRx(-M_PI_2, 0.0, -M_PI_2), Point3(0.25, -0.10, 1.0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TestSmartProjectionFactor factor(measurements, model, views, K, body_P_sensor);
 | 
					  TestSmartProjectionFactor factor(views, measurements, model, K, body_P_sensor);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ************************************************************************* */
 | 
					/* ************************************************************************* */
 | 
				
			||||||
| 
						 | 
					@ -98,8 +98,8 @@ TEST( SmartProjectionFactor, Equals ) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::vector<Key> views;
 | 
					  std::vector<Key> views;
 | 
				
			||||||
  views += X(1);
 | 
					  views += X(1);
 | 
				
			||||||
  TestSmartProjectionFactor factor1(measurements, model, views, K);
 | 
					  TestSmartProjectionFactor factor1(views, measurements, model, K);
 | 
				
			||||||
  TestSmartProjectionFactor factor2(measurements, model, views, K);
 | 
					  TestSmartProjectionFactor factor2(views, measurements, model, K);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  CHECK(assert_equal(factor1, factor2));
 | 
					  CHECK(assert_equal(factor1, factor2));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -113,8 +113,8 @@ TEST( SmartProjectionFactor, EqualsWithTransform ) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::vector<Key> views;
 | 
					  std::vector<Key> views;
 | 
				
			||||||
  views += X(1);
 | 
					  views += X(1);
 | 
				
			||||||
  TestSmartProjectionFactor factor1(measurements, model, views, K, body_P_sensor);
 | 
					  TestSmartProjectionFactor factor1(views, measurements, model, K, body_P_sensor);
 | 
				
			||||||
  TestSmartProjectionFactor factor2(measurements, model, views, K, body_P_sensor);
 | 
					  TestSmartProjectionFactor factor2(views, measurements, model, K, body_P_sensor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  CHECK(assert_equal(factor1, factor2));
 | 
					  CHECK(assert_equal(factor1, factor2));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -631,8 +631,8 @@ TEST( SmartProjectionFactor, 3poses_2land_rotation_only_smart_projection_factor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  typedef SmartProjectionFactor<Pose3, Point3, Cal3_S2> SmartFactor;
 | 
					  typedef SmartProjectionFactor<Pose3, Point3, Cal3_S2> SmartFactor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  SmartFactor::shared_ptr smartFactor1(new SmartFactor(measurements_cam1, noiseProjection, views, K));
 | 
					  SmartFactor::shared_ptr smartFactor1(new SmartFactor(views, measurements_cam1, noiseProjection, K));
 | 
				
			||||||
  SmartFactor::shared_ptr smartFactor2(new SmartFactor(measurements_cam2, noiseProjection, views, K));
 | 
					  SmartFactor::shared_ptr smartFactor2(new SmartFactor(views, measurements_cam2, noiseProjection, K));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const SharedDiagonal noisePrior = noiseModel::Isotropic::Sigma(6, 0.10);
 | 
					  const SharedDiagonal noisePrior = noiseModel::Isotropic::Sigma(6, 0.10);
 | 
				
			||||||
  const SharedDiagonal noisePriorTranslation = noiseModel::Isotropic::Sigma(3, 0.10);
 | 
					  const SharedDiagonal noisePriorTranslation = noiseModel::Isotropic::Sigma(3, 0.10);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue