国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

3d激光SLAM:LIO-SAM框架---位姿融合輸出

這篇具有很好參考價值的文章主要介紹了3d激光SLAM:LIO-SAM框架---位姿融合輸出。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

前言

LIO-SAM的全稱是:Tightly-coupled Lidar Inertial Odometry via Smoothing and Mapping

從全稱上可以看出,該算法是一個緊耦合的雷達慣導里程計(Tightly-coupled Lidar Inertial Odometry),借助的手段就是利用GT-SAM庫中的方法。

LIO-SAM 提出了一個利用GT-SAM的緊耦合激光雷達慣導里程計的框架。
實現(xiàn)了高精度、實時的移動機器人的軌跡估計和建圖。

在之前的博客講解了imu如何進行預積分,最終以imu的頻率發(fā)布了imu的預測位姿里程計。
3d激光SLAM:LIO-SAM框架---位姿融合輸出

本篇博客主要講解,最終是如何進行位姿融合輸出的

3d激光SLAM:LIO-SAM框架---位姿融合輸出

Eigen::Affine3f

其中功能的核心在于 位姿間的變換,所以要了解 Eigen::Affine3f 部分的內(nèi)容
Affine3f 是eighen庫的 仿射變換矩陣
實際上就是:平移向量+旋轉(zhuǎn)變換組合而成,可以同時實現(xiàn)旋轉(zhuǎn),縮放,平移等空間變換。

Eigen庫中,仿射變換矩陣的大致用法為:

  1. 創(chuàng)建Eigen::Affine3f 對象a。
  2. 創(chuàng)建類型為Eigen::Translation3f 對象b,用來存儲平移向量;
  3. 創(chuàng)建類型為Eigen::Quaternionf 四元數(shù)對象c,用來存儲旋轉(zhuǎn)變換;
  4. 最后通過以下方式生成最終Affine3f變換矩陣: a=b*c.toRotationMatrix();
  5. 一個向量通過仿射變換時的方法是result_vector=test_affine*test_vector;

仿射變換包括:

  • 平移
  • 旋轉(zhuǎn)
  • 放縮
  • 剪切
  • 反射

平移(translation)和旋轉(zhuǎn)(rotation)顧名思義,兩者的組合稱之為歐式變換(Euclidean transformation)或剛體變換(rigid transformation);放縮(scaling)可進一步分為uniform scaling和non-uniform scaling,前者每個坐標軸放縮系數(shù)相同(各向同性),后者不同;如果放縮系數(shù)為負,則會疊加上反射(reflection)——reflection可以看成是特殊的scaling;剛體變換+uniform scaling 稱之為,相似變換(similarity transformation),即平移+旋轉(zhuǎn)+各向同性的放縮;

位姿融合輸出

在imu預積分的節(jié)點中,在main函數(shù)里面 還有一個類的實例對象,那就是

TransformFusion TF

其主要功能是做位姿融合輸出

最終輸出imu的預測結果,與上節(jié)中的imu預測結果的區(qū)別就是:

該對象的融合輸出是基于全局位姿的基礎上再進行imu的預測輸出。全局位姿就是 經(jīng)過回環(huán)檢測后的lidar位姿。

該對象的本質(zhì)功能如下圖
3d激光SLAM:LIO-SAM框架---位姿融合輸出

建圖優(yōu)化會輸出兩種激光雷達的位姿:

  • lidar 增量位姿
  • lidar 全局位姿

其中l(wèi)idar 增量位姿就是 通過 lidar的匹配功能,優(yōu)化出的幀間的相對位姿,通過相對位姿的累積,形成世界坐標系下的位姿
lidar全局位姿 則是在 幀間位姿的基礎上,通過 回環(huán)檢測,再次進行優(yōu)化的 世界坐標系下的位姿,所以對于增量位姿,全局位姿更加精準

在前面提到的發(fā)布的imu的預測位姿是在lidar的增量位姿上基礎上預測的,那么為了更加準確,本部分功能就預測結果,計算到基于全局位姿的基礎上面。

