3. 环境搭建与配置:Docker化部署仿真环境,依赖库安装与版本管理
说实话,搞自动驾驶仿真最头疼的事,不是算法写不出来,而是环境搭不起来。
我见过太多团队,代码写得挺好,一换机器就崩。库版本冲突、系统依赖缺失、Python 环境乱成一锅粥。嗯,这章我们就来解决这个问题。
3.1 为什么一定要用 Docker?
你想想看,一个典型的仿真环境要装多少东西?
- ROS 2(Humble 或 Galactic)
- Carla / SUMO / Gazebo 仿真器
- Python 3.8+ 以及一堆科学计算库
- CUDA + cuDNN + TensorRT(如果你用 GPU 加速)
- 各种消息中间件和协议库
这些依赖之间互相打架是常有的事。我个人习惯,从一开始就把所有环境锁在 Docker 里。好处很明显:
| 问题 | 传统方式 | Docker 方式 |
|---|---|---|
| 环境迁移 | 重装一遍,踩坑无数 | 一条命令拉镜像 |
| 版本冲突 | pip 和 apt 互相覆盖 | 隔离的容器层 |
| 团队协作 | 每个人环境不一样 | 完全一致的镜像 |
| CI/CD 集成 | 手动配置,容易漏 | Dockerfile 自动化 |
核心原则:把环境当作代码来管理。Dockerfile 就是你的环境说明书,版本控制里必须包含它。
3.2 我们的 Docker 镜像架构
先给你看一张整体架构图,心里有个底。
为什么要分这么多层?说白了,就是利用 Docker 的缓存机制。你改一行 Python 代码,不需要重新编译 CUDA 和 ROS。我在项目中遇到过,一开始把所有东西写在一个 RUN 指令里,每次改个参数都要等半小时重新构建。后来拆成五层,构建时间从 30 分钟降到了 2 分钟。
3.3 编写 Dockerfile
好,我们直接上手。这是我们的 Dockerfile 核心部分:
# ===== Layer 1: 基础系统 =====
FROM nvidia/cuda:11.8.0-devel-ubuntu22.04 AS base
RUN apt-get update && apt-get install -y \
build-essential \
cmake \
git \
wget \
python3-pip \
python3-dev \
&& rm -rf /var/lib/apt/lists/*
# ===== Layer 2: ROS 2 Humble =====
FROM base AS ros2
RUN apt-get update && apt-get install -y \
ros-humble-desktop \
ros-humble-rmw-fastrtps-cpp \
&& rm -rf /var/lib/apt/lists/*
# ===== Layer 3: 仿真引擎 =====
FROM ros2 AS simulator
RUN pip3 install carla==0.9.14
RUN apt-get update && apt-get install -y sumo=1.18.0
# ===== Layer 4: 算法库 =====
FROM simulator AS algo
RUN pip3 install torch==2.0.0 torchvision==0.15.0
RUN pip3 install numpy==1.24.3 scipy==1.10.1 matplotlib==3.7.1
# ===== Layer 5: 应用层 =====
FROM algo AS app
WORKDIR /workspace
COPY ./src /workspace/src
RUN pip3 install -e /workspace/src
小技巧:把 apt-get install 和 pip install
3.4 依赖库版本管理
光有 Dockerfile 还不够。你想想看,Python 库的依赖关系有多复杂?
我个人习惯用 requirements.txt 配合 pip freeze 来管理。但这里有个坑:pip freeze 会把所有间接依赖也列出来,导致文件臃肿。我建议只锁定直接依赖,间接依赖让 pip 自己解析。
这是我们的 requirements.txt 示例:
# 核心依赖
numpy==1.24.3
scipy==1.10.1
matplotlib==3.7.1
pyyaml==6.0
# 深度学习
torch==2.0.0
torchvision==0.15.0
# 仿真接口
carla==0.9.14
sumo==1.18.0
# 轨迹处理
shapely==2.0.1
transforms3d==0.4.1
注意:不要在生产镜像里用 pip install --upgrade。我曾经在 CI 里加了 --upgrade,结果 numpy 从 1.24 被升到 1.26,接口变了,整个轨迹验证模块全部报错。排查了整整一天。
3.5 构建与启动脚本
每次手动敲 docker build 太累了。我写了个 Makefile 来封装常用操作:
# Makefile
IMAGE_NAME = sim-env
TAG = latest
build:
docker build -t $(IMAGE_NAME):$(TAG) .
run:
docker run -it --rm \
--gpus all \
--net=host \
-v $(PWD)/data:/workspace/data \
-v $(PWD)/config:/workspace/config \
$(IMAGE_NAME):$(TAG)
shell:
docker run -it --rm \
--gpus all \
--net=host \
-v $(PWD):/workspace \
$(IMAGE_NAME):$(TAG) \
/bin/bash
clean:
docker system prune -f
使用方式很简单:
make build— 构建镜像make run— 启动仿真联调make shell— 进入容器调试
3.6 避坑指南
嗯,这里总结几个我踩过的坑:
坑 1:CUDA 版本不匹配
我曾经把 CUDA 11.8 的镜像和 PyTorch 2.0(需要 CUDA 11.7)混用,结果训练时 GPU 利用率一直上不去。后来发现是 CUDA 运行时库版本冲突。解决办法:用 nvidia-smi 和 nvcc --version 确认版本一致。
坑 2:ROS 2 通信问题
Docker 默认网络模式是 bridge,ROS 2 的 DDS 发现协议会失败。我折腾了两天才发现,加 --net=host 就能解决。或者用 --env ROS_DOMAIN_ID=42 来隔离不同容器。
坑 3:磁盘空间爆炸
Docker 镜像每层都会缓存。如果你频繁构建,/var/lib/docker 会迅速膨胀。我养成了每周跑一次 docker system prune -a 的习惯,能释放几十 GB 空间。
3.7 验证环境是否搭建成功
环境搭好了,怎么确认一切正常?我写了一个简单的验证脚本:
#!/usr/bin/env python3
"""环境验证脚本"""
import sys
def check_imports():
"""检查关键库是否能导入"""
libs = [
('numpy', '1.24.3'),
('torch', '2.0.0'),
('carla', '0.9.14'),
('sumo', '1.18.0'),
]
for lib_name, expected_version in libs:
try:
module = __import__(lib_name)
actual_version = module.__version__
if actual_version != expected_version:
print(f"[WARN] {lib_name}: 期望 {expected_version}, 实际 {actual_version}")
else:
print(f"[OK] {lib_name}: {actual_version}")
except ImportError:
print(f"[FAIL] {lib_name}: 未安装")
return False
return True
def check_gpu():
"""检查 GPU 是否可用"""
try:
import torch
if torch.cuda.is_available():
print(f"[OK] GPU: {torch.cuda.get_device_name(0)}")
else:
print("[WARN] GPU: 不可用,将使用 CPU")
except:
print("[WARN] GPU: 检查失败")
if __name__ == "__main__":
print("=== 仿真环境验证 ===")
success = check_imports()
check_gpu()
sys.exit(0 if success else 1)
跑一下这个脚本,所有依赖一目了然。我在 CI 流程里也集成了这个验证,每次构建完镜像自动跑一遍,有问题立刻报警。
3.8 小结
这一章我们做了三件事:
- 用 Docker 分层构建了仿真环境镜像
- 锁死了所有依赖库的版本
- 写了构建脚本和验证脚本
环境搭好了,后面才能安心做仿真联调和轨迹验证。记住一句话:环境问题不解决,算法再牛也跑不起来。