Files
SystemSimulationApp/docs/other/机械元件事件覆盖与Amesim对照-2026-09-17.md
T
ljz 7611f13208 修复循环信号与事件采样并接入 LSTP 接触定位,补充八路验证及复用实验
相较上一版 Jacobian 确定性复用更新,本次补齐事件边界一致性、结果两侧采样及接触事件定位;保留已有物性复用和组件力学公式。

- 统一 UD00 信号求值与下一事件查询的绝对时间边界,修复循环边界浮点舍入导致的阶段错位、重复或漏报,并覆盖零时长、多阶段及长周期场景。
- 引入原生输出语义 v2:保留规则网格真实时间,补充内部时间事件和状态事件的左邻及事件后采样,按保存时间、状态和离散模式重放结果。
- 两条代码生成路径均发出 LSTP 接触描述,默认定位间隙过零及非负力模式的力截断;仅在接受事件时更新防重复记录,增加 contactEvents 诊断计数。
- 补充 MASS/LSTP 独立事件实验、八路全曲线与驱动阶段配对评估,以及 Amesim 不连续点输出对照和力差定位报告;MASS 新增释放机制仍保留为独立实验。
- 保存局部 probe、context 访问与回退、shadow replay、R288 real skip/typed replay 及阀门数值尾部诊断工具和报告;未证明净收益的实验不启用为生产默认优化。
- 更新原生运行说明和元件建模规范,补充信号边界、输出语义、接触事件和实验依赖回归测试。

验证:五组专项回归共 34 项全部通过;37 个待提交 Python 文件语法检查通过;git diff --cached --check 通过。
2026-09-17 23:50:13 +08:00

15 KiB
Raw Blame History

机械元件事件覆盖与 Amesim 对照

本次核查基于当前平台源码、八路工程的实际生成代码、本机 Amesim 2404 子模型源码及随安装提供的帮助。没有修改机械内核,也没有重新运行 Amesim;数值验收证据引用上一轮修复后的回归日志。

1. UD00 修复的影响范围

生产代码改动仅在 native/components/modules/signal.c。MASS、接触力公式、机械事件定位及求解器重启代码没有修改。已有机械事件仍然生效,不需要因为这次信号修复而重新注册。

若机械系统由 UD00 驱动,修正信号边界的取值会影响驱动力、后续轨迹和碰撞时刻;积分步分布也可能变化。因此“机械事件机制没有改动”不代表耦合系统的每一个数值结果都保持不变。纯机械模型若没有使用 UD00,则没有这条直接数值调用依赖。

2. 逐类比较

元件或模式 当前平台 Amesim 2404 本机证据 判断
MECMAS21 理想限位,stoptype=1 注册 NativeStop;在接受步内用密集插值和二分定位上下界;命中后位置置于界面,速度置零,再重启积分 MECMAS21.c 调用 endst2_;帮助说明其碰撞处理为位置等于限位、速度为零,并维护状态标记 撞击事件已具备,无需重复添加;应核验脱离限位、初始就在限位及同时事件
MECMAS21 恢复碰撞,stoptype=3 注册相同的限位定位;入射速度超过阈值时按恢复系数反向,否则置零 调用 endstrc_;帮助说明恢复系数及防止无限反弹的低速阈值 核心撞击事件已具备;保留并补边界组合验收
MECMAS21 弹性限位,stoptype=2 计算上下限穿透及弹簧阻尼力,未向 NativeStop 或其他通用事件表注册接触/脱离 允许负力时调用 endst1b_,否则调用 mecEndStop_ 且 handle_disc=1;帮助说明维护接触状态 建议补充上下界接触/脱离事件,非负力模式还应处理原始接触力的截断边界
LSTP00A 弹性接触 用间隙计算非负穿透,再调用 native_contact;没有接触状态事件注册 与弹性限位复用上述接触工具;mecEndStop_ 明确启用不连续处理 当前八路模型应优先补充这一项
静摩擦、库仑摩擦、Karnopp/Stribeck 模式 已有 NativeFriction、保存的离散模式、停滑与起滑定位;密集插值定位速度阈值和净驱动力超过静摩擦阈值的时刻 MECMAS21.c 调用摩擦工具;linert1c 帮助说明低速区、起滑阈值及保存的模式标记 已有基础,不是缺失整套事件;需核验换向、阈值相等、与限位/信号同时触发
无限位 MASS,stoptype=4 不注册限位;若启用干摩擦仍有摩擦事件 同样绕过限位工具,保留所选摩擦模型 无需人为添加上下限位事件
普通双向线性弹簧、黏性阻尼 当前公开机械目录主要提供 LSTP00A 接触件;不能把它等同于普通双向弹簧阻尼 Amesim SD0000.c 直接计算连续的弹簧、阻尼力及导数 将来新增这类光滑模型通常不需要事件;出现间隙、单向作用、饱和或摩擦切换时再添加

