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 车辆属性分类双维度模型 归属维度(谁定义) × 取值维度(值如何变化) 维度一:归属分类 系统属性 AOSP 统一定义 厂商属性 OEM/Tier1 自定义 PERF_VEHICLE_SPEED GEAR_SELECTION HVAC_TEMPERATURE_SET VENDOR_AIR_SUSPENSION VENDOR_SEAT_MASSAGE VENDOR_AMBIENT_SCENE 维度二:取值分类 连续属性 浮点/整型 离散属性 枚举值 混合属性 枚举+连续 车速 / 转速 电池 SOC 空调设定温度 挡位 P/R/N/D 车门开关 转向灯状态 吹风方向+风量 挡位+目标挡位 座椅位置+记忆 典型组合示例:属性画像 = 归属 × 取值 系统 + 连续 PERF_VEHICLE_SPEED 系统 + 离散 GEAR_SELECTION 厂商 + 连续 VENDOR_AIR_SUSPENSION 厂商 + 混合 VENDOR_SEAT_MASSAGE 同一属性在两个维度上各有归属,组合后决定其数据类型、访问权限与变更通知策略 系统属性保证跨平台兼容,厂商属性提供品牌差异化能力

二、方法流程:属性定义与注册的关键步骤

在 VHAL 中新增或修改属性,需要遵循一套标准流程,确保属性 ID、数据类型与访问权限一致。

  1. 确定归属区段:若功能属于通用车辆语义,优先复用系统属性;若为品牌特有,则分配厂商属性 ID,并确保不与 AOSP 保留区段冲突。
  2. 选择取值类型:根据物理量特征选择连续、离散或混合。连续属性使用 FLOAT 或 INT32,离散属性使用 INT32 配合枚举,混合属性使用 INT32_VEC 或 MIXED 类型。
  3. 声明访问权限:通过 VehiclePropertyAccess 指定 READ、WRITE 或 READ_WRITE,并设置 VehiclePropertyChangeMode 为 ON_CHANGE 或 CONTINUOUS。
  4. 配置区域与配置数组:对于多区域属性(如四个车门、多个座椅),使用 VehicleArea 与配置数组描述每个区域的独立状态。
  5. 实现 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 层与底层信号链一致。通过双维度分类模型,团队可以在设计早期发现属性定义冲突,减少后期集成返工。