精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

反光板導航SLAM:VEnus代碼淺析

3D視覺工坊 ? 來源:古月居 ? 2023-03-14 10:54 ? 次閱讀

通過研究具體的代碼我們可以簡單了解VEnus中對于反光柱定位的具體流程。

1、IntensityExtraction::Extract

IntensityExtraction::IntensityRange2D &cloud,
                 VEnus::IntensityRange2D &candidate_cloud)

Extract函數的主要作用是從激光點云中提取出高反點,然后存儲到對應的容器中。輸入的數據類型為

VEnus::IntensityRange2D

IntensityRange2D數據類型是定義在sensor/proto/sensor.proto文件內

message IntensityRange2D
{
  int64 timestamp = 1;
  string frame_id = 2;
  repeated IntensityPoint2D points = 3;
}

IntensityPoint2D的數據格式如下:

message IntensityPoint2D
{
  float x = 1;
  float y = 2;
  float intensity = 3;
}

repeated 類似于std的vector,可以用來存放N個相同類型的內容。所以這個函數的輸入cloud是一系列帶有強度信息的2D坐標點。函數的candidate_cloud代表的是匹配到的可能的反光柱點。所以它們數據結構是一樣的。

然后是函數實現,這個函數其實很簡單,它只是對整個點云進行了一次遍歷,取連續的n個點,這個由一個參數intensity_median_filter_param決定,如果反光柱粗一點的或者激光分辨率高一點的話可以設置大一點,否則的話可以設置小一點,例如3。

然后對這些點進行判斷,只要其中有一半的點云強度超過閾值intensity_threshold則認為這里存在一個反光柱,將其中的點云強度處于中間值的那個點存入到容器candidate_cloud。這里其實有點隨機性在里面,因為沒有把所有的點都加入到容器中,所以是存在一定遺漏的。

2、DBscanAssociation::Association

DBscanAssociation::IntensityRange2D& candidate_cloud,
                  VEnus::Feature2DList& feature_list)

前面我們提取出了反光柱的中心點,但是這里的點云中可能會出現很多個點代表同一個反光柱的情況。所以這個函數即是對剛才的這些點進行一次類似于聚類的操作。

candidate_cloud為第一步中選出來的高反點。feature_list為可能的反光柱中心。然后我們具體看一下函數實現:

Association的第一部分主要是遍歷了所有點,通過調用expand_cluster函數進行一個分類:

 for (; iter < dataset.end(); ++iter) {
 ? ?if (iter->status == UNCLASSIFIED) {
   //聚類,將所有高反點根據相互之間距離分類,分類完成的點status為CLASSIFIED,同時處于同一類的點ID一致。
   if (expand_cluster(iter, cluster_id)) {
    cluster_id++;
   }
  }
 }

dataset里面存儲的就是當前幀的高反點,來自于candidate_cloud,數據類型為:

PointDBSCAN(double px, double py) {
   x = px;
   y = py;
   status = UNCLASSIFIED;
   id = 0;
  }

可以看到對于每一個高反點,都有坐標x/y、狀態status以及id等幾個屬性。初始狀態下狀態都為UNCLASSIFIED未區分,id都為0。然后函數對于每個點調用expand_cluster函數。

這個函數的作用是:對于每一個candidate_cloud,找到所有candidate_cloud中的點與其接近的點(兩者間距離小于一定閾值)這些點的status都會被設置為CLASSIFIED防止重復判斷。id都會被設置為相同代表同一個反光柱。

通過這種方式可以將所有點都劃分成一個個點的區域,每個區域代表了一個反光柱。

在劃分完成后,當然是要對每個區域做處理:

//按照ID將所有點放到map容器中
 unordered_map > feature_dict;
 iter = dataset.begin();
 for (; iter < dataset.end(); ++iter) {
 ? ?if (iter->status == CLASSIFIED) {
   feature_dict[iter->id].push_back(iter - dataset.begin());
  }
 }
 //找到每一組點的中心點的坐標,存放到tmp_res里面
 vector > tmp_res;
 for (auto pr : feature_dict) {
  double center_x = 0;
  double center_y = 0;
  for (int idx : pr.second) {
   center_x += dataset.at(idx).x;
   center_y += dataset.at(idx).y;
  }
  int sz = pr.second.size();
  //ROS_INFO("center point,x = %f,y = %f",center_x / double(sz),center_y / double(sz));
  tmp_res.push_back(std::make_pair(center_x / double(sz), center_y / double(sz)));
 }
 //判斷每個中心點之間的距離,將距離過近的中心點視為代表同一個反光柱,更新容器中反光柱中心點坐標
 merge_cluster(tmp_res);

