简介:这份《代客泊车HAVP-功能规范》产品文档面向自动驾驶泊车功能的产品经理、系统工程师与测试人员,系统讲解记忆泊车辅助(HAVP)的完整功能定义与实现逻辑。文档围绕建图、记忆泊入与记忆泊出三大子功能展开,涵盖信号需求(输入/输出信号)、状态机与状态迁移条件、功能流程、HUT与APP交互逻辑、性能需求、关联件要求及适用场景等模块,并延伸至系统架构、安全机制与未来展望,可帮助读者理解从路径学习到自动泊车的完整链路。资源为1个PDF文件,压缩包约2.22MB,共79页,目录层级清晰,便于按章节查阅。目前已有744人学习下载,适合需要梳理HAVP功能规范、撰写需求文档或搭建测试用例的从业者参考。
1. 代客泊车HAVP功能规范:从一纸文档到可落地的工程约束
很多人第一次接触代客泊车HAVP功能规范,是把它当成一份“需求说明书”来读的——翻两页觉得都是些场景描述,就丢到一边了。但真正做过泊车项目的人知道,这份规范是整个系统的“宪法”:它决定了车位怎么找、路径怎么规划、什么条件下必须退出、出了事算谁的责任。我见过太多团队在Demo阶段跑得挺欢,一上真实地库就翻车,根因往往不是算法不行,而是功能规范里的边界条件没吃透。
HAVP(Home Automated Valet Parking)的核心逻辑是:用户在指定下客点下车,车辆自主完成从下客点到目标车位的驾驶,以及从车位到上客点的召回。它和普通泊车辅助最大的区别在于——全程无人在车内,所以功能规范必须把“系统能做什么、不能做什么、什么时候必须停下来叫人”写得极其明确。这篇文章面向的是正在做HAVP功能定义、系统设计或测试验证的工程师,我会把一份可落地的功能规范拆成可执行的模块,给出参数建议和踩坑记录,让你少走弯路。
2. 功能规范的骨架:场景定义、状态机与接口约束
2.1 用场景清单锁定系统边界
功能规范的第一件事不是写算法,而是把场景穷举清楚。HAVP的场景可以按三个维度切分:触发方式(用户主动召唤 vs 系统自动执行)、环境复杂度(地面停车场 vs 地下多层地库)、交通参与者(纯静态障碍 vs 有动态行人/车辆)。我一般会先画一张场景矩阵表,把每个格子的预期行为和退出条件填上。
| 场景编号 | 触发方式 | 环境类型 | 动态障碍 | 系统行为 | 退出条件 |
|---|---|---|---|---|---|
| S01 | 下客点出发 | 单层地库 | 无 | 自主泊入目标车位 | 到达车位并完成驻车 |
| S02 | 下客点出发 | 多层地库 | 无 | 跨层泊入 | 到达车位或路径阻断 |
| S03 | 下客点出发 | 单层地库 | 有行人 | 减速避让后继续 | 无法避让时原地等待 |
| S04 | 车位召回 | 单层地库 | 有车辆 | 绕行或等待 | 到达上客点或超时 |
| S05 | 任意 | 任意 | 传感器失效 | 安全停车并请求接管 | 驾驶员接管 |
这张表看起来简单,但每填一格都要和感知、规划、控制团队对齐。比如S03里“无法避让时原地等待”的等待时长是多少?超过多久要升级为请求远程协助?这些数字不写进规范,开发就会各自拍脑袋。
2.2 状态机设计:把“谁在控制”说清楚
HAVP系统必须有一个明确的状态机,定义每个状态下谁拥有控制权。常见做法是分五个顶层状态:待机、准备、自主行驶、暂停等待、退出。每个状态之间的迁移条件要写成布尔表达式,不能有歧义。
# HAVP顶层状态机迁移条件(伪代码示意) states = { "STANDBY": { "to_READY": "user_command == 'start' and self_check_passed", "to_EXIT": "fault_detected or user_cancel" }, "READY": { "to_DRIVING": "path_planned and no_immediate_obstacle", "to_STANDBY": "user_cancel or timeout_30s" }, "DRIVING": { "to_PAUSE": "obstacle_detected and cannot_avoid", "to_EXIT": "fault_detected or user_takeover", "to_ARRIVED": "reached_target and parked" }, "PAUSE": { "to_DRIVING": "obstacle_cleared and wait_time < 120s", "to_EXIT": "wait_time >= 120s or user_takeover" }, "EXIT": { "to_STANDBY": "safe_stop_confirmed and user_acknowledged" } }这段代码的关键在于每个迁移条件都是可判定的。self_check_passed要展开成具体的传感器自检项列表,cannot_avoid要定义清楚是距离小于多少米且横向余量不足多少厘米。我见过有团队把obstacle_cleared写成“障碍物消失”,结果测试时一个塑料袋飘过去又飘走,系统反复在PAUSE和DRIVING之间跳变,这就是规范没写细的后果。
2.3 接口约束:别让上下游互相猜
HAVP不是孤立系统,它要和整车网关、云端、手机App、地库设施通信。功能规范里必须有一章专门定义接口,包括信号名、数据类型、更新频率、超时处理。常见做法是用一张接口表把关键信号列出来。
| 信号名 | 方向 | 类型 | 频率 | 超时行为 |
|---|---|---|---|---|
| HAVP_Status | 输出 | 枚举 | 10Hz | 超时后App显示“连接中断” |
| Vehicle_Speed | 输入 | float | 50Hz | 超时后降级为安全停车 |
| Target_Slot_ID | 输入 | uint16 | 事件触发 | 无有效车位则拒绝启动 |
| Emergency_Stop | 输入 | bool | 100Hz | 超时视为触发急停 |
| Remote_Assist_Req | 输出 | bool | 事件触发 | 重试3次后本地安全停车 |
这里有个血泪经验:Emergency_Stop这种安全信号,超时行为必须定义为“视为触发”,而不是“忽略”。因为通信中断时你无法确认对方状态,保守策略永远是安全侧。
3. 从规范到代码:把行为约束翻译成可执行逻辑
3.1 路径规划的功能规范怎么写才不空
功能规范里写“系统应规划一条安全、舒适的路径”是没用的,开发看了不知道怎么实现,测试看了不知道怎么判。我一般会把它拆成可量化的约束:曲率上限、速度上限、离障碍物最小距离、换挡次数上限。
# 路径规划约束检查(示意) def validate_path(path, vehicle_params): max_curvature = 0.15 # 1/m,对应最小转弯半径约6.7m max_speed = 5.0 # m/s,地库内限速 min_clearance = 0.3 # m,离静态障碍物最小距离 max_gear_shifts = 3 # 单次泊入允许的最大换挡次数 for point in path: if abs(point.curvature) > max_curvature: return False, "曲率超限" if point.speed > max_speed: return False, "速度超限" if point.clearance < min_clearance: return False, "离障碍物过近" if path.gear_shifts > max_gear_shifts: return False, "换挡次数过多" return True, "通过"参数说明:max_curvature取0.15是因为一般乘用车最小转弯半径在5.5到6.5米之间,留点余量。min_clearance取0.3米是考虑到超声波雷达和环视摄像头的融合感知精度,再小就容易误触发。max_gear_shifts限制3次是为了避免原地反复揉库,用户体验差还伤转向系统。这些数字不是拍脑袋,是结合车辆动力学和传感器能力算出来的,规范里最好附上计算依据。
3.2 安全停车策略的规范落地
HAVP最核心的安全机制是“失效可运行”——任何单点故障都不能导致车辆失控。功能规范里要定义清楚不同故障等级对应的动作。
| 故障等级 | 典型故障 | 系统动作 | 响应时间 |
|---|---|---|---|
| 一级 | 单个超声波雷达失效 | 降速至2m/s,继续任务 | 立即 |
| 二级 | 环视摄像头全部失效 | 安全停车,请求接管 | 200ms内 |
| 三级 | 制动系统故障 | 紧急制动,打开双闪 | 100ms内 |
| 四级 | 转向系统故障 | 紧急制动,保持当前方向 | 50ms内 |
这里有个容易翻车的地方:一级故障降速后,如果降速过程中又发生二级故障,状态机要能正确迁移到安全停车,而不是卡在降速逻辑里。规范里要写明故障等级的叠加处理规则。
3.3 人机交互的规范细节
HAVP的人机交互不只是App上点个按钮。功能规范要定义:下客点怎么选、用户离车后多久系统启动、过程中用户能不能通过App看到车辆状态、紧急情况下怎么远程干预。
// App端状态显示逻辑(示意) const havpStatusMap = { 'STANDBY': { text: '待机中', color: 'gray', canCancel: true }, 'READY': { text: '准备出发', color: 'blue', canCancel: true }, 'DRIVING': { text: '泊车中', color: 'green', canCancel: false }, 'PAUSE': { text: '等待避让', color: 'yellow', canCancel: true }, 'EXIT': { text: '已退出,请接管', color: 'red', canCancel: false } }; function updateUI(status) { const info = havpStatusMap[status]; if (!info) return; // 关键:DRIVING状态下禁止取消,避免用户误操作导致车辆中途停下 document.getElementById('cancel-btn').disabled = !info.canCancel; document.getElementById('status-text').innerText = info.text; }逻辑说明:DRIVING状态下禁止取消是硬约束,因为车辆已经在移动中,突然取消可能导致停在路中间。如果用户确实需要中止,应该走“请求接管”流程,由系统安全停车后再交还控制权。这个细节不写进规范,App开发可能就做成随时可取消了。
4. 避坑与排查:HAVP功能规范落地时的五个常见问题
4.1 现象:地库信号弱导致定位跳变,车辆画龙
原因:功能规范里只写了“定位精度应满足要求”,但没定义信号遮挡场景下的降级策略。地库多层结构对GNSS信号遮挡严重,单纯依赖GNSS+IMU会在长直道上累积误差。
解决:规范里补充“定位降级策略”——当GNSS信噪比低于阈值时,切换为视觉里程计+轮速计+地库预建地图匹配。同时定义定位置信度低于0.6时降速至1m/s,低于0.3时安全停车。这个阈值要根据实际地库测试标定,不能照搬公开数据。
4.2 现象:泊入车位时反复揉库,超过5次还没进去
原因:规范里只写了“应泊入目标车位”,没定义泊入失败的处理流程。规划模块在狭窄车位里可能陷入局部最优,反复调整。
解决:在规范里加一条“单次泊入尝试超过3次换挡或总时长超过90秒,判定为泊入失败,系统应退出车位,重新规划或请求远程协助”。这个数字来自实际测试统计,超过3次换挡后成功率急剧下降。
4.3 现象:行人突然出现,车辆急刹但距离过近
原因:规范里定义了“应避让行人”,但没定义避让的舒适性约束。控制模块为了满足安全距离,可能直接触发最大减速度。
解决:规范里区分“安全距离”和“舒适距离”。安全距离是硬约束(比如0.5米),舒适距离是软约束(比如2米)。在舒适距离内用正常减速度,进入安全距离才允许紧急制动。同时定义减速度变化率上限,避免急刹导致后车追尾。
4.4 现象:用户手机App显示“泊车中”,但车辆实际已停下
原因:状态同步机制没定义清楚。车辆端状态更新了,但App端因为网络延迟或轮询间隔太长,显示滞后。
解决:规范里定义状态同步的机制——车辆端状态变化时主动推送,App端同时以1Hz频率轮询作为兜底。推送和轮询的状态不一致时,以车辆端最后一次推送为准,并在App上显示“状态同步中”。超时5秒未收到推送,App显示“连接不稳定”。
4.5 现象:测试时一切正常,量产车上偶发“幽灵刹车”
原因:功能规范里的测试用例覆盖了典型场景,但没覆盖传感器噪声和极端天气的组合。比如地库顶部的管道滴水,被超声波雷达误判为障碍物。
解决:规范里增加“传感器噪声过滤”章节,定义连续N帧检测到同一位置有障碍物才确认为真实障碍,N的取值根据传感器类型不同(超声波取3,毫米波取2,视觉取5)。同时定义雨天/洗车后等特殊场景的灵敏度调整策略。
5. 进阶技巧:用场景覆盖率验证功能规范的完整性
功能规范写完不是终点,怎么验证它覆盖了足够多的场景才是关键。我一般会用“场景覆盖率”这个指标来量化——把HAVP可能遇到的所有场景按维度展开,看规范里明确定义了行为的场景占比。
具体做法是建一个三维矩阵:X轴是环境复杂度(简单/中等/复杂),Y轴是交通参与者(无/静态/动态),Z轴是系统状态(正常/降级/故障)。每个格子代表一类场景,规范里必须对每个格子给出明确的系统行为定义。我做过的一个项目里,初始规范只覆盖了约60%的格子,补齐后测试阶段的意外退出率下降了四成多。
# 场景覆盖率计算(示意) import itertools env_levels = ['simple', 'medium', 'complex'] traffic_levels = ['none', 'static', 'dynamic'] system_states = ['normal', 'degraded', 'fault'] all_scenarios = list(itertools.product(env_levels, traffic_levels, system_states)) defined_scenarios = load_defined_scenarios('havp_spec.yaml') # 从规范文档解析 coverage = len(defined_scenarios) / len(all_scenarios) print(f"场景覆盖率: {coverage:.1%}") # 输出未覆盖的场景,逐条补充 for s in all_scenarios: if s not in defined_scenarios: print(f"未定义: 环境={s[0]}, 交通={s[1]}, 系统={s[2]}")这个脚本跑一遍,就能把规范里的盲区找出来。我习惯在规范评审会上直接跑这个,让每个模块负责人认领未覆盖的场景,当场定行为、定参数。比逐页翻文档效率高得多。
还有一个技巧是“反向验证”——从测试用例反推规范。把测试团队设计的极端场景拿过来,看规范里有没有对应的行为定义。如果没有,要么补规范,要么明确说“这个场景不在HAVP设计运行域内”。最怕的是规范里没写、测试也没测,量产车上第一次遇到就抓瞎。
最后说个我自己的教训:早期做HAVP规范时,我花了很多篇幅写正常流程,对降级和故障场景一笔带过。结果实车测试时,一个简单的超声波雷达被泥水遮挡就导致车辆在路中间停了十分钟,因为规范里没定义“单传感器失效后是继续还是退出”。后来我把故障场景的篇幅加到正常场景的两倍,每个故障等级都配了状态迁移图和恢复条件。这份规范后来成了团队新人的必读材料,因为看完就知道系统在什么情况下会做什么、不会做什么。希望这些经验帮到你。
本文还有配套的精品资源,点击获取