SLAM

GIS TO SLAM

本篇随项目推进持续更新,记录每一步进展。

今天是2026-9-23,刚刚接触 ROS 环境,也才开始了解 SLAM 的一些基础知识。站在这个全新的起点上,我想写下这篇博客,记录此刻的学习、探索,以及那些还略显生涩的理解。或许多年以后,当我再次翻到这里,会怀念这个一切才刚刚开始的秋天。

一、为什么我决定深耕SLAM方向?

AI 的发展正在改变传统 GIS 岗位,制图、空间数据处理、遥感影像解译中的许多重复性工作也在逐渐被自动化。而我更喜欢探索技术、理解原理,而不是长期停留在重复性的生产工作中。

找到一个既热爱、又能给自己一口饭吃的方向并不容易。恰好在车老师的引导下,我接触到了 SLAM。它涉及 ROS、机器人、激光雷达与算法,看似跨出了 GIS,但点云数据、地图、坐标系、定位——恰恰是我的老本行。

所以,这不是从零跨行,而是从 GIS 出发,走向定位、感知与空间智能。「GIS + SLAM」的交叉也给了我更大的探索空间。未来无论是研究生阶段还是更长远的发展,我都希望继续深耕这个方向——面向技术,面向原理,也面向算法。

二、我的SLAM项目

1、什么是SLAM?

Simultaneous Localization and Mapping:同步定位与建图。

问题前提求什么例子
定位(Localization)已经有了一张地图我在哪GPS导航
建图(Mapping)已经知道自己每一刻在哪地图长什么样测绘

定位、建图这两件事单看,都不算难。难的是把前提去掉,也就是提前没有地图,提前不知道自己每一刻在哪,而SLAM正是同时进行这两件事情,这也是SLAM的魅力与所在,hh,也是更容易出科研成果的地方。

2、项目初期开始,我做了哪些准备?

首先操作系统环境问题,由于我的电脑是WIN11,对于ROS2的环境搭建很不友好,于是我购买了一块固态硬盘,放在电脑上,装了Ubuntu系统。

可见,我装上了Ubuntu 26.04版本以及对应的ROS2版本:

主要硬件清单如下:

部件规格
主控树莓派 4B(4核/~3.7GB可用内存/214GB空间存储)
激光雷达RPLIDAR A1M8,固件1.28,硬件Re5,SN64b09a86…623078

开发在本机做,树莓派只负责采雷达、把数据发到局域网,所以它也需要一套 ROS 2 环境。可它的宿主是 Debian 12 bookworm(Raspberry Pi OS,aarch64)——ROS 2 官方只按 Ubuntu 发二进制包,Debian 不在支持范围内,装不了本机那套 Lyrical。于是用 Docker 补上:容器镜像是 Ubuntu 26.04 LTS / arm64,和本机对齐。

ROS 2 的二进制发行版严格按「一个发行版 ↔ 一个 Ubuntu 代号」发布。Lyrical 只对应 resolute(=Ubuntu 26.04)。

关于在电脑本机和Pi的ROS2环境搭建,我都交给了AGENT。

3、当前进度项目系统架构(9月27日)

当前阶段的系统是一条「数据在车上采集、建图在笔记本上算」的两机链路:树莓派是车上唯一的硬件入口,一套 Flask 后端独占 /dev/serial0 串口与雷达电机的 PWM(GPIO11),负责把雷达字节解析成整圈点云,并把这份点云从两个出口分岔送出——一路经 Socket.IO(:5000)降采样后直接推给浏览器画粗略点云,另一路按行 JSON 从裸 TCP(:5001)吐出整圈全量数据;后者由跑在树莓派 Docker 容器里的 lidar_bridge.py 接走,翻译成 ROS 2 的 /scan 话题,再经跨机 DDS 送到笔记本,笔记本上的 slam_toolbox 订阅它建图、rviz2 实时显示、map_service.py 把 /map 转成 HTTP 接口(:5002),浏览器最后轮询这个接口把地图画到画布上。浏览器全程只是纯客户端,同时维持着三条互不依赖的连接——控制与点云走树莓派的 :5000,地图走笔记本的 :5002,页面本身来自笔记本的 :8080——所以断掉任何一条都不影响另外两条,而整条链路里唯一真正跨网的一跳是 DDS,也正是最容易坏的一跳。

这一版架构有意缺一个器官:车上没有编码器和 IMU,odom → base_link 由静态 TF 发布,SLAM 只能假设小车从未移动过——因此它的验收场景被限定为小车静止,车一动地图就会糊(下图为绕圈38-610所建,可见精度较低):

(未完…下一阶段为接入里程计和IMU,重新跑SLAM ToolBox算法)

二编见下

4、IMU、编码器接入,并重构项目(10月2日)

上一版架构里我故意留了个缺口:车上没有编码器和 IMU,odom → base_link 由一条静态 TF 发布——等于 SLAM 每天睁眼第一件事是假装小车从没动过。所以它只能”静止建图”,车一动地图就糊。

10 月 2 日到 3 日,这个器官装上了。现在的数据流长这样:

【车上 · 树莓派】
  4×轮编码器(GPIO) ──► encoder.py   ←─ pigpio 事件流,四倍频解码
  IMU(Type-C→USB串口) ─► imu.py     ←─ CH340 芯片,115200,47Hz
            │
            ▼
     odometry.py(纯函数:tick+陀螺 → 距离/速度/航向)
            │
     odom_exporter.py ──TCP :5003──┐
                                   │(NDJSON,每拍三种消息)
【车上 · Docker 容器】             ▼
     odom_bridge.py ──► /wheel_odom + /imu/data_raw(ROS 2 话题)
                                   │
                              DDS 跨机(和 /scan 同机制)
                                   │
【笔记本】                         ▼
     robot_localization EKF ──► /odometry/filtered + 真实的 odom→base_link TF
                                   │
     slam_toolbox(mapping.launch,阈值 0.5)──► /map

5、项目阶段性进度

硬件状态:

部件状态备注
激光雷达✅ 5.5 Hz 稳定前任是一根断芯的 RX 杜邦线(引脚下拉电平测法定位的);电源两根已换粗线,3 次启停加严验收通过
IMU✅ 47 HzI2C 方案放弃(总线会被探测指令打楔),改走 USB 串口后一次点亮
编码器 ×4✅ 四路全通双向计数,四轮离散度 0.2%
轮子✅ 前后都转顺带学到的:轮子不转先查电池开关(真事)

里程计参数:全部实测,零名义值

参数值怎么来的
编码器尺度13629 tick/m推车 1 米实测(规格书的 624 PPR 不适用这批电机,差 2.8 倍!)
航向陀螺积分原地转 180° 实测:陀螺积分 179.3°,误差 0.4°
等效轮距0.0704 m四轮原地转有”蹭地”打滑,几何轮距 ≠ 等效轮距
判向符号前进全 +编码器相位反向的那一路,软件取负

闭环验证:标定后重新推 1 米,里程计读 0.988 m,误差 1.2%。

(未完..下步开始建图、调参数、学算法原理)

10月4、5日,学习了理论知识,见:https://geocommunity.vip/index.php/2026/10/04/mapping-topic-data-flow/

10月9日,跑通了开源算法slamtoolbox,并跑通了基准参数,构建了两张地图:

619室:

38号楼一楼大厅:

详情见:https://geocommunity.vip/index.php/2026/10/09/practice1/。

发表评论