首先這里通過map維護了每一個待選的反光柱信息,所有的同一個反光柱的信息放到一起。

進行一個劃分,然后對每一類點集調用merge_cluster進行一個中心點的求取。求取的方式其實很簡單就是簡單相加求平均。這樣子就可以知道了所有反光柱中心點所在的位置。

3、CartoMapping::InsertFeatureList

這個函數的功能還是挺多的,包括匹配,位姿估計,位姿優化等一系列其實都是在這個函數中實現的。詳細看一下這個函數具體情況:

3.1 初始化

InsertFeatureList函數的第一步判斷了feature_points容器是否為空,這里面存儲的是全局坐標下的反光柱。這個容器為空說明目前沒有已經確定的反光柱。則進行初始化。

if (feature_points.empty())

初始化的方式比較簡單,將第一幀的反光柱坐標存儲到feature_points中作為初始狀態下反光柱的中心坐標,然后更新FeatureGraph。

注意到這里的函數:InsertToFeatureGraph,這個函數的意義是對于每一個待插入的點(反光柱),計算它與周圍反光柱之間的距離,然后存儲到feature_graph中。注意到feature_graph的數據類型

第一個int為對應的feature_points的ID,第二個std::unordered_map中的int為與這個feature_points相互關聯的反光柱點的ID,后面的double類型數據為兩個點之間的距離。

3.2 特征點匹配

SiftNewFeaturePoints(input_fpts, hit_id_pair, wait_insert);

在確認初始化完成的情況下,調用SiftNewFeaturePoints函數進行反光柱的匹配。這個函數有三個參數:input_fpts為前面識別出來的反光柱坐標,hit_id_pair為當前幀反光柱與世界坐標系下的反光柱匹配上的ID,wait_insert為當前幀中沒能跟世界坐標系下反光柱所匹配上的點的ID。函數主要執行了以下工作:

首先,對于所有當前點,建立一個局部的local_feature_graph,記錄當前點與點之間的距離。

然后,對于每一個當前幀的點,使用其局部local_feature_graph與全局點進行匹配。

注意這里不是點與點的匹配而是類似于線與線的匹配,如果一個點到其他點的距離與全局點中某個點到其周圍點的距離基本一致,則認為這兩個點是匹配上了的,這時候會把這一對ID存放到hit_id_pair中。這個方式其實應該是有問題的,如果兩個點到周圍點的距離都很接近,就可能發生誤匹配。

最后,對于input_fpts中剩下沒有匹配到的點,則會將其存放到wait_insert中,這個數據代表這里檢測出一個反光柱但是在全局中沒有,后面需要另外處理。

3.3 初始位姿估計

ComputeCurrentPose(localization_hit, pose)

這個函數emmm其實我沒看,因為似乎它基本就沒有正確計算出來過。不過也不要緊,直接看下一步

3.4 位姿優化

OptimizeCurrentPose(localization_hit, pose);

OptimizeCurrentPose中需要輸入兩個變量:localization_hit里面存放的是當前幀下匹配點全局點之間的坐標。

pose是機器人當前初步估計下的位姿,按照邏輯它應該會來自于步驟3,但是由于3總是出問題所以大部分情況下它來自于上一次估計出來的位姿。

然后根據輸入的約束關系localization_hit以及初始位姿pose,調用ceres優化得到一個新的位姿:

 ceres::Problem problem;
 double pose[3] = {robot_pose.x(), robot_pose.y(), robot_pose.theta()};


 for (auto fpt_pair : match_result) {
  problem.AddResidualBlock(new ceres::AutoDiffCostFunction(
                 new FeaturePairCost(fpt_pair.second, fpt_pair.first)),
               new ceres::CauchyLoss(0.2), pose);
 }


 ceres::Options options;
 options.linear_solver_type = ceres::DENSE_QR;
 options.minimizer_progress_to_stdout = false;


 ceres::Summary summary;
 ceres::Solve(options, &problem, &summary);

