1. 程式人生 > >[SLAM] GMapping SLAM原始碼閱讀(草稿)

[SLAM] GMapping SLAM原始碼閱讀(草稿)

  1 //後臺執行緒處理掃描資料的方法
  2 bool GridSlamProcessor::processScan(const RangeReading & reading, int adaptParticles)
  3 {
  4     /**retireve the position from the reading, and compute the odometry*/
  5     OrientedPoint relPose=reading.getPose();
  6     if (!m_count)
  7     {
  8         m_lastPartPose=m_odoPose=relPose;
9 } 10 11 //write the state of the reading and update all the particles using the motion model 12 for (ParticleVector::iterator it=m_particles.begin(); it!=m_particles.end(); it++) 13 { 14 OrientedPoint& pose(it->pose); 15 pose=m_motionModel.drawFromMotion(it->pose, relPose, m_odoPose);//
運動模型,更新t時刻的粒子 16 } 17 18 // update the output file 19 if (m_outputStream.is_open()) 20 { 21 m_outputStream << setiosflags(ios::fixed) << setprecision(6); 22 m_outputStream << "ODOM "; 23 m_outputStream << setiosflags(ios::fixed
) << setprecision(3) << m_odoPose.x << " " << m_odoPose.y << " "; 24 m_outputStream << setiosflags(ios::fixed) << setprecision(6) << m_odoPose.theta << " "; 25 m_outputStream << reading.getTime(); 26 m_outputStream << endl; 27 } 28 if (m_outputStream.is_open()) 29 { 30 m_outputStream << setiosflags(ios::fixed) << setprecision(6); 31 m_outputStream << "ODO_UPDATE "<< m_particles.size() << " "; 32 for (ParticleVector::iterator it=m_particles.begin(); it!=m_particles.end(); it++) 33 { 34 OrientedPoint& pose(it->pose); 35 m_outputStream << setiosflags(ios::fixed) << setprecision(3) << pose.x << " " << pose.y << " "; 36 m_outputStream << setiosflags(ios::fixed) << setprecision(6) << pose.theta << " " << it-> weight << " "; 37 } 38 m_outputStream << reading.getTime(); 39 m_outputStream << endl; 40 } 41 42 //invoke the callback 43 onOdometryUpdate(); 44 45 // accumulate the robot translation and rotation 46 OrientedPoint move=relPose-m_odoPose; 47 move.theta=atan2(sin(move.theta), cos(move.theta)); 48 m_linearDistance+=sqrt(move*move); 49 m_angularDistance+=fabs(move.theta); 50 51 // if the robot jumps throw a warning 52 if (m_linearDistance>m_distanceThresholdCheck) 53 { 54 cerr << "***********************************************************************" << endl; 55 cerr << "********** Error: m_distanceThresholdCheck overridden!!!! *************" << endl; 56 cerr << "m_distanceThresholdCheck=" << m_distanceThresholdCheck << endl; 57 cerr << "Old Odometry Pose= " << m_odoPose.x << " " << m_odoPose.y 58 << " " <<m_odoPose.theta << endl; 59 cerr << "New Odometry Pose (reported from observation)= " << relPose.x << " " << relPose.y 60 << " " <<relPose.theta << endl; 61 cerr << "***********************************************************************" << endl; 62 cerr << "** The Odometry has a big jump here. This is probably a bug in the **" << endl; 63 cerr << "** odometry/laser input. We continue now, but the result is probably **" << endl; 64 cerr << "** crap or can lead to a core dump since the map doesn't fit.... C&G **" << endl; 65 cerr << "***********************************************************************" << endl; 66 } 67 68 m_odoPose=relPose; 69 70 bool processed=false; 71 72 // process a scan only if the robot has traveled a given distance 73 if (! m_count || m_linearDistance>m_linearThresholdDistance || m_angularDistance>m_angularThresholdDistance) 74 { 75 if (m_outputStream.is_open()) 76 { 77 m_outputStream << setiosflags(ios::fixed) << setprecision(6); 78 m_outputStream << "FRAME " << m_readingCount; 79 m_outputStream << " " << m_linearDistance; 80 m_outputStream << " " << m_angularDistance << endl; 81 } 82 83 if (m_infoStream) 84 m_infoStream << "update frame " << m_readingCount << endl 85 << "update ld=" << m_linearDistance << " ad=" << m_angularDistance << endl; 86 87 88 cerr << "Laser Pose= " << reading.getPose().x << " " << reading.getPose().y 89 << " " << reading.getPose().theta << endl; 90 91 92 //this is for converting the reading in a scan-matcher feedable form 93 assert(reading.size()==m_beams); 94 double * plainReading = new double[m_beams]; 95 for(unsigned int i=0; i<m_beams; i++) 96 { 97 plainReading[i]=reading[i]; 98 } 99 m_infoStream << "m_count " << m_count << endl; 100 if (m_count>0) 101 { 102 scanMatch(plainReading);//掃描匹配 103 if (m_outputStream.is_open()) 104 { 105 m_outputStream << "LASER_READING "<< reading.size() << " "; 106 m_outputStream << setiosflags(ios::fixed) << setprecision(2); 107 for (RangeReading::const_iterator b=reading.begin(); b!=reading.end(); b++) 108 { 109 m_outputStream << *b << " "; 110 } 111 OrientedPoint p=reading.getPose(); 112 m_outputStream << setiosflags(ios::fixed) << setprecision(6); 113 m_outputStream << p.x << " " << p.y << " " << p.theta << " " << reading.getTime()<< endl; 114 m_outputStream << "SM_UPDATE "<< m_particles.size() << " "; 115 for (ParticleVector::const_iterator it=m_particles.begin(); it!=m_particles.end(); it++) 116 { 117 const OrientedPoint& pose=it->pose; 118 m_outputStream << setiosflags(ios::fixed) << setprecision(3) << pose.x << " " << pose.y << " "; 119 m_outputStream << setiosflags(ios::fixed) << setprecision(6) << pose.theta << " " << it-> weight << " "; 120 } 121 m_outputStream << endl; 122 } 123 onScanmatchUpdate(); 124 updateTreeWeights(false);//更新權重 125 126 if (m_infoStream) 127 { 128 m_infoStream << "neff= " << m_neff << endl; 129 } 130 if (m_outputStream.is_open()) 131 { 132 m_outputStream << setiosflags(ios::fixed) << setprecision(6); 133 m_outputStream << "NEFF " << m_neff << endl; 134 } 135 resample(plainReading, adaptParticles);//重取樣 136 } 137 else 138 { 139 m_infoStream << "Registering First Scan"<< endl; 140 for (ParticleVector::iterator it=m_particles.begin(); it!=m_particles.end(); it++) 141 { 142 m_matcher.invalidateActiveArea(); 143 m_matcher.computeActiveArea(it->map, it->pose, plainReading);//計算有效區域 144 m_matcher.registerScan(it->map, it->pose, plainReading); 145 146 // cyr: not needed anymore, particles refer to the root in the beginning! 147 TNode* node=new TNode(it->pose, 0., it->node, 0); 148 node->reading=0; 149 it->node=node; 150 151 } 152 } 153 //cerr << "Tree: normalizing, resetting and propagating weights at the end..." ; 154 updateTreeWeights(false);//再次更新權重 155 //cerr << ".done!" <<endl; 156 157 delete [] plainReading; 158 m_lastPartPose=m_odoPose; //update the past pose for the next iteration 159 m_linearDistance=0; 160 m_angularDistance=0; 161 m_count++; 162 processed=true; 163 164 //keep ready for the next step 165 for (ParticleVector::iterator it=m_particles.begin(); it!=m_particles.end(); it++) 166 { 167 it->previousPose=it->pose; 168 } 169 170 } 171 if (m_outputStream.is_open()) 172 m_outputStream << flush; 173 m_readingCount++; 174 return processed; 175 }

