1. 环境准备搭建一个“刚刚好”的标定工作台你好我是老张一个在机器人感知领域摸爬滚打了十来年的工程师。今天咱们不聊那些高深的理论就手把手地带你走一遍 Mid-70 激光雷达和相机的无目标标定。这活儿听起来挺“学术”但说白了就是让雷达和相机“对上眼”让它们知道彼此的位置和朝向这样它们看到的世界才能融合成一个。很多朋友卡在第一步——环境搭建上尤其是各种库的版本兼容问题能把人折腾得够呛。别担心跟着我的步骤来咱们一步步把坑填平。我强烈建议你和我一样使用Ubuntu 16.04和ROS Kinetic这个组合。我知道你可能想用更新的系统比如 Ubuntu 20.04 甚至 22.04但实话告诉你我踩过这个坑。新系统里默认的ceres-solver、eigen3和g版本太高和我们要用的开源标定工具livox_camera_calib兼容性很差编译错误五花八门解决起来非常耗时。为了省下这几天甚至几周的折腾时间不如一开始就选对舞台。Ubuntu 16.04.7 的镜像很容易从官网下载我们就在这个稳定的基础上开工。你可以选择在物理机上直接安装也可以像我一样使用虚拟机。我用的是 VirtualBox分配了6核CPU、6GB内存和30GB硬盘。这个配置对于编译和运行标定程序足够了内存再小的话编译ceres-solver这类库时可能会因为内存不足而失败。安装完系统后记得安装 VirtualBox 的“增强功能”并设置一个共享文件夹。这个操作非常关键因为后续我们需要在虚拟机和宿主机之间传递采集到的点云数据PCD文件和图片共享文件夹是最方便快捷的通道。1.1 安装ROS Kinetic打好感知框架的地基ROSRobot Operating System是我们的核心框架所有传感器驱动和数据流转都靠它。Kinetic 是 Ubuntu 16.04 对应的官方ROS版本兼容性最好。安装过程其实很标准化但有几个细节需要注意能帮你避开网络问题的坑。首先我们把软件源换成国内的镜像下载速度会快很多。打开终端依次执行下面的命令。这里我使用的是中科大的源你也可以根据自己网络情况选择清华、阿里云等镜像。# 设置软件源 sudo sh -c echo deb http://mirrors.ustc.edu.cn/ros/ubuntu/ xenial main /etc/apt/sources.list.d/ros-latest.list # 设置密钥 sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 # 更新软件包列表 sudo apt update # 安装ROS Kinetic完整桌面版这会包含ROS、Rviz、Rqt等核心工具 sudo apt install ros-kinetic-desktop-full安装完成后为了让系统每次启动终端都能自动识别ROS命令我们需要把ROS的环境设置脚本添加到用户的.bashrc文件里。echo source /opt/ros/kinetic/setup.bash ~/.bashrc source ~/.bashrc接下来是初始化rosdep这个工具用于安装ROS包的依赖。这一步常常因为网络问题失败如果遇到sudo rosdep init或rosdep update报错可以多尝试几次或者搜索一下针对国内网络的替代方案比如手动下载rosdistro文件到本地指定目录。完成这一步ROS的骨架就搭好了。1.2 安装ceres-solver与eigen3标定算法的数学引擎标定的核心是一个优化问题我们需要一个强大的数学库来求解。ceres-solver就是谷歌出品的一个用于解决大规模非线性最小二乘问题的库而eigen3是一个高性能的C矩阵运算库ceres依赖于它。好消息是安装ROS Kinetic时系统通常已经自动安装了eigen3版本大约是3.2.97这正好是我们需要的。现在来安装指定版本的ceres-solver。版本号1.14.x至关重要这是经过验证能与后续标定程序完美配合的版本。我们去GitHub上克隆特定分支的代码来编译安装。# 创建一个工作目录保持整洁 mkdir -p ~/workspace cd ~/workspace # 克隆代码并指定 1.14.x 分支 git clone https://github.com/ceres-solver/ceres-solver.git --branch 1.14.x cd ceres-solver # 创建并进入编译目录 mkdir build cd build # 生成编译配置 cmake .. # 开始编译-j4 表示用4个线程并行加速数字可按你CPU核心数调整 make -j4 # 安装到系统目录 sudo make install编译过程可能会花上十几二十分钟泡杯茶休息一下。如果没有报错那么恭喜你最棘手的依赖之一已经搞定了。这个组合ROS Kinetic ceres 1.14 eigen 3.2是我试过多次最稳定的“铁三角”能确保后续编译一路绿灯。2. 驱动与数据让雷达和相机“活”起来环境搭好了接下来就得请出我们的两位“主角”Livox Mid-70激光雷达和工业相机。这一步的目标是让雷达能稳定输出点云让相机能采集图像并把它们的数据接入到ROS系统中为后续的标定准备好“原材料”。2.1 安装Livox Mid-70雷达驱动首先要明确你的雷达型号。Livox Mid-70 和更新的 Mid-360 使用的驱动和SDK是不同的装错了就无法通信。Mid-70 对应的是Livox-SDK和livox_ros_driver。我们依次安装。先安装底层 SDKcd ~/workspace git clone https://github.com/Livox-SDK/Livox-SDK.git cd Livox-SDK mkdir build cd build cmake .. make -j4 sudo make install然后安装ROS驱动包。这里我们采用ROS标准的工作空间workspace管理方式cd ~/workspace mkdir -p ws_livox/src cd ws_livox/src git clone https://github.com/Livox-SDK/livox_ros_driver.git cd .. catkin_make如果编译成功驱动就安装好了。但在启动前有个关键配置必须修改雷达的广播码Broadcast Code。这个码相当于雷达的身份证印在雷达机身或包装盒上。我们需要修改驱动包内的配置文件。找到~/workspace/ws_livox/src/livox_ros_driver/config/livox_lidar_config.json文件用文本编辑器打开。将broadcast_code后面的字符串替换成你雷达的实际SN码。其他参数如return_mode,coordinate等初次使用保持默认即可。{ lidar_config: [ { broadcast_code: 3GGDJAB00100401, // 务必改为你的雷达SN码 enable_connect: true, return_mode: 0, coordinate: 0, imu_rate: 0, extrinsic_parameter_source: 0, enable_high_sensitivity: false } ], ... }保存文件后就可以启动驱动测试了。用一根USB线连接雷达和电脑在终端中运行source ~/workspace/ws_livox/devel/setup.bash roslaunch livox_ros_driver livox_lidar_rviz.launch如果一切正常RvizROS的可视化工具窗口会弹出并且你应该能看到动态刷新的点云数据。这证明雷达驱动工作正常数据已经成功流入ROS系统。你可以移动一下雷达看看点云是否随之变化。2.2 准备标定程序获取开源利器驱动搞定后我们请出今天的“神器”——香港大学MARS实验室开源的livox_camera_calib项目。这个算法的厉害之处在于“无目标”你不需要打印一张棋盘格或者制作一个特定的标定板只需要让雷达和相机同时观察一个任意、有丰富纹理和结构的自然场景比如一个房间的角落它就能通过算法自动估算出两者的外参。我们来获取并编译这个工具# 假设你的ROS工作空间是 ~/catkin_ws如果没有就创建一个 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone https://github.com/hku-mars/livox_camera_calib.git cd ~/catkin_ws catkin_make编译过程会调用我们之前安装好的ceres-solver等库。编译成功后别忘了source一下环境设置source ~/catkin_ws/devel/setup.bash。至此我们的软件工具箱已经全部备齐。3. 数据采集与处理收集标定的“食材”标定就像做一道菜食材数据的质量直接决定最终味道标定结果的好坏。我们需要准备两样食材一张来自相机的图片和一段来自雷达的点云序列。关键是图片和点云必须是在雷达和相机相对位置完全不变的情况下同时或近似同时采集的同一场景。3.1 采集并处理激光雷达点云数据对于Livox雷达官方提供了Livox Viewer软件进行数据录制。去Livox官网下载对应Ubuntu 16.04的版本。打开Viewer连接雷达点击界面上的录制按钮开始录制在场景中缓慢移动雷达或者保持静止如果场景足够丰富录制大约25-30秒后停止。数据会保存为.lvx格式文件。接下来我们需要把这个专有格式转换成ROS通用的bag格式再进一步处理成标定程序需要的PCD点云文件。转换过程在之前安装livox_ros_driver的ws_livox工作空间下进行。cd ~/workspace/ws_livox source devel/setup.bash # 启动转换节点请将 /path/to/your/data.lvx 替换为实际的lvx文件路径 roslaunch livox_ros_driver lvx_to_rosbag.launch lvx_file_path:/path/to/your/data.lvx运行后会在当前目录生成一个.bag文件。接着我们使用pcl_ros工具包将这个bag文件里的点云话题数据转换成一系列单独的PCD文件。# 创建一个目录存放PCD文件 mkdir pcd_frames # 进行转换/livox/lidar 是雷达驱动默认发布点云的话题名 rosrun pcl_ros bag_to_pcd input_file.bag /livox/lidar pcd_frames你会得到几十甚至上百个按时间戳命名的PCD文件。标定程序只需要一个静态的、融合了多帧信息的点云。所以我们需要把这些帧合并成一整块点云。这里我推荐使用开源软件CloudCompare。在Ubuntu上可以用以下命令通过flatpak安装sudo apt install flatpak flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo flatpak install flathub org.cloudcompare.CloudCompare flatpak run org.cloudcompare.CloudCompare打开CloudCompare后使用菜单File-Open批量选中pcd_frames目录下的所有PCD文件导入。在数据库树状图中全选所有加载的点云然后点击菜单Edit-Merge。软件会将所有点云合并成一个图层。最后选中这个合并后的图层点击File-Save在保存类型中选择“Point Cloud Library cloud (*.pcd)”保存为一个单独的PCD文件比如scene_merged.pcd。这个文件就是我们的最终点云食材。3.2 采集相机图像图像采集就相对简单了。确保相机已经完成内参标定知道它的焦距、畸变等参数并且固定好位置。在雷达录制点云的同一时间段内用相机拍摄一张清晰的场景照片。你可以使用相机的官方软件比如海康威视的MVS或者用ROS的image_view工具抓取相机发布的图像话题。将图片保存为常见的格式如scene.jpg或scene.png。记住拍摄时相机和雷达都不能移动确保场景一致。4. 配置与运行启动自动化标定流程食材备齐灶火已旺现在开始烹饪。我们需要配置标定程序的“食谱”然后启动它让它自动完成复杂的计算。4.1 修改标定配置文件进入标定程序目录找到核心配置文件~/catkin_ws/src/livox_camera_calib/config/calib.yaml。用文本编辑器打开它我们需要修改几个关键路径和参数。common: image_file: /home/你的用户名/data/calib/image/scene.png # 替换为你的图片绝对路径 pcd_file: /home/你的用户名/data/calib/pcd/scene_merged.pcd # 替换为你的PCD文件绝对路径 result_file: /home/你的用户名/data/calib/extrinsic.txt # 标定结果输出路径 camera: # 相机内参矩阵 [fx, 0, cx; 0, fy, cy; 0, 0, 1]必须替换为你相机的真实内参 camera_matrix: [1364.45, 0.0, 958.327, 0.0, 1366.46, 535.074, 0.0, 0.0, 1.0] # 相机畸变系数 [k1, k2, p1, p2, k3]必须替换 dist_coeffs: [0.0958277, -0.198233, -0.000147133, -0.000430056, 0.000000] calib: calib_config_file: /home/你的用户名/catkin_ws/src/livox_camera_calib/config/config_outdoor.yaml use_rough_calib: true # 如果你对初始外参一无所知保持为true这里有两个重中之重文件路径确保image_file和pcd_file的路径正确无误。建议使用绝对路径避免相对路径可能带来的问题。相机内参camera_matrix和dist_coeffs绝对不能使用我例子中的值这是我从我的相机标定结果里随便摘的。你必须填入你自己相机的标定结果。如果不知道需要先用ROS的camera_calibration包或张正友标定法对相机进行内参标定。填错内参标定结果不可能正确。calib_config_file指向另一个配置文件里面定义了一些算法参数。对于室内或室外场景算法有不同的优化策略。通常室内场景纹理丰富用默认的config.yaml或config_indoor.yaml即可如果是开阔的室外场景使用config_outdoor.yaml效果更好你可以根据实际情况选择。4.2 启动标定与结果解读配置完成后激动人心的时刻到了。在一个终端中启动标定程序cd ~/catkin_ws source devel/setup.bash roslaunch livox_camera_calib calib.launch你会看到Rviz再次启动左侧显示相机图像右侧显示点云。算法开始运行后最有趣的环节开始了Rviz中的点云会开始“动起来”。算法会根据当前估计的外参将三维点云投影到二维图像平面上并在图像上显示一个绿色的边界框。这个框会不断迭代调整目标是让框内的点云特征如建筑物的边缘、桌角等与图像中的对应边缘尽可能对齐。这个过程完全是自动的你可以泡杯咖啡看着它工作。通常需要几分钟时间。迭代收敛后程序会弹出一个新的可视化窗口对比显示标定前和标定后的点云着色效果。标定后的点云颜色会根据其在图像中的投影位置进行着色如果标定准确你会看到点云的颜色和图像的颜色在物体轮廓上基本对齐比如墙的点云是墙的颜色桌子的点云是桌子的颜色。最终的外参结果一个4x4的变换矩阵描述了雷达坐标系到相机坐标系的旋转和平移会保存在你之前配置的result_file路径中通常命名为extrinsic.txt。这个文件就是本次标定的最终成果后续在融合感知算法中直接加载使用即可。5. 避坑指南与实战心得走完整个流程你可能一次成功也可能遇到些小波折。这里我分享几个最常见的坑和解决思路都是我真金白银踩出来的经验。坑一编译ceres-solver时内存不足。如果你的虚拟机内存分配小于4GB在make -j4这一步可能会被系统杀死进程。解决方法就是给虚拟机分配更多内存建议6GB或以上或者在编译时减少并行线程数比如用make -j2。坑二启动雷达驱动后Rviz里没点云。首先检查USB连接是否稳定Livox Mid-70对USB3.0接口兼容性更好。其次反复确认livox_lidar_config.json文件中的broadcast_code是否修改正确。最后在终端运行rostopic echo /livox/lidar看看有没有数据流如果没有说明驱动没发布数据需要检查驱动编译和启动日志。坑三标定程序运行后点云不动或很快报错。这通常是配置文件的问题。首先百分之百确认你的相机内参填对了。一个粗略检查内参是否离谱的方法是焦距fx,fy的值通常在几百到几千之间像素单位主点cx,cy大概在图像中心例如对于1920x1080的图像cx约960cy约540。其次检查PCD文件路径确保文件存在且内容有效。最后尝试更换calib_config_file室内场景换室外配置可能会失败。坑四标定结果看起来不准。无目标标定对场景有要求。理想的场景需要有丰富的、不同深度的几何结构和纹理比如一个摆放了书籍、显示器和一些杂物的办公桌角落。避免在空旷的白色墙壁前或者特征极其单一的走廊里进行标定。此外采集数据时尽量保持雷达和相机静止避免运动模糊。点云录制时间25-30秒足够时间太短点云太稀疏时间太长数据冗余且容易引入漂移。关于自动化原始流程中数据转换步骤确实繁琐。在实际项目中我通常会写几个简单的Shell脚本或Python脚本来自动化这个过程监测到新的.lvx文件自动触发转换、合并PCD、甚至调用标定程序。这能大大提升迭代效率。标定本身是一个需要反复微调和验证的过程第一次得到结果后可以将其作为use_rough_calib: false时的初始值输入在小范围内移动传感器后再次标定观察结果是否稳定以此来评估标定结果的可靠性。记住没有一劳永逸的标定当传感器安装架发生震动或移位后重新标定是有必要的。