3. 源码交付规范
无人车项目交付中,源码是算法、控制逻辑与硬件接口的最终载体。与普通软件项目不同,无人车源码涉及感知、定位、规划、控制、驱动等多个模块,且与ROS/ROS2、CUDA、OpenCV、PCL等重型依赖深度耦合。若交付时缺乏清晰的目录结构、严格的版本管理、可复现的依赖锁定、自动化的编译构建以及准确的运行说明,接手方将面临“代码能看但跑不起来”“依赖冲突无法解决”“硬件接线与代码参数对不上”等严重问题。本章将围绕源码交付的四个核心维度展开,明确规范要求与实操方法,确保交付物具备可读性、可构建性与可运行性。
上图展示了源码交付规范的四个核心支柱及其相互关系。目录结构是骨架,版本管理是时间轴,依赖管理是外部接口,编译构建与运行说明是落地验证手段。四者缺一不可,共同构成可交付、可维护、可演进的源码包。以下逐一展开。
3.1 代码目录结构:让接手者30分钟内找到关键文件
核心原理:无人车项目通常基于ROS/ROS2构建,其目录结构应遵循“功能包(Package)”思想。每个功能包负责一个独立模块(如感知、规划、控制),包内包含源码、头文件、配置文件、启动文件、测试代码和文档。顶层目录则负责组织所有功能包、依赖清单、构建脚本和部署说明。良好的目录结构能显著降低认知负担,使新成员快速定位“控制参数在哪改”“激光雷达驱动在哪个包”“启动文件如何组织”。
推荐目录结构(ROS2 + colcon):
unmanned_ground_vehicle/
├── README.md # 项目总览、硬件平台、快速开始
├── LICENSE # 开源许可
├── .gitignore # Git忽略规则
├── .gitlab-ci.yml # CI/CD配置(可选)
├── src/ # 所有功能包源码
│ ├── perception/ # 感知模块
│ │ ├── lidar_detection/ # 激光雷达目标检测包
│ │ │ ├── CMakeLists.txt
│ │ │ ├── package.xml
│ │ │ ├── include/lidar_detection/
│ │ │ ├── src/
│ │ │ ├── config/ # 参数文件(yaml)
│ │ │ ├── launch/ # 启动文件
│ │ │ └── test/ # 单元测试
│ │ └── camera_fusion/ # 相机融合包
│ ├── planning/ # 路径规划模块
│ ├── control/ # 控制模块(PID、MPC等)
│ ├── vehicle_interface/ # 底盘/线控驱动接口
│ └── third_party/ # 第三方依赖源码(如有)
├── scripts/ # 构建、部署、运行辅助脚本
│ ├── build_all.sh
│ ├── run_simulation.sh
│ └── install_deps.sh
├── config/ # 全局配置(地图、参数)
├── docs/ # 设计文档、API文档、接线说明
└── tools/ # 调试工具、数据回放工具
操作流程:在交付前,应执行以下目录检查清单:
- 每个功能包内必须有
package.xml和CMakeLists.txt,且包名与目录名一致。 - 所有配置文件(YAML/JSON)不得包含路径,应使用
$(find pkg_name)/config/xxx.yaml形式。 - 启动文件(Launch)应放在
launch/目录,并明确注释每个参数的作用。 - 提供
README.md说明每个功能包的用途、输入输出话题(Topic)和服务(Service)。
vehicle_interface/config/vehicle_params.yaml,并在README中增加参数映射表,问题解决。
3.2 版本管理:Git Flow与语义化版本控制
核心原理:无人车项目涉及算法迭代、硬件适配和参数调优,版本管理必须做到“可追溯、可回滚、可对比”。采用Git作为唯一版本管理工具,使用语义化版本号(SemVer)格式 主版本.次版本.修订号,例如 v1.3.2。主版本升级表示不兼容的API变更;次版本升级表示向后兼容的功能新增;修订号表示向后兼容的问题修复。同时,需要维护长期支持分支(如 main)和开发分支(如 dev),每个发布版本打Tag。
判断方法与操作流程:
- 分支策略:采用Git Flow或GitHub Flow。对于交付项目,建议使用
main(稳定版)、dev(集成测试版)、feature/*(功能分支)、hotfix/*(紧急修复)。 - 提交规范:提交信息使用Conventional Commits格式,如
feat(perception): add yolo v8 support、fix(control): correct pid integral windup。 - Tag管理:每次正式交付或里程碑节点,必须打Tag,并附上发布说明(Release Notes),列出新增功能、修复问题、已知限制和依赖变更。
- 大文件管理:模型文件(如ONNX、TensorRT引擎)、地图数据、录制的Bag包不应直接存入Git仓库,应使用Git LFS(Large File Storage)或外部对象存储,并在
.gitignore中排除。
| 版本类型 | 示例 | 变更内容 | 交付要求 |
|---|---|---|---|
| 主版本 | v2.0.0 | 感知算法框架更换(如从ROS1迁移到ROS2) | 需更新全部文档、重新验证硬件接口 |
| 次版本 | v1.4.0 | 新增“动态避障”功能 | 需提供新功能的启动文件和参数说明 |
| 修订号 | v1.4.1 | 修复特定场景下的规划死锁问题 | 需提供补丁说明和影响范围 |
git filter-repo 清理历史记录,并更换所有凭据。
3.3 依赖管理:锁定版本,一键安装
核心原理:无人车源码依赖系统库(如PCL、OpenCV)、ROS依赖包(如 nav2)、Python库(如 numpy、torch)以及硬件驱动库(如 livox_ros_driver2)。依赖管理的目标是保证“在任何一台干净机器上,通过一条命令即可安装所有依赖,且版本与开发环境一致”。
操作流程:
- ROS依赖:使用
rosdep工具,在package.xml中声明所有依赖项。交付时提供rosdep install --from-paths src --ignore-src -r -y命令。 - Python依赖:提供
requirements.txt或environment.yaml(Conda),并锁定精确版本号(如numpy==1.24.3),避免使用>=范围。 - 系统依赖:提供
scripts/install_deps.sh脚本,包含apt-get install命令,并注明Ubuntu版本(如20.04/22.04)。 - 第三方源码:若依赖的第三方库需要从源码编译(如特定版本的CUDA算子),应将其作为子模块(Git Submodule)或提供编译脚本,并锁定提交哈希。
package.xml 中仅声明了 opencv,未指定版本。解决方案:在 README.md 中明确“仅支持Ubuntu 20.04 + ROS Foxy”,并在 install_deps.sh 中固定安装 libopencv-dev=4.2.0。同时,在CI中增加两个Ubuntu版本的编译验证。
3.4 编译构建与运行说明:从源码到可运行系统的闭环
核心原理:编译构建必须实现“一键化”和“可重复”。对于ROS2项目,推荐使用 colcon 构建工具。运行说明则需覆盖从启动到验证的完整流程,包括环境变量设置、硬件连接检查、启动命令、预期输出和常见故障排查。
编译构建流程:
# 1. 安装系统依赖
./scripts/install_deps.sh
# 2. 设置ROS环境
source /opt/ros/foxy/setup.bash
# 3. 安装ROS依赖
rosdep install --from-paths src --ignore-src -r -y
# 4. 编译
colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=Release
# 5. 设置工作空间环境
source install/setup.bash
运行说明文档(README.md)应包含:
- 硬件准备:列出所有传感器型号、连接端口(如激光雷达连接主机网口IP)、串口设备权限(
sudo chmod 666 /dev/ttyUSB0)。 - 启动步骤:分步给出启动命令,例如先启动底盘驱动,再启动感知,最后启动规划控制。
- 验证方法:提供
ros2 topic echo /vehicle/status等命令,确认数据流正常。 - 仿真模式:提供无需实车的仿真启动方式(如使用Gazebo或录制Bag回放),便于功能验证。
192.168.1.2,但实际车辆配置为 192.168.1.100,导致无法建图。交付物中必须包含一份 docs/hardware_mapping.md,以表格形式列出每个硬件接口对应的配置文件字段和默认值。
3.5 总结复盘:交付验收清单与常见问题
核心原理:源码交付的最终目标是让接手方“不打电话也能跑通”。因此,交付前应进行自测,模拟一个全新的Ubuntu环境,按照README文档从零开始操作,记录所有偏差并修正。
交付验收清单:
| 检查项 | 验收标准 | 是否通过 |
|---|---|---|
| 目录结构 | 符合3.1节规范,无冗余文件,README索引有效 | ☐ |
| 版本管理 | Git历史清晰,Tag存在,LFS文件可拉取 | ☐ |
| 依赖管理 | 在干净环境执行 install_deps.sh 无报错 | ☐ |
| 编译构建 | 执行 colcon build 一次通过,无警告(或已说明) | ☐ |
| 运行说明 | 按文档启动后,话题数据正常,机器人可遥控/自动运行 | ☐ |
| 硬件映射 | 所有传感器、执行器的IP/串口/参数在文档中有明确对应 | ☐ |
常见误区与规避:
- 误区一:将编译中间文件(
build/、install/、log/)提交到Git。规避:在.gitignore中明确排除。 - 误区二:依赖管理只写“见某某文档”,未提供一键脚本。规避:所有依赖必须可脚本化安装。
- 误区三:运行说明中省略了“硬件上电顺序”或“急停按钮检查”。规避:增加安全检查清单,确保操作安全。
- 误区四:代码注释与实现不符。规避:交付前进行代码走查,重点核对参数默认值与注释。
scripts/self_check.sh 脚本,自动检查环境变量、依赖版本、端口连通性,并输出检查报告。这能极大减少接手方的排障时间,提升交付专业度。