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

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

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

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

3D視覺工坊 ? 來源:古月居 ? 作者:月照銀海似蛟龍 ? 2022-10-31 09:25 ? 次閱讀

前言

LIO-SAM的全稱是:Tightly-coupled Lidar Inertial Odometry via Smoothing and Mapping,從全稱上可以看出,該算法是一個(gè)緊耦合的雷達(dá)慣導(dǎo)里程計(jì)(Tightly-coupled Lidar Inertial Odometry),借助的手段就是利用GT-SAM庫中的方法。

LIO-SAM 提出了一個(gè)利用GT-SAM的緊耦合激光雷達(dá)慣導(dǎo)里程計(jì)的框架。實(shí)現(xiàn)了高精度、實(shí)時(shí)的移動機(jī)器人的軌跡估計(jì)和建圖。在之前的博客講解了imu如何進(jìn)行預(yù)積分,最終以imu的頻率發(fā)布了imu的預(yù)測位姿里程計(jì)。

fbb2dc46-58aa-11ed-a3b6-dac502259ad0.png

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

fbcbbef0-58aa-11ed-a3b6-dac502259ad0.png

Eigen::Affine3f

其中功能的核心在于 位姿間的變換,所以要了解 Eigen::Affine3f 部分的內(nèi)容,Affine3f 是eighen庫的仿射變換矩陣

實(shí)際上就是:平移向量+旋轉(zhuǎn)變換組合而成,可以同時(shí)實(shí)現(xiàn)旋轉(zhuǎn),縮放,平移等空間變換。

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

創(chuàng)建Eigen::Affine3f 對象a。

創(chuàng)建類型為Eigen::Translation3f 對象b,用來存儲平移向量;

創(chuàng)建類型為Eigen::Quaternionf 四元數(shù)對象c,用來存儲旋轉(zhuǎn)變換;

最后通過以下方式生成最終Affine3f變換矩陣:a=b*c.toRotationMatrix();

一個(gè)向量通過仿射變換時(shí)的方法是result_vector=test_affine*test_vector;

仿射變換包括:平移、旋轉(zhuǎn)、放縮、剪切、反射

平移(translation)和旋轉(zhuǎn)(rotation)顧名思義,兩者的組合稱之為歐式變換(Euclidean transformation)或剛體變換(rigid transformation);

放縮(scaling)可進(jìn)一步分為uniform scaling和non-uniform scaling,前者每個(gè)坐標(biāo)軸放縮系數(shù)相同(各向同性),后者不同;

如果放縮系數(shù)為負(fù),則會疊加上反射(reflection)——reflection可以看成是特殊的scaling;

剛體變換+uniform scaling 稱之為,相似變換(similarity transformation),即平移+旋轉(zhuǎn)+各向同性的放縮;

位姿融合輸出

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

TransformFusion TF

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

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

fbe75688-58aa-11ed-a3b6-dac502259ad0.png

建圖優(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é)果,計(jì)算到基于全局位姿的基礎(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幀是不是同一個(gè)坐標(biāo)系,通常baselink指車體系,如果不是,查詢 一下 lidar 和baselink 之間的 tf變換 ros::Time(0) 表示最新的,等待兩個(gè)坐標(biāo)系有了變換,更新兩個(gè)的變換 lidar2Baselink

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

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

    pubImuOdometry  = nh.advertise(odomTopic, 2000);    pubImuPath    = nh.advertise  ("lio_sam/imu/path", 1);

發(fā)布兩個(gè)信息 odomTopic ImuPath,然后看第一個(gè)回調(diào)函數(shù)lidarOdometryHandler

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

將全局位姿保存下來,將ros的odom格式轉(zhuǎn)換成 Eigen::Affine3f 的形式,將最新幀的時(shí)間保存下來,第二個(gè)回調(diào)函數(shù)是imuOdometryHandler,imu預(yù)積分之后所發(fā)布的imu頻率的預(yù)測位姿

  void imuOdometryHandler(const nav_msgs::ConstPtr& odomMsg)  {

    static tf::TransformBroadcaster tfMap2Odom;    static tf::Transform map_to_odom = tf::createQuaternionFromRPY(0, 0, 0), tf::Vector3(0, 0, 0));

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

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

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

imuOdomQueue.push_back(*odomMsg);

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

    if (lidarOdomTime == -1)      return;

如果沒有收到lidar位姿 就returen

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

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

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

計(jì)算最新隊(duì)列里imu里程計(jì)的增量

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時(shí)間戳之前的軌跡全部擦除      while(!imuPath.poses.empty() && imuPath.poses.front().header.stamp.toSec() < lidarOdomTime - 1.0)        imuPath.poses.erase(imuPath.poses.begin());      // 發(fā)布軌跡,這個(gè)軌跡實(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里程計(jì)的軌跡,控制一下更新頻率,不超過10hz,將最新的位姿送入軌跡中,把lidar時(shí)間戳之前的軌跡全部擦除,發(fā)布軌跡,這個(gè)軌跡實(shí)踐上是可視化imu預(yù)積分節(jié)點(diǎn)輸出的預(yù)測值

result

fbfb02c8-58aa-11ed-a3b6-dac502259ad0.png

其中粉色的部分就是imu的位姿融合輸出path。







審核編輯:劉清

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

    關(guān)注

    2

    文章

    753

    瀏覽量

    33479
  • SLAM
    +關(guān)注

    關(guān)注

    23

    文章

    405

    瀏覽量

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

    關(guān)注

    967

    文章

    3863

    瀏覽量

    188744
  • 回調(diào)函數(shù)
    +關(guān)注

    關(guān)注

    0

    文章

    87

    瀏覽量

    11508

原文標(biāo)題:3d激光SLAM:LIO-SAM框架-位姿融合輸出

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

收藏 人收藏

    評論

    相關(guān)推薦

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

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

    激光雷達(dá)分類以及應(yīng)用

    激光雷達(dá)實(shí)際上是種工作在光學(xué)波段(特殊波段)的雷達(dá),它的優(yōu)點(diǎn)非常明顯:1、具有極高的分辨率:激光雷達(dá)工作于光學(xué)波段,頻率比微波高2~3個(gè)數(shù)
    發(fā)表于 09-19 15:51

    常見激光雷達(dá)種類

    單線激光雷達(dá)特點(diǎn):結(jié)構(gòu)簡單、掃描速度快、分辨率高、可靠性高、成本低。單線激光雷達(dá)實(shí)際上就是個(gè)高同頻激光脈沖掃描儀,加上
    發(fā)表于 09-25 11:30

    激光雷達(dá)

    想了解行業(yè)國內(nèi)做固態(tài)激光雷達(dá)的廠家,激光雷達(dá)里面是怎么樣的啊
    發(fā)表于 01-17 15:29

    如何理解SLAM用到的傳感器輪式里程計(jì)IMU、雷達(dá)、相機(jī)的工作原理與使用場景?精選資料分享

    視覺慣性里程計(jì) 綜述 VIO Visual Inertial Odometry msckf ROVIO ssf msf okvis ORB-VINS VINS-Mono gtsam目錄里程計(jì)
    發(fā)表于 07-27 07:21

    請問如何理解SLAM用到的傳感器輪式里程計(jì)IMU、雷達(dá)、相機(jī)的工作原理?

    請問如何理解SLAM用到的傳感器輪式里程計(jì)IMU、雷達(dá)、相機(jī)的工作原理?
    發(fā)表于 10-09 08:52

    Cortex-A53嵌入式處理器平臺上實(shí)現(xiàn)激光雷達(dá)SLAM的方法

    移動底座和激光雷達(dá)與Cortex-A53平臺都是通過串口來通信的。在基于Cortex-A53處理器的平臺上處理激光雷達(dá)的掃描數(shù)據(jù)以及底座中采集的里程計(jì)數(shù)據(jù),結(jié)合激光雷達(dá)的數(shù)據(jù)和
    的頭像 發(fā)表于 03-13 09:15 ?9367次閱讀
    Cortex-A53嵌入式處理器平臺上實(shí)現(xiàn)<b class='flag-5'>激光雷達(dá)</b>SLAM的方法

    計(jì)算機(jī)視覺方向簡介之視覺慣性里程計(jì)

    實(shí)現(xiàn)SLAM的算法,根據(jù)融合框架的不同又分為松耦合耦合。 其中VO(visual odometry)指僅視覺的里程計(jì),T表示位置和姿態(tài)。
    的頭像 發(fā)表于 04-07 16:57 ?2409次閱讀
    計(jì)算機(jī)視覺方向簡介之視覺慣性<b class='flag-5'>里程計(jì)</b>

    個(gè)利用GT-SAM耦合激光雷達(dá)導(dǎo)里程計(jì)框架

    從全稱上可以看出,該算法是個(gè)耦合雷達(dá)導(dǎo)
    的頭像 發(fā)表于 09-14 10:11 ?1684次閱讀

    種快速的激光視覺導(dǎo)融合的slam系統(tǒng)

    個(gè)建立在兩個(gè)基于直接法的耦合的完整的激光視覺
    的頭像 發(fā)表于 11-09 09:55 ?1390次閱讀

    輪式移動機(jī)器人里程計(jì)分析

    方案(ORB SLAM)、基于激光雷達(dá)里程計(jì)方案(Hector SLAM)、基于IMU的里程計(jì)方案,以及多傳感器融合的方案。
    的頭像 發(fā)表于 04-19 10:17 ?1681次閱讀

    介紹種新的全景視覺里程計(jì)框架PVO

    論文提出了PVO,這是種新的全景視覺里程計(jì)框架,用于實(shí)現(xiàn)場景運(yùn)動、幾何和全景分割信息的更全面建模。
    的頭像 發(fā)表于 05-09 16:51 ?1665次閱讀
    介紹<b class='flag-5'>一</b>種新的全景視覺<b class='flag-5'>里程計(jì)</b><b class='flag-5'>框架</b>PVO

    基于相機(jī)和激光雷達(dá)的視覺里程計(jì)和建圖系統(tǒng)

    提出種新型的視覺-LiDAR里程計(jì)和建圖系統(tǒng)SDV-LOAM,能夠綜合利用相機(jī)和激光雷達(dá)的信息,實(shí)現(xiàn)高效、高精度的姿態(tài)估計(jì)和實(shí)時(shí)建圖,且性能優(yōu)于現(xiàn)有的相機(jī)和
    發(fā)表于 05-15 16:17 ?598次閱讀
    基于相機(jī)和<b class='flag-5'>激光雷達(dá)</b>的視覺<b class='flag-5'>里程計(jì)</b>和建圖系統(tǒng)

    3d激光SLAMLIO-SAM框架介紹

    導(dǎo)里程計(jì)(Tightly-coupled Lidar Inertial Odometry),借助的手段就是利用GT-SAM庫中的方法。 L
    的頭像 發(fā)表于 11-22 15:04 ?807次閱讀
    3d<b class='flag-5'>激光</b>SLAMLIO-<b class='flag-5'>SAM</b><b class='flag-5'>框架</b>介紹

    LIO-SAM框架是什么

    導(dǎo)里程計(jì)(Tightly-coupled Lidar Inertial Odometry),借助的手段就是利用GT-SAM庫中的方法。 L
    的頭像 發(fā)表于 11-24 17:08 ?968次閱讀
    LIO-<b class='flag-5'>SAM</b><b class='flag-5'>框架</b>是什么