Example: slam_icp_simple_example
C++ example source code:
/* +------------------------------------------------------------------------+ | Mobile Robot Programming Toolkit (MRPT) | | https://www.mrpt.org/ | | | | Copyright (c) 2005-2022, Individual contributors, see AUTHORS file | | See: https://www.mrpt.org/Authors - All rights reserved. | | Released under BSD License. See: https://www.mrpt.org/License | +------------------------------------------------------------------------+ */ #include <mrpt/gui.h> #include <mrpt/maps/CSimplePointsMap.h> #include <mrpt/math/utils.h> #include <mrpt/obs/CObservation2DRangeScan.h> #include <mrpt/obs/stock_observations.h> #include <mrpt/poses/CPose2D.h> #include <mrpt/poses/CPosePDF.h> #include <mrpt/poses/CPosePDFGaussian.h> #include <mrpt/slam/CICP.h> #include <fstream> #include <iostream> using namespace mrpt; using namespace mrpt::slam; using namespace mrpt::maps; using namespace mrpt::obs; using namespace mrpt::math; using namespace mrpt::poses; using namespace std; bool skip_window = false; int ICP_method = (int)icpClassic; // ------------------------------------------------------ // TestICP // ------------------------------------------------------ void TestICP() { CSimplePointsMap m1, m2; CICP::TReturnInfo info; CICP ICP; // Load scans: CObservation2DRangeScan scan1; stock_observations::example2DRangeScan(scan1, 0); CObservation2DRangeScan scan2; stock_observations::example2DRangeScan(scan2, 1); // Build the points maps from the scans: m1.insertObservation(scan1); m2.insertObservation(scan2); // ----------------------------------------------------- // select which algorithm version to use // ICP.options.ICP_algorithm = icpLevenbergMarquardt; // ICP.options.ICP_algorithm = icpClassic; ICP.options.ICP_algorithm = (TICPAlgorithm)ICP_method; // configuration options for the icp algorithm ICP.options.maxIterations = 100; ICP.options.thresholdAng = DEG2RAD(10.0f); ICP.options.thresholdDist = 0.75f; ICP.options.ALFA = 0.5f; ICP.options.smallestThresholdDist = 0.05f; ICP.options.doRANSAC = false; ICP.options.dumpToConsole(); // ----------------------------------------------------- CPose2D initialPose(0.8f, 0.0f, (float)DEG2RAD(0.0f)); CPosePDF::Ptr pdf = ICP.Align(&m1, &m2, initialPose, info); printf( "ICP run in %.02fms, %d iterations (%.02fms/iter), %.01f%% goodness\n " "-> ", info.executionTime * 1000, info.nIterations, info.executionTime * 1000.0f / info.nIterations, info.goodness * 100); cout << "Mean of estimation: " << pdf->getMeanVal() << endl << endl; CPosePDFGaussian gPdf; gPdf.copyFrom(*pdf); cout << "Covariance of estimation: " << endl << gPdf.cov << endl; cout << " std(x): " << sqrt(gPdf.cov(0, 0)) << endl; cout << " std(y): " << sqrt(gPdf.cov(1, 1)) << endl; cout << " std(phi): " << RAD2DEG(sqrt(gPdf.cov(2, 2))) << " (deg)" << endl; // cout << "Covariance of estimation (MATLAB format): " << endl << // gPdf.cov.inMatlabFormat() << endl; cout << "-> Saving reference map as scan1.txt" << endl; m1.save2D_to_text_file("scan1.txt"); cout << "-> Saving map to align as scan2.txt" << endl; m2.save2D_to_text_file("scan2.txt"); cout << "-> Saving transformed map to align as scan2_trans.txt" << endl; CSimplePointsMap m2_trans = m2; m2_trans.changeCoordinatesReference(gPdf.mean); m2_trans.save2D_to_text_file("scan2_trans.txt"); cout << "-> Saving MATLAB script for drawing 2D ellipsoid as view_ellip.m" << endl; CMatrixFloat COV22 = CMatrixFloat(CMatrixDouble(gPdf.cov)); COV22.setSize(2, 2); CVectorFloat MEAN2D(2); MEAN2D[0] = gPdf.mean.x(); MEAN2D[1] = gPdf.mean.y(); { ofstream f("view_ellip.m"); f << math::MATLAB_plotCovariance2D(COV22, MEAN2D, 3.0f); } // If we have 2D windows, use'em: #if MRPT_HAS_WXWIDGETS if (!skip_window) { gui::CDisplayWindowPlots win("ICP results"); // Reference map: vector<float> map1_xs, map1_ys, map1_zs; m1.getAllPoints(map1_xs, map1_ys, map1_zs); win.plot(map1_xs, map1_ys, "b.3", "map1"); // Translated map: vector<float> map2_xs, map2_ys, map2_zs; m2_trans.getAllPoints(map2_xs, map2_ys, map2_zs); win.plot(map2_xs, map2_ys, "r.3", "map2"); // Uncertainty win.plotEllipse(MEAN2D[0], MEAN2D[1], COV22, 3.0, "b2", "cov"); win.axis(-1, 10, -6, 6); win.axis_equal(); cout << "Close the window to exit" << endl; win.waitForKey(); } #endif } int main(int argc, char** argv) { try { skip_window = (argc > 2); if (argc > 1) { ICP_method = atoi(argv[1]); } TestICP(); return 0; } catch (exception& e) { cout << "MRPT exception caught: " << e.what() << endl; return -1; } catch (...) { printf("Another exception!!"); return -1; } }