0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

LIO-SAM框架位姿融合輸出

麥辣雞腿堡 ? 來源:古月居 ? 作者:月照銀海似蛟龍 ? 2023-11-24 17:28 ? 次閱讀

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

其主要功能是做位姿融合輸出,最終輸出imu的預(yù)測結(jié)果,與上節(jié)中的imu預(yù)測結(jié)果的區(qū)別就是:

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

圖片

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

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

其中l(wèi)idar 增量位姿就是 通過 lidar的匹配功能,優(yōu)化出的幀間的相對位姿,通過相對位姿的累積,形成世界坐標(biāo)系下的位姿

lidar全局位姿 則是在 幀間位姿的基礎(chǔ)上,通過 回環(huán)檢測,再次進(jìn)行優(yōu)化的 世界坐標(biāo)系下的位姿,所以對于增量位姿,全局位姿更加精準(zhǔn)

在前面提到的發(fā)布的imu的預(yù)測位姿是在lidar的增量位姿上基礎(chǔ)上預(yù)測的,那么為了更加準(zhǔn)確,本部分功能就預(yù)測結(jié)果,計算到基于全局位姿的基礎(chǔ)上面。首先看構(gòu)造函數(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幀是不是同一個坐標(biāo)系,通常baselink指車體系,如果不是,查詢 一下 lidar 和baselink 之間的 tf變換 ros::Time(0) 表示最新的,等待兩個坐標(biāo)系有了變換,更新兩個的變換 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é)點(diǎn)的全局位姿 和預(yù)積分節(jié)點(diǎn)的 增量位姿

pubImuOdometry   = nh.advertise&lt;nav_msgs::Odometry&gt;(odomTopic, 2000);        pubImuPath       = nh.advertise&lt;nav_msgs::Path&gt;    ("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預(yù)積分之后所發(fā)布的imu頻率的預(yù)測位姿

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));

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

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

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

imuOdomQueue.push_back(*odomMsg);

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

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;

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

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ā)布軌跡,這個軌跡實(shí)踐上是可視化imu預(yù)積分節(jié)點(diǎn)輸出的預(yù)測值            if (pubImuPath.getNumSubscribers() != 0)            {                imuPath.header.stamp = imuOdomQueue.back().header.stamp;                imuPath.header.frame_id = odometryFrame;                pubImuPath.publish(imuPath);            }        }    }

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

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 框架
    +關(guān)注

    關(guān)注

    0

    文章

    398

    瀏覽量

    17405
  • 檢測
    +關(guān)注

    關(guān)注

    5

    文章

    4413

    瀏覽量

    91305
  • SAM
    SAM
    +關(guān)注

    關(guān)注

    0

    文章

    111

    瀏覽量

    33480
  • 激光雷達(dá)
    +關(guān)注

    關(guān)注

    967

    文章

    3921

    瀏覽量

    189445
