4. Stateflow模型仓库结构设计
Stateflow 模型一旦进入量产项目,就不再是单个工程师电脑里的一个 .slx 文件,而是一套需要被多个车型、多个团队、多个版本同时复用的资产。仓库结构设计的核心目标,是让“谁引用了谁、哪个车型用哪个版本、改动会影响哪些项目”这三个问题在目录层面就能被看清。本节围绕目录组织、命名规范、引用关系和变体管理四个维度展开,并给出一套可直接落地的仓库骨架。
一、目录组织:按“资产类型 + 复用层级”分层
量产仓库最常见的错误是按“项目名”平铺目录,例如 ProjectA/、ProjectB/ 各放一份模型,导致同一段控制逻辑被复制多份,修一个 bug 要改 N 个地方。更合理的做法是按资产类型分层,把“可复用单元”和“项目装配”分开:
stateflow-repo/
├── lib/ # 可复用库,跨车型共享
│ ├── core/ # 基础状态机:上电、下电、故障降级
│ ├── bms/ # 电池管理状态逻辑
│ └── thermal/ # 热管理状态逻辑
├── variants/ # 车型变体配置(只放差异,不放逻辑)
│ ├── variant_A.yaml
│ ├── variant_B.yaml
│ └── variant_C.yaml
├── projects/ # 项目装配层,引用 lib + variants
│ ├── project_A/
│ │ ├── top.slx # 顶层装配模型
│ │ └── project_A.mk # 构建/生成配置
│ └── project_B/
├── interfaces/ # 接口定义:数据字典、总线、枚举
│ ├── can_signals.sldd
│ └── enums.sldd
└── tools/ # 校验脚本、CI 配置
├── check_naming.m
└── check_refs.m
关键原则是:lib 只放逻辑,variants 只放差异,projects 只放装配。任何一段状态逻辑如果被两个以上车型使用,就必须下沉到 lib;任何车型差异如果只是参数或枚举取值不同,就不应该复制一份模型,而应通过变体配置注入。
二、命名规范:让文件名自解释
命名规范要解决“看到文件名就知道它是什么、属于谁、什么状态”。建议采用分段式命名,段间用下划线,段内用驼峰:
- 库模型:
lib_<域>_<功能>.slx,例如lib_bms_socEstimation.slx; - 项目顶层:
proj_<车型>_top.slx,例如proj_variantA_top.slx; - 状态机内部:State 用
ST_前缀,如ST_Init、ST_Fault;转移条件用TR_前缀; - 数据对象:输入
u_、输出y_、参数p_、标定cal_,例如u_ignition、p_socLowThreshold。
命名规范必须可被脚本检查。例如用正则 ^lib_[a-z]+_[A-Za-z]+\.slx$ 校验库模型名,在 CI 中拦截不合规提交。规范不落到脚本,三个月后就会形同虚设。
三、模型引用关系:单向依赖,禁止环
Stateflow 模型之间通过 Model Reference、Library、Data Dictionary 建立引用。量产仓库必须保证引用关系是有向无环图(DAG):lib 可以被 projects 引用,projects 之间不能互相引用,lib 内部也尽量保持单向。下图展示了一个典型的多车型引用拓扑:
引用关系必须可自动校验。一个实用的做法是在 tools/check_refs.m 中遍历所有 .slx,解析其 Model Reference 列表,构建邻接矩阵后检测环;一旦发现环或跨层引用(如 lib 引用 projects),CI 直接失败。这样可以在合并请求阶段就拦住结构性问题,而不是等到集成时才暴露。
四、多车型变体管理:差异外置,逻辑共享
多车型变体管理的本质是“把变化点集中到一处”。常见的变化点包括:阈值参数(如 SOC 低报警阈值)、枚举取值(如车型专属故障码)、状态机分支(某车型多一个“快充预热”状态)。前两类适合用变体配置文件注入,第三类才需要条件编译或变体模型。
以 SOC 低报警阈值 p_socLowThreshold 为例,variant_A 设为 20%,variant_B 设为 15%,variant_C 设为 25%。在 variants/variant_A.yaml 中只写差异:
variant: A
overrides:
p_socLowThreshold: 20
p_fanStartTemp: 45
enums:
faultCode_thermal: 0x21A
构建时由脚本读取对应 yaml,生成项目专属的标定数据文件,再与 lib 模型一起编译。这样 lib 模型本身不含任何车型硬编码,新增车型只需新增一个 yaml,而不是复制模型。对于确实需要新增状态分支的车型,建议在 lib 中预留可配置的“扩展状态”接口,通过变体开关决定是否激活,而不是在项目层直接改库模型。
五、落地检查清单
仓库结构设计完成后,建议用以下清单做一次自检:目录是否按 lib/variants/projects/interfaces 分层;命名是否可被正则校验;引用关系是否为 DAG 且无跨层反向引用;车型差异是否全部外置到 variants;CI 是否包含命名检查和引用检查。这五项都通过,仓库才具备支撑多车型量产迭代的基础条件。