84 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			84 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C++
		
	
	
| /**
 | |
|  * @file Pose2SLAMStressTest.cpp
 | |
|  * @brief Test GTSAM on large open-loop chains
 | |
|  * @date May 23, 2018
 | |
|  * @author Wenqiang Zhou
 | |
|  */
 | |
| 
 | |
| // Create N 3D poses, add relative motion between each consecutive poses. (The
 | |
| // relative motion is simply a unit translation(1, 0, 0), no rotation). For each
 | |
| // each pose, add some random noise to the x value of the translation part.
 | |
| // Use gtsam to create a prior factor for the first pose and N-1 between factors
 | |
| // and run optimization.
 | |
| 
 | |
| #include <gtsam/geometry/Cal3_S2Stereo.h>
 | |
| #include <gtsam/geometry/Pose3.h>
 | |
| #include <gtsam/nonlinear/GaussNewtonOptimizer.h>
 | |
| #include <gtsam/nonlinear/LevenbergMarquardtOptimizer.h>
 | |
| #include <gtsam/nonlinear/NonlinearEquality.h>
 | |
| #include <gtsam/nonlinear/NonlinearFactorGraph.h>
 | |
| #include <gtsam/nonlinear/Values.h>
 | |
| #include <gtsam/slam/BetweenFactor.h>
 | |
| #include <gtsam/slam/StereoFactor.h>
 | |
| 
 | |
| #include <random>
 | |
| 
 | |
| using namespace std;
 | |
| using namespace gtsam;
 | |
| 
 | |
| void testGtsam(int numberNodes) {
 | |
|   std::random_device rd;
 | |
|   std::mt19937 e2(rd());
 | |
|   std::uniform_real_distribution<> dist(0, 1);
 | |
| 
 | |
|   vector<Pose3> poses;
 | |
|   for (int i = 0; i < numberNodes; ++i) {
 | |
|     Matrix4 M;
 | |
|     double r = dist(e2);
 | |
|     r = (r - 0.5) / 10 + i;
 | |
|     M << 1, 0, 0, r, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1;
 | |
|     poses.push_back(Pose3(M));
 | |
|   }
 | |
| 
 | |
|   // prior factor for the first pose
 | |
|   auto priorModel = noiseModel::Isotropic::Variance(6, 1e-4);
 | |
|   Matrix4 first_M;
 | |
|   first_M << 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1;
 | |
|   Pose3 first = Pose3(first_M);
 | |
| 
 | |
|   NonlinearFactorGraph graph;
 | |
|   graph.addPrior(0, first, priorModel);
 | |
| 
 | |
|   // vo noise model
 | |
|   auto VOCovarianceModel = noiseModel::Isotropic::Variance(6, 1e-3);
 | |
| 
 | |
|   // relative VO motion
 | |
|   Matrix4 vo_M;
 | |
|   vo_M << 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1;
 | |
|   Pose3 relativeMotion(vo_M);
 | |
|   for (int i = 0; i < numberNodes - 1; ++i) {
 | |
|     graph.add(
 | |
|         BetweenFactor<Pose3>(i, i + 1, relativeMotion, VOCovarianceModel));
 | |
|   }
 | |
| 
 | |
|   // inital values
 | |
|   Values initial;
 | |
|   for (int i = 0; i < numberNodes; ++i) {
 | |
|     initial.insert(i, poses[i]);
 | |
|   }
 | |
| 
 | |
|   LevenbergMarquardtParams params;
 | |
|   params.setVerbosity("ERROR");
 | |
|   params.setOrderingType("METIS");
 | |
|   params.setLinearSolverType("MULTIFRONTAL_CHOLESKY");
 | |
|   LevenbergMarquardtOptimizer optimizer(graph, initial, params);
 | |
|   auto result = optimizer.optimize();
 | |
| }
 | |
| 
 | |
| int main(int args, char* argv[]) {
 | |
|   int numberNodes = stoi(argv[1]);
 | |
|   cout << "number of_nodes: " << numberNodes << endl;
 | |
|   testGtsam(numberNodes);
 | |
|   return 0;
 | |
| }
 |