平台依据:

Amesim 依据:

  • MECMAS21.c:理想、弹性、恢复碰撞和摩擦模式的实际调用分支。
  • LSTP00A.c:接触工具调用及 handle_disc=1。
  • SD0000.c:普通弹簧阻尼连续方程。
  • 本机 amehelp.qch 内的 libmec/doc/html/utils/endst1b.html、mecEndStop.html、endst2.html、endstrc.html、linert1c.html。这些帮助页通过只读查询 Qt 帮助数据库取得。

本机安装未提供上述接触工具的完整内部源代码。因此可以确认 Amesim 的接触状态管理和不连续处理接口,但不据此声称已完全复原其全部根函数、内部容差或同一时刻的执行顺序。

3. 当前八路工程的优先级

从 tests/data/test-mql-8-corrected.json 实际生成得到:

  • 共 10 个 MECMAS21:9 个无限位,1 个理想限位;理想限位元件为 amesim_mecmas21_10,范围 [0, 0.37] m。
  • 共 8 个 LSTP00A,均为数值刚度、允许负接触力;kcont=1e11 N/m、rcont=1e11 N·s/m、Pdis≈1e-7 m。
  • 生成头文件为 NSTATES=132、NSTOPS=1、NFRICTIONS=0。这 1 组 NativeStop 包含上下两个位置界面,不代表只有一个事件时刻。
  • model_next_break 只汇总信号时间事件,没有注册这 8 个接触件的间隙事件。接触力仍被计算,只是没有单独定位接触/脱离时刻。

建议优先顺序:

  1. 先补 LSTP00A 的接触/脱离定位。 它直接覆盖当前八路模型的 8 个接触件。
  2. 复用同一机制覆盖 MASS 弹性限位。 当前八路工程没有启用该模式,但这是平台组件能力中明显未显式覆盖的事件。
  3. 完善已有理想/恢复限位和摩擦的组合边界。 当前理想限位通过 native_stop_motion 的条件方程处理保持与离开,没有单独注册“约束反力消失/自由净驱动力反向”的根函数;应核验连续驱动力下的离开时刻,再补充需要的释放事件。

缺少接触事件不等于当前接触力公式错误。自适应积分可以通过缩小步长处理部分分段变化,已有温和工况也能通过对照。显式事件的目的,是更稳定地确定作用阶段、接触时刻及峰值附近的积分历史。此次核查不能证明之前八路模型的全部力峰差异均由这一缺口导致。

4. 应怎样添加

