谷歌cartographer直接使用速腾聚创3d激光雷达三维数据进行2d建图

本文介绍如何利用Cartographer_ros工具包与小强ROS机器人平台进行2D地图构建的过程。主要内容包括数据包准备、配置Cartographer_ros参数、启动软件并播放数据包以开始建图,最后使用map_server保存构建好的地图。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原链接: https://community.bwbot.org/topic/524
运行测试平台:小强ROS机器人

谷歌cartographer_ros请参考这篇安装教程http://community.bwbot.org/topic/136/google激光雷达slam算法cartographer的安装及bag包demo测试

1. 数据包准备

使用激光雷达进行2d建图,一般是使用2d雷达数据,3d雷达需要先转换成2d。cartographer_ros的2d建图直接支持三维点云输入,因此可以不需要转换。本文建图将使用里程计和三维点云数据。
rosbag数据包的详细制作过程,请参考这篇教程: https://community.bwbot.org/topic/522/使用rosbag录制和回放3d激光雷达数据和小强ros开发平台的里程计imu数据
下文教程将以蓝鲸机器人录制的bag包为例,演示如何建立2d地图。bag包百度云下载地址

2. 配置cartographer_ros

蓝鲸机器人github上的cartographer_ros已经配置好了所有文件,对于加装速腾聚创小强xq5开发平台采集的数据包,cartographer_ros需要使用的是下列文件,简略的说明在下文。cartographer_ros的详细文档可以参考官方wiki

cartographer_ros/launch/demo_xiaoqiang_rslidar_2d.launch #建图时启动的launch文件,负责启动rviz,加载cartographer_ros主要的启动节点和参数文件,话题数据名字的remap也在这个文件设定。

cartographer_ros/urdf/rslidar_2d.urd #模型文件,用来发布3d激光雷达、小车里程计、IMU、小车本体之间的tf关系

cartographer_ros/configuration_files/xiaoqiang_rslidar_2d.lua #cartographer_ros算法参数配置文件,优化建图效果需要调整的参数就是这个文件。

ros中坐标系的设置,请参考这篇教程,小强xq5平台的base_link原点设置在两个主动轮轴中间位置。

# cartographer_ros/configuration_files/xiaoqiang_rslidar_2d.lua文件里面设置是否使用imu、odom数据的参数是这两个:
use_odometry = true  #true使能里程计,false禁用里程计
TRAJECTORY_BUILDER_2D.use_imu_data = false  #true使能里程计,false禁用里程计
# cartographer_ros)/urdf/rslidar_2d.urd文件需要调整的参数是3d雷达相对base_link的安装位置,laserbase_link等价于base_link
<joint name="horizontal_laser_link_joint" type="fixed">
    <parent link="laserbase_link" />
    <child link="rslidar" />
    <origin xyz="0 0 0.4" rpy="0 0 0" />
  </joint>

3. 启动cartographer_ros,播放rosbag数据包,开始建图

#先关闭小车的ros启动节点
#在小车主机上新开一个命令终端
sudo service startup stop
roscore
#启动cartographer
#在小车主机上新开一个命令终端
roslaunch cartographer_ros demo_xiaoqiang_rslidar_2d.launch 
#播放bag数据
#在小车主机上新开一个命令终端
rosbag play  --clock  2018-08-11-13-20-34.bag

0_1534131252839_2d_1.png
0_1534131282229_Screenshot from 2018-08-13 11-32-47.png
0_1534131505449_Screenshot from 2018-08-13 11-38-14.png

4. bag播放完成后,用map_server保存地图

rosrun map_server map_saver --occ 51 --free 49 -f work0

保存成功后,会在home目录里面生成work0.yaml work0.pgm两个地图文件,这两个文件可以用来amcl导航。