首先看構造函數(shù)

    TransformFusion()
    {
        if(lidarFrame != baselinkFrame)
        {
            try
            {   
                tfListener.waitForTransform(lidarFrame, baselinkFrame, ros::Time(0), ros::Duration(3.0));
                tfListener.lookupTransform(lidarFrame, baselinkFrame, ros::Time(0), lidar2Baselink);
            }
            catch (tf::TransformException ex)
            {
                ROS_ERROR("%s",ex.what());
            }
        }

判斷l(xiāng)idar幀和baselink幀是不是同一個坐標系
通常baselink指車體系
如果不是,
查詢 一下 lidar 和baselink 之間的 tf變換 ros::Time(0) 表示最新的
等待兩個坐標系有了變換
更新兩個的變換 lidar2Baselink

        subLaserOdometry = nh.subscribe<nav_msgs::Odometry>("lio_sam/mapping/odometry", 5, &TransformFusion::lidarOdometryHandler, this, ros::TransportHints().tcpNoDelay());
        subImuOdometry   = nh.subscribe<nav_msgs::Odometry>(odomTopic+"_incremental",   2000, &TransformFusion::imuOdometryHandler,   this, ros::TransportHints().tcpNoDelay());

訂閱地圖優(yōu)化的節(jié)點的全局位姿 和預積分節(jié)點的 增量位姿

        pubImuOdometry   = nh.advertise<nav_msgs::Odometry>(odomTopic, 2000);
        pubImuPath       = nh.advertise<nav_msgs::Path>    ("lio_sam/imu/path", 1);

發(fā)布兩個信息 odomTopic ImuPath

然后看第一個回調(diào)函數(shù) lidarOdometryHandler

    void lidarOdometryHandler(const nav_msgs::Odometry::ConstPtr& odomMsg)
    {
        std::lock_guard<std::mutex> lock(mtx);
        lidarOdomAffine = odom2affine(*odomMsg);
        lidarOdomTime = odomMsg->header.stamp.toSec();
    }

將全局位姿保存下來

  • 將ros的odom格式轉(zhuǎn)換成 Eigen::Affine3f 的形式
  • 將最新幀的時間保存下來

第二個回調(diào)函數(shù)是 imuOdometryHandler
imu預積分之后所發(fā)布的imu頻率的預測位姿

    void imuOdometryHandler(const nav_msgs::Odometry::ConstPtr& odomMsg)
    {
        static tf::TransformBroadcaster tfMap2Odom;
        static tf::Transform map_to_odom = tf::Transform(tf::createQuaternionFromRPY(0, 0, 0), tf::Vector3(0, 0, 0));

建圖的話 可以認為 map坐標系和odom坐標系 是重合的(初始化時刻)

tfMap2Odom.sendTransform(tf::StampedTransform(map_to_odom, odomMsg->header.stamp, mapFrame, odometryFrame));

發(fā)布靜態(tài)tf,odom系和map系 他們是重合的

imuOdomQueue.push_back(*odomMsg);

imu得到的里程計結果送入到這個隊列中

        if (lidarOdomTime == -1)
            return;

如果沒有收到lidar位姿 就returen

        while (!imuOdomQueue.empty())
        {
            if (imuOdomQueue.front().header.stamp.toSec() <= lidarOdomTime)
                imuOdomQueue.pop_front();
            else
                break;
        }

彈出時間戳 小于 最新 lidar位姿時刻之前的imu里程計數(shù)據(jù)

        Eigen::Affine3f imuOdomAffineFront = odom2affine(imuOdomQueue.front());
        Eigen::Affine3f imuOdomAffineBack = odom2affine(imuOdomQueue.back());
        Eigen::Affine3f imuOdomAffineIncre = imuOdomAffineFront.inverse() * imuOdomAffineBack;

計算最新隊列里imu里程計的增量

Eigen::Affine3f imuOdomAffineLast = lidarOdomAffine * imuOdomAffineIncre;

增量補償?shù)絣idar的位姿上去,就得到了最新的預測的位姿

        float x, y, z, roll, pitch, yaw;
        pcl::getTranslationAndEulerAngles(imuOdomAffineLast, x, y, z, roll, pitch, yaw);

分解成平移 + 歐拉角的形式

        nav_msgs::Odometry laserOdometry = imuOdomQueue.back();
        laserOdometry.pose.pose.position.x = x;
        laserOdometry.pose.pose.position.y = y;
        laserOdometry.pose.pose.position.z = z;
        laserOdometry.pose.pose.orientation = tf::createQuaternionMsgFromRollPitchYaw(roll, pitch, yaw);
        pubImuOdometry.publish(laserOdometry);

發(fā)送全局一致位姿的 最新位姿

        static tf::TransformBroadcaster tfOdom2BaseLink;
        tf::Transform tCur;
        tf::poseMsgToTF(laserOdometry.pose.pose, tCur);
        if(lidarFrame != baselinkFrame)
            tCur = tCur * lidar2Baselink;

更新tf

        tf::StampedTransform odom_2_baselink = tf::StampedTransform(tCur, odomMsg->header.stamp, odometryFrame, baselinkFrame);
        tfOdom2BaseLink.sendTransform(odom_2_baselink);

更新odom到baselink的tf

        static nav_msgs::Path imuPath;
        static double last_path_time = -1;
        double imuTime = imuOdomQueue.back().header.stamp.toSec();
        // 控制一下更新頻率,不超過10hz
        if (imuTime - last_path_time > 0.1)
        {
            last_path_time = imuTime;
            geometry_msgs::PoseStamped pose_stamped;
            pose_stamped.header.stamp = imuOdomQueue.back().header.stamp;
            pose_stamped.header.frame_id = odometryFrame;
            pose_stamped.pose = laserOdometry.pose.pose;
            // 將最新的位姿送入軌跡中
            imuPath.poses.push_back(pose_stamped);
            // 把lidar時間戳之前的軌跡全部擦除
            while(!imuPath.poses.empty() && imuPath.poses.front().header.stamp.toSec() < lidarOdomTime - 1.0)
                imuPath.poses.erase(imuPath.poses.begin());

            // 發(fā)布軌跡,這個軌跡實踐上是可視化imu預積分節(jié)點輸出的預測值
            if (pubImuPath.getNumSubscribers() != 0)
            {
                imuPath.header.stamp = imuOdomQueue.back().header.stamp;
                imuPath.header.frame_id = odometryFrame;
                pubImuPath.publish(imuPath);
            }
        }
    }

