4. 车辆属性定义与分类
在 AAOS VHAL(Vehicle Hardware Abstraction Layer)体系中,车辆属性是应用层、框架层与 HAL 层之间进行数据交互的最小语义单元。每一个属性都通过唯一的属性 ID 标识,并携带数据类型、访问权限、区域(Area)、变更模式等元信息。理解属性的分类方式,是正确设计 VHAL 接口、编写属性配置以及排查集成问题的前提。本节从两个正交维度切入:按归属划分的系统属性与厂商属性,按取值形态划分的连续属性、离散属性与混合属性。
一、核心原理:两个正交的分类维度
VHAL 属性的分类并非单一树状结构,而是两个相互独立的维度。第一个维度回答“谁定义、谁负责”,即系统属性与厂商属性;第二个维度回答“值如何变化”,即连续、离散与混合属性。同一个属性可以同时是“系统属性 + 连续属性”,也可以是“厂商属性 + 离散属性”,两个维度组合后形成完整的属性画像。
系统属性由 AOSP 统一定义,属性 ID 位于 VehicleProperty 枚举的固定区段,所有 AAOS 设备必须遵循相同的语义。典型代表包括 PERF_VEHICLE_SPEED、GEAR_SELECTION、HVAC_TEMPERATURE_SET 等。厂商属性则使用 VENDOR 区段(通常从 0x0100 起或使用 VehicleVendorPermission 约定的高位区段),由 OEM 或 Tier1 自行定义,用于表达品牌特有的功能,例如空气悬架高度、座椅按摩模式、氛围灯场景等。
连续属性在物理量上可取任意数值,通常以浮点或整型表示,如车速、电机转速、电池 SOC、空调设定温度。离散属性只能取有限枚举值,如挡位(P/R/N/D)、转向灯状态、车门开关状态。混合属性则兼具两者特征:它拥有离散的枚举取值,但每个枚举值又对应一个连续量或复合结构,例如 HVAC_FAN_DIRECTION 的吹风方向枚举配合风量等级,或 GEAR_SELECTION 与目标挡位、当前挡位的组合。
二、方法流程:属性定义与注册的关键步骤
在 VHAL 中新增或修改属性,需要遵循一套标准流程,确保属性 ID、数据类型与访问权限一致。
- 确定归属区段:若功能属于通用车辆语义,优先复用系统属性;若为品牌特有,则分配厂商属性 ID,并确保不与 AOSP 保留区段冲突。
- 选择取值类型:根据物理量特征选择连续、离散或混合。连续属性使用
FLOAT或INT32,离散属性使用INT32配合枚举,混合属性使用INT32_VEC或MIXED类型。 - 声明访问权限:通过
VehiclePropertyAccess指定READ、WRITE或READ_WRITE,并设置VehiclePropertyChangeMode为ON_CHANGE或CONTINUOUS。 - 配置区域与配置数组:对于多区域属性(如四个车门、多个座椅),使用
VehicleArea与配置数组描述每个区域的独立状态。 - 实现 HAL 读写:在
IVehicle实现中完成get/set逻辑,并确保subscribe回调按变更模式触发。
关键原则:属性 ID 一旦发布,其数据类型与语义不应随意变更;厂商属性应集中在独立头文件中管理,避免与系统属性 ID 空间交叉。
三、典型应用场景与配置示例
不同分类的属性在整车功能中承担不同角色。下表列出典型属性及其分类、数据类型与场景。
| 属性名称 | 归属 | 取值类型 | 数据类型 | 典型场景 |
|---|---|---|---|---|
| PERF_VEHICLE_SPEED | 系统 | 连续 | FLOAT | 仪表车速显示、自适应巡航 |
| GEAR_SELECTION | 系统 | 离散 | INT32 | 挡位显示、启动互锁 |
| HVAC_TEMPERATURE_SET | 系统 | 连续 | FLOAT | 空调温度调节 |
| HVAC_FAN_DIRECTION | 系统 | 混合 | INT32_VEC | 吹风方向与风量组合控制 |
| VENDOR_AIR_SUSPENSION_HEIGHT | 厂商 | 连续 | FLOAT | 空气悬架高度调节 |
| VENDOR_SEAT_MASSAGE_MODE | 厂商 | 离散 | INT32 | 座椅按摩模式切换 |
| VENDOR_AMBIENT_LIGHT_SCENE | 厂商 | 混合 | INT32_VEC | 氛围灯场景与亮度组合 |
以下是一个厂商混合属性的配置片段,展示如何声明枚举与连续量组合:
// vendor_vehicle_property.h
#define VENDOR_AMBIENT_LIGHT_SCENE 0x2100
#define VENDOR_AMBIENT_LIGHT_BRIGHTNESS 0x2101
// 属性配置
{
.prop = VENDOR_AMBIENT_LIGHT_SCENE,
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
.valueType = VehiclePropertyType::INT32_VEC,
.areaType = VehicleAreaType::GLOBAL,
.configArray = {SCENE_OFF, SCENE_WELCOME, SCENE_SPORT, SCENE_RELAX}
}
// 场景枚举与亮度连续量组合
// SCENE_SPORT + brightness=80 表示运动氛围灯,亮度80%
四、常见误区与复盘
误区一:把连续属性当离散属性用。例如将车速用枚举表示,导致精度丢失且无法支持自适应巡航的平滑控制。连续量应保留浮点精度,仅在显示层做格式化。
误区二:厂商属性 ID 与系统属性冲突。部分开发者直接使用 0x0001 等低位 ID,与 AOSP 保留区段重叠,导致 get 返回错误或属性被覆盖。应严格使用厂商区段并集中注册。
误区三:混合属性只实现枚举部分。混合属性的连续分量若未在 get 中返回,应用层会收到默认值,造成控制逻辑异常。需确保 INT32_VEC 的每个元素都有明确语义。
误区四:忽略变更模式与订阅关系。连续属性应使用 CONTINUOUS 模式并按采样率上报,离散属性使用 ON_CHANGE,否则会造成总线负载过高或状态更新延迟。
复盘时建议建立属性清单表,逐项核对归属、取值类型、访问权限、变更模式与区域配置。对于厂商属性,还应记录其对应的 ECU 信号来源与诊断接口,确保 VHAL 层与底层信号链一致。通过双维度分类模型,团队可以在设计早期发现属性定义冲突,减少后期集成返工。