zoukankan      html  css  js  c++  java
  • MRPT EKF SLAM (3D表示) 编程学习笔记

    An implementation of EKF-based SLAM with range-bearing sensors, odometry, a full 6D robot pose, and 3D landmarks.

    The main method is "processActionObservation" which processes pairs of action/observation.

    The following Wiki page describes an front-end application based on this class: http://babel.isa.uma.es/mrpt/index.php/Application:kf-slam

    See also:
    An implementation for 2D only: CRangeBearingKFSLAM2D

    类之间调用关系:以CKalmanFilterCapable<>为基类,关键的方法在于processActionObservation,getCurrentState和getCurrentRobotPose

    Inheritance graph

    类的详细文档:http://babel.isa.uma.es/mrpt/reference/stable/classmrpt_1_1slam_1_1_c_range_bearing_k_f_s_l_a_m.html#_details

    附上代码:

    // EKF SLAM
    void EKFSLAM()
    {
    	std::string configFile="../EKF-SLAM_test.ini";
    	CRangeBearingKFSLAM  mapping;
    	CConfigFile			 cfgFile( configFile );
    	std::string			 rawlogFileName;
    
    	//mapping.debugOut = &myDebugStream;
    	CDisplayWindow3D        win("My window");
    
    	// The rawlog file:
    	rawlogFileName = cfgFile.read_string("MappingApplication","rawlog_file",std::string("log.rawlog"));
    	unsigned int	rawlog_offset = cfgFile.read_int("MappingApplication","rawlog_offset",0);
    	unsigned int SAVE_LOG_FREQUENCY= cfgFile.read_int("MappingApplication","SAVE_LOG_FREQUENCY",1);
    	bool  SAVE_3D_SCENES = cfgFile.read_bool("MappingApplication","SAVE_3D_SCENES", true);
    	bool  SAVE_MAP_REPRESENTATIONS = cfgFile.read_bool("MappingApplication","SAVE_MAP_REPRESENTATIONS", true);
    	string OUT_DIR = cfgFile.read_string("MappingApplication","logOutput_dir","OUT_KF-SLAM");
    	string ground_truth_file = cfgFile.read_string("MappingApplication","ground_truth_file","");
    	//cout << "RAWLOG FILE:" << endl << rawlogFileName << endl;
    	ASSERT_( fileExists( rawlogFileName ) );
    	CFileGZInputStream	rawlogFile( rawlogFileName );
    
    	// 创建输出目录
    	//deleteFilesInDirectory(OUT_DIR);
    	//createDirectory(OUT_DIR);
    
    	// Load the config options for mapping:
    	mapping.loadOptions( CConfigFile(configFile) );
    	/* mapping.KF_options.dumpToConsole();
    	mapping.options.dumpToConsole();
    	*/
    	//			INITIALIZATION
    	// ----------------------------------------
    	//mapping.initializeEmptyMap();
    
    	// The main loop:
    	CActionCollectionPtr	action;
    	CSensoryFramePtr		observations;
    	size_t			rawlogEntry = 0, step = 0;
    	deque<CPose3D>   meanPath; // The estimated path
    	CPose3DPDFGaussian		robotPose;
    	std::vector<CPoint3D>	LMs;
    	std::map<unsigned int,CLandmark::TLandmarkID> LM_IDs;
    	CMatrixDouble	fullCov;
    	CVectorDouble   fullState;
    
    	for(;;)
    	{
    		if (os::kbhit())
    		{	// Esc quit the program
    			char	pushKey = os::getch();
    			if (27 == pushKey)
    				break;
    		}
    
    		// Load action/observation pair from the rawlog:
    		if (! CRawlog::readActionObservationPair( rawlogFile, action, observations, rawlogEntry) )
    			break; // file EOF
    
    		if (rawlogEntry>=rawlog_offset)
    		{
    			// Process the action and observations:
    			mapping.processActionObservation(action,observations);
    
    			// Get current state:
    			mapping.getCurrentState( robotPose,LMs,LM_IDs,fullState,fullCov );
    			//cout << "Mean pose: " << endl << robotPose.mean << endl;
    			//cout << "# of landmarks in the map: " << LMs.size() << endl;
    
    			// Build the path:
    			meanPath.push_back( robotPose.mean );
    
    			
    			// Free rawlog items memory:
    			action.clear_unique();
    			observations.clear_unique();
    		}// (rawlogEntry>=rawlog_offset)
    
    		//cout << format("\nStep %u  - Rawlog entries processed: %i\n", (unsigned int)step, (unsigned int)rawlogEntry);
    		step++;
    
    		// Show Mapping
    		opengl::COpenGLScenePtr &scene3D = win.get3DSceneAndLock();
    
    		// Modify the scene:
    		opengl::CGridPlaneXYPtr grid = opengl::CGridPlaneXY::Create(-1000,1000,-1000,1000,0,5);
    		grid->setColor(0.4,0.4,0.4);
    		scene3D->insert( grid );
    
    		// Robot path:
    		opengl::CSetOfLinesPtr linesPath = opengl::CSetOfLines::Create();
    		linesPath->setColor(1,0,0);
    
    		double x0=0,y0=0,z0=0;
    
    		if (!meanPath.empty())
    		{
    			x0 = meanPath[0].x();
    			y0 = meanPath[0].y();
    			z0 = meanPath[0].z();
    		}
    
    		for (deque<CPose3D>::iterator it=meanPath.begin();it!=meanPath.end();++it)
    		{
    			linesPath->appendLine(
    				x0,y0,z0,
    				it->x(), it->y(), it->z() );
    			x0=it->x();
    			y0=it->y();
    			z0=it->z();
    		}
    		scene3D->insert( linesPath );
    		opengl::CSetOfObjectsPtr  objs = opengl::CSetOfObjects::Create();
    		mapping.getAs3DObject(objs);
    		scene3D->insert( objs );
    
    		// Unlock it, so the window can use it for redraw:
    		win.unlockAccess3DScene();
    		// Update window, if required
    		win.forceRepaint();
    
    	}	// end "while(1)"
    }
    
    void CMrptImageBasicTestView::OnSlamEkfslam()
    {
    	// 调用EKF-SLAM
    	HANDLE handle;
    	DWORD id;
    	handle=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)EKFSLAM,NULL,0,&id);
    	CloseHandle(handle);
    }
    执行结果 按3D格式显示,可以自主调整视角
    image 

    参考:MRPT Project

    ps:有谁也做SLAM方面的研究,可以跟我联系,大家相互交流学习。

  • 相关阅读:
    hdu 4123 树形dp+rmq
    POJ 2761 Feed the dogs 求区间第k大 划分树
    hdu 4585 shaolin 平衡树
    *hdu 4616 Game 树形DP
    hdu 5379 Mahjong tree 树形DP入门
    CF 581F Contest Page 树形DP
    hdu 2778 LCR 模拟题
    hdu 2896 病毒侵袭 AC自动机
    hdu 2222 Keywords Search AC自动机模板题
    透过c的编程原则,来规范自己现在的一些编程习惯
  • 原文地址:https://www.cnblogs.com/feisky/p/1683296.html
Copyright © 2011-2022 走看看