發(fā)布imu里程計的軌跡

  • 控制一下更新頻率,不超過10hz
  • 將最新的位姿送入軌跡中
  • 把lidar時間戳之前的軌跡全部擦除
  • 發(fā)布軌跡,這個軌跡實踐上是可視化imu預積分節(jié)點輸出的預測值

result

3d激光SLAM:LIO-SAM框架---位姿融合輸出
其中粉色的部分就是imu的位姿融合輸出path文章來源地址http://www.zghlxwxcb.cn/news/detail-419191.html

到了這里,關于3d激光SLAM:LIO-SAM框架---位姿融合輸出的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • LIO-SAM學習與運行測試數(shù)據(jù)集

    LIO-SAM學習與運行測試數(shù)據(jù)集

    環(huán)境配置: ubuntu18.04, ros1(ros-melodic) 注: 在ros1的kinetic, melodic, noetic(https://github.com/TixiaoShan/LIO-SAM/issues/206)上被測試過; ros1的github代碼: https://github.com/TixiaoShan/LIO-SAM/tree/master ros2的github代碼: https://github.com/TixiaoShan/LIO-SAM/tree/ros2 論文:LIO-SAM:Tightly-coupled Lidar Inertial Odometry vis Smoothin

    2023年04月16日
    瀏覽(24)
  • LIO-SAM從0到1運行自己的數(shù)據(jù)集

    LIO-SAM從0到1運行自己的數(shù)據(jù)集

    ? 筆者在學習LIO_SAM時踩了不少坑,在此記錄從開始到最后整個踩坑過程。文中參考了很多大佬的文章,我只是個搬運工。 可以直接跳到第二部分從0到1實現(xiàn) 有疑問可以隨時聯(lián)系我,歡迎交流。 ?種激光慣導緊耦合的SLAM框架,可在室內(nèi)和室外實現(xiàn)效果不錯的建圖。 (1) Image

    2024年02月02日
    瀏覽(44)
  • 《LIO-SAM閱讀筆記》-為何要引入增量式里程計?

    前言: LIO-SAM在后端中同時維護著兩個里程計,一個是增量式里程計,一個是優(yōu)化后的里程計,其中優(yōu)化后的里程計是經(jīng)過imu、回環(huán)、gps因子圖聯(lián)合優(yōu)化后的結果,是整個系統(tǒng)中最準確的位姿估計,那么為什么還需要維護增量式里程計呢? 以下是我的理解 ,不一定正確,如有

    2024年01月22日
    瀏覽(23)
  • Ubuntu20.04 ROS noetic中編譯和運行LIO-SAM

    Ubuntu20.04 ROS noetic中編譯和運行LIO-SAM

    本文是對自己學習過程的一個記錄和總結,如果內(nèi)容有誤,請大家指點,感謝。 ????????本文是在已經(jīng)安裝好ROS環(huán)境中進行的,不需要提前安裝其他庫,只需按照步驟進行操作,便能完成LIO-SAM的編譯和運行,并且每一步都有我執(zhí)行時的截圖進行參考。 1.【創(chuàng)建工作空間】

    2024年03月24日
    瀏覽(46)
  • Ubuntu20.04安裝LeGO-LOAM和LIO-SAM

    Ubuntu20.04安裝LeGO-LOAM和LIO-SAM

    Ubuntu20.04安裝LIO-SAM真是挺折磨人的,填了一路的坑,在此記錄分享一下,為大家安裝編譯算法提供一個全面的參考。 目錄 1. GTSAM安裝 1.1 GTSAM安裝準備 1.1.1 目錄/usr/local/lib下清理gatsam 1.1.2 目錄/opt/ros/noetic/lib/下清理gtsam 1.2 GTSAM安裝過程 2. LIO-SAM算法依賴項安裝 3. LeGO-LOAM算法編

    2024年04月28日
    瀏覽(43)
  • Ubuntu 20.04 與 ROS noetic安裝 gtsam 編譯 LIO-SAM 的適配版本

    本文簡介在 Ubuntu 20.04 下以 ROS noetic 為基礎安裝 GTSAM 并成功編譯 LIO-SAM 的適配版本。 安裝前請檢查cmake 和boost版本,Ubuntu 20.04.06自帶cmake(= 3.0) 和libboost-all-dev(= 1.65)已滿足要求。編譯LIO-SAM適配版本的其它依賴包也已滿足要求(主要是PCL, Eigen和OpenCV等, 詳見其CMakeList)。 當前

    2024年02月13日
    瀏覽(26)
  • LOAM、Lego-liom、Lio-sam軌跡保存,與Kitti數(shù)據(jù)集真值進行評估

    LOAM、Lego-liom、Lio-sam軌跡保存,與Kitti數(shù)據(jù)集真值進行評估

    ????????首先需要保存軌跡,軌跡保存參考下面的代碼,最好自己 添加一個節(jié)點 (如下圖),用新節(jié)點來訂閱和保存軌跡至txt文件,因為直接在算法的線程中加入此步驟我試了好像保存不了,好像是在不同線程間的參數(shù)傳遞格式的問題(也可能是我個人的問題)。 ????

    2023年04月08日
    瀏覽(211)
  • 在Ubuntu20.04系統(tǒng)上LIO-SAM跑KITTI數(shù)據(jù)集和自己數(shù)據(jù)集代碼修改

    在Ubuntu20.04系統(tǒng)上LIO-SAM跑KITTI數(shù)據(jù)集和自己數(shù)據(jù)集代碼修改

    參考我的另一篇文章: Ubuntu20.04下的編譯與運行LIO-SAM【問題解決】 因為liosam 要求輸入的點云每個點都有ring 信息和相對時間time信息,目前的雷達驅(qū)動基本具備這些信息,但是早期的KITTI數(shù)據(jù)集不具備,所以代碼要自己計算一下 ring和time。方法可以參考lego-loam中這部分內(nèi)容,

    2024年02月01日
    瀏覽(20)
  • 6.如何利用LIO-SAM生成可用于機器人/無人機導航的二維/三維柵格地圖--以octomap為例

    6.如何利用LIO-SAM生成可用于機器人/無人機導航的二維/三維柵格地圖--以octomap為例

    目錄 1 octomap的安裝 2 二維導航節(jié)點的建立及柵格地圖的構建 3 三維柵格地圖的建立 ??????? 這里采用命令安裝: ??????? 這樣子就是安裝好了。 ??????? 我們進入liosam的工作空間下的launch文件夾: ??????? 新建一個launch文件,就叫octomap2D.launch ??????? 將下面的

    2024年01月16日
    瀏覽(227)
  • 激光SLAM:Faster-Lio 算法編譯與測試

    激光SLAM:Faster-Lio 算法編譯與測試

    Faster-LIO是基于FastLIO2開發(fā)的。FastLIO2是開源LIO中比較優(yōu)秀的一個,前端用了增量的kdtree(ikd-tree),后端用了迭代ESKF(IEKF),流程短,計算快。Faster-LIO則把ikd-tree替換成了iVox,順帶優(yōu)化了一些代碼邏輯,實現(xiàn)了更快的LIO。在典型的32線激光雷達中可以取得100-200Hz左右的計算頻

    2024年02月02日
    瀏覽(15)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包