K4-02 基于模型开发(MBD):Simulink 建模与代码生成
课程代码 K4-02 · 板块 K 控制、软件与标定 / K4 嵌入式软件与开发 时长 约 4.0 小时(6 讲 + 1 次建模与定点实操) 适合对象 控制 / 仿真工程师;做控制算法向嵌入式代码转化的人(必修) 前置 K3-01 整车热管理控制策略总览与模式管理 整车热管理控制策略总览与模式管理;体系外前置(需自备):Simulink/Stateflow 基础操作 本讲义定位 讲师授课蓝本 / 学员自学讲义,是 K4-02 大纲的完整展开版
引言:模型在仿真里跑通了——而这句话对「这段代码在 ECU 上跑得怎么样」,一个字都没说
做热管理控制的人现在很少手写 C 代码了:控制逻辑在 Simulink 里画成模型,模式切换交给 Stateflow,仿真波形看着满意,再用代码生成器吐出一份能编进 ECU 的 C 代码。这条链本身不难学,工具手册讲得比任何一门课都细。真正卡住人的是三个场合,而它们没有一个是「Simulink 不会用」。第一个场合在模型评审会上:模型跑得很好,阶跃响应漂亮,评审签字放行;三个月后软件集成,那个任务偶发超时,回头查才发现从来没有人测过这段代码在目标处理器上跑一次要多久——控制工程师以为代码生成器会保证,软件工程师以为模型侧已经核过,这笔账掉在两个人中间的缝里。第二个场合在台架上:同一个模型,浮点仿真时表现良好,定点部署之后被控量开始小幅来回摆;于是回去调 PID,调小变迟钝、调大更振,两个方向都不解决,而每一轮台架验证都是真金白银。第三个场合在评审桌的另一头:交出一份写着覆盖率数字的报告,对方问「这个数是在模型上测的还是在生成代码上测的」,答不上来——而这两个数的分母根本不是同一批分支。这门课要处理的正是这三件事。
所以本课教的不是「怎么在 Simulink 里把模型搭出来」,而是模型跑通之后,还有哪几笔账没人替你算。学完你应该能做五件事,每一件都对应一个当场可验的动作:按可维护、可复用的原则搭出控制模型的架构——交付物是一张架构图与接口定义,自检只有一句话「这个子系统能用一句不含『和』的话说清它负责什么吗」;选择定点还是浮点,并核算量化误差对控制精度的影响——交付物是一张定点方案表,每一行都写着量程依据,积分与累加通路单独标记;用建模规范与静态分析这两道扫描闸约束模型——交付物是扫描报告加一份显式成表的偏离记录,每条偏离带理由与批准人;核算生成代码的 ROM 与静态 RAM 占用,并知道执行时间读不出于代码生成报告——交付物是一张资源与时间核算表,每个数标明它是估算还是实测、从哪一层取到的;建立需求到模型到代码的追溯关系——它不是交付前补的表,而是建模那一刻就该记下的东西。这五件事之外,本课要么只给去向、要么明说不给,下面逐类交代清楚。
全课六讲。第 1 讲把位置与入口摆平——这条开发方式在 V 模型上覆盖哪一段、它的入口为什么必须是条目化的控制功能规格而不是一段散文、相对手写代码换来了什么又把什么变成了权衡项、谁建模谁看代码、以及那道只有一句判据的建模入口检查;第 2 讲讲架构——按什么切而不是切成几层,层次与接口怎样直接决定生成代码长什么样,模型里每个数都要过的三分判定,以及 Stateflow 与数据流之间那条边界画在哪;第 3 讲讲两道扫描闸——一道扫模型、一道扫生成代码,机器扫得到什么、只有人能判什么,以及告警的处置回路;第 4 讲是本课最硬的一讲,讲数据类型与数值精度——浮点还是定点由什么定死,Q 格式里量程与分辨率的跷跷板,量化误差为什么要看比值不看绝对值,粗量化加积分器怎么长出极限环,以及自动定点转换工具给的到底是什么;第 5 讲讲代码生成与两笔看不见的账——生成代码长什么样、ROM 与静态 RAM 的真值在哪、最坏栈用量为什么要单列一行、执行时间为什么只有一个可信来源;第 6 讲收口到交给下游验证的那一包证据——追溯矩阵的四层与两个方向、覆盖率的种类与各自的分母、以及覆盖率回答不了的那两类问题。前置是 K3-01 整车热管理控制策略总览与模式管理(整车热管理的模式怎么定义、怎么仲裁),Simulink 与 Stateflow 的基础操作属体系外前置、需自备。
钉子 1:模型在仿真里跑通,对「这段代码在 ECU 上跑得怎么样」一个字都没说。有四笔账仿真替不了,而且每一笔都要换一层、换一种手段才量得到。第一笔是数据类型——浮点仿真里根本不存在的量化误差,定点部署之后进入控制回路,上一段那个「浮点仿真好好的、定点一上就开始摆」的场合,正是这一支。第二笔是空间——ROM 与静态 RAM 的真值在目标编译器与链接器产出的 map 文件里,不在代码生成报告里,而且它随优化等级变。第三笔是时间——执行时间根本不在代码生成报告里;主机上跑的软件在环剖出的是主机 CPU 时间,只有把生成代码放到目标处理器或评估板上跑的处理器在环(PIL)、或目标端的性能剖析与操作系统任务时序跟踪,测到的才代表 ECU。第四笔是覆盖率的分母——生成代码里新增的防御分支(饱和限幅、数据类型转换、除零保护)从来不在模型覆盖率的分母里。⇒ 由这根钉子可以直接得到本课全程都要用的一个动作:交任何一件「验证通过」的证据之前,先问它回答了这四笔里的哪一笔。
钉子 2(它是钉子 1 的可执行版):每一个数、每一份报告,都要说清它是在哪一层、用什么手段量出来的;层与手段说不清,这个数就不许用来做判断。本课要求所有交付物的每一行都带这两个标签。有四组对绝不可互相替代,它们构成本课判据的核心:模型覆盖率 ≠ 代码结构覆盖率(分母不同)· 代码生成报告的静态估算 ≠ map 文件里的实际占用(中间隔着编译优化、库代码与启动代码)· 软件在环的主机 CPU 时间 ≠ 目标 ECU 的执行时间 · 目标端观测到的最大单步时间 ≠ 最坏执行时间(前者是「跑过的路径里最长的那条」,后者是「所有可能路径里最长的那条」)。⛔ 这四组里任何一组被当成等价,后果都不是精度问题,而是把一个根本没测过的东西当成证据交了出去——它会一路顺利过完前期的模型在环与软件在环,拖到硬件在环甚至整车上,才以任务超时或资源溢出的形态暴露出来。⚠ 注意这一路上不会有任何一项检查报错:每一项都按它自己的口径做到了,只是那个口径回答的不是被问的那个问题。
★ 本课最容易被读反的,是这样一句话:「定点是为了省资源,所以字长能短就短;而现在车规芯片都带浮点运算单元了,所以能用浮点就别碰定点。」这句话的两半各自都有对的部分——正是这个组合让它成为本课最危险的一句:定点确实曾经是为了省资源;带硬件浮点运算单元(FPU)的车规平台上,单精度浮点部署确实已经是常态。错的是它把「浮点还是定点」当成了一种偏好或者一股时代趋势,而它其实是一个由三组输入定死的判断——目标芯片有没有硬件 FPU、是单精度还是双精度 · 既有代码基线的数据类型约定、要不要求位精确复现老基线 · ROM 与执行时间预算。读者会做错的动作有三个方向,本课都要写清。方向 A:在带 FPU 的平台上白付定点的成本——看到「车规、量产、资源紧」就默认走定点,于是付出三笔本来不必付的成本:定标设计、量化误差核算、与标定工程师逐个量沟通量程与最小分辨单元;更坏的是把一个本来根本不存在的量化误差引进了控制回路。方向 B:在没有 FPU 的节点上无脑上浮点——反过来,因为「现在都用浮点了」,就在低端节点控制器或智能执行器上直接用浮点、甚至用双精度。无硬件 FPU 时浮点运算要靠编译器的软件浮点库模拟;只有单精度 FPU 的芯片上用双精度,同样退回软件模拟。⚠ 会恶化多少取决于芯片、编译器与运算构成,本课不给倍数——既然本课判定执行时间是平台相关量、不给单点值,就不能反过来拿它做倍数或数量级比较;本课只给方向,以及一条动作:必须在目标芯片上用 PIL 或目标端剖析实测。方向 C 是同一根源的第二层,也最隐蔽——把「量化误差太大」直接读成「字长不够」,于是只去加字长。而分辨率由「最小分辨单元 LSB = 量程 / 2ⁿ,n 为字长」决定,量程与字长两个量共同定死它:同样的字长,量程取得过宽会把分辨率白白浪费掉一大截,只调字长不看量程,加完仍然消不掉极限环;而反过来把量程压到信号真实范围之内,瞬态时会溢出或被饱和截掉——那是比量化误差更硬的一类错,因为它不是精度变差,是数值直接错。
⇒ 本课由此立一条硬口径(这是本课归纳的,不是哪份规范的既有条款):数据类型不是偏好,是由「平台能力 + 基线约束 + 预算」三组输入定的判断;判断做完之后还有第二道,即把最小分辨单元拿去与这条回路要分辨的最小信号变化量比。前一道决定走哪条路,后一道决定这条路上的参数取多少。⛔ 两道必须分开做,不许拿第二道的结论去倒推第一道——「定点定标做不出来,所以改浮点」,那是把预算与平台能力的判断,交给了一次失败的定标尝试。⇒ 于是有一组自检问句,动任何一个字长或数据类型之前先答三问:① 目标芯片有没有硬件 FPU,是单精度还是双精度?② 这条信号的量程是多少、这条回路要分辨的最小变化是多少?③ 这个量里有没有积分或累加环节(误差会随时间累积,而不是一次性的)?⛔ 全课不把「定点更省」「浮点更先进」当成选型依据;这两句只以被点破的错句形态出现在本节与常见误区一节里,⛔ 不会以正面表述出现在别处。
★ 还有一条同型的读反,本课在第 6 讲显式点破:「覆盖率越高越好,所以一律做修正条件 / 判定覆盖(MC-DC)」。实际的判据是档位由被测功能的汽车安全完整性等级决定,而不是越高越好;MC-DC 是高定级才强制的高推荐项,热管理软件常见的档位下,模型层的判定覆盖或条件覆盖即够。做错的动作同样有两个方向:一是对全部热管理软件强推最高档,把有限的测试资源从真正需要它的那几个功能上抽走;二是反过来,因为「热管理常见档位即够」这句话,就对一个实际定级更高的功能也只做模型层的判定覆盖——⚠ 那句话是行业观察,不是本项目的定级结论。⛔ 本课不给分档表、不写任何等级号:定级依据去向 K2-03 功能安全(ISO 26262)在热管理中的应用,分档表与关卡序列去向 K4-03 MIL/SIL/HIL 验证流程。
本课凡是要「列一张表」的地方——从模型到代码在 ECU 上跑起来中间要过哪几层、模型架构可以按哪些维度切、「模型能跑但代码不能用」有哪几类失败面、数据类型决策要哪些输入、资源与时间的每个量在哪一层才量得到、覆盖率一共有哪些种类——一律先把全集画出来、再逐格核射程,而不是顺着自己最熟的那条线索往下数。这不是讲究:沿单一线索枚举时漏掉的从来不是「少了一条」,而是整类不出现,而表面上那张表还是齐的。三个已经踩实的例子。其一,只沿「Simulink → 代码生成器 → C 代码」这条工具链数,会整类漏掉入口的需求层(于是模型里长出没有任何需求支撑的功能)、编译与链接层(而 ROM 与静态 RAM 的真值恰恰只在这一层才拿得到)、以及制品管理层——漏掉的不是一两个环节,是三整类。其二,沿「顶层 → 子系统 → 原子子系统」这条层次线索数架构,它只回答「切成几层」,根本不回答「按什么切」;一个把输入处理、控制逻辑与输出限幅混在同一个子系统里的模型,在层次上完全可以是规规矩矩的三层。其三,沿「资源超标」这一条数失败面,会整类漏掉时间类、数值算法类与状态机可达性类;而数值算法类是最隐蔽的一类——变步长仿真与定步长代码用的求解器不是同一个,它不会在任何一次模型在环仿真里暴露,看起来模型完全正常。
射程也先划清,免得在正文里白找。本课的落点是模型侧与代码生成侧:模型架构与接口、建模规范扫描、数据类型与定标、代码生成配置与生成代码的结构、以及从 map 文件读出 ROM 与静态 RAM 这一层,都在射程内。射程外的,本课只给类型与去向,不给限值、不给等级号、不给条款内容:控制功能规格怎么条目化、怎么评审、怎么向 Tier1 交接去向 K4-07 热管理控制功能规格(软件需求)的编写、评审与向 Tier1 交接;模型在环 / 软件在环 / 处理器在环 / 硬件在环的关卡序列与做法、以及模型与代码一致性比对的完整做法去向 K4-03 MIL/SIL/HIL 验证流程(本课只讲它的雏形与动机,并把 PIL 当作「执行时间唯一可信来源」这条判据的去向来用);生成代码集成到运行时环境、任务与 Runnable 的映射、CPU 利用率合账去向 K4-01 热管理嵌入式软件架构与 AUTOSAR 基础;状态机的不可达状态、死迁移、迁移空洞与互斥条件缺失怎么检出去向 K4-05 模式状态机的完备性核对与可验证性设计;参数对象的轴点、插值与外插保护、上下限与不可标量去向 K6-10 标定量规格定义:轴点、插值/外插保护、上下限与不可标量,标定流程与工具去向 K6-01 热管理标定流程与工具(INCA/CANape)(本课只做模型侧那一次「标定量 / 常量 / 结构参数」的三分);模型与配置的版本、变体管理去向 K4-04 软件版本、配置与变量管理;回归范围怎么裁剪去向 K4-08 控制软件回归验证:基线与激励库、回归范围裁剪、自动执行与失败分诊;非易失存储(学习值、累计量)的持久化去向 K4-06 控制器非易失存储设计:学习值、诊断数据与累计量的持久化;偏离记录与交付物怎么随软件走、跨企业交付边界怎么划去向 K4-09 热管理控制软件的跨企业交付边界:交付物形态、DIA/SEooC、权限分级与联合验证签署;总线信号的打包与端序去向 K2-02 CAN/LIN/CAN-FD 通信与整车 EEA 集成。⚠ 还有一条边界要说在前面:本课不重讲控制算法本身——PID 三个参数怎么整定、前馈与增益调度怎么设计去向 K3-05 PID/前馈/增益调度控制实战,模型预测控制的预测模型与代价函数去向 K3-06 模型预测控制(MPC)在热管理中的应用;本课接过来的是「把它们搭成什么形状的模型」。⛔ 反过来说,「积分项该用几位定点」也不该在那两门课里讨论,那是本课的活。误差分项之间怎么合账,去向 K1-01 热管理传感器信号处理与故障诊断 与 K1-02 执行器驱动:电子阀/泵/风扇/压缩机 PWM。
标准与规范这一层,本课引用三个体系,它们各管一层:MAB 建模规范管模型(MathWorks Advisory Board;2020 年 v5.0 起由旧称 MAAB 改为此名,⚠ 版本与年份以 MathWorks 现行发布为准,引用前须核;日本侧另有独立维护的 JMAAB 指南,⛔ 三个名字不许混用);MISRA C:2012 管生成代码,由静态分析工具扫;ISO 26262 按生命周期分为若干部分,其中第 6 部分对应软件单元的设计与实现(⚠ 版次与年份以现行目录为准,引用前须核;⛔ 全课按用法写到部分号,不裸写这个标准号)。⛔ 而这三者的条文内容,本课一份都没有取到原文——所以正文与图上只写标准号、管什么、去哪查,不写规则号、不写条款号、不写限值、也不写「一共多少条」。⚠ 特别提醒两处:把 MAB 当成强制标准是错的,它是行业指南,采纳与裁剪由项目定;把某条标准要求转述一遍再当作本课的判据用,也是错的——转述值不能当标准值。
最后交代一类数,同样免得在正文里白找。这些量本课一个都不给:某个控制信号的量程、这条回路要分辨的最小变化量、以及据此定出的字长与最小分辨单元;案例里极限环的振荡幅值与周期;ROM 与静态 RAM 的预算值与实际占用值;最坏栈用量;单步执行时间、最坏执行时间、任务周期,以及「最坏单步执行时间相对任务周期留多少裕量」的那个门槛;无对应 FPU 平台上浮点相对定点、或双精度相对单精度的执行时间恶化倍数;生成代码相对手写代码的体积与效率差异;模型覆盖率与代码结构覆盖率之间那个分母差集有多大;模型架构的层数、单层模块数、接口个数这类规模阈值;以及各档模型覆盖率的目标百分比。它们全是平台相关量,取决于目标芯片与编译器、本 ECU 分给这块软件的配额、这条回路的增益与带宽、以及本项目的工况定义,只能由本项目的实测与系统仿真给出——⛔ 本课不给,⛔ 也禁止抄上一代平台的数,⛔ 图上同样不会偷偷画一条门槛线代替它(凡属这一类的量,图上都画成可沿轴自由平移的带,并写明它由本项目给出)。⚠ 规模阈值那一类本课还额外多一句:本课明确不设这类阈值,因为数量指标会退化成凑数指标;正文用自检问句代替阈值。
本课能给的数只有三类。一类是代数结论:最小分辨单元 LSB = 量程 / 2ⁿ(n 为字长),以及均匀量化下的误差界(落在正负半个 LSB 之内)——两式都会写清变量、单位与失效边界,⚠ 其中一条边界要现在就说:它们不适用于浮点,浮点的分辨率随数值大小变化、不是常数,把最小分辨单元的直觉带到浮点上是本课要显式点破的一处。一类是由目标平台整数宽度决定的结构事实:定点字长的常见档位是 8 / 16 / 32 位,⚠ 但某个具体信号取哪一档由该信号的量程与分辨需求决定,⛔ 常见档位不是推荐值。还有一类是本课自己立的结构划分,用到时会标明是本课归纳的——例如追溯矩阵的需求 / 模型 / 代码 / 测试用例四层。⛔ 除此之外,正文里凡是要走一遍口径的算例,一律使用明确标注为教学假设值的数,它们不对应任何平台、禁止照抄取用。这门课的交付物不是一组推荐值,是一串每个数都说得出「它在哪一层、用什么手段量出来」的证据。
第 1 讲 MBD 的起点不是打开 Simulink,是一份指得回条款的规格
模型跑通了,代码也生成出来了,评审仍然被打回——最常见的两处都不在建模技巧上,而在还没开始建模之前。一处是入口:手上拿到的「控制需求」是一段自然语言的策略描述,或者干脆是一张状态机草图,于是模型里每一个子系统都指不回任何一条可被指认的条款,第 6 讲要交的追溯矩阵从源头上就建不起来。另一处是缝隙:控制工程师建模型、软件工程师看生成代码,两边各自都很尽责,可模型跑通之后那四笔账——数据类型带进来的量化误差、ROM 与静态 RAM 的真实占用、这段代码在 ECU 上的执行时间、覆盖率的分母里究竟有哪些分支——一笔都没有落到具名的收件人手上:控制工程师认为代码生成器会保证,软件工程师认为模型侧已经核过。这两处都发生在「划线」这一层,代价却落在后面五讲的每一讲上。
⇒ 所以本讲不搭任何一个模型,只做五件事:画出 MBD 在 V 模型上占哪一段、本课的射程线画在哪里(1.1);说清 MBD 相对手写代码确定换来了什么、又把什么变成了权衡项(1.2);把每一层出口证据的产出方与收件方钉死,指出那条分工缝到底在哪两格(1.3);给出建模入口检查那一句判据,并说明它为什么必须放在最前面而不是最后面(1.4);最后画清本课与控制算法那几门课之间的边界(1.5)。⚠ 本讲一个数都不给:它交付的全部是射程、入口形态、角色与判据。凡是带数的结论都在后面几讲,而且每一个都要带上「在哪一层测的、用什么手段测的」两个标签——这是全课反复要敲的第二件事,从本讲的判据写法开始就照它办。
1.1 MBD 覆盖的是「规格 → 模型 → 代码」这一段,而它的入口是条目化规格、不是一段散文
是什么。把 V 模型摊开看:左侧自上而下是控制功能规格 → 模型架构 → 模型(Simulink/Stateflow)→ 生成代码,右侧自下而上是 MIL(模型在环)→ SIL(软件在环)→ PIL(处理器在环)→ HIL(硬件在环)与集成验证(⚠ 这四个缩写全课只在此处配一次中文名,后文一律只写缩写),V 的底部横着一条自动代码生成带把左侧末端接到右侧起点。基于模型开发(MBD)占的就是左侧的下半段与右侧下半段的接口——它不是一整套开发流程的替代品,而是这一段上「用什么形态的制品往下传」的一个选择。
而这一段的入口形态是被规定死的:往模型里送的不是一段自然语言的策略描述,是条目化的控制功能规格——每一条带自己的验证方法与 owner(责任人)。这一条不是文档洁癖,它决定了后面所有追溯工作有没有立足点。
为什么。追溯矩阵的最小单元是「规格的一个条目」。规格若是散文,就没有可指认的条目边界,模型里的每个子系统便指不回任何一条;第 6 讲要交的那张矩阵不是「填不满」,而是从源头上建不起来——因为矩阵的一整列没有取值集合。⇒ 由此还能推出一条更实际的后果:变更影响分析做不了。改一个子系统时,说不清要重跑哪些用例,于是回归要么全跑(贵)、要么凭记忆跑(漏)。
⚠ V 的左右两侧是层次对应关系,不是时间先后:右侧某一层验的正是左侧同一层写下的东西。所以追溯矩阵不是额外附加的一份文档,它就是 V 的结构本身。
工程量级。本条不涉及任何数值——规格条目数、规格页数都是平台相关量,取决于本项目的功能范围与规格粒度约定,⛔ 本课不给。本条给的是一个结构事实:从规格到验证之间是四层可双向查询的链——规格条目 / 模型子系统或 Runnable / 生成代码函数 / 测试用例。★ 这个四层划分是本课归纳的,⛔ 不是任何标准既有的分层方式;它的完整用法(正向证明、反向定位)在第 6 讲展开。
易错点。两个。①把「控制需求」理解成一份策略说明文档或一张状态机草图——两者都描述了行为,却都没有条目边界,因此都接不住追溯。②以为追溯是写完之后补的——追溯关系在建模那一刻就该被记下来;事后补是把它降级成一次考古:人要反过来猜「当初这个子系统是为了哪一条」,猜出来的对应关系没有任何证据力。⛔ 规格本身怎么写、怎么评审、怎么向 Tier1 交接不在本课射程,去向 K4-07 热管理控制功能规格(软件需求)的编写、评审与向 Tier1 交接。
1.2 一致性与可仿真验证是确定的改善;可读性与效率是权衡项,由配置与建模方式决定
是什么。把同一个功能分别用手写代码和 MBD 做出来,放在四个维度上问同一个问题,会得到两类性质完全不同的答案:
- 一致性(同一个输入是否必得同一个产物)——确定改善。来源是「代码不再是人写的」:模型改一处,全部相关代码同步变,⛔ 不存在「改了模型忘了改代码」这一类缺陷。
- 可仿真验证(写完能不能立刻跑)——确定改善。来源是「模型本身就是可执行规格」:行为在成为代码之前就已经可以被激励、被观察。
- 生成物可读性——权衡项。
- 资源与执行效率——权衡项。
后两项是本节的重点:它们不是必然更差,也不是必然更好。
为什么。代码生成器在生成每一段代码时都要在两个方向之间选:一边是贴近模型结构、便于追溯(子系统对一个函数、信号名对一个变量名、中间量都留着),另一边是合并表达式、复用临时变量、减少中间量。这个选择由代码生成配置项决定(配置项本身与生成代码的结构在第 5 讲展开),同时也由建模方式决定——把一个功能画成一层原子子系统还是摊平成一堆模块,生成出来的代码结构就不同。⇒ 所以它是可调的,不是宿命:拿到一份难读或超预算的生成代码,正确动作是回去看配置与建模方式,⛔ 不是给 MBD 判一个「生成代码就是这样」的结论。
工程量级。⛔ 本课不给「生成代码比手写代码大百分之多少、慢多少」这类数字——它是平台相关量(取决于目标芯片、编译器与优化等级),而且与建模方式强相关;⚠ 更要紧的是一条口径纪律:一个本课自己判定为「不给单点值」的量,也不许反过来拿它去做倍数或数量级比较,否则就是用一个自己都不肯给的数去支撑结论。本条给的是判据,而且两条判据各有各的层与手段:
- 可读性看两件可当场核的事——函数与子系统是否一一对应、变量名是否可回溯到信号名;
- 效率看两件必须实测的事——ROM 与静态 RAM 以目标编译器/链接器的 map 文件为准,执行时间以 PIL(生成代码跑在目标处理器或评估板上)或目标端 profiling 为准。
⛔ 两者都不由观感判。「这代码看着挺乱」「这看着不占地方」不是判据,它们既说不清在哪一层,也说不清用什么手段量的。★ 这正是全课第二件要敲的事在本讲的第一次落地:每一个数、每一份报告,都要说清它是在哪一层、用什么手段量出来的;层与手段说不清,这个数就不许用来做判断。
易错点。两个。①把「自动生成」等同于「不用看生成代码」——分工那一条(1.3)明确要求软件工程师看生成代码与集成,而资源与时间这两笔账只能在生成之后的那一层才量得到。②把一次配置不当的生成结果当成 MBD 本身的缺陷——这会导致一个很贵的错误动作:放弃 MBD 回去手写,于是把已经确定拿到的一致性也一起扔掉了。
1.3 分工线本身会制造缺陷:每一层出口证据都要有产出方,也要有收件方
是什么。角色分工在这条链上是硬的:控制工程师建模型,软件工程师看生成代码与集成。两侧评审看的东西并不重叠——
- 模型侧评审:架构划分与接口定义、建模规范的符合性、算法在模型层的正确性;
- 代码侧评审:生成代码的结构、静态分析结果、资源占用与向调度和通信层的集成。
为什么这条线本身是缺陷源。因为「模型跑通之后的那四笔账」恰好一笔都不落在任何一侧的常规视野里,而每一笔都要换一层、换一种手段才量得到:
- 数据类型——浮点仿真里根本不存在的量化误差,只有在定点部署之后才进入控制回路(第 4 讲);
- 空间——ROM 与静态 RAM 的真值在目标编译器/链接器的 map 文件里,不在代码生成报告里,且随编译优化等级变(第 5 讲);
- 时间——执行时间根本不在代码生成报告里;SIL 剖出的是主机 CPU 时间,只有 PIL 或目标端 profiling 才代表 ECU(第 5 讲);
- 覆盖率的分母——生成代码里新增的防御分支(饱和限幅、数据类型转换、除零保护)从来不在模型覆盖率的分母里(第 6 讲)。
⇒ 于是就有了那句典型的对话:控制工程师认为代码生成器会保证,软件工程师认为模型侧已经核过。没有人说错话,账掉在两句话中间。本课对此只给一条结构判据(★ 本课归纳,⛔ 不是既有的评审制度要求):每一层的出口证据必须同时写上两个具名角色——产出方与收件方;只有产出方、没有收件方的证据,等于没有。因为没有收件方就没有人有义务读它,也就没有人会在它缺一半时提出异议。
工程量级。⛔ 本条不给人数、不给评审时长、不给评审关卡数——那些取决于本项目的组织形态与流程设置,是平台与组织相关量。给的是上面那条结构判据,以及一个可当场做的动作:把制品链上每一件出口证据列出来,逐件填「产出方 / 收件方」两格,填不满的那一格就是缝。
易错点。两个。①把「评审」理解成一次会议而不是一份带收件方的证据——会议开过了,但没有人接收任何东西,缝还在原处。②把定点方案表当成控制工程师的私事——它同时是标定工程师的输入:一个量的量程与 LSB(最小分辨单元)直接决定标定时能调到多细。⚠ 定点方案本身怎么做在第 4 讲;标定量的规格(轴点、上下限、插值与外插保护、存储区)不在本课射程,去向 K6-10 标定量规格定义:轴点、插值/外插保护、上下限与不可标量。
1.4 建模入口检查只有一句判据,而且它放在最前面:指不回条款的子系统,就是无源功能
是什么。建模开始之前(不是评审之前,更不是交付之前),逐个子系统与 Runnable(可被任务调度的最小软件执行单元;它与任务的映射细节去向 K4-01 热管理嵌入式软件架构与 AUTOSAR 基础)填一格:它对应控制功能规格的哪一条条款?判据只有一句——
每个子系统/Runnable 都要能指回控制功能规格里的一条条款;指不回的就是无源功能,评审时打回。
「指不回」有两个方向相反的正确出口(★ 这两个出口与下面三条后果是本课归纳的处置,⛔ 不是既有条款):
- 它其实是必要的 ⇒ 回去补规格条目,补完再建模(规格怎么写去向 K4-07 热管理控制功能规格(软件需求)的编写、评审与向 Tier1 交接);
- 它是历史遗留或想当然加上的 ⇒ 删掉。
⛔ 所以它不是「一律打回重做」——那样会把该补规格的那一支也一起砍掉。
为什么必须放在最前面。因为无源功能是最难清的一类技术债,而它的难清是结构性的:它没有需求 ⇒ 所以没有验收用例 ⇒ 所以覆盖率永远差那一块,而未覆盖项还说不清该不该覆盖;同时没有人敢删它,因为没有人知道它当初为什么在那里。⇒ 再看成本的两端:入口检查的成本只是填一格;事后追溯的成本是逐个反查——要把已经写成的模型拿去和规格做双向比对,还得为每一个对不上的地方开一次考古。两者不在一个量级上,而且事后那一次做完也拿不到同等的证据力(1.1 的第②个易错点)。
⚠ 追溯这件事在本课刻意分成两处:一半在这里的入口检查(建模那一刻就把对应关系记下来),另一半在第 6 讲的追溯矩阵(把四层链条接起来、用于变更影响分析)。两处必须互相呼应——只看第 6 讲,很容易把追溯读成一件收尾时补的文书工作。
工程量级。本条给的是动作与判据,⛔ 不给「允许存在多少个无源功能」这类阈值——正确答案是零,而且这不是一个可以商量的阈值,它是定义:指不回条款的那一块,按定义就是无源功能。⛔ 同样不给「一个子系统该对应几条条款」的数——那由规格的粒度约定与功能划分决定。
易错点。两个。①把「指回规格」写成「指回某个大功能」——粒度必须到条款级;指到「热管理策略」「电池冷却功能」那种粒度等于没指,因为反查时它会把整个模型都圈进影响范围。②把诊断、限幅与防御逻辑当成不需要规格条目的东西(「这是保护性的,不用写需求」)——它们恰恰最需要:这些逻辑的行为发生在异常路径上,是最不容易被测到的一类;没有条款,就没有人写针对它们的用例,于是它们既没被验证过、又长期挂在模型里。
1.5 算法整定归 K3,模型形状归本课——这条边界不画,本课会退化成第二遍控制课
是什么。MBD 承接的是控制算法那几门课的产物,模型建的就是那些算法:K3-05 PID/前馈/增益调度控制实战 管 PID、前馈与增益调度的结构与整定,交出来的是三个参数与前馈/调度的形式;K3-06 模型预测控制(MPC)在热管理中的应用 管模型预测控制(MPC),交出来的是预测模型与代价函数;K3-01 整车热管理控制策略总览与模式管理 管整车热管理的模式管理与策略总览,是本课的前置。本课接过来的问题只有一个:把它搭成什么形状的模型——一个可生成代码、可追溯、可测覆盖率的模型。
为什么这条线必须画。因为不画它,本课会自然地退化成第二遍控制课:讲义会被「这个增益该取多大」「积分要不要抗饱和」这类问题填满,而本课真正难、也真正没人替你做的那四件事——定标、资源、时间、覆盖率——被挤到最后草草带过。⇒ 而这四件恰恰是「模型跑通」这句话一个字都没有回答的那四笔账(1.3)。
工程量级。本课的典型案例与动手做都以过热度 PID 控制为载体(过热度这类小信号对分辨率敏感,是讲定点化最合适的载体,第 4 讲展开)。⚠ 但整定口径一律前指 K3-05 PID/前馈/增益调度控制实战,本课不重推参数怎么定、也不给任何增益或时间常数的值——那既不是本课的判据源,也是随被控对象而变的量。
易错点。两个方向,都是错位。①在本课里讨论「这个 PID 该调多大」——那是 K3-05 PID/前馈/增益调度控制实战 管的事;在这里讨论它,会得到一个脱离了被控对象的答案。②反过来,在整定那一侧讨论「积分项该用几位定点」——那是本课管的事;在那里讨论它,会得到一个脱离了目标芯片与量程的答案。★ 这两个错位有一个共同的形态:把一个需要两组输入的判断,放到只有其中一组输入的地方去做。
⇒ 本讲收口,落到从今天起要反复做的两个动作上。第一个:拿到任何一个要建的子系统,先问「它指回规格的哪一条条款」——答不出来就先别画框。第二个:交出任何一件写着「验证通过」的证据之前,先问「它回答了那四笔账里的哪一笔,是在哪一层、用什么手段量出来的」——两个标签说不清,这份证据就还不能用来支撑判断。第 2 讲开始,我们就带着这两问进到模型里面,先看架构与接口该按什么切。
后面还有 5 讲正文 · 关键公式 · 案例拆解 · 常见误区 · 动手做