通過幀間確定動態障礙物,剔除動態3D點雲資料後用於生成柵格地圖
在使用rtabmap建圖時,障礙物層的柵格地圖無法清除動態障礙物,對於3D障礙物點雲僅僅是簡單的累加的過程!
因此嘗試通過兩幀之間的變化消除動態障礙物點雲。
在MapsManager.cpp
中剔除動態障礙物
ROS_INFO("x:%fs,y:%fs,z:%fs",iter->second.x(),iter->second.y(),iter->second.z());
首先在該cpp
檔案中確定了里程計pose
,利用該pose
進行cropBoxFilter
過濾
在更新障礙物的過程中,將之前簡單的累加,先改成如下所示,確定一下剔除的範圍:
//like
pcl::CropBox<pcl::PointXYZRGB> cropBoxFilter;
double x_min = +iter->second.x()-1;
double y_min = +iter->second.y()-1;
double z_min = +iter->second.z()-1;
double x_max = +iter->second.x()+1;
double y_max = +iter->second.y()+1;
double z_max = +iter->second.z()+1;
cropBoxFilter.setMin(Eigen::Vector4f(x_min, y_min, z_min, 1.0));
cropBoxFilter.setMax(Eigen::Vector4f(x_max, y_max, z_max, 1.0));
cropBoxFilter.setNegative(false);
cropBoxFilter.setInputCloud(subtractedCloud);
cropBoxFilter.filter(*subtractedCloud);
*assembledObstacles_=*subtractedCloud;
可以看見,此時只保留了每一幀中的附近二米內的障礙物點雲
接下來定義倆點雲資料,注意智慧指標初始化!
lastObstacles(new pcl::PointCloud<pcl::PointXYZRGB>),
currentObstacles(new pcl::PointCloud<pcl::PointXYZRGB>),
首先簡單的確定一下靜態障礙物,即在上一幀和當前幀重疊的區域裡,上一幀存在的點雲在該幀同樣存在,簡單理解就是該障礙物在這兩幀中處於同樣的位置,即靜止狀態!如果要區分動態和靜態障礙物,還需要設計更加嚴格的判斷規則。
這裡,我使用的kdtree查詢最近點,來判斷上一幀的點雲在該幀同樣位置是否存在!由於對PCL庫的使用不熟悉,如果有更好的方法,歡迎私信留言!
if(lastObstacles->size()){
//建立kdtree 結構
ROS_INFO("create kdtree");
for(unsigned int i=0; i<lastObstacles->size(); ++i){
pcl::PointXYZRGB searchPoint;
searchPoint.x = lastObstacles->at(i).x;
searchPoint.y = lastObstacles->at(i).y;
searchPoint.z = lastObstacles->at(i).z;
if(fabs(searchPoint.x - iter->second.x()) <3 &&fabs(searchPoint.y - iter->second.y()) <3 &&fabs(searchPoint.z - iter->second.z()) <3){
//確定是否為靜態障礙物
...
}
}
//剔除掉不為靜態障礙物的點雲
*currentObstacles+=*lastObstacles;
}
*lastObstacles = *subtractedCloud;
首先判斷上一幀的點雲資料,是否在該幀內,即:
fabs(searchPoint.x - iter->second.x()) <3 &&fabs(searchPoint.y - iter->second.y()) <3 &&fabs(searchPoint.z - iter->second.z()) <3
如果在該幀內的話,則在該幀的區域內去查詢,上一幀中出現的點雲是否依然存在,這裡考慮到里程計的誤差,將radius
設定為0.08
,如果發現該點,則認為該點為靜態障礙物,則保留,否則將過濾剔除掉!
pcl::KdTreeFLANN<pcl::PointXYZRGB> kdtree;
kdtree.setInputCloud(subtractedCloud);
std::vector<int> pointIdxRadiusSearch;
std::vector<float> pointRadiusSquaredDistance;
float radius = 0.08;
if ( kdtree.radiusSearch (searchPoint, radius, pointIdxRadiusSearch, pointRadiusSquaredDistance) > 0 ){
inliers->indices.push_back(i);
}
當確定好靜態障礙物之後,通過ExtractIndices
分割演算法提取靜態部分點雲資料。
extract.setInputCloud(lastObstacles);
extract.setIndices(inliers);
extract.setNegative(false);
extract.filter(*lastObstacles);
ROS_INFO("lastObstacles point size:%d",(int)lastObstacles->size());
在該方法中,每次都是在下一幀中確定上一幀裡的障礙物點是否可以加到障礙物層中,而本幀的障礙物點雲,則是直接拼接上去:
*assembledObstacles_ = *currentObstacles + *subtractedCloud;
這樣則每次保留了最新幀的所有障礙物點雲,和之前幀裡認為是靜態障礙物的點雲,此時可以明顯的剔除掉大部分的動態障礙物點雲。
未剔除動態障礙物點雲如下所示,可以明顯的看到身邊走動的人留下的點:
在經過動態剔除之後,可以看見基本上能去除所有動態的點雲:
去除掉動態障礙物之後,便可以使用該點雲資料,來生成2D柵格地圖,用於路徑規劃!!
目前只是簡單的嘗試了一下,細節部分還有待優化。
相關文章
- 動態避障-圖撲自動尋路 3D 視覺化3D視覺化
- 通過類名動態生成物件物件
- 小區確診病例動態分佈圖,怎麼定製防疫地圖?地圖
- echarts之靜態與動態地圖Echarts地圖
- vue圖片插入與設定夜間模式/動態過渡Vue模式
- 教你如何動態生成Sitemap.xml網站地圖!XML網站地圖
- mysql 動態生成測試資料MySql
- Gazebo新增模型並控制模型運動作為動態障礙物(Ubuntu16.04, Gazebo7.16),附錄動態連結庫和靜態連結庫區別模型Ubuntu
- 實現鏈上生態資料資訊無障礙流轉
- Android 幀動畫打造動態ImageViewAndroid動畫View
- 關於 Lumen 如何通過動態版本號配置路由資訊。路由
- APEX 通過PL/SQL動態展示區域中動態內容SQL
- 自動駕駛中的障礙物行為預測自動駕駛
- Scrapy框架-通過scrapy_splash解析動態渲染的資料框架
- 深挖JDK動態代理(二):JDK動態生成後的位元組碼分析JDK
- 如何正確設定動態TextView的textSizeTextView
- 圖表外掛Highcharts的動態化賦值,實現圖表資料的動態化設定顯示賦值
- 直播軟體開發,通過js動態設定字型大小JS
- 動態圖
- nginx-通過lua動態更改upstreamNginx
- 基於結構化資料的文字生成:非嚴格對齊生成任務及動態輕量的GCN生成模型GC模型
- 動態時間
- elementui表格動態資料單元格合併UI
- JS如何動態生成變數名[重點]JS變數
- 通過url動態獲取圖片大小方法總結
- 關於dotnet動態生成controller的問題Controller
- JavaScript動態設定元素背景圖片JavaScript
- cmake:生成靜態庫和動態庫
- vue如何通過變數動態拼接urlVue變數
- 騰訊地圖SDK全面支援無障礙及適老化地圖
- Vue專案資料動態過濾實踐Vue
- js動態時間JS
- 自己做一個table外掛 (一)Ajax獲取資料後動態生成table
- 室內三維3D地圖開發,自動繪製生成地圖軟體3D地圖
- Flutter 動態更改應用程式啟動圖示Flutter
- 2018中國大資料產業生態地圖調研工作正式啟動大資料產業地圖
- DataV動態GPS資料來源在高德地圖上座標轉換方案地圖
- 如何優雅地動態插入資料到UITableViewUIView