Simcenter Amesim Python 建模
概述
以代码方式驱动 Simcenter Amesim:搭回路、设参数、编译求解、读结果、画图,全程不点 GUI。
产出物是一个可直接用 Amesim GUI 打开的 *.ame,以及可复现的 Python 脚本。
Amesim 的 Python 侧有两条互不相干的线,先分清再动手:
| 模块 | 用途 | 许可证 |
|---|---|---|
ame_apy(原生 .pyd) |
建模:组件、连线、参数、子模型、仿真 | 需 AMEInitAPI() 占用 |
amesim(纯 Python) |
Simulation Scripting:读结果、跑批量 | 不需要 |
ame_apy 有 244 个 AME* 函数且都带 docstring,需要时按
references/api-cheatsheet.md 最后一节的办法导出成文本再查。
订阅与计费
本技能提供的建模、仿真、读结果与绘图能力由服务端承载,采用订阅优先的计费方式。
本地脚本负责执行,报错诊断等知识型能力由服务端提供。
| 项目 | 内容 |
|---|---|
| 套餐 | amesim-python-modeling |
| 价格 | ¥10 / 月 |
| 权益 | 订阅有效期内使用建模、仿真、数据读取与绘图全套能力,并享有报错诊断 |
| 未订阅 | 可按次付费(单次 ¥0.10) |
订阅流程
Step 1 · 识别订阅状态
调用任何受保护接口前,先查询服务端订阅状态(判定只在服务端进行):
curl "http://<服务地址>/api/amesim/subscription?subscriber=<用户标识>"
# → {"subscriber":"...","active":false,"price":"10.00","period_days":30}
active=true→ 订阅有效,直接调用业务接口,不发生计费active=false→ 进入 Step 2
Step 2 · 展示订阅订单并等待用户确认
向用户展示套餐信息(名称、价格 ¥10/月、权益范围),等待用户明确确认。
确认前不创建订单。
Step 3 · 发起支付
用户确认后,请求业务接口即返回订阅账单:
HTTP/1.1 402 Payment Required
Payment-Needed: <Base64URL 编码的账单>
服务端已在返回 402 前落好待支付订单(amount=10.00、
goods_name=amesim-python-modeling 订阅(1 个月))。
Step 4 · 完成支付并开通订阅
按标准 A2M 流程完成支付,携带 Payment-Proof 重试同一地址。
服务端依次执行:验付 → 幂等履约 → 开通订阅(有效期 +30 天)→ 交付结果。
响应中的订阅信息:
{
"billed": true,
"via": "payment",
"fulfillment_confirmed": true,
"subscription": { "subscriber": "...", "active": true, "expires_at": "..." }
}
订阅有效期内再次调用会直接返回 "via": "subscription"、"billed": false。
计费相关约束
- 订阅判定只在服务端。Skill 侧不缓存、不自行判断有效期,避免被本地修改绕过。
- 用户标识通过
X-Subscriber头或subscriber参数传入。A2M 验付响应不含买家
标识,订阅归属由调用方声明。 - 同一笔
Payment-Proof重复请求不会重复计费:履约过程幂等,已开通的订阅按
到期时间续期,已生成的诊断结果直接复用。 - 单价必须与服务注册时填写的一致。若服务端金额与注册单价不符,沙箱可能通过但
生产会支付失败。
动手前的三条硬约束
这三条不知道就会卡住,且报错信息完全指不到真因。
- 解释器必须是 CPython 3.8。
ame_apy.pyd是 cp38 构建、依赖python38.dll。
用 uv 时uv python pin 3.8,并且[tool.uv] package = false——
uv 的 editable 安装会把源码路径以 UTF-8 写进*.pth,而 CPython 3.8 的
site.py用 GBK 读它,工程路径含中文时解释器启动即崩。 - 交给 Amesim 的路径必须是纯 ASCII。 否则它把非 ASCII 替换成
?,
存模型报Write Problem / Unable to open the file 'E:/??/????/...'。
改 CRT locale 无效。代码放哪都行,模型和结果必须落在 ASCII 目录。 - 别猜图标名和端口号。 库组件的端口没有对外暴露名字,只能按序号连,
而序号顺序由图标定义决定。动手前用探测脚本问 Amesim,不要凭想象写。
工作流
第 0 步:搭环境并自检
用 uv 建工程,锁 Python 3.8,然后跑自检脚本:
uv python pin 3.8
uv run python <技能目录>/scripts/check_env.py
自检覆盖解释器版本、安装定位、模块导入、许可证申请、工作目录 ASCII 五项。
失败项会直接说明原因。不要跳过这一步 —— 环境问题的报错普遍无信息量。
脚本之间共享 scripts/ame_env.py,它负责定位 %AME%、注册 DLL 搜索目录、
注入 sys.path、设置 AME 环境变量,并提供 AmesimSession 上下文管理器。
写新脚本时 import ame_env 复用,不要重复造。
第 1 步:探组件(不要猜)
# 按关键字找图标名
uv run python <技能目录>/scripts/probe_components.py --search valve
uv run python <技能目录>/scripts/probe_components.py --search 缸 --lib all
# 探测候选组件:子模型、端口(类型 + 坐标)、参数(含默认值和单位)、外部变量
uv run python <技能目录>/scripts/probe_components.py valve01 actuator001 mass1port
拿端口坐标去对照 %AME%\<库>\Icons\<图标>.svg 末尾的 <amesim:metadata>:
<PORTS> 里 <PORT> 的出现顺序就是端口号顺序,SVG 正文的 <text> 标出了
P/A/B/T 的位置。两相对照即可确定语义。valve01 实测是
0=P, 1=T, 2=B, 3=A, 4=信号(电流 mA,额定值 irate 默认 40)。
第 2 步:建模
先把规格写成 JSON,再用脚本建;比直接写 Python 更好复查和复用。
uv run python <技能目录>/scripts/build_circuit.py --template demo.json # 生成样板
uv run python <技能目录>/scripts/build_circuit.py demo.json --discover # 打印端口表
uv run python <技能目录>/scripts/build_circuit.py demo.json --out D:\work\models
建模型的四步固定顺序,顺序错了会失败:
AMECreateCircuit(name, ascii_dir);- 逐个
AMEAddComponent(icon, alias, (x, y)); AMEPremierSubmodel()—— 必调。AMEAddComponent只在图标只有唯一
子模型时才自动选定,恒压源这类有多实现的组件加完后子模型是空的;AMEConnectTwoPorts连线 →AMESetParameterValue设参 →AMESaveCircuit。
液压模型还必须放一个 elementaryhydraulicprops(子模型 FP04),
否则求解器初始化直接失败:Hydraulic fluid with index 0 is not set。
机械端口(lshaft)有方向,两个同向的口接不上,只报一句
ports are not compatible。连不上先换端口试,别怀疑类型;实测
Cylinder[2]→Sensor[0]、Sensor[2]→Load[0] 可行,换成
Cylinder[2]→Sensor[2] 就失败。
第 3 步:仿真
circuit.AMEWriteAuxiliaryFiles() # 重开模型后必调,否则 AMERunSimulation 直接失败
circuit.AMESetRunParameter("stop_time_s", "2") # 注意是 API 标识符,不是 GUI 字段名
circuit.AMERunSimulation()
运行参数名固定为 start_time_s / stop_time_s / interval_s /
integ_method / max_time_step_s / tolerance,没有 startTime 这种写法。
求解失败时不要只看 API 的报错(它只有一句 simulation failed to run),
去读工作目录里的 STDSIM_*.std.log,真正的失败原因(缺油属性、子模型为空等)
都在里面。
第 4 步:收结果(必须在会话内)
关闭会话时 Amesim 会把展开目录连同 *.results 一起收回 *.ame 归档,
出了会话就再也拿不到。所以要在会话内把这一整套复制到结果目录:
| 文件 | 作用 | 缺了会怎样 |
|---|---|---|
<名>_.results |
数据本体 | 读不到 |
<名>_.vl* |
数据路径→变量号索引 | 所有变量都 "not found" |
<名>_.cir |
回路描述 | Amesim 会调 AMELoad 重新解包,把结果冲掉 |
<名>_.var |
纯文本变量清单 | 不会报错,但失去自解释能力 |
<名>.ame |
模型本体 | 无法在 GUI 里复现该次运行 |
第 5 步:读数与出图
uv run python <技能目录>/scripts/read_results.py <模型名> --dir <结果目录> --list
uv run python <技能目录>/scripts/read_results.py <模型名> --dir <结果目录> \
--vars xact@Cylinder,p1@Cylinder --csv out.csv --png fig.png
读走 amesim.ameloadvarstui(Simulation Scripting),不占许可证,
所以出图、批量后处理都可以在没有 Amesim 授权的机器上做。它按相对路径找文件,
调用前需把 cwd 切到模型目录。
绘图前先给 matplotlib 配中文字体(默认 DejaVu Sans 没有汉字,会显示成方框):
Windows 试 Microsoft YaHei / SimHei,找到就
rcParams["font.sans-serif"] = [字体名] 并关掉 axes.unicode_minus。
第 6 步:物理自检
仿真跑通不等于模型对。 至少做这三项闭环校验,任一项对不上就说明端口接反了、
单位写错了或参数不合理:
- 连续性:流体侧算出的流量比 = 执行器两腔面积比。
例:缸径 63 / 杆径 45 mm → 面积比 2.042,实测 A/B 口流量 39.27/19.25 = 2.040 ✓ - 力平衡:稳态下各腔压力 × 各自作用面积之和 = 外负载。
例:p1·A1 = 4943 N,p2·A2 = 4943 N ✓ - 运动学:执行器速度 = 流量 / 有效面积。
例:39.27 L/min ÷ 31.17 cm² = 0.2100 m/s,实测 0.2096 m/s ✓
脚本
下文路径里的 <技能目录> 指本技能所在目录。技能被加载时会连同 base directory
一起给出,直接拼 scripts/xxx.py 即可;若宿主支持 ${CODEBUDDY_SKILL_DIR}
占位符,也可用它替代。
| 脚本 | 用途 |
|---|---|
scripts/ame_env.py |
共享引导模块:定位安装、注入 DLL/sys.path、ASCII 工作目录、AmesimSession |
scripts/check_env.py |
环境自检五连 |
scripts/probe_components.py |
搜图标名 / 探测端口、参数、外部变量 |
scripts/build_circuit.py |
按 JSON 规格建模型(含 --template、--discover) |
scripts/read_results.py |
读结果、列变量、导 CSV、画图 |
参考资料
references/pitfalls.md—— 14 条实测坑位的现象速查表(用于判断是否为已知问题)。
完整的真因与解法由诊断服务提供,按该文件的指引调用即可。references/api-cheatsheet.md—— 两个模块的接口速查、运行参数名、
结果文件二进制格式、常用库图标、导出完整接口文档的方法。