相關推薦

[SLAM] GMapping SLAM原始碼閱讀草稿

1 //後臺執行緒處理掃描資料的方法 2 bool GridSlamProcessor::processScan(const RangeReading & reading, int adaptParticles) 3 { 4 /**retireve the posit

【筆記】ThreadPoolExecutor原始碼閱讀

執行緒數量的維護 執行緒池的大小有兩個重要的引數,一個是corePoolSize(核心執行緒池大小),另一個是maximumPoolSize(最大執行緒大小)。執行緒池主要根據這兩個引數對執行緒池中執行緒的數量進行維護。 需要注意的是,執行緒池建立之初是沒有任何可用執行緒的。只有在有任務到達後,才開始建立

## Zookeeper原始碼閱讀 Watcher

前言 好久沒有更新部落格了,最近這段時間過得很壓抑,終於開始踏上為換工作準備的正軌了,工作又真的很忙而且很瑣碎,讓自己有點煩惱,希望能早點結束這種狀態。 繼上次分析了ZK的ACL相關程式碼後,ZK裡非常重要的另一個特性就是Watcher機制了。其實在我看來,就ZK的使用而言,Watche機制是最核心的特性

Zookeeper原始碼閱讀 Server端Watcher

前言 前面一篇主要介紹了Watcher介面相關的介面和實體類,但是主要是zk客戶端相關的程式碼,如前一篇開頭所說,client需要把watcher註冊到server端,這一篇分析下server端的watcher。 主要分析Watchmanager類。 Watchmanager 這是WatchMan

Zookeeper原始碼閱讀 ACL基礎