最后這里輸出得到的是一個新的優化后的位姿pose

3.5 更新反光柱信息

注意到前面3.2中還有一個東西沒有處理,就是返回的wait_insert容器。

這個里面存放的是當時檢測到的反光柱但是這個反光柱沒能與地圖上其他地方的反光柱相匹配上,說明它可能是一個新的反光柱,對于這些信息我們要將其更新到最新的反光柱信息中:

 Eigen::Isometry2d matrixT = Eigen::Identity();
 matrixT.pretranslate(Eigen::Vector2d(pose.x(), pose.y()));
 matrixT.rotate(pose.theta());
 //  Eigen::Isometry2d matrixTinv = matrixT.inverse();


 vector > new_fpt_wait_insert;
 vector new_fpt_assigned_id;
 for (auto unhit : wait_insert) {
  Eigen::Vector3d local_fpt(unhit.first, unhit.second, 1.0);
  auto global_fpt = matrixT * local_fpt;


  auto new_fpt = make_pair(global_fpt[0], global_fpt[1]);
  feature_points[feature_point_cnt] = new_fpt;
  new_fpt_wait_insert.push_back(new_fpt);
  new_fpt_assigned_id.push_back(feature_point_cnt);
  feature_point_cnt++;
 }

首先是通過矩陣matrixT將這些反光柱點轉到世界坐標系下,然后再根據初始化時候的方式一樣更新feature_points容器,存儲新的反光柱信息。當然最后還要調用:

InsertToFeatureGraph(new_fpt_wait_insert, new_fpt_assigned_id);

來更新feature_graph,也就是反光柱之間的距離信息。

通過以上一系列步驟我們就可以得到一個連續的基于反光柱匹配的位姿估計算法。當然這個算法還有一點小問題,比如線匹配意味著每一個反光柱到周圍反光柱之間的距離都要獨一無二,否則就可能出現誤匹配的問題。

匹配閾值也不能設計的太大,否則也會發生匹配錯誤,但是設計的太小就可能導致本來是一個地方的反光柱沒有成功匹配上,最后該位置會生成出很多個反光柱,類似于這樣:

06b9ee62-c003-11ed-bfe3-dac502259ad0.png

這里先介紹完代碼思路,具體的代碼實現以及優化過程下一章單獨展開介紹。

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 導航
    +關注

    關注

    7

    文章

    523

    瀏覽量

    42379
  • 函數
    +關注

    關注

    3

    文章

    4307

    瀏覽量

    62434
  • 代碼
    +關注

    關注

    30

    文章

    4751

    瀏覽量

    68359
  • SLAM
    +關注

    關注

    23

    文章

    419

    瀏覽量

    31788
  • Venus
    +關注

    關注

    0

    文章

    7

    瀏覽量

    2665

原文標題:反光板導航SLAM:VEnus代碼淺析

