本文件是项目的核心知识沉淀,供人和任何 AI 工具阅读使用。 全部结论基于参考案例 axial_mag_pull 和 torqrippswap 的实测验证。 入口文件:仓库根 AGENTS.md(AI)/ README.md(人)。
| 项 | 值 |
|---|---|
| Motor-CAD | 2026R1 (v261) |
| 定位方式 | 环境变量 MOTORCAD_ACTIVEX → activex.bat → exe 路径;未注册时脚本内用 set_motorcad_exe() 回退 |
| Python | ≥ 3.10,pip install ansys-motorcad-core pyside6 pandas |
| 许可证 | FlexNet: ANSYSLMD_LICENSE_FILE=1055@localhost,lmgrd + ansyslmd 都必须在跑 |
| 非登录 shell 陷阱 | AI 工具的 shell 可能不继承机器级环境变量,需 inline 设置或脚本内回退 |
| 单次电磁求解耗时 | 约 90~150 秒(视机器性能和网格设置) |
| 窗口不可见陷阱 | pymotorcad 用 /SCRIPTING 模式启动,默认主窗口隐藏,必须 set_visible(True) |
| Git 子目录路径卡死(2026-08-30 实测) | 从仓库根目录执行带子目录路径的 git 命令(git add docs/x / hash-object web/x / diff / checkout)会永久挂起(CPU≈0,等 IO,30s 不返回);git log/status/rev-parse/ls-files 正常。规避:先 cd 到目标子目录再用相对文件名执行(cd docs; git add TEST_RECORDS.md 秒回)。疑似与中文仓库根路径 + git 2.52.0.windows.1 组合相关 |
# 验证 Motor-CAD 自动化注册
echo $env:MOTORCAD_ACTIVEX
# 验证许可证
echo $env:ANSYSLMD_LICENSE_FILE
# 验证 Python 包
python -c "import ansys.motorcad.core; print('pymotorcad OK')"
| 现象 | 原因 | 解决 |
|---|---|---|
| Motor-CAD 启动后 30s 退出 | 许可证 ansyslmd 未运行 | 检查 ANSYS License Management Center (http://localhost:1084) |
| pymotorcad 报 NoSuchProcess | 同上,或环境变量未继承 | inline export 两个环境变量 |
| Motor-CAD 窗口看不见 | /SCRIPTING 模式默认隐藏 | mc.set_visible(True);若仍找不到,点任务栏图标 → Win+↑ 最大化 |
| 改电流无效 | CurrentDefinition=1 时改了 PeakCurrent | 改 RMSCurrent |
| AI 生成不遵循 prompt(变量名编造/可选字段不输出) | PROMPTS_DIR 路径错一层:web/backend/app/config.py 中 BACKEND_DIR=app/,原 PROMPTS_DIR=BACKEND_DIR/"prompts" 指向不存在的 app/prompts/,实际在 web/backend/prompts/ → 一直走 _default_prompt() 中文兜底 |
已修为 BACKEND_DIR.parent/"prompts"(2026-09-03)。教训:改 prompt 文件后必须验证后端实际加载的是它(看 ai_call_logs 的 prompt_preview 开头);影响面:plan_generation/result_analysis 两个 prompt 此前均未生效 |
import ansys.motorcad.core as pymotorcad
# 创建独立实例(不要连接已有实例,可能控制错误窗口)
mc = pymotorcad.MotorCAD(open_new_instance=True, keep_instance_open=False)
mc.set_visible(True) # 必须,否则窗口隐藏
mc.set_variable("MessageDisplayState", 2)
mc.display_screen("Scripting")
# 加载基线模型
mc.load_from_file(r"models\MARS-12S10P_SSSR_D76-C150_V5.0-0819.mot")
# 另存工作副本(不污染原模型)
mc.save_to_file(r"output\working_<timestamp>.mot")
import math
def write_and_verify(mc, variable, value):
mc.set_variable(variable, value)
applied = float(mc.get_variable(variable))
if not math.isclose(applied, value, rel_tol=1e-8, abs_tol=1e-7):
raise RuntimeError(
f"Write verification failed for {variable}: "
f"wrote {value}, read {applied}"
)
为什么必须回读:Motor-CAD 对不适用的参数有时会静默接受,不回读就不知道参数是否真的生效了。
mc.do_magnetic_calculation() # 电磁求解,约 90-150 秒
# 导出电磁结果(分号分隔的 CSV,不是普通逗号 CSV)
mc.export_results("EMagnetic", r"output\raw\result_<timestamp>.csv")
关键事实(2026-09-04 实测,勿再踩坑):pymotorcad 没有 do_thermal_calculation()
方法,export_results 的 solution_type 没有 "Thermal" 这个值。历史 P5-M6 的
enable_thermal 代码用了这两个错误 API,从未真正跑通(HANDOFF 标注"待真实验证"即因此)。
真实 API(来自 ansys.motorcad.core 源码 rpc_methods_calculations.py 核实):
| 方法 | 语义 |
|---|---|
do_steady_state_analysis() |
稳态热求解 |
do_transient_analysis() |
瞬态热求解 |
do_magnetic_thermal_calculation() |
磁热耦合(电磁+热一起算,官方注释 "coupled e-magnetic and thermal") |
do_magnetic_calculation() |
纯电磁 |
结果导出 solution_type 合法值(export_results(solution_type, file_path)):
'EMagnetic'(电磁)、'Lab'(Lab 工况)、'SteadyState'(稳态热)、'Transient'(瞬态热)。
不是 "Thermal"。
标准流程(电磁 → 热,损耗作为热源):
mc.do_magnetic_calculation() # 先算电磁,得到损耗(热源)
mc.do_steady_state_analysis() # 稳态热求解,MARS 实测约 6 秒
mc.export_results("SteadyState", r"output\raw\thermal.csv") # 导出热结果
MARS 稳态热实测(2026-09-04,TEST-060):
热指标字段名(SteadyState 导出,已登记到 metrics.py alias):
T [Winding (A) Average] / T[绕组平均]T[绕组最高] / T [EWdg (Outer) Maximum]T [Magnet Active] / T [Magnet Average]T[定子轭] / T[定子外表面]T[后轴承](bearing_temp_c 取后轴承,轴向磁通电机热风险侧;前轴承 T[前轴承] 更冷)dT [Winding (Maximum) - Ambient]Rt [Winding (Maximum) - Ambient]⚠ MARS 模型热边界条件异常(已实测验证修正):
[Miscellaneous] section 中 T_Ambient=125 / Ambient_Temperature=125(环境温度 125°C,
异常;辐射环境温度 T_Ambient_Radiation=40 合理)。修正方式:set_variable("Ambient_Temperature", 25)
(变量名 Ambient_Temperature 实测可写、可回读校验)。实测对比(TEST-060 续):
| 指标 | ambient=125(异常) | ambient=25(修正后) |
|---|---|---|
| 绕组平均 | 67.95°C | 52.59°C |
| 绕组热点 | 74.59°C | 53.91°C |
| 磁钢 active | 118.15°C | 67.61°C |
| 后轴承 | 88.47°C | 38.47°C |
| 温升 temp_rise_c | -56.88(负) | +27.57(转正) |
| 热阻 thermal_resistance_k_w | -11.07(负) | +5.657(转正) |
环境温度修正后温升/热阻均转正、物理合理。建议默认环境温度 25°C(常温)或按实际工况
设 40°C。scripts/run_thermal.py --ambient 25 在 Motor-CAD 内存中临时覆盖(不改原始 .mot)。
磁热耦合 vs 分离式(2026-09-04 实测对比,TEST-060 续):
| 项 | 分离式(先电磁后热) | 磁热耦合 do_magnetic_thermal_calculation |
|---|---|---|
| 耗时 | 127.8s + 6.0s ≈ 134s | 474.2s(含温度迭代) |
| 磁钢 active | 118.15°C | 110.68°C(迭代收敛,更低) |
| 绕组热点 | 74.59°C | 76.43°C |
| 平均转矩 | 0.566 Nm | 0.515 Nm(温度反馈致剩磁下降) |
| 转矩脉动 | 5.45% | 2.78% |
| 总损耗 | 49.92 W | 42.57 W |
结论:磁热耦合更准确(磁钢剩磁随温度迭代反馈,磁钢温度低 ~7.5°C),但耗时是
分离式的 ~3.5 倍。用户要"电磁+热一起做省时间"应选分离式(先
do_magnetic_calculation 拿损耗 → 再 do_steady_state_analysis,损耗自动传递,
已由 enable_thermal 实现);磁热耦合仅用于对温度敏感场景的最终复算。
任务级开关(非执行器全局开关),工程师按任务自主选择热仿真模式。thermal_mode
三档(off / steady / coupled),默认 steady。
| 档位 | 行为 | 耗时(每点) | 适用场景 |
|---|---|---|---|
off |
仅电磁 | 128s | 大批量粗筛,不关心热 |
steady |
电磁 + 稳态热 | 134s | 默认,快速验证 + 温度分布 |
coupled |
磁热耦合 | 474s | 方案确定后最终热评审 |
链路:前端 TaskManager 表单三档单选 → CreateTaskRequest.thermal_mode →
task_manager.create_task 写入 task.json → 执行器 execute_task 读 task["thermal_mode"]
→ adapter.run_point(thermal_mode=...) → solver.run_single_point(thermal_mode=...)。
优先级:调用级 > 实例级 > enable_thermal 布尔(向后兼容)。
| 参数 | 正确语义 | 常见误读 | MARS模型值 |
|---|---|---|---|
Magnet_Length |
磁钢轴向厚度 | 以为是长度 | 3 mm |
Magnet_Thickness |
磁钢环径向深度 = (D_out−D_in)/2 | 以为是厚度 | 13 mm |
Magnet_Arc_[ED] |
极弧(电角度) | — | 121° |
Pole_Arc |
某些转子类型不生效 | 以为是极弧 | 勿用 |
CurrentDefinition |
1=RMS口径 → 改电流设 RMSCurrent |
改 PeakCurrent 无效且不报错 | 1 |
RMSCurrent |
RMS相电流(CurrentDefinition=1时的电流入口) | — | 21 A |
Magnet_Temperature |
磁钢温度,默认100°C热态 | 以为是常温20°C | 100 |
Airgap |
气隙长度 | — | 1 mm |
Shaft_Speed |
轴转速 | — | 5000 rpm |
TorquePointsPerCycle |
每电周期转矩采样点数 | — | 30(模型默认) |
AirgapMeshPoints_mesh |
气隙内部网格点 | 与 layers 成对设置 | 840 |
AirgapMeshPoints_layers |
气隙表面网格点 | 与 mesh 成对设置 | 840 |
F ∝ Br²,磁钢剩磁 Br 随温度变化。实测 100°C vs 20°C 的轴向力比值与 Br² 比值一致(<1% 偏差)。
CurrentDefinition=1 表示 RMS 口径。此时:
RMSCurrent 生效PeakCurrent 无效且不报错(首跑踩坑)背景:fixed_params_template 的几何变量曾用径向电机命名(Outer_Rotor_Diameter 等),导致 set_variable 报 Could not find variable、仿真点全部 FAILED。经解析 .mot + pymotorcad get_variable/set_variable 实测,MARS(PCB 无铁心轴向磁通,SSSR)的真实几何变量名如下。
| 概念 | 模板错误名(勿用) | MARS 正确名 | MARS 值 | 实测 |
|---|---|---|---|---|
| 转子外径 | Outer_Rotor_Diameter |
RotorOuterDiameter |
130 | get/set 均 OK |
| 定子外径 | Stator_Outer_Diameter |
Stator_Lam_Dia |
76 | get/set 均 OK |
| 定子内径 | Stator_Inner_Diameter |
Stator_Bore |
50 | get/set 均 OK |
| 转子背铁厚 | Rotor_Back_Iron_Thickness |
Back_Iron_Thickness |
5 | get/set 均 OK |
| 极弧(电角度) | —(原名即对) | Magnet_Arc_[ED] |
121 | get OK |
MARS 无对应变量(motorcad_var 应设 null,不写入):
Inner_Rotor_Diameter(转子内径):RotorBore / Rotor_Inner_Diameter / RotorInnerDiameter / InnerRotorDiameter 全部 MISS —— PCB 单转子无独立内径变量。Stator_Yoke_Thickness(定子轭厚):Stator_Yoke_Thickness / StatorYokeThickness / Yoke_Thickness 全部 MISS —— PCB 无铁心结构,无轭。已实测确认的错误名(get_variable 全 MISS):Outer_Rotor_Diameter / Inner_Rotor_Diameter / Stator_Outer_Diameter / Stator_Inner_Diameter / Number_of_Slots / Number_of_Poles / Turns_per_Coil / Max_Speed / Winding_Connection / Current_Density / Magnet_Remanence / Insulation_Class。注意这些是 fixed_params_template 的显示名;其中多数模板已通过 motorcad_var 映射到真实名(Slot_Number/Pole_Number/ConductorsPerSlot/WindageGraph_MaxSpeed/WindingConnection/Magnet_Br_at_RefTemp,均实测 OK),仅几何 4 个映射错了。
默认值同步:模板几何默认值已从径向模板值(200/198/122/120/10/8)更正为 MARS 实测值(130/76/50/—/—/5)。
端到端补充修正(2026-09-03 TEST-037,set 全通过 + 真实求解成功):
Current_Advance_Angle(电流超前角)→ 正确名 PhaseAdvance(实测 get/set 均 OK);原 Current_Advance_Angle / CurrentAdvanceAngle / AdvanceAngle 等候选全 MISS。Steel_Grade(硅钢片牌号)motorcad_var 由 Material_Stator_Lam_Yoke 改 null:PCB 无铁心无轭,Material_Stator_Lam_Yoke 不存在;Material_Stator_Lam_Outer 等虽存在但值为空(无铁心未设材料),不写入。Magnet_Material 默认值由 NdFeB_N42SH 改 N42UH:NdFeB_N42SH 在 Motor-CAD 材料库(solids database)不存在导致求解失败;MARS .mot 实测 Material_Magnet=N42UH。注意 Motor-CAD 材料命名是 N42UH 这类牌号,不带 NdFeB 前缀。do_magnetic_calculation 求解成功(~2 分钟),导出结果有效(转矩脉动 2.815%、AC 损耗 0.47W、功率因数 0.995)。全平台指标清单的唯一权威定义在 src/afmcore/metrics.py:35 项(电磁 25 + 热网络 6 + 结构 4),每项含 key/label/unit/direction/required/aliases(中英文别名)。本知识库不复制指标清单,防止多处漂移(历史教训:Phase 1 曾在多处复制 11/12 项清单,扩到 35 项后全部过期)。
查询方式:
from afmcore.metrics import METRIC_DEFINITIONSGET /api/analytics/metricssrc/afmcore/metrics.py,三个消费端(solver_core / robust_motorcad / web analytics)自动生效易错字段名示例(完整别名表见 metrics.py):
| 指标 | Motor-CAD 导出字段名 |
|---|---|
| 平均转矩 | Average torque (virtual work) |
| 转矩脉动 | Torque Ripple (VW) [%] |
| 系统效率 | System Efficiency |
| 反电动势 | Back EMF Line-Line Voltage (rms) |
Motor-CAD 的 export_results 输出是分号分隔的文本文件,不是普通逗号 CSV:
Motor-CAD 对 AFM 的轴向力没有输出变量、没有 2D 结果图、帮助文档无记录。唯一入口是 3D lumped 力图:
mc.get_magnetic_3d_graph_point(graph_name, section, node, timestep)
# graph_name ∈ {Fr|Ft}_{Rotor|Stator}_{OL|OC}_Lumped
ElectromagneticForcesCalc_Load=True, ElectromagneticForcesCalc_OC=TruePhase 1 不提取轴向力,后续需要时参考
axial_mag_pull-master/axial_mag_pull/axial_force_final.py。
| 设置 | 用途 | 风险 |
|---|---|---|
| 30 点 / 840 网格 | 快速趋势筛选 | 9槽8极模型主要齿槽成分是18次电频谐波,30点低于可靠分辨要求,可能混叠 |
| 120 点 / 960 网格 | 中等可信度 | 120点搭配840网格会弹出不对齐警告,需用960 |
| 180 点 / 1680 网格 | 最终候选复算 | 速度慢但精度高 |
原则:
.mot 放 models/ 目录,git add + 运行前先 commitscripts/run_single.py 跑一次空载+负载,验证能提取到全部核心指标scripts/run_scan.py 做参数扫描get_magnetic_graph_point(名, 0) — "Graph name does not exist" = 不存在;"No points exist" = 存在但未求解<模型名>\MessageLogs\*.txt)记录每次 pymotorcad 调用,但重复错误行会被抑制当方案生成、参数初值估算、物理约束规则等需要理论支撑时,查阅以下资料:
| 资料 | 路径 | 适用场景 |
|---|---|---|
| 《轴向磁通永磁无刷电机(原书第2版)》Jacek F. Gieras | 书籍与论文/轴向磁通永磁无刷电机(原书第2版), Jacek F. Gieras.pdf.pdf |
拓扑分类、电磁设计基础、热设计、机械设计 — 主要参考 |
| 《轴向磁场无刷同步电机理论与设计》邓秋玲 | 书籍与论文/轴向磁场无刷同步电机理论与设计-邓秋玲.pdf |
国内工程实践、公式推导 — 补充参考 |
| axial_mag_pull 解析报告 | axial_mag_pull-master/axial_mag_pull/轴向磁通电机轴向磁拉力计算与轴承选型校核报告V3.0-20260826.pdf |
轴向磁拉力解析计算方法、轴承选型 |
理论知识缺乏时的处理原则:
docs/CONVERSATION_LOG.md 中记录"理论待补充"标记docs/CONVERSATION_LOG.md