这类事件由状态决定,不能像 UD00 那样只向 model_next_break(t,end) 添加预定时间。应扩展状态事件接口,允许组件提供事件面、穿越方向、有效模式及事件后的操作。

  • 接触边界: LSTP00A 使用带符号间隙 gap = gap0 + x2 - x1 的 gap=0;MASS 弹性限位使用 x-xmin=0、x-xmax=0。不要用已截成非负的 penetration 作为唯一找根量,否则脱离区间整段为零,失去跨越方向。
  • 非负接触力边界: 仅在 discContactOption=2 且处于接触区时,处理未截断力 Fraw=0 的分支切换。允许负力的模式没有这个截断开关,不应因力过零就重启。
  • 事件动作不同: 弹性接触只重新确认分段并重启积分,位置和速度保持连续;理想碰撞、恢复碰撞才按其模型重置状态。不能把弹性接触事件直接当成硬碰撞。
  • 不需要的事件: Pdis 是指数过渡尺度,不是“穿透达到它就突然切换”的阈值;也不应在 3*Pdis 处造事件。数值刚度/几何刚度是初始化参数模式,若运行中不切换,也不产生事件。
  • 防止重复触发: 初始恰好接触、贴边不动、离开后重新接触、同一时刻多个接触和信号跳变都需明确阶段与方向,并保证试探求值不提交离散模式。

最低验收应覆盖:单 MASS 上下碰撞及释放、单弹性限位、双质量块 LSTP00A 接触/脱离、允许/禁止负力两种模式、非零/零阻尼过渡尺度,并对 BDF/RK45、不同最大步长比较事件时刻和接触峰值。与 Amesim 对照时还需区分事件前后值。

5. 已有验证能说明什么

上一轮修复后的完整回归日志中,恢复碰撞双求解器测试、LSTP00A 接触测试、MASS 摩擦保持以及 test_amesim_stick_slip_endstops_and_joint_circuits 均通过。

最后一项使用独立 Amesim 2404 运行生成的参考数据,覆盖理想限位、弹性限位、摩擦与联合机械等场景;每个参考场景检查 40 个选定时刻,测试设置最大步长 0.002 s。它支持“相关常规数值行为仍可用”,不足以证明当前八路模型的高刚度接触全过程、所有边界组合都与 Amesim 严格一致。

6. 补充接触/脱离事件的求解时间成本

结论及适用范围

事件检查、定位和处理会增加计算工作,但总求解时间不一定增加。若它减少了跨接触边界的拒步、非线性迭代和反复缩步,这些节省可能抵消部分甚至全部开销。当前尚未实现接触事件,不能给出已测得的变慢百分比。

以下分析针对前文建议的“状态事件定位后重启积分”实现。单纯记录零点与切换接触阶段不是同一件事,也不应假设所有事件定位都必然要求相同的重启方式。

成本来自哪里

环节 当前代码依据及新增成本 判断
每个接受步检查接触状态 native_accept 已经检查硬限位/摩擦;新增 LSTP00A 间隙可直接由两个位置状态及常数计算 对 8 个接触件,轻量状态判断预计成本较低;这是算法量级判断,不是计时结果
定位实际跨越时刻 现有 locate 固定执行 60 次二分,每次调用密集插值;BDF 使用 CVodeGetDky,RK45 计算状态插值多项式 纯间隙根函数不需要重算整个气动网络;定位次数和精度决定成本
截断并重启积分 native_accept 可把已接受步截回事件;BDF 调用 CVodeReInit,RK45 重新计算导数和初始步长 会放弃事件之后那部分试算工作,并产生重新起步的工作;BDF 的历史重建尤其值得关注
雅可比及线性求解 BDF 原生路径使用差分雅可比和稠密线性求解器;新起步需要相应初始化与后续数值建立工作 成本作用于整个耦合系统,而非只作用于触发事件的那一个弹簧
保存事件点及输出重放 若沿用现有状态事件存储流程,每个新增事件时刻会保存状态,输出阶段再次调用 model_eval 通常少量事件时不突出;大量事件会增加结果体积与后处理时间,需要与纯求解耗时区分

CVODE 7.4.0 的官方实现中,CVodeReInit 将当前阶次重设为 1,并重置步数/历史起点;下一次积分进入初始设置与初始步长计算。它复用已有内存,不是重新编译模型或重新分配整个求解器。见 CVODE 7.4.0 官方源代码。平台对应入口见 cvode_solver.c、rk45.c 和 common.c。

因此,主要风险是频繁切换造成的整系统重新起步,不是“多写了几个 if 判断”。重启不清除从仿真开始以来的物理运动结果,而是从事件处的状态继续积分。