文章出處:【微信號:3D視覺工坊,微信公眾號:3D視覺工坊】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    反光板的選用

    推薦一款用在智能小車上紅外測距傳感器的反光板吧{:19:}
    發表于 07-19 12:57

    激光導航AGV控制系統解決方案(無反光板非工控機)

    LNM-v1.0(工業級)無軌導航無軌導航LNM-v1.0激光導航模塊是一款基于室內復雜壞境的導航模塊,該模塊通過激光雷達對室內環境進行掃描,自主構建地圖并自主規劃路徑行走。LNM模塊
    發表于 06-10 14:07

    AGV激光雷達SLAM定位導航技術

    agv自由行走的問題。  定位和導航一般是相輔相成,傳統的定位導航方式(電磁導航、磁條導航)的優缺點如下方圖表所示,這些方案的優點和局限性都很明顯。稍微靈活點的
    發表于 11-09 15:59

    SLAM技術的應用及發展現狀

    結合激光雷達或者攝像頭的方法,讓掃地機可以高效繪制室內地圖,智能分析和規劃掃地環境,成功讓自己步入了智能導航的陣列。除了掃地機之外,SLAM技術在其他服務機器人(例如商場導購機器人、銀行機器人
    發表于 12-06 10:25

    激光SLAM與視覺SLAM有什么區別?

    機器人定位導航中,目前主要涉及到激光SLAM與視覺SLAM,激光SLAM在理論、技術和產品落地上都較為成熟,因而成為現下最為主流的定位導航
    發表于 07-05 06:41

    怎么利用51單片機去實現風扇轉速測量的源程序+電路圖呢

    項目功能:將被測風扇葉片(三葉風扇)置于紅外光電傳感器和其反光板之間,當光電傳感器接收到對面的反光板反射回來的信號時(即葉片間的空隙通過時)輸出低電平,當光電傳感器沒收到反光板反射回的信號時(即葉片
    發表于 09-08 06:59

    有沒有辦法用VL53L0X 區分反光板和其他反光材料?

    如您所知,無論反光片表面角度如何,反光片都非常明亮。然而,其他反光材料,如鏡子,只有在表面角度垂直于 VL53L0X 時才會亮。在這種情況下,僅憑亮度的差異是很難區分的。 有沒有辦法用 VL53L0X 區分
    發表于 12-27 06:24

    SLAM算法在AGV小車中的使用

    導航一般是相輔相成,傳統的定位導航方式(電磁導航、磁條導航)的優缺點如下方圖表所示,這些方案的優點和局限性都很明顯。稍微靈活點的導航定位方
    發表于 09-11 16:01 ?1269次閱讀

    艾吉威:智慧物流“剛需”下的推陳出新

    艾吉威成功將無反光板激光自主導航叉車AGV運用于輪胎制造領域,成為全球首例大規模運用無標識導航AGV的案例。
    的頭像 發表于 06-19 17:47 ?2758次閱讀

    無人叉車的種類有哪些,關于它的選擇方法的介紹

    的無人叉車也成為目前廣大用戶所關心的問題。 我們在選擇無人叉車的時候,要了解它們的性能和結構,其中激光導航叉車可分為分為有反光板和無反光板兩種: 我們在選擇有反光板激光
    發表于 10-20 12:06 ?2340次閱讀

    關于SEER SRC核心控制器的八問八答

    。 問:SEER 機器人支持哪些導航呢? 答:激光 SLAM 導航,激光反光板導航,二維碼導航
    的頭像 發表于 11-03 18:18 ?2171次閱讀

    激光SLAM搬運式叉車SFL-CBD20-S

    SFL-CBD20-S采用了目前最穩定最主流的導航方式——激光SLAM導航,無反光板,部署方便,內置仙工智能(SEER)SRC核心控制器,可提供地圖構建、定位、
    的頭像 發表于 02-04 16:43 ?2420次閱讀

    反光導航開發與實驗

    VEnus算法對于反光導航的基本思路,其主要分為了高反點提取、高反點聚類查找中心、高反點與已知反光柱位姿匹配以及調用ceres庫進行位姿優化等步驟。
    的頭像 發表于 07-14 15:37 ?595次閱讀
    <b class='flag-5'>反光</b>柱<b class='flag-5'>導航</b>開發與實驗

    淺析基于SLAM的機器人自主定位導航

    正如圖中所示,機器人自主定位導航技術中包括:定位和地圖創建(SLAM)與路徑規劃和運動控制兩個部分,而SLAM本身只是完成機器人的定位和地圖創建,二者有所區別。
    發表于 08-03 11:12 ?921次閱讀
    <b class='flag-5'>淺析</b>基于<b class='flag-5'>SLAM</b>的機器人自主定位<b class='flag-5'>導航</b>

    光電傳感器反光板能否用鏡子替代?

    反光板是所有回歸反射型光電傳感器必不可少的配套元件,它的使命是將光電傳感器中的發射器發出去的光反射回來,以便傳感器接收器能夠接收到光信號。那么一定有不少工程師想過這個問題鏡子也可以反光可以用鏡子
    的頭像 發表于 07-02 08:24 ?502次閱讀
    光電傳感器<b class='flag-5'>反光板</b>能否用鏡子替代?