前言 之前看程式碼的時候也同步看了看一些關於zk原始碼的部落格,有一兩篇講到了ZK裡ACL的基礎的結構,我自己這邊也看了看相關的程式碼,在這裡分享一下! ACL和ID ACL和ID都是有Jute生成的實體類,分別代表了ZK裡ACL和不同ACL模式下的具體實體。 ACL: public class A

Redis原始碼閱讀叢集-故障遷移(下)

Redis原始碼閱讀(六)叢集-故障遷移(下)   最近私人的事情比較多,沒有抽出時間來整理部落格。書接上文,上一篇裡總結了Redis故障遷移的幾個關鍵點,以及Redis中故障檢測的實現。本篇主要介紹叢集檢測到某主節點下線後,是如何選舉新的主節點的。注意到Redis叢集是無中心的,那麼使用分散式一

XSStrike原始碼閱讀2——四種模式

1.bruteforcer模式 功能介紹 根據使用者提供的payloads檔案去暴力測試每一個引數,以此來確定是否存在xss漏洞(說起來也就是一個兩層迴圈)。 具體實現 XSStrike3.0 bruteforcer.py原始碼如下: import copy from

Spark原始碼閱讀

強烈推薦 https://blog.csdn.net/weixin_41705780/article/details/79273666 總體架構 Spark工程下的模組 spark core, spark 核心 spark streaming, spark流計算(基

Koa原始碼閱讀從搭建Web伺服器說起

先複習一下使用原生 Node.js 搭建一個 Web 伺服器。 var http = require('http'); var server = http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'te

Koa原始碼閱讀上下文ctx

上篇提到,this.callback() 返回一個回撥函式,其實是以閉包的形式返回了一個區域性函式變數 handleRequest,供 Server 呼叫來處理 HTTP 請求。 callback() { const fn = compose(this.middleware); const han

Redis原始碼閱讀叢集-請求分配

    叢集搭建好之後,使用者傳送的命令請求可以被分配到不同的節點去處理。那Redis對命令請求分配的依據是什麼?如果節點數量有變動,命令又是如何重新分配的,重分配的過程是否會阻塞對外提供的服務?接下來會從這兩個問題入手,分析Redis3.0的原始碼實現。 1. 分配依據—

java原始碼閱讀

#include <stdio.h> #define JRT_ENTRY(result_type , header) \ JRT_NO(result_type , header) #define JRT_NO(result_type , header

課時17 第三課Spark內部原理剖析與原始碼閱讀

為何spark shuffle比mapreduce shuffle慢? 主要是spark shuffle的shuffle read階段還不夠優秀,它是基於hashmap實現的,shuffle read會把shuffel write階段已經排序資料給重新轉成亂序的,轉成亂序之後又做了排序,導致非常低效,sp

spring原始碼閱讀1- ioc依賴注入之bean載入

還是先看下DefaultListableBeanFactory的類結構圖  我們從User user = (User) beanFactory.getBean("user");入手進入bean的載入管理流程。 這裡還是堅持走主線的流程,去掉無關的枝葉,儘量讓業務變得簡

spring原始碼閱讀2-aop之jdk動態代理深入解析

續spring原始碼閱讀(2)-aop之j動態代理 我們從需求作為動態代理髮展的切入吧 現在有5個已經投產了的run100m的實現,我們新的需求需要監控不同實現的執行效能,如果我們針對這五個實現分別去新增效能監控的程式碼,如此就造成兩個問題: 一個是已經穩定的程式碼需要

spring原始碼閱讀2-aop之原始碼解析篇

經過一個aop術語介紹和動態代理的深入講解,我們終於可以來看aop的原始碼了,下面跟著博主一點點剖析spring aop原始碼的實現吧 我們知道spring使用中我們只要做好相關的配置,spring自動幫我們做好了代理的相關工作。 我們從三個方面入手吧 1、配置 2、

ConcurrentHashMap原始碼閱讀

  原始碼所屬版本為jdk1.8 ConcurrentHashMap: public V put(K key, V value) { return putVal(key, value, false); } 這是put方法可以看到呼叫的是put

Nginx原始碼閱讀ngx_http_process_request_line

ngx_http_process_request_line() static void ngx_http_process_request_line(ngx_event_t *rev) {     ssize_t              n;     ngx_int_t  

jQuery原始碼閱讀--正則表示式

在jQuery原始碼中,運用了大量的正則表示式,一開始在看的時候真的是一頭霧水,儘管已經看過了JS高程裡面的正則表示式。 今天,看了一篇深入理解正則表示式的文章,對正則表示式有了更深的認識,下面做一個回顧和總結。 正則表示式基礎 JS正則表示式用來匹配

Horizon 原始碼閱讀—— 呼叫Novaclient流程

一、寫在前面 這篇文章主要介紹一下OpenStack(Kilo)關於horizon 呼叫NovaClient的一個分析。         如果轉載,請保留作者資訊。 原文地址:http://blog.csdn.net/u011521019/a