收藏 人收藏

    評論

    相關(guān)推薦

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

    Faster-LIO是基于FastLIO2開發(fā)的。FastLIO2是開源LIO中比較優(yōu)秀的一個,前端用了增量的kdtree(ikd-tree),后端用了迭代ESKF(IEKF),流程短,計算快
    的頭像 發(fā)表于 01-12 10:22 ?2633次閱讀
    激光SLAM:Faster-<b class='flag-5'>Lio</b>算法編譯與測試

    #硬聲創(chuàng)作季 LIO-SAM:一種緊耦合激光雷達(dá)-慣性里程計

    激光SAM計算機(jī)視覺
    Mr_haohao
    發(fā)布于 :2022年10月12日 15:21:47

    基于多傳感器信息融合的物體位姿檢測方法

    提出了利用攝像機(jī)和超聲傳感器信息融合對機(jī)器人操作對象進(jìn)行姿檢測的方法。該方法通過單幅圖像獲取目標(biāo)點(diǎn)在圖像中的理想坐標(biāo),求得投影矢量的方向,然后通過機(jī)器人末端的
    發(fā)表于 06-23 10:43 ?13次下載

    一種移動機(jī)器人的姿檢測模塊設(shè)計_方慶山

    一種移動機(jī)器人的姿檢測模塊設(shè)計_方慶山
    發(fā)表于 03-19 11:45 ?1次下載

    工業(yè)機(jī)器人姿準(zhǔn)確度_重復(fù)性測量儀設(shè)計

    激光 姿測量
    發(fā)表于 08-07 17:36 ?4次下載

    裝配機(jī)器人姿誤差建模與補(bǔ)償研究

    姿精度是研究機(jī)器人的關(guān)鍵性能指標(biāo)。國內(nèi)外學(xué)者一直關(guān)注并不斷研究發(fā)現(xiàn)多種多樣的誤差補(bǔ)償方法如硬件補(bǔ)償法、攝動補(bǔ)償算法和直接修正算法對機(jī)器人的姿誤差進(jìn)行補(bǔ)償。陳明哲與張啟先采用雅可比矩
    發(fā)表于 04-20 16:56 ?1次下載
    裝配機(jī)器人<b class='flag-5'>位</b><b class='flag-5'>姿</b>誤差建模與補(bǔ)償研究

    Microchip為PIC?和SAM單片機(jī)提供統(tǒng)一的軟件開發(fā)框架_MPLAB Harmony v3

    Microchip Technology 今日宣布推出最新版本的統(tǒng)一軟件框架MPLAB? Harmony 3.0(v3),首次為SAM MCU提供支持。
    發(fā)表于 03-25 16:50 ?1284次閱讀

    基于自適應(yīng)模糊控制方法的噴桿姿主動控制器

    基于自適應(yīng)模糊控制方法的噴桿姿主動控制器
    發(fā)表于 07-01 16:11 ?8次下載

    一個利用GT-SAM的緊耦合激光雷達(dá)慣導(dǎo)里程計的框架

    LIO-SAM 提出了一個利用GT-SAM的緊耦合激光雷達(dá)慣導(dǎo)里程計的框架。實(shí)現(xiàn)了高精度、實(shí)時的移動機(jī)器人的軌跡估計和建圖。
    的頭像 發(fā)表于 10-31 09:25 ?2325次閱讀

    如何去使用深度學(xué)習(xí)的model SLAM姿估計的自訓(xùn)練方法

    如何進(jìn)行魯棒的姿圖優(yōu)化來得到比較可靠的SLAM估計?提出了一種自動協(xié)方差調(diào)整的姿圖優(yōu)化,這里如果展開講可能需要很長時間,在這邊只做一個比較宏觀的介紹。
    發(fā)表于 03-29 09:53 ?764次閱讀

    常見姿估計算法的比較:三角測量、PNP、ICP

    相機(jī)標(biāo)定工程用到的是DLT(直接線性變換算法) ,它是一類PnP問題 (3D-2D) 。請參考【姿估計 | 視覺SLAM| 筆記】常見姿估計算法的比較 PnP
    發(fā)表于 06-07 11:56 ?0次下載
    常見<b class='flag-5'>位</b><b class='flag-5'>姿</b>估計算法的比較:三角測量、PNP、ICP

    從8AVR到32SAM D21 MCU的應(yīng)用程序移植

    電子發(fā)燒友網(wǎng)站提供《從8AVR到32SAM D21 MCU的應(yīng)用程序移植.pdf》資料免費(fèi)下載
    發(fā)表于 09-20 11:41 ?1次下載
    從8<b class='flag-5'>位</b>AVR到32<b class='flag-5'>位</b><b class='flag-5'>SAM</b> D21 MCU的應(yīng)用程序移植

    從8PIC18F到32SAM D21 MCU的應(yīng)用程序移植

    電子發(fā)燒友網(wǎng)站提供《從8PIC18F到32SAM D21 MCU的應(yīng)用程序移植.pdf》資料免費(fèi)下載
    發(fā)表于 09-20 11:22 ?0次下載
    從8<b class='flag-5'>位</b>PIC18F到32<b class='flag-5'>位</b><b class='flag-5'>SAM</b> D21 MCU的應(yīng)用程序移植

    3d激光SLAMLIO-SAM框架介紹

    里程計的框架。 實(shí)現(xiàn)了高精度、實(shí)時的移動機(jī)器人的軌跡估計和建圖。 本篇博客重點(diǎn)解讀LIO-SAM框架下IMU預(yù)積分功能數(shù)據(jù)初始化代碼部分 LIO-SAM 的代碼主要在其主目錄內(nèi)的src
    的頭像 發(fā)表于 11-22 15:04 ?996次閱讀
    3d激光SLAMLIO-<b class='flag-5'>SAM</b><b class='flag-5'>框架</b>介紹

    LIO-SAM框架是什么

    里程計的框架。實(shí)現(xiàn)了高精度、實(shí)時的移動機(jī)器人的軌跡估計和建圖。在之前的博客講解了imu如何進(jìn)行預(yù)積分,最終以imu的頻率發(fā)布了imu的預(yù)測位姿里程計。 本篇博客主要講解,最終是如何進(jìn)行姿
    的頭像 發(fā)表于 11-24 17:08 ?1123次閱讀
    <b class='flag-5'>LIO-SAM</b><b class='flag-5'>框架</b>是什么