既有八路运行数据能支持什么判断

早先正确性评估中的 50 s 循环工况记录如下,来源为 native-summary.json。这是 UD00 修复前的历史样本,仅用于估计工作量,不能作为当前代码已经完成的性能 A/B 对比。

指标 历史样本
求解壁钟时间 solveSeconds 12.414 s
接受步数 19,412
误差测试失败次数 rejectedSteps 1,511
方程求值计数 nfev 84,268
其中雅可比差分求值 50,512
雅可比刷新次数 1,804
线性求解器 setup 次数,输出字段 nlu 5,903
求解器启动次数,含初次启动 20
已注册状态事件的触发批次数 9

该生成模型包含 132 个状态、1,784 个输出和 27 个雅可比分色组。历史数据中每次雅可比刷新对应 28 次方程求值(27 组扰动加一个基准求值),合计 1804 × 28 = 50512。这说明多余的整模型求值、雅可比刷新和重新起步比单纯间隙算术更值得控制;不能把方程调用次数占比直接当作耗时占比。

若接受步数暂按历史样本不变估算,8 个接触件每步检查一次是 8 × 19412 = 155296 次简单间隙检查;两个端点均重算则约为其两倍。间隙直接读取位置即可,不需要为这些检查各自求解气动物性、管道流量和全部输出。

另一方面,历史的 stateTransitions=9 不包含当时没有注册的 LSTP00A 接触/脱离,所以不能据此预测新增事件数量。8 个接触件可能长期保持接触,也可能反复接触和脱离;真正影响重启成本的是整个仿真期间的切换次数,以及是否出现数值反复触发。

不能将 12.414 s 除以启动次数来推算单次事件成本,也不能把平台求解时间与报告中的 Amesim 完整进程时间直接比较。

建议采用的成本控制措施

  1. 专门生成轻量事件函数。 直接读取位置/速度状态,批量计算间隙和需要的局部接触力;避免为了事件检查调用完整 model_eval。在不需要新增物理动态量时,不人为增加连续状态维度。
  2. 先筛查,后定位。 只对可能跨界的区间执行找根;同时覆盖区间内转向等情况,不能为了省时漏掉端点同号但中间跨界的情形。定位达到所需精度或浮点区间不再可分后停止,不必机械重复满 60 次。
  3. 仅在阶段实际切换时处理。 保持接触期间不反复重启;明确初始贴边、穿越方向和离开后的再次触发规则。不能以放大物理间隙、移动事件时间或粗暴忽略真实小振荡来换速度。
  4. 同一时刻的多个事件批量提交、一次重启。 包括多个接触件,以及与信号边界重合的情况;不得为了减少启动次数把有真实先后关系的事件强行合并。
  5. 只注册启用模式所需的边界。 当前八路的接触件均允许负力,不额外注册非负力截断事件;也不在 Pdis 或 3*Pdis 处造事件。

按上述实现,接触/脱离次数较少时,额外成本预期可控;频繁真实碰撞或边界数值反复触发时,成本可能明显增加。事件处理不会消除模型本身的高刚度,也不能保证 RK45 因此适合所有高刚度工况。

如何验证增量成本

完成实现后,在同一份 JSON、求解器、容差、最大步长和输出设置下,对修改前后分别重复运行,使用已构建的可执行文件,比较中位数并记录波动。分别记录纯求解时间、进程总时间、事件检查/定位次数、实际切换数、启动次数、接受步/拒步、nfev、njev 和线性 setup 次数。

平台 solveSeconds 不包含后续全部输出重放和 JSON 写出,所以事件点增多的输出成本还应检查总进程时间。现有 nfev 也不统计纯密集插值调用,新增定位计数/耗时才能解释这部分成本。

除当前八路模型外,至少检查长期不接触、持续接触、单次接触/脱离及反复碰撞四种情况;在事件时刻与接触力精度得到验证的前提下评估速度。本轮仅完成成本评估,没有修改机械事件实现或进行新增事件的性能实测。