<think>好的,我现在需要帮助用户找到在Qt中显示激光雷达2D点云数据的示例代码。首先,用户提到了引用中的几个资源,特别是引用[3]和[4],它们涉及Qt的GIS开发和点云可视化。我应该先回顾这些引用内容,看看是否有直接相关的代码示例。 引用[3]讲的是使用Qt的QGraphicsView来显示瓦片地,支持多线程加载和显示,这可能与点云的显示有相似之处,比如处理大量的数据点和坐标换。而引用[4]提到基于QOpenGLWindow的点云可视化,这更接近用户的需求,因为OpenGL适合高性能渲染,适合处理大量的点云数据。不过用户需要的是2D点云,而引用[4]可能更偏向3D,但也许可以调整。 用户明确想要2D显示,所以可能需要使用QGraphicsView或者QOpenGLWidget。QGraphicsView适合2D形,可以处理大量的形项,但性能可能不如OpenGL。如果点云数据量很大,使用OpenGL会更高效。因此,我应该考虑这两种方法,并参考现有的引用内容提供示例。 接下来,我需要检查引用中的示例代码是否有相关的部分。引用[3]中的C++代码示例可能涉及瓦片地的显示,但点云的结构不同,可能需要自定义绘制。引用[4]的Qt OpenGL示例可能更接近,但需要调整到2D。此外,用户提供的引用[2]提到了Python的点云编码,但用户可能需要C++的Qt代码。 我需要结合这些信息,构造一个简单的示例,可能基于QGraphicsView或者QOpenGLWidget。考虑到用户可能希望快速实现,QGraphicsView可能更容易上手,代码结构更简单。但若数据量大,推荐使用OpenGL。因此,我应该提供两种方法的示例,或者选择其中一种进行详细说明。 现在,我需要确保代码示例正确,符合Qt的编程规范,并且能够处理激光雷达2D点云数据激光雷达2D数据通常是一系列的距离和角度,换为笛卡尔坐标系下的x和y坐标。代码需要将这些点绘制在视中。 此外,用户可能需要数据加载和实时更新的功能。例如,从文件读取点云数据,或者通过实时传输接收数据并动态更新视。不过,用户可能首先需要一个基础的显示示例,后续再扩展功能。 检查引用[3]中的瓦片地示例,它使用QGraphicsView和QGraphicsScene来管理元,这可能适用于点云显示。每个点可以作为QGraphicsEllipseItem或自定义的QGraphicsItem添加到场景中。对于大量点,可能需要优化,比如使用批处理或简化绘制方法。 在引用[4]中,使用QOpenGLWindow进行3D点云渲染,但可以调整着色器代码以2D方式显示,忽略Z轴。这可能更高效,但代码复杂度较高,适合有OpenGL经验的开发者。 综合考虑,用户可能希望一个简单易懂的示例,因此先提供基于QGraphicsView的代码,再提到OpenGL的优化方向。同时,结合引用中的信息,例如引用[2]提到的点云编码方法,可能需要将点云数据换为适合显示的坐标系统。 最后,生成相关问题,帮助用户进一步探索性能优化、实时显示和坐标换等内容。</think>### 使用Qt显示激光雷达2D点云数据的实现方法 #### 1. 基于QGraphicsView的简单实现 适用于数据量较小的场景,代码简洁易理解: ```cpp #include <QGraphicsView> #include <QGraphicsScene> #include <QApplication> class PointCloudView : public QGraphicsView { public: PointCloudView(QWidget* parent = nullptr) : QGraphicsView(parent) { scene = new QGraphicsScene(this); setScene(scene); // 设置坐标系(示例:范围-10m到10m) scene->setSceneRect(-1000, -1000, 2000, 2000); // 单位:毫米级精度 } void addPoint(float x, float y) { scene->addEllipse(x*100, y*100, 2, 2, Qt::NoPen, QBrush(Qt::red)); // 坐标放大100倍显示 } private: QGraphicsScene* scene; }; // 使用示例 int main(int argc, char *argv[]) { QApplication a(argc, argv); PointCloudView viewer; // 模拟添加点云数据(极坐标笛卡尔坐标) for(int angle=0; angle<360; angle+=5) { float radians = qDegreesToRadians(float(angle)); float distance = 5.0f; // 模拟5米距离 viewer.addPoint(distance*qCos(radians), distance*qSin(radians)); } viewer.show(); return a.exec(); } ``` ▲ 此代码实现了: - 笛卡尔坐标系映射 - 极坐标到直角坐标的换 - 点云可视化基础框架[^3] #### 2. 基于QOpenGLWindow的高性能实现 适用于大规模点云数据(每秒数万点): ```cpp #include <QOpenGLWindow> #include <QOpenGLBuffer> #include <QOpenGLShaderProgram> class GLPointCloud : public QOpenGLWindow { public: GLPointCloud() { points = { // 示例数据(x,y,r,g,b) 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f }; } protected: void initializeGL() override { initializeOpenGLFunctions(); program = new QOpenGLShaderProgram; program->addShaderFromSourceCode(QOpenGLShader::Vertex, "attribute vec2 position;" "void main() { gl_Position = vec4(position, 0.0, 1.0); }"); program->addShaderFromSourceCode(QOpenGLShader::Fragment, "uniform vec3 color;" "void main() { gl_FragColor = vec4(color, 1.0); }"); program->link(); } void paintGL() override { glClear(GL_COLOR_BUFFER_BIT); program->bind(); QOpenGLBuffer vbo(QOpenGLBuffer::VertexBuffer); vbo.create(); vbo.bind(); vbo.allocate(points.constData(), points.size()*sizeof(float)); int posLoc = program->attributeLocation("position"); program->enableAttributeArray(posLoc); glVertexAttribPointer(posLoc, 2, GL_FLOAT, GL_FALSE, 5*sizeof(float), 0); glDrawArrays(GL_POINTS, 0, points.size()/5); vbo.release(); program->release(); } private: QVector<float> points; QOpenGLShaderProgram* program; }; ``` ▲ 此方案利用GPU加速,支持实时刷新(需配合激光雷达数据接口)[^4] #### 3. 关键实现要点 1. **坐标换**: - 激光雷达原始数据通常为极坐标$(r,θ)$,需换为笛卡尔坐标: $$x = r \cdot \cosθ,\quad y = r \cdot \sinθ$$ 2. **性能优化**: - 使用顶点缓冲区对象(VBO)存储点数据 - 批量绘制代替逐点绘制 - 动态LOD(Level of Detail)控制[^2] 3. **交互功能**: ```cpp // 添加鼠标交互(继承QWidget的event处理) void mouseMoveEvent(QMouseEvent* event) { QPointF scenePos = mapToScene(event->pos()); qDebug() << "当前坐标:" << scenePos.x()/100.0 << "m," << scenePos.y()/100.0 << "m"; } ```
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值