[自动驾驶-传感器融合] 激光雷达的运动补偿

news/2025/2/23 20:51:09

文章目录

  • 引言
  • 相关原理及代码示例
    • IMU
    • 运动补偿的基本原理
    • 代码示例
  • 参考文献

引言

由于激光雷达成像原理是利用接发器与时间计算来获取光点的位置,所以在传感器的空间运动时,会出现雷达拖影现象(点云畸变),因此需要采用运动补偿来校准激光雷达的点云,本文及介绍下激光雷达的运动补偿原理及实现代码。

相关原理及代码示例

激光雷达(LiDAR)在运动过程中会产生运动畸变,影响点云的精度。运动补偿的基本原理是通过测量激光在发射和接收过程中的时间差来计算目标物体与激光雷达之间的距离,然后结合雷达运动过程中的速度信息进行运动补偿,从而得到准确的目标位置信息。

运动补偿一般需要通过结合惯性测量单元(IMU)的数据,校正每个激光点的位置。其目标则是将所有的激光雷达点校正到同一时刻的位置。

IMU

IMU(Inertial Measurement Unit,惯性测量单元)是一种用于测量物体运动状态的传感器,通常由加速度计、陀螺仪和磁力计组成。

在本文中IMU提供角速度和线性加速度,用于推算雷达的姿态和位置变化。

运动补偿的基本原理

假设激光雷达在时间 t t t 采集到点 P P P,其坐标为 p t \mathbf{p}_t pt。运动补偿将该点校正到参考时间 t 0 t_0 t0 的坐标 p t 0 \mathbf{p}_{t_0} pt0。基本操作是姿态补偿与位置补偿。

  • 姿态补偿:
    IMU提供角速度 ω \boldsymbol{\omega} ω,通过积分得到姿态变化 Δ θ \Delta \boldsymbol{\theta} Δθ。旋转矩阵 R \mathbf{R} R 用于描述姿态变化: R = exp ⁡ ( Δ θ ∧ ) \mathbf{R} = \exp(\Delta \boldsymbol{\theta}^\wedge) R=exp(Δθ)其中 Δ θ ∧ \Delta \boldsymbol{\theta}^\wedge Δθ 是角速度的反对称矩阵。
  • 位置补偿:
    IMU提供线性加速度 a \mathbf{a} a,通过积分得到位置变化 Δ p \Delta \mathbf{p} Δp

将点 p t \mathbf{p}_t pt 校正到 t 0 t_0 t0 时刻的坐标: p t 0 = R − 1 ( p t − Δ p ) \mathbf{p}_{t_0} = \mathbf{R}^{-1} (\mathbf{p}_t - \Delta \mathbf{p}) pt0=R1(ptΔp)其中: R − 1 \mathbf{R}^{-1} R1 是旋转矩阵的逆。- Δ p \Delta \mathbf{p} Δp 是位置变化。最后将雷达的每个点均校正至 t 0 t_0 t0 时刻,得到最终的校正点云,则完成了最基本的激光雷达的运动补偿操作。

代码示例

void MotionCompensation(const std::vector<IMUData>& imu_data_vector,
                        const pcl::PointCloud<PointXYZIRT>& input_cloud,
                        pcl::PointCloud<PointXYZIRT>& output_cloud) {
  if (input_cloud.points.empty()) return;

  if (imu_data_vector.size() < 5) {
    pcl::copyPointCloud(input_cloud, output_cloud);
    return;
  }
  int points_size = input_cloud.points.size();
  output_cloud.reserve(points_size);

  int imu_index = 0;
  int imu_index_size = imu_data_vector.size() - 1;

  for (int i = 0; i < points_size; i++) {
    PointXYZIRT now_point = input_cloud.points[i];
    if (!std::isfinite(now_point.x) || !std::isfinite(now_point.y) ||
        !std::isfinite(now_point.z))
      continue;

    Eigen::Vector3f this_point(now_point.x, now_point.y, now_point.z);
    const double now_point_time = now_point.timestamp;

    // 寻找与当前点时间最接近的IMU数据
    for (; imu_index < imu_index_size; ++imu_index) {
      if (imu_data_vector[imu_index + 1].time < now_point_time ||
          imu_data_vector[imu_index + 1].time <=
              imu_data_vector[imu_index].time)
        continue;

      const double dis_time = now_point_time - imu_data_vector[imu_index].time;
      const double front_scale =
          dis_time / (imu_data_vector[imu_index + 1].time -
                      imu_data_vector[imu_index].time);
      const Eigen::Quaternionf tran_quater =
          imu_data_vector[imu_index].quater.slerp(
              front_scale, imu_data_vector[imu_index + 1].quater);
      // lidar_to_imu_ 表示的是IMU坐标系到激光坐标系标定位置
      this_point = tran_quater * (this_point + lidar_to_imu_) - lidar_to_imu_;
      break;
    }

    now_point.x = this_point.x();
    now_point.y = this_point.y();
    now_point.z = this_point.z();
    output_cloud.points.emplace_back(std::move(now_point));
  }

  output_cloud.width = output_cloud.points.size();
  output_cloud.height = 1;
  output_cloud.is_dense = true;
  return;
}

参考文献

[1] Hong S , He J , Zheng X ,et al.LIV-GaussMap: LiDAR-Inertial-Visual Fusion for Real-time 3D Radiance Field Map Rendering[J].IEEE Robotics and Automation Letters, 2024.DOI:10.1109/LRA.2024.3400149.

[2] 王军,赵子豪,李玉莲,等.一种基于IMU的激光雷达三维点云实时运动补偿方法:CN202110559368.1[P].CN202110559368.1[2025-02-15].

[3] weixin_39878698——激光雷达+imu_激光雷达slam-激光点云畸变补偿


http://www.niftyadmin.cn/n/5863760.html

相关文章

助力DeepSeek私有化部署服务:让企业AI落地更简单、更安全

在数字化转型的浪潮中&#xff0c;越来越多的企业选择私有化部署AI技术&#xff0c;以保障数据安全、提升业务效率并实现自主可控。DeepSeek作为行业领先的AI开源技术&#xff0c;其技术可以支持企业私有化部署&#xff0c;企业需要一站式服务私有化部署&#xff0c;涵盖硬件采…

DeepSeek 给我一个 DeepSeekUI 页面

接着上次分享内容 三步安装 DeepSeek 说&#xff0c;DeepSeek 下载好了&#xff0c;总不能是黑框框对话吧&#xff0c;总得找一个 UI 界面使用吧。 本地运行 DeepSeek 比安装 python、jdk 简单多了&#xff0c;本地还没装过的可以参考上次的文档安装。 于是找了几个开源的试了试…

前端面试-JavaScript 数据类型检测全解

目录 一、基础检测方法 二、方法深度解析 1. typeof 运算符 2. instanceof 运算符 3. 终极检测方案 三、特殊场景检测方案 四、手写实现原理 1. 通用类型检测函数 2. 改进版数组检测&#xff08;兼容旧浏览器&#xff09; 五、常见面试陷阱 六、最佳实践指南 七、扩…

MySQL 中的索引数量是否越多越好?为什么?如何使用 MySQL 的 EXPLAIN 语句进行查询分析?MySQL 中如何进行 SQL 调优?

MySQL 中的索引数量是否越多越好&#xff1f;为什么&#xff1f; 索引的优点 加速查询 &#xff1a;索引能够帮助 MySQL 快速定位数据&#xff0c;避免全表扫描。例如&#xff0c;当对一个经常查询的字段&#xff08;如 WHERE 条件中的字段&#xff09;建立索引时&#xff0c…

深度学习在图像识别中的应用-以花卉分类系统为例

深度学习在图像识别中的应用 图像识别是计算机视觉领域的重要分支&#xff0c;旨在让计算机能够像人类一样理解图像内容。近年来&#xff0c;深度学习技术的突破性进展极大地推动了图像识别的发展&#xff0c;使其在医疗诊断、自动驾驶、安防监控等场景中实现了广泛应用。本文…

DeepSeek 与网络安全:AI 在网络安全领域的应用与挑战

&#x1f4dd;个人主页&#x1f339;&#xff1a;一ge科研小菜鸡-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 1. 引言 在当今数字化时代&#xff0c;网络安全已成为国家、企业和个人面临的重要挑战。从传统的病毒、木马攻击&#xff0c;到高…

einops测试

文章目录 1. einops2. code3. pytorch 1. einops einops 主要是通过爱因斯坦标记法来处理张量矩阵的库&#xff0c;让矩阵处理上非常简单。 conda : conda install conda-forge::einopspython: 2. code import torch import torch.nn as nn import torch.nn.functional as…

【沐风老师】3DMAX快速体块生成插件QuickBlocks使用方法详解

3DMAX快速体块生成插件QuickBlocks&#xff0c;一键在指定区域范围内快速生成&#xff08;建筑&#xff09;体块工具。对于大面积的配景楼制作&#xff0c;这款插件是最好的选择之一。QuickBlocks使用起来快捷灵活&#xff0c;不仅可以自定义生成的范围&#xff0c;而且还可以设…