python - 如何通过 OMPython 在重新声明语句中修改组件的值
问题描述
我需要能够通过 Python 修改 Modelica 包/模型的内容,用于自动仿真等。大多数情况下,这适用于 OMPython,但有一个我无法解决的特殊问题:
考虑这两个文件:1)example.mo(一个Modelica包)
package Example "Example Package"
model Component "A component with some settings"
parameter Real value=100 "Some value";
replaceable BasicSensor sensor "Replaceable sensor" annotation (
Placement(transformation(extent={{-10,-10},{10,10}})),
__Dymola_choicesAllMatching=true);
annotation (Icon(graphics={Rectangle(extent={{-40,40},{40,-40}}, lineColor={28,
108,200})}));
end Component;
model System "A system with a component"
Component component(value=50, redeclare SpecialSensor sensor(sensitivity=10))
"Modified component"
annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
coordinateSystem(preserveAspectRatio=false)));
end System;
model BasicSensor
parameter Real sensitivity=1 "Some value";
annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
Ellipse(extent={{-40,40},{40,-40}}, lineColor={28,108,200})}),
Diagram(coordinateSystem(preserveAspectRatio=false)));
end BasicSensor;
model SpecialSensor
extends BasicSensor;
annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
coordinateSystem(preserveAspectRatio=false)));
end SpecialSensor;
end Example;
2) test.py(一个 Python 脚本)
"""Python test script for replacing information in modelica models."""
from OMPython import OMCSessionZMQ
omc = OMCSessionZMQ()
cmds = [
'loadFile("example.mo")',
'setComponentModifierValue(Example.System, component.value, $Code(=200))',
# 'setComponentModifierValue(Example.System, component.sensor.sensitivity, $Code(=20))',
'saveModel("example_edit.mo", Example)',
]
for cmd in cmds:
answer = omc.sendExpression(cmd)
print(cmd, answer)
在 Modelica 中,我们有一个“系统”,其中包含一个“组件”,而该组件又包含一个可替换的“传感器”。使用 Python 脚本,我可以正确修改“component.value”。运行脚本会产生以下结果文件 example_edit.mo(仅显示有更改的部分):
model System "A system with a component"
Component component(value = 200, redeclare SpecialSensor sensor(sensitivity = 10)) "Modified component" annotation(
Placement(transformation(extent = {{-10, -10}, {10, 10}})));
annotation(
Icon(coordinateSystem(preserveAspectRatio = false)),
Diagram(coordinateSystem(preserveAspectRatio = false)));
end System;
根据需要,“component.value”已从 50 更改为 200。
但是,我不知道如何更改重新声明的传感器的“灵敏度”。天真的方法是 python 脚本中的注释行。如果我们包括那条线,被替换的传感器就会从生成的模型中消失
model System "A system with a component"
Component component(value = 200) "Modified component" annotation(
Placement(transformation(extent = {{-10, -10}, {10, 10}})));
annotation(
Icon(coordinateSystem(preserveAspectRatio = false)),
Diagram(coordinateSystem(preserveAspectRatio = false)));
end System;
最后,实际问题: 如何将“灵敏度”更改为 20 以达到以下预期结果?(通过 OMPython 界面,而不是使用正则表达式或类似的黑客。)
model System "A system with a component"
Component component(value = 200, redeclare SpecialSensor sensor(sensitivity = 20)) "Modified component" annotation(
Placement(transformation(extent = {{-10, -10}, {10, 10}})));
annotation(
Icon(coordinateSystem(preserveAspectRatio = false)),
Diagram(coordinateSystem(preserveAspectRatio = false)));
end System;
问候和非常感谢!
解决方案
通过 openmodelica.org 的反馈,我意识到 OpenModelica 当前(1.14.1)不完全支持这些重新声明语句。因此,想要的结果显然还不可能。它似乎计划用于 1.16.0。
请参阅openmodelica.org 上的问题和路线图以供将来参考。这也可能是跟踪的正确票证。
编辑:
使用 OpenModelica v1.17.0-dev-326-g94acb25482(64 位)的当前开发版本,以下 Python 代码允许设置重新声明语句并回答原始问题:
"""Python test script for replacing information in modelica models."""
from OMPython import OMCSessionZMQ
omc = OMCSessionZMQ()
cmds = [
'loadFile("example.mo")',
'removeElementModifiers(Example.System, "component", false)',
'setElementModifierValue(Example.System, component.sensor, $Code((redeclare SpecialSensor sensor(sensitivity = 20))))',
'setElementModifierValue(Example.System, component.value, $Code(=200))',
'saveModel("example_edit.mo", Example)',
]
for cmd in cmds:
answer = omc.sendExpression(cmd)
print(cmd, ':', answer)
这将创建所需的输出:
model System "A system with a component"
Component component(value = 200, redeclare SpecialSensor sensor(sensitivity = 20)) "Modified component" annotation(
Placement(transformation(extent = {{-10, -10}, {10, 10}})));
annotation(
Icon(coordinateSystem(preserveAspectRatio = false)),
Diagram(coordinateSystem(preserveAspectRatio = false)));
end System;
但是,当前似乎removeElementModifiers()
需要该命令,因为没有它...
"""Python test script for replacing information in modelica models."""
from OMPython import OMCSessionZMQ
omc = OMCSessionZMQ()
cmds = [
'loadFile("example.mo")',
# 'removeElementModifiers(Example.System, "component", false)',
'setElementModifierValue(Example.System, component.sensor, $Code((redeclare SpecialSensor sensor(sensitivity = 20))))',
'setElementModifierValue(Example.System, component.value, $Code(=200))',
'saveModel("example_edit.mo", Example)',
]
for cmd in cmds:
answer = omc.sendExpression(cmd)
print(cmd, ':', answer)
...redeclare SpecialSensor
输出中缺少该部分:
model System "A system with a component"
Component component(value = 200) "Modified component" annotation(
Placement(transformation(extent = {{-10, -10}, {10, 10}})));
annotation(
Icon(coordinateSystem(preserveAspectRatio = false)),
Diagram(coordinateSystem(preserveAspectRatio = false)));
end System;
推荐阅读
- python - 在 Django 中按字段区分分组
- node.js - 添加“less”和“less-loader”模块后如何修复损坏的vuejs项目
- pytest - 如何将场景特定的参数传递给 pytest bdd after_scenario 挂钩?
- python - 熊猫使用 loc 更改特定行的数据集值
- c# - 未修改的 asp.net 模板中的 NullReferenceException (Visual Studio)
- mysql - 我想知道是否有任何方法可以添加新的元组而不干扰mysql中的当前数据序列?
- ios - func tableView 中的异步函数
- intersystems-iris - 将表格和其他组件动态添加到 ZEN PDF 报告
- python - TypeError: QThread(parent: QObject = None): 参数 1 具有意外类型 'Ui_Form'
- amazon-web-services - 如何让 AWS 网站显示和更新 S3 内容?