激光雷达和RTK的标定(无人小车)

2023-05-16

总结一下最近的标定工作,标定平台是实验室的无人小车,目标是实现激光雷达(lidar)和RTK的标定,也就是求解lidar到RTK的位姿变换矩阵。采用的代码是ETH的lidar align(https://github.com/ethz-asl/lidar_align)。对其代码的详细解读可以参考:https://zhuanlan.zhihu.com/p/256306094
需要对其读取RTK位姿信息的的代码做一定的修改。RTK所采用的ros消息类型为geometry_msgs/PoseStamped,修改代码如下,将其loader.cpp里的Loader::loadTformFromROSBag函数修改一下

    bool Loader::loadTformFromROSBag(const std::string& bag_path, Odom* odom) {
        rosbag::Bag bag;
        try {
            bag.open(bag_path, rosbag::bagmode::Read);
        } catch (rosbag::BagException e) {
            ROS_ERROR_STREAM("LOADING BAG FAILED: " << e.what());
            return false;
        }
         std::vector<std::string> types;
         types.push_back(std::string("geometry_msgs/PoseStamped"));
         rosbag::View view(bag, rosbag::TypeQuery(types));

         size_t tform_num = 0;
         for (const rosbag::MessageInstance& m : view) {
           std::cout << " Loading transform: \e[1m" << tform_num++
                     << "\e[0m from ros bag" << '\r' << std::flush;

           geometry_msgs::PoseStamped transform_msg =
               *(m.instantiate<geometry_msgs::PoseStamped>());

//             sensor_msgs::Imu imu=*(m.instantiate<sensor_msgs::Imu>());

           Timestamp stamp = transform_msg.header.stamp.sec * 1000000ll +
                             transform_msg.header.stamp.nsec / 1000ll;

           Transform T(Transform::Translation(transform_msg.pose.position.x,
                                              transform_msg.pose.position.y,
                                              transform_msg.pose.position.z),
                       Transform::Rotation(transform_msg.pose.orientation.w,
                                           transform_msg.pose.orientation.x,
                                           transform_msg.pose.orientation.y,
                                           transform_msg.pose.orientation.z
                                           ));
           odom->addTransformData(stamp, T);
         }

        if (odom->empty()) {
            ROS_ERROR_STREAM("No odom messages found!");
            return false;
        }

        return true;
    }

录制的包的msg.fields由于pcl库版本的原因可能不含"time_offset_us",然后就会从intensity中读取时间信息,但实际上代码中,并没有往点云的intensity中添加时间信息,时间戳都保存在private变量timestamps_us_中,而对intensity没有赋值(会赋随机值),从而导致代码运行出错,所以对loader.cpp中的函数void Loader::parsePointcloudMsg(const sensor_msgs::PointCloud2 msg,LoaderPointcloud* pointcloud)进行修改(增加一行即可):

void Loader::parsePointcloudMsg(const sensor_msgs::PointCloud2 msg,
                                    LoaderPointcloud* pointcloud) {
        bool has_timing = false;
        bool has_intensity = false;
        for (const sensor_msgs::PointField& field : msg.fields) {
            if (field.name == "time_offset_us") {
                has_timing = true;
            } else if (field.name == "intensity") {
                has_intensity = true;
            }
        }

//        std::cout<<has_intensity<<" "<<has_timing<<std::endl;

        if (has_timing) {
            pcl::fromROSMsg(msg, *pointcloud);
            return;
        } else if (has_intensity) {
            Pointcloud raw_pointcloud;
            pcl::fromROSMsg(msg, raw_pointcloud);

            for (const Point& raw_point : raw_pointcloud) {
                PointAllFields point;
                point.x = raw_point.x;
                point.y = raw_point.y;
                point.z = raw_point.z;
                point.intensity = raw_point.intensity;
                point.time_offset_us=0; #增加这一行即可

                if (!std::isfinite(point.x) || !std::isfinite(point.y) ||
                    !std::isfinite(point.z) || !std::isfinite(point.intensity)) {
                    continue;
                }

                pointcloud->push_back(point);
            }
            pointcloud->header = raw_pointcloud.header;
        } else {
            pcl::PointCloud<pcl::PointXYZ> raw_pointcloud;
            pcl::fromROSMsg(msg, raw_pointcloud);

            for (const pcl::PointXYZ& raw_point : raw_pointcloud) {
                PointAllFields point;
                point.x = raw_point.x;
                point.y = raw_point.y;
                point.z = raw_point.z;

                if (!std::isfinite(point.x) || !std::isfinite(point.y) ||
                    !std::isfinite(point.z)) {
                    continue;
                }

                pointcloud->push_back(point);
            }
            pointcloud->header = raw_pointcloud.header;
        }
    }

提醒

1、实验前可以先录一组数据,使用EVO(https://blog.csdn.net/weixin_47074246/article/details/109134740)画出RTK和lidar的轨迹,使用-a命令看是否可以对齐,这里注意不要使用-s命令,确保RTK和lidar的轨迹之间不存在尺度问题。
2、由于RTK在室内收不到信号,只能在室外采集数据,录rosbag的时候,尽量选择环境结构性强,最近物体或者墙面较多的地方,并且动态物体越少越好。
3、录rosbag的时候,尽量选择有上下坡,并且有较多转弯的地方,使其在yaw和pitch上有充分的运动变换,受限与无人小车的结构,很难在roll上有充分的运动。
4、针对自己的激光,本实验采用的是velodyne vpl16,可以适当修改sensor.h里的参数,实验结果显示将max_point_distance修改为30后取得了不错的效果。
5、优化过程中计算的error是累计误差,rosbag越长,对应的点云帧数也越多,error也相应的会变大,不具有很强的说服力,可以修改为平均误差,具体做法是将aligner.cpp中的Aligner::lidarOdomKNNError函数的返回值由原本的total_error改为total_error/base_pointcloud.size()。

程序运行结束会生成相应的txt和ply文件。
txt文件如下
在这里插入图片描述
ply文件可以通过pcl_ply2pcd 1.ply 1.pcd命令将对应的ply文件转化为pcd文件,然后使用pcl_viewer 1.pcd查看具体点云内容,实验点云图如下:
在这里插入图片描述
当误差较小并且点云匹配OK的情况下,我们认为标定结果可靠。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

激光雷达和RTK的标定(无人小车) 的相关文章

  • 我们无法设置移动热点_中海达系列RTK连接千寻CORS设置步骤及注意问题

    信号稳定 单机作业 xff0c 操作方便 xff0c 千寻CORS已成为rtk测量的普遍选择 一 使用前提 1 千寻CORS是需要网络流量的 xff0c 所以首先确认工作区域要有稳定手机网络信号 xff01 联网常采用以下三种方法 xff1
  • 【高精度定位】关于GPS、RTK、PPK三种定位技术的探讨

    高精度定位通常是指亚米级 厘米级以及毫米级的定位 xff0c 从市场需求来看 xff0c 定位的精度越高往往越好 高精度 低成本 的定位方案无疑将是未来市场的趋势 在物联网时代 xff0c 大多数的应用或多或少都与位置服务相关联 xff0c
  • 激光雷达RPLIDAR A1使用教程

    激光雷达RPLIDAR A1使用教程 一 雷达硬件连接 1 A1雷达包含组件 RPLIDAR A1开发套装包含了如下组件 xff1a o RPLIDAR A1模组 xff08 内置 PWM电机驱动器 xff09 o USB适配器 o RPL
  • 什么是RTK?

    国内习惯把GNSS接收机叫成RTK这倒是真的 xff0c 因为RTK技术的普及 xff0c 让大家对接收机的作用就 限定 在了RTK xff0c 在之前没有RTK时 xff0c 接收机就是接收机 目前 xff0c GNSSj接收机约99 的
  • RTK与PPK

    1 通讯方式不同 RTK技术需要无线电台或网络来传输差分数据 PPK技术不需要通信技术的支持 xff0c 并且可以记录静态数据 2 定位方法不同 RTK所使用的实时定位技术使您可以随时在流动站上查看测量点的坐标和精度 xff1b PPK定位
  • GPS、RTK、PPK三种定位技术的原理及应用

    一 GPS技术 1 原理 之前做过集成GPS功能的产品 xff0c 对这种不以定位为主要功能的产品 xff0c 精度是没有要求的 xff0c 例如我只是用它来得到当前社区的位置 xff0c 一般的GPS模块都能满足要求 理论上 xff0c
  • vins-fusion 融合rtk原理

    vins fusion融合rtk原理 xff1a 使用优化的方式融合 xff0c 假设融合后的位姿是fusion T n vio输出的位姿是vio T n xff0c rtk输出的位姿是rtk T 只有最后一帧 那么 fusion T的初值
  • RTK和GPS定位

    GPS定位的基本原理是 xff0c 测量出已知位置的卫星到地面GPS接收器之间的距离 xff0c 然后接收器通过与至少4颗卫星通讯 xff0c 计算与这些卫星间的距离 xff0c 就能确定其在地球上的具体位置 普通GPS的定位精度 1米 x
  • 激光雷达--看图

    转载于 https www cnblogs com tiandi p 10057244 html
  • DGPS与RTK的区别

    2013 10 11 10 49 11 分类 xff1a GNSS 举报 字号 订阅 最近一直感觉身在这个行业不能对这个行业理论知识一无所知 xff0c 这对于技术人来说应该是一种遗憾 所以决定要学一些东西 xff0c 并记录下来以便于以后
  • 关于PPP-RTK技术优势的一些思考与总结

    文章目录 一 前言二 SSR修正与PPP三 RTK与PPP RTK的对比四 PPP RTK的技术优势五 总结参考文章 欢迎关注个人公众号 xff1a 导航员学习札记 一 前言 感觉近几年PPP和PPP RTK一直都是GNSS比较火的方向 x
  • 5G+北斗RTK定位:高精度定位技术发展更进一步

    5G 43 北斗RTK定位采用5G定位与北斗RTK定位技术 xff0c 在信号 信息 设施 应用等层面深度融合 xff0c 5G自身可实现亚米级的定位能力与北斗形成信号覆盖互补 xff0c 实现从室内到室外无缝隙衔接与定位 5G通信技术的到
  • 网络RTK——主辅站误差改正法(MAC)

    主辅站误差改正法的基本思想是 xff0c 首先 xff0c 将基准网内所有基准站的相位距离转换到公共整周未知数水平 xff0c 即整周模糊度被消除 其次 xff0c 计算各个误差改正项 xff0c 充分考虑误差的色散和非色散特性 xff0c
  • 思岚科技RPlidar A3激光雷达ROS源码详解

    思岚科技RPlidar A3激光雷达ROS源码详解 使用 RPLIDARD 的 SDK 其实重点在于看懂client cpp和node cpp两个sample代码 xff0c 因此在这里我们讲从这里入手学习 RPLIDAR A3 的SDK
  • RTKLIB ppp rtk_post

    1 实时ppp xff1a IGS MGEX数据处理中心的播发的实时轨道钟差产品 xff0c 结合广播星历 xff0c 实现实时定位 2 事后的 xff08 近似实时 xff09 xff1a 下载精密星历 钟差产品 xff0c 结合其他的精
  • RTKLIB源码解析(二)、 RTK定位(rtkpos.c)

    本博客是转载 感谢 rtklib代码详解 rtkpos c 博客园 哆啦A梦 博客园 主函数 rtkpos 1 设置基站位置 2 统计基站和流动站的卫星数量 3 单点定位解算 4 若定位模式为单点定位 直接返回 5 精密单点定位 6 动基线
  • 激光雷达,揭开面具下隐藏的“丑陋”

    没有在激光雷达身上 吃过亏 的自动驾驶公司 就像笔者年代没有痴迷过 龟仙人 的小朋友 童年是遗憾的 纸面上的200m测距能力 在视场角边缘为何只有100m 在烈日当头和夕阳西下时 激光雷达点云的噪点水平怎么和化妆和未化妆的姑娘相差这么大 遇
  • Point-GNN README批注

    Point GNN README批注 Point GNN 1 Getting Started 1 1 Prerequisites 1 2 KITTI Dataset 1 3 Download Point GNN 2 Inference 2
  • ADAS的八大系统

    简述 ADAS Advanced Driving Assistant System 即高级驾驶辅助系统 ADAS 是利用安装于车上的各式各样的传感器 在第一时间收集车内外的环境数据 进行静 动态物体的辨识 侦测与追踪等技术上的处理 从而能够
  • 【KITTI】KITTI数据集简介(一) — 激光雷达数据

    本文为博主原创文章 未经博主允许不得转载 本文为专栏 python三维点云从基础到深度学习 系列文章 地址为 https blog csdn net suiyingy article details 124017716 KITTI数据集的详

随机推荐

  • RLock锁的使用

    try RLock lock 61 redissonClient getLock 34 ppt pos sms code lock 34 43 34 orderSmsCode 34 System out println 34 得到的锁 34
  • Ubuntu开机自动挂载SD卡到指定挂载点并将Docker默认存储路径改为SD卡

    Ubuntu开机自动挂载SD卡到指定挂载点并将Docker默认存储路径改为SD卡 查看磁盘信息查看磁盘原挂载点永久开机自动挂载分区 修改文件 etc fstab应用挂载修改docker默认存储路径 查看磁盘信息 sudo fdisk l 如
  • JS数组对象,过滤掉不要的对象

    其实本来很简单 xff0c 奈何我自己把自己绕进去了 又是觉得自己不适合干开发的一天啊 const array1 61 id null name null id null name null id 1 name 2 我需要筛出不同时为空的数
  • Hadoop权威指南

    1 Hadoop基础知识 第1章 初识Hadoop Hadoop代替配有大量硬盘的数据库来进行大规模数据分析的原因是 xff1a 传输速率 xff08 取决于硬盘的带宽 xff09 的提升远大于寻址时间 xff08 将磁头移动到特定硬盘位置
  • 创建新分支,拉取代码

    1 查看当前已存在分支 git branch 2 创建新的分支 创建一个dev分支 git checkout b dev 3 提交分支到远程仓库 git push origin dev 4 删除本地分支 git branch D dev
  • 操作系统之什么是中断?

    什么是中断 xff1f 在学习操作系统中 xff0c 经常性的会看到中断这个概念 xff0c 最典型的就是汇编代码中的int命令 用一个比较通俗的概念来说 xff0c 就是计算机会连接许多外接设备 xff0c 包括磁盘 显示器 键盘鼠标等等
  • 树莓派断网自动重连WiFi

    树莓派WiFi有时候信号不好会断 xff0c 并不会自动重新连网 解决办法是 xff1a 写一个自动断网重连的脚本 xff0c 让pi定时执行并检查网络是否连通 xff0c 如断网则自动重新连接 连接还是失败 xff0c 重启 1 xff0
  • Flask 中使用 AJAX 异步加载 Bootstrap 表格(Tables)

    Flask 中使用 AJAX 异步加载 Bootstrap 表格 Tables 1 快速安装 2 一步一步做 3 概述 4 项目结构 4 1 Python 部分 app py 4 2 HTML 部分 index html 4 3 Styli
  • OpenMV超声波测距

    OpenMV超声波测距 本文首发于 xff1a https www bilibili com read cv3051569 参考链接 xff1a https blog csdn net bei dai he article details
  • Git常用命令pull、push、fetch

    pull pull意为拉 xff0c 这里引申为拉取代码 在Git命令中使用pull xff0c 会将你的远程代码拉取到本地并进行合并 格式 xff1a git pull lt 远程主机名 gt lt 远程分支名 gt lt 本地分支名 g
  • Ubuntu系统man命令中文汉化

    1 下载中文包 进入 opt xff0c 使用管理权限下载 xff1a wget https src fedoraproject org repo pkgs man pages zh CN manpages zh 1 5 1 tar gz
  • 文末彩蛋 | 这个 Request URL 长得好不一样

    有朋友拿到一个网站请求的链接问这要怎么解密 xff1f 很明显这不是加密的数据 xff0c 这是一张图片 base64 后的结果 xff0c 第一次写爬虫朋友遇到这样的请求 xff0c 可能需要琢磨一下这是什么东西 如果有遇到类似数据 xf
  • Redis(十) 布隆过滤器

    速记 为什么使用布隆过滤器 xff1f 1 为了省内存 xff0c 提高速率 2 因为1所以布隆过滤器不需要百分百正确 3 说存在不一定存在 xff0c 说不存在一定不存在 4 在解决缓存穿透的问题时 xff0c 拦截了大部分的请求 xff
  • 第五章:数学运算-statistics:统计计算-平均值

    5 5 statistics 统计计算 statistics模块实现常用的统计公式 xff0c 允许使用python的各种数值类型 xff08 int float xff0c Decimal和Fraction 来完成高效计算 5 5 1 平
  • 用proxychains4解决rosdep init问题教程

    在终端下载源码 sudo git clone https github com rofl0r proxychains ng git 进入安装目录 cd proxychains ng 配置 configure prefix 61 usr sy
  • 使用 TX2 和 realsense D435i 相机运行 ORBSLAM3

    非 ROS 版本 之后可能会更新 ROS 版本的 ORBSLAM3 配置指南 TODO 目录 TX2 刷机JetPack 4 6 1安装 realsense SDK 2 0编译 opencv 4 5 0编译 Pangolin 0 5编译运行
  • 解决 cv_bridge 与 opencv4 版本冲突问题

    解决了在 ROS melodic noetic 下 cv bridge 与 opencv4 版本冲突导致的 opencv 操作 导致 Segmentation fault core dumped 的问题 目录 问题描述解决方法参考 问题描述
  • 我对onSizeChange方法的源码解析

    如果当前的自定义控件是继承ViewGroup xff0c 那么在ViewGroup重写的layout方法中 xff1a 可知调用父类也就是View的layout方法 再看View的layout方法 xff1a 查看设置自己坐标的setFra
  • 5 个你不知道的关于 Python 类的技巧

    5 个你不知道的关于 Python 类的技巧 1 创建 一个 常量值2 多个类构造函数3 创建枚举4 迭代器5 以列表的形式访问一个类 Python 有许多强大的特性 xff0c 在处理类时提供了极大的灵活性 在这里 xff0c 我将向您展
  • 激光雷达和RTK的标定(无人小车)

    总结一下最近的标定工作 xff0c 标定平台是实验室的无人小车 xff0c 目标是实现激光雷达 lidar 和RTK的标定 xff0c 也就是求解lidar到RTK的位姿变换矩阵 采用的代码是ETH的lidar align https gi