3、源码交付规范:代码目录结构、版本管理、依赖管理、编译构建与运行说明

无人车项目交付中,源码是算法、控制逻辑与硬件接口的最终载体。与普通软件项目不同,无人车源码涉及感知、定位、规划、控制、驱动等多个模块,且与ROS/ROS2、CUDA、OpenCV、PCL等重型依赖深度耦合。若交付时缺乏清晰的目录结构、严格的版本管理、可复现的依赖锁定、自动化的编译构建以及准确的运行说明,接手方将面临“代码能看但跑不起来”“依赖冲突无法解决”“硬件接线与代码参数对不上”等严重问题。本章将围绕源码交付的四个核心维度展开,明确规范要求与实操方法,确保交付物具备可读性、可构建性与可运行性。

源码交付规范 代码目录结构 src / include / config 版本管理 Git / Tag / Branch 依赖管理 rosdep / vcpkg / lock 编译构建与运行 CMake / colcon / launch 交付验收关键检查项 ✓ 目录层级与README一致 ✓ Git历史完整,Tag对应发布版本 ✓ 依赖清单可一键安装 ✓ 编译脚本无路径 ✓ 运行说明含硬件接线映射 ✓ 提供仿真环境验证入口

上图展示了源码交付规范的四个核心支柱及其相互关系。目录结构是骨架,版本管理是时间轴,依赖管理是外部接口,编译构建与运行说明是落地验证手段。四者缺一不可,共同构成可交付、可维护、可演进的源码包。以下逐一展开。

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)。
实战场景:某园区无人车交付时,接手方反馈“找不到底盘速度指令在哪里修改”。排查发现,控制参数散落在三个不同包的config目录中,且没有索引文档。最终通过重构目录,将底盘限速、加速度等参数统一收敛至 vehicle_interface/config/vehicle_params.yaml,并在README中增加参数映射表,问题解决。

3.2 版本管理:Git Flow与语义化版本控制

核心原理:无人车项目涉及算法迭代、硬件适配和参数调优,版本管理必须做到“可追溯、可回滚、可对比”。采用Git作为唯一版本管理工具,使用语义化版本号(SemVer)格式 主版本.次版本.修订号,例如 v1.3.2。主版本升级表示不兼容的API变更;次版本升级表示向后兼容的功能新增;修订号表示向后兼容的问题修复。同时,需要维护长期支持分支(如 main)和开发分支(如 dev),每个发布版本打Tag。

判断方法与操作流程:

  1. 分支策略:采用Git Flow或GitHub Flow。对于交付项目,建议使用 main(稳定版)、dev(集成测试版)、feature/*(功能分支)、hotfix/*(紧急修复)。
  2. 提交规范:提交信息使用Conventional Commits格式,如 feat(perception): add yolo v8 support、fix(control): correct pid integral windup。
  3. Tag管理:每次正式交付或里程碑节点,必须打Tag,并附上发布说明(Release Notes),列出新增功能、修复问题、已知限制和依赖变更。
  4. 大文件管理:模型文件(如ONNX、TensorRT引擎)、地图数据、录制的Bag包不应直接存入Git仓库,应使用Git LFS(Large File Storage)或外部对象存储,并在 .gitignore 中排除。
版本类型示例变更内容交付要求
主版本v2.0.0感知算法框架更换(如从ROS1迁移到ROS2)需更新全部文档、重新验证硬件接口
次版本v1.4.0新增“动态避障”功能需提供新功能的启动文件和参数说明
修订号v1.4.1修复特定场景下的规划死锁问题需提供补丁说明和影响范围
风险提示:切勿将包含敏感信息(如IP地址、内部IP、密钥)的文件提交至Git历史。交付前必须使用 git filter-repo 清理历史记录,并更换所有凭据。

3.3 依赖管理:锁定版本,一键安装

核心原理:无人车源码依赖系统库(如PCL、OpenCV)、ROS依赖包(如 nav2)、Python库(如 numpy、torch)以及硬件驱动库(如 livox_ros_driver2)。依赖管理的目标是保证“在任何一台干净机器上,通过一条命令即可安装所有依赖,且版本与开发环境一致”。

操作流程:

  1. ROS依赖:使用 rosdep 工具,在 package.xml 中声明所有依赖项。交付时提供 rosdep install --from-paths src --ignore-src -r -y 命令。
  2. Python依赖:提供 requirements.txt 或 environment.yaml(Conda),并锁定精确版本号(如 numpy==1.24.3),避免使用 >= 范围。
  3. 系统依赖:提供 scripts/install_deps.sh 脚本,包含 apt-get install 命令,并注明Ubuntu版本(如20.04/22.04)。
  4. 第三方源码:若依赖的第三方库需要从源码编译(如特定版本的CUDA算子),应将其作为子模块(Git Submodule)或提供编译脚本,并锁定提交哈希。
案例拆解:某项目交付时,接手方在Ubuntu 22.04上编译失败,原因是开发环境为Ubuntu 20.04,且OpenCV版本从4.2升级到4.5导致API不兼容。复盘发现,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回放),便于功能验证。
常见误区:很多交付团队只提供“编译命令”和“启动命令”,但忽略了硬件接线与代码参数的映射关系。例如,代码中默认激光雷达IP为 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 脚本,自动检查环境变量、依赖版本、端口连通性,并输出检查报告。这能极大减少接手方的排障时间,提升交付专业度。