共计 2578 个字符,预计需要花费 7 分钟才能阅读完成。
背景与痛点
自动驾驶泊车场景看似简单,实则充满技术挑战。相比开放道路驾驶,泊车环境有几个显著特点:

- 空间极度受限:传统泊车位宽度往往仅有车身宽度的 1.2-1.5 倍,对定位精度要求极高(厘米级)
- 动态障碍复杂:行人、宠物、突然开启的车门等不可预测因素频发
- 传感器视野受限:近距离盲区增大,传统雷达易受多径效应干扰
- 路径规划特殊:需要支持多段式倒车、微调等特殊机动动作
这些特点使得直接套用开放道路的自动驾驶方案效果不佳。Apollo 针对性地开发了泊车专用技术栈。
技术架构
Apollo 泊车系统采用经典的四层架构,但各模块实现有显著差异:
┌───────────────────────┐
│ HMI 交互层 │
└──────────┬────────────┘
↓
┌───────────────────────┐
│ 决策规划层 │
│ • 强化学习决策引擎 │
│ • 多阶段路径规划 │
└──────────┬────────────┘
↓
┌───────────────────────┐
│ 感知定位层 │
│ • 多传感器融合 │
│ • 语义 SLAM │
└──────────┬────────────┘
↓
┌───────────────────────┐
│ 线控执行层 │
│ • 转向 / 制动 / 档位控制 │
└───────────────────────┘
数据流有三个关键特点:
- 高频定位更新:采用 10Hz 的紧耦合 SLAM,比开放道路方案(通常 1 -5Hz)更高
- 分层规划机制:全局规划(车位选择)与局部规划(轨迹生成)解耦
- 控制回环加速:控制指令下发周期缩短到 20ms 级
核心算法
传感器融合方案
Apollo 泊车采用前视摄像头 + 环视摄像头 + 超声波雷达 +4D 毫米波雷达的组合:
- 视觉处理:
- 环视鱼眼镜头做车位线检测(基于 CNN+ 几何约束)
- 前视镜头识别障碍物类型(分类网络)
- 雷达处理:
- 超声波用于 0 -5m 近距探测(精度±2cm)
- 4D 毫米波解决常规雷达的俯仰角测量问题
融合算法采用改进的卡尔曼滤波,运动模型特别考虑了低速场景的特性:
# 低速运动模型简化示例
def vehicle_motion_model(x, u, dt):
"""
x: 状态向量 [x,y,θ,v]
u: 控制输入 [方向盘转角, 加速度]
dt: 时间步长
注:忽略横向滑移,适合低速场景
"""
L = 2.8 # 轴距
beta = np.arctan(0.5 * np.tan(u[0])) # 转向等效角度
dx = np.zeros_like(x)
dx[0] = x[3] * np.cos(x[2] + beta) * dt # x 方向
dx[1] = x[3] * np.sin(x[2] + beta) * dt # y 方向
dx[2] = x[3] * np.tan(u[0]) * dt / L # 航向角
dx[3] = u[1] * dt # 速度
return x + dx
语义增强 SLAM
传统 SLAM 在车库环境容易因重复纹理失效。Apollo 的方案:
- 特征点筛选:优先选择车位线角点、消防设备等语义特征
- 动态过滤:通过时序一致性检测移除行人等移动物体
- 多源约束:融合轮速计、转向角等车辆本体传感器数据
强化学习决策
泊车决策的挑战在于难以用规则覆盖所有情况。Apollo 采用 PPO 算法训练决策模型:
- 状态空间:包含相对车位位置、障碍物分布、历史轨迹等 32 维特征
- 动作空间:离散动作(前进 / 后退 / 换挡)+ 连续动作(转向角 / 加速度)
- 奖励函数 设计要点:
- 成功泊入:+100
- 碰撞:-50
- 每步耗时:-0.1
- 偏离参考路径:-0.5×距离
代码实现
关键路径规划算法示例(Hybrid A* 改进版):
// Apollo 中的泊车轨迹生成核心逻辑
ParkingTrajectory Planner::GenerateTrajectory(const VehicleState& state,
const ParkingSpace& space) {
// 1. 构建状态网格
GridMap grid = BuildGridMap(space, obstacles_);
// 2. 启发式搜索
std::priority_queue<Node*, std::vector<Node*>, NodeCompare> open_set;
open_set.push(new Node(state.x, state.y, state.theta));
while (!open_set.empty()) {Node* current = open_set.top();
open_set.pop();
// 3. 到达检查(放宽位置容忍度,严格要求角度)if (ReachGoal(current, space)) {return ExtractTrajectory(current);
}
// 4. 扩展节点(考虑倒车、转向等动作)for (auto& action : GetParkingActions()) {Node* next = ApplyAction(current, action);
if (!CollisionCheck(next, grid)) {next->cost = current->cost + ActionCost(action);
next->h = Heuristic(next, space);
open_set.push(next);
}
}
}
return ERROR_TRAJECTORY; // 搜索失败
}
性能优化
实际部署中的关键优化点:
- 计算资源分配:
- 视觉处理:限制在 15ms/ 帧(720P 分辨率)
- 规划控制:固定占用 1 个 CPU 核心保证实时性
- 内存管理:
- SLAM 特征点缓存不超过 500 个
- 轨迹预测仅保留未来 3 秒内的结果
- 通信优化:
- 使用共享内存传递传感器数据(替代 ROS 默认的 TCP)
- 关键消息采用零拷贝设计
避坑指南
常见问题及解决方案:
- 超声波误触发:
- 问题:潮湿地面、金属井盖易引发误报
-
方案:增加多帧确认逻辑,结合视觉校验
-
车位识别偏差:
- 问题:倾斜光照导致车位线检测偏移
-
方案:动态白平衡 + 多视角投票
-
控制震荡:
- 问题:狭小空间反复调整方向
- 方案:在代价函数中增加平滑项惩罚
思考题
- 如何设计失效安全机制,当传感器出现矛盾信息时仍能安全停车?
- 在极端狭窄车位(如两侧各 5cm 余量),控制系统需要哪些特殊处理?
- 怎样利用 V2X 技术提升地下车库等 GPS 拒止环境的定位可靠性?
通过 Apollo 的开源实现,我们可以看到自动驾驶泊车技术已经形成完整的技术体系。但在实际应用中,仍需要根据具体场景不断调优参数和算法。建议开发者先从仿真环境验证基础功能,再逐步过渡到实车测试。
正文完
