FMI接口支持
与外部设备通信的应用程序在单独测试时本质上是困难的。存在大量的仿真工具,这些工具允许这样的应用程序与模拟设备进行接口连接。这使得在缺少实际设备的情况下进行应用开发、测试和评估成为可能。此外,仿真可以轻松地提供有关当前设备状态的信息,并模拟在物理设备上难以实现的条件(例如,特定的故障)。Squish支持使用FMI接口与这些工具进行通信。
功能性模拟接口(Functional Mockup Interface,简称FMI)是动态模型交换和协同仿真的行业标准。它介绍了功能性模拟单元(Functional Mockup Units,简称FMUs)的导出器和导入器之间的接口。Squish具有导入支持FMI 2.0协同仿真模式的FMU的能力。作为FMU导入器,Squish可以访问FMU暴露的所有变量,并负责驱动仿真过程。以下部分介绍了Squish提供的用于导入和执行FMUs的API。
完整的FMI 2.0规范文本可以在以下网址获得:https://www.fmi-standard.org。Squish对FMI接口的支持基于JModelica平台上的FMI库。
FMI概述
注意:此处描述的接口不是最终版本。描述的API的细节可能会在功能的发布版本中发生变化。
FMI标准指定FMU可以包含编译后的可执行代码,以平台特定的共享对象文件的形式,或者是一组可以被FMI导入器编译的源代码文件。Squish只支持前者。
不建议将FMU加载到与AUT相同的上下文中。为了将FMU与其他任何进程分开,Squish提供了一个实用程序可执行文件fmiutil
。FMI功能仅在fmiutil
工具的应用程序上下文中可用。它位于Squish二进制安装目录中。要启动fmiutil
,请使用ApplicationContext startFMI()函数。
ApplicationContext startFMI
ApplicationContext startFMI(host)
ApplicationContext startFMI(host, port)
ApplicationContext startFMI(host, port, timeoutSecs)
启动一个新的fmiutil
实例并返回其应用程序上下文的句柄。
可选地,作为第一个和第二个参数可以指定host
和port
。如果使用这些参数,将连接到指定的主机和端口上监听的squishserver(而不是连接到在squishide的设置中或在squishrunner的命令行中指定的默认主机和端口)。
第三个参数是timeoutSecs
(以秒为单位的整数值)。这告诉Squish应在抛出错误之前准备等待应用程序启动多长时间。如果指定,此值将覆盖squishrunner的默认AUT超时。如果没有指定,将使用squishserver的默认值——这是20秒,除非已更改。请参阅Squish服务器设置对话框。
如果您想指定超时,但又不想更改主机或端口,可以通过传递空字符串作为主机(这将使Squish使用配置的主机—默认为localhost
)和传递-1作为端口来实现。
Fmi2Import类
Fmi2Import
类是Squish FMI接口支持的核心。它表示由Squish导入的FMU。
Fmi2Import
Fmi2Import.create(filename, workingDirectory)
Fmi2Import
Fmi2Import.create(filename)
此静态方法使用指定的目录作为工作目录打开指定的FMU,并返回一个 Fmi2Import
对象。如果未指定 workingDirectory
,则在每个方法调用时在 %TEMP% 目录中创建一个临时目录。
Fmi2Import.lastError
该只读属性包含描述FMU遇到的上一个错误的字符串。当 Fmi2Import
方法返回错误时将其设置。
Fmi2Import.name
Fmi2Import.identifierME
Fmi2Import.identifierCS
Fmi2Import.guid
Fmi2Import.description
Fmi2Import.author
Fmi2Import.copyright
Fmi2Import.license
Fmi2Import.version
Fmi2Import.standardVersion
Fmi2Import.generationTool
Fmi2Import.generationDate
Fmi2Import.namingConvetion
Fmi2Import.continuousStates
Fmi2Import.eventIndicators
Fmi2Import.defaultExperimentStart
Fmi2Import.defaultExperimentStop
Fmi2Import.defaultExperimentTolerance
Fmi2Import.defaultExperimentStep
这些只读属性包含根据FMI 2.0标准指定的FMU对象元数据。
Fmi2Import.fmuKind
该只读属性包含表示FMU支持的FMI模式值的值。它可以是一下之一
Fmi2Import.KindUnknown
— 未知FMU类型Fmi2Import.KindME
— 仅支持模型交换模式的FMUFmi2Import.KindCS
— 仅支持协同仿真的FMUFmi2Import.KindMECS
— 支持模型交换和协同仿真模式的FMU
Fmi2Import.state
该只读属性包含FMU的当前状态。可以是一下之一
Fmi2Import.Preloaded
— 解析了描述FMU的XML文件,但尚未加载二进制模型可执行文件。Fmi2Import.Instantiated
— 成功加载二进制模型可执行文件并实例化了模型。Fmi2Import.Init
— FMU已进入初始化模式。Fmi2Import.Event
— FMU处于事件状态。此状态仅适用于模型交换FMU。Fmi2Import.Continous
— FMU处于连续状态。此状态仅适用于模型交换FMU。Fmi2Import.StepComplete
— 上一个仿真步骤成功完成。此状态仅适用于协同仿真FMU。Fmi2Import.StepFailed
— 上一个仿真步骤失败。此状态仅适用于协同仿真FMU。Fmi2Import.Terminated
— 仿真过程已被终止。Fmi2Import.Error
— 发生仿真错误。仿真应被终止或恢复到之前保存的状态。Fmi2Import.Fatal
— FMU内部发生致命错误。应放弃当前状态的FMU。
Fmi2Import.type
只读属性,描述已实例化的FMU的类型。在FMU实例化之前此属性的值是不确定的。它可以是以下之一
Fmi2Import.TypeME
— FMU在模型交换模式中实例化。Fmi2Import.TypeCS
— FMU在协同仿真模式中实例化。
Fmi2Import.time
此只读属性包含FMU的当前仿真时间。
Fmi2Import.typesPlatform
此只读属性包含一个字符串标识符,对应于在当前平台上FMI应用程序使用的基原始数据类型集合。如果尝试使用使用与Squish编译不同的typesPlatform编译的FMU,将引起错误,这是FMI 2.0标准的强制要求。
Fmi2Import.types
此只读属性包含一个Fmi2Type对象数组,用于描述FMU的类型定义。
Fmi2Import.units
此只读属性包含一个Fmi2Unit对象数组,用于描述FMU使用的单位。
Fmi2Import.variables
此只读属性包含一个Fmi2Variable对象数组,用于描述FMU使用的变量。
Fmi2Import.vendors
此只读属性包含一个字符串数组,每个字符串描述了一个为加载的FMU做出贡献的软件供应商。
Fmi2Import.logCategories
此只读属性包含一个字符串标识符数组,描述了FMU使用的日志分类。
Fmi2Import.logCategoriesDescriptions
此只读属性包含一个字符串描述数组,描述了FMU使用的日志分类。
Fmi2Import.sourceFilesME
此只读属性包含一个文件名数组。如果FMU为模型交换二进制文件提供源代码,则此数组包含那些源文件的名称。
Fmi2Import.sourceFilesCS
此只读属性包含一个文件名数组。如果FMU为协同仿真二进制文件提供源代码,则此数组包含那些源文件的名称。
Fmi2Import.outputs
此只读属性包含一个Fmi2VariableArray对象,列出了为FMU定义的输出变量。
Fmi2Import.derivatives
此只读属性包含一个Fmi2VariableArray对象,列出了为FMU定义的导数变量。
Fmi2Import.discreteStates
此只读属性包含一个Fmi2VariableArray对象,列出了为FMU定义的离散状态变量。
Fmi2Import初始未知值
这个只读属性包含一个 Fmi2VariableArray
对象,该对象列出了为FMU定义的初始未知值的变量。
Fmi2Import.instantiate(name, type, visible)
此方法加载与FMU捆绑的动态库并实例化一个FMU对象。type
必须是 Fmi2Import.TypeME
或 Fmi2Import.TypeCS
。选择类型必须由 Fmi2Import.fmuKind 属性指示的支持 FMU 支持。如果 FMU 支持,则此参数的默认值为 Fmi2Import.TypeCS
,否则为 Fmi2Import.TypeME
。
name
应该是一个短字符串。它用于错误信息中的模型标识符。此参数的默认值为 Fmi2Import.name 属性的值。
visible
应该是一个布尔值。如果 FMU 通过直接或外部和可能已存在的应用程序显示自己的 GUI,则此参数指示是否应立即将此类 GUI 置于前台。如果 FMU 不显示任何类型的 GUI,则忽略此参数。
注意: 如果调用 Fmi2Import
对象的任何非静态方法,则此方法将使用默认参数值隐式调用。
Fmi2Import.setupExperiment(startTime, stopTime, tolerance)
此方法通知 FMU 设置实验并使 FMU 进入初始化模式。此方法要求 FMU 已实例化。如果在已进入初始化模式后调用此方法,则将报告错误。参数的默认值分别为 Fmi2Import.defaultExperimentStart、Fmi2Import.defaultExperimentStop 和 Fmi2Import.defaultExperimentTolerance。
注意: 如果调用需要设置的任何 Fmi2Import
对象方法的操作,则此方法将使用默认参数值隐式调用。
Fmi2Import.exitInitializationMode()
此方法使 FMU 离开初始化模式并进入 Fmi2Import.StepComplete
(对于协仿真 FMU)或 Fmi2Import.Event
(对于模型交换 FMU)状态。此方法要求 FMU 处于初始化状态。
注意: 如果调用需要初始化的任何 Fmi2Import
对象方法的操作,则此方法将隐式调用。
Fmi2Import.getCapability(capability)
此方法返回一个整数,用于描述请求的 FMU capability
。capablity
可以是以下之一
Fmi2Import.ME_needsExecutionTool
— 如果此能力的值为 1,则 FMU 不包含完整的模型交换模型实现,并且需要额外的软件可用。Fmi2Import.ME_canBeInstantiatedOnlyOncePerProcess
— 如果此能力的值为 1,则 FMU 仅能在模型交换模式下实例化一次。这只有信息价值,因为 Squish 只允许任何 FMU 单个实例。Fmi2Import.ME_canGetAndSetFMUstate
— 如果此能力的值为 1,则模型交换 FMU 可以使用 Fmi2State Fmi2Import.getState() 和 Fmi2Import.setState(state) 保存和恢复当前 FMU 状态。Fmi2Import.ME_canSerializeFMUstate
— 如果此功能的值为1,则ModelExchange FMU状态可以序列化。Fmi2Import.CS_needsExecutionTool
— 如果此功能的值为1,则FMU不包含完整的CoSimulation模型实现,需要其他软件可用。Fmi2Import.CS_canHandleVariableCommunicationStepSize
— 如果此功能的值为0,使用与CoSimulation FMU不同的步长值可能会引发错误。Fmi2Import.CS_canBeInstantiatedOnlyOncePerProcess
— 如果此功能的值为1,该FMU在CoSimulation模式下只能实例化一次。这只有信息价值,因为Squish只允许任何FMU的单个实例。Fmi2Import.CS_canGetAndSetFMUstate
— 如果此功能的值为1,CoSimulation FMU可以使用Fmi2State Fmi2Import.getState()和Fmi2Import.setState(state)来保存和恢复当前FMU状态。Fmi2Import.CS_canSerializeFMUstate
— 如果此功能的值为1,CoSimulation FMU状态可以序列化。
Fmi2Import.getAliasBase(var)
如果var
是一个别名变量,则返回var
所指定的非别名变量。如果var
是非别名变量,则返回var
。
Fmi2Import.getAliases(var)
此方法返回一个包含var
变量的所有已知别名的Fmi2VariableArray
对象。数组包括基础(非别名)变量。
Fmi2Import.getVariable(name)
此方法返回一个描述具有给定name
的变量的Fmi2Variable对象。如果在FMU中找不到名为name
的变量,则报告错误。
Fmi2Import.getVariables(names)
此方法返回一个包含names
数组中名称的变量的Fmi2VariableArray
对象。如果names
数组中的任何名称在FMU中找不到,则报告错误。
Fmi2Import.getVariableByName(name)
此方法返回一个描述具有给定name
的变量的Fmi2Variable对象。如果在FMU中找不到名为name
的变量,则返回null
。
Fmi2Import.getVariableByReference(vref)
此方法返回一个描述具有给定vref
变量引用的变量的Fmi2Variable对象。如果在FMU中找不到具有vref
变量引用的变量,则返回null
。
Fmi2Import.setDebugLogging(loggingOn, categories)
此方法设置FMU的调试日志。如果loggingOn
为true
,则启用日志。categories
是一个数组,指定要记录的日志类别。此数组的条目可以是Fmi2Import.logCategories数组中找到的任何标识符。
Fmi2Import.setReal(variables, values)
此方法将FMU变量的值设置为指定的值。如果成功,则返回 true
,如果值被FMU拒绝,则返回 false
。这通常是由于数值原因:设置了超出范围的值,积分器无法收敛等。
variables
应该是一个 Fmi2VariableArray
对象,或者是一个变量名数组或 Fmi2Variable 类 对象的数组。指定的变量必须是实变量。
values
应该是相应变量的数值数组。变量数组和值的数组的长度必须相同。此方法需要已实例化的FMU。
Fmi2Import.setInteger(variables, values)
此方法将FMU变量的值设置为指定的值。如果成功,则返回 true
,如果值被FMU拒绝,则返回 false
。这通常是由于数值原因:设置了超出范围的值,积分器无法收敛等。
variables
应该是一个 Fmi2VariableArray 对象,或者是一个变量名数组或 Fmi2Variable 类 对象的数组。指定的变量必须是整数或枚举变量。
values
应该是相应变量的数值数组。变量数组和值的数组的长度必须相同。此方法需要已实例化的FMU。
Fmi2Import.setBoolean(variables, values)
此方法将FMU变量的值设置为指定的值。如果成功,则返回 true
,如果值被FMU拒绝,则返回 false
。这通常是由于数值原因:设置了超出范围的值,积分器无法收敛等。
variables
应该是一个 Fmi2VariableArray
对象,或者是一个变量名数组或 Fmi2Variable 类 对象的数组。指定的变量必须是布尔变量。
values
应该是相应变量的布尔值数组。变量数组和值的数组的长度必须相同。此方法需要已实例化的FMU。
Fmi2Import.setString(variables, values)
此方法将FMU变量的值设置为指定的值。如果成功,则返回 true
,如果值被FMU拒绝,则返回 false
。这通常是由于数值原因:设置了超出范围的值,积分器无法收敛等。
variables
应该是一个 Fmi2VariableArray
对象,或者是一个变量名数组或 Fmi2Variable 类 对象的数组。指定的变量必须是字符串变量。
values
应该是相应变量的字符串值数组。变量数组和值的数组的长度必须相同。此方法需要已实例化的FMU。
Fmi2Import.setValue(variables, values)
此方法将FMU变量的值设置为指定的值。如果成功,则返回 true
,如果值被FMU拒绝,则返回 false
。这通常是由于数值原因:设置了超出范围的值,积分器无法收敛等。
variables
应该是一个 Fmi2VariableArray
对象,或者是一个变量名数组或 Fmi2Variable 类 对象的数组。指定的变量可以是任何类型。values
应该是相应变量的值数组。变量数组和值的数组的长度必须相同,且值的类型必须与相应的变量定义匹配。此方法需要已实例化的FMU。
Fmi2Import.getReal(variables)
此方法返回一个包含指定FMU变量值的数组。variables
应该是一个变量名数组,一个 Fmi2Variable 类 对象数组,或一个 Fmi2VariableArray
对象。指定的变量必须是实变量。此方法需要已配置的FMU。
Fmi2Import.getInteger(variables)
此方法返回一个包含指定FMU变量值的数组。variables
应为变量名称的数组、Fmi2Variable类对象的数组或一个Fmi2VariableArray
对象。指定的变量必须是整数或枚举变量。此方法需要设置FMU。
Fmi2Import.getBoolean(variables)
此方法返回一个包含指定FMU变量值的数组。variables
应为变量名称的数组、Fmi2Variable类对象的数组或一个Fmi2VariableArray
对象。指定的变量必须是布尔变量。此方法需要设置FMU。
Fmi2Import.getString(variables)
此方法返回一个包含指定FMU变量值的数组。variables
应为变量名称的数组、Fmi2Variable类对象的数组或一个Fmi2VariableArray
对象。指定的变量必须是字符串变量。此方法需要设置FMU。
Fmi2State Fmi2Import.getState()
此方法返回一个表示当前FMU状态的 Fmi2State
对象。它可以作为 Fmi2Import.setState(state) 的参数使用,以从先前保存的状态恢复FMU。此方法需要一个实例化的FMU。
Fmi2Import.setState(state)
此方法将FMU状态恢复到在 Fmi2State类 对象 state
中保存的状态。此方法需要一个实例化的FMU。
Fmi2Import.terminate()
此方法终止当前模拟并将当前FMU状态更改为 Fmi2Import.Terminated
。此方法需要一个初始化的FMU,且不在 Fmi2Import.Error
状态。
Fmi2Import.reset()
此方法将FMU恢复到 Fmi2Import.Instantiated
状态。此方法需要一个实例化的FMU。
Fmi2Import.doStep(stepSize, noPriorState)
此方法在CoSimulation模式下执行模拟步骤。它通过stepSize
增加内部FMU模拟时间 Fmi2Import.time。如果模拟步骤正确执行,则返回 true
;如果无法完成模拟步骤,则返回 false
。这通常是由于数值原因发生的;即,内部FMU积分器没有收敛。回到之前保存的状态并使用修改后的输入重新尝试模拟步骤可能会成功。此方法需要一个初始化的FMU。
可以指定一个可选参数 noPriorState
,它通知FMU它将不再恢复到在当前FMU时间之前的时间的状态。FMU可以用作清除缓存缓冲区的提示。此参数的默认值是 true
。
Fmi2Import.run(runtime, stepSize, timeFactor)
Fmi2Import.run(runtime, stepSize)
此方法执行一系列 stepSize
的模拟步骤。模拟将继续进行,直到内部FMU时间增加 runtime
或直到无法执行模拟步骤,在这种情况下,此方法返回 false
。此方法需要一个初始化的FMU。
可选参数timeFactor
用于控制模拟步骤执行的速度。它提供了模拟时间与模拟执行时间之间的关系。例如,如果时间因子等于0.5
,则两秒的模拟时间应该在执行时间一秒内完成。对于与外部软件交互的实时系统模拟,timeFactor
为1
可能最为有用。此参数的默认值为0
——模拟步骤将以环境和FMU允许的速度执行。
注意:Squish不能执行比FMU和执行环境允许的更快的模拟。如果模拟运行速度低于请求的速度,请考虑增加步长以减少FMU交互频率。
Fmi2Import.runDetached(stepSize, timeFactor)
Fmi2Import.runDetached(stepSize)
此方法执行一系列模拟步骤,步长为stepSize
,就像Fmi2Import.run(runtime, stepSize, timeFactor)。区别在于,该方法立即返回并执行模拟,同时并行于其他测试脚本的执行。在模拟过程中遇到的任何错误都通过Fmi2Import.sync()方法报告。此方法需要一个初始化的FMU。
Fmi2Import.sync()
如果FMU通过Fmi2Import.runDetached(stepSize, timeFactor)启动脱机模拟,它将等待请求的模拟步骤执行完毕,并在模拟提前中断时返回false
。如果在模拟过程中遇到错误,则抛出异常。
Fmi2Variable类
Fmi2Variable
类表示一个由FMU公开的变量。
Fmi2Variable.name
此只读属性包含变量名。
Fmi2Variable.value
此属性包含变量的当前值。如果FMU尚未准备好提供变量值(即未完全初始化),则结果为默认空值——数值类型为零,布尔变量为false
,字符串变量为空字符串。
此属性为只读。要更改输入变量的值,请使用Fmi2Import.setValue(variables, values)或类型特定的Fmi2Import.set*
方法。
Fmi2Variable.description
此只读属性包含一个可读的变量描述。
Fmi2Variable.valueReference
此只读属性包含变量的值引用。值引用是一个整数,由FMU内部用于识别变量。别名变量使用与其基本变量相同的值引用,因此始终具有相同的值。
Fmi2Variable.declaredType
如果变量有声明类型,则此只读属性包含Fmi2Type类类型的对象,否则为null
。
Fmi2Variable.baseType
此只读属性包含描述变量基本数据类型的值。它可以是一个
Fmi2Import.Real
——一个实数变量Fmi2Import.Integer
——一个整数变量Fmi2Import.Boolean
——一个布尔变量Fmi2Import.String
— 一个字符串变量Fmi2Import.Enum
— 一个枚举变量
Fmi2Variable.hasStart
这个只读属性包含一个布尔值,表示该变量是否有一个已定义的启动值。
Fmi2Variable.variability
这个只读属性包含一个值,描述了何时允许变量值的变化。它可以是指定的其中之一
Fmi2Variable.Constant
— 变量的值永远不会改变Fmi2Variable.Fixed
— 变量的值在FMU初始化后保持不变Fmi2Variable.Tunable
— 值不能在事件之间(模型交换)或仿真步骤之间(协同仿真)改变Fmi2Variable.Discrete
— 值不能在事件之间(模型交换)或仿真步骤之间(协同仿真)改变Fmi2Variable.Continuous
— 对值的变化没有限制Fmi2Variable.UnknownVariability
— 未知的可变性
Fmi2Variable.causality
这个只读属性指示变量值的获取方式。它可以是指定的其中之一
Fmi2Variable.Parameter
— 一个独立参数;可以由测试脚本设置Fmi2Variable.CalculatedParameter
— 在FMU模型初始化期间或在参数更改后进行计算Fmi2Variable.Input
— 一个输入变量;可以由测试脚本设置Fmi2Variable.Output
— 一个输出变量Fmi2Variable.Local
— 内部FMU变量Fmi2Variable.Independent
— 模拟的一个独立变量。所有其他变量都定义为独立变量的函数。默认独立变量是 '时间'。一个FMU中最多只能有一个独立变量Fmi2Variable.UnknownCausaility
— 未知的原因
Fmi2Variable.initial
这个只读属性包含一个值,表示变量初始值的获取方式。它可以是指定的其中之一
Fmi2Variable.Exact
— 使用start
属性作为初始值Fmi2Variable.Approx
— 通过迭代计算初始值。使用start
属性作为计算的初始值Fmi2Variable.Calculated
— 初始值是在初始化期间从其他变量的值计算出来的
Fmi2Variable.previous
这个只读属性包含一个Fmi2Variable
,它包含变量的上一个值,或者如果没有定义此类变量,则包含null
Fmi2Variable.isAlias
这个只读属性包含一个布尔值,表示如果变量是另一个变量的别名,则为真
Fmi2RealVariable Fmi2Variable.asReal()
如果变量的baseType
是Real
,则此方法将该变量转换为Fmi2RealVariable
对象,否则为null
Fmi2IntegerVariable Fmi2Variable.asInteger()
如果变量的baseType
是Integer
,则此方法将该变量转换为Fmi2IntegerVariable
对象,否则为null
Fmi2EnumVariable Fmi2Variable.asEnum()
此方法将变量强制转换为 Fmi2EnumVariable
对象,如果其 baseType
是 Enum
,否则是 null
。
Fmi2StringVariable Fmi2Variable.asString()
如果变量的 baseType
是 String
,则此方法将变量强制转换为 Fmi2StringVariable
对象,否则是 null
。
Fmi2BooleanVariable Fmi2Variable.asBoolean()
如果变量的 baseType
是 Boolean
,则此方法将变量强制转换为 Fmi2BooleanVariable
对象,否则是 null
。
Fmi2RealVariable.start
Fmi2IntegerVariable.start
Fmi2EnumVariable.start
Fmi2StringVariable.start
Fmi2BooleanVariable.start
这些只读属性持有变量的适当类型的起始值。
Fmi2RealVariable.min
Fmi2RealVariable.max
Fmi2IntegerVariable.min
Fmi2IntegerVariable.max
Fmi2EnumVariable.min
Fmi2EnumVariable.max
这些只读属性持有变量的最小和最大值。
Fmi2RealVariable.derivativeOf
此只读属性持有变量是其导数的 Fmi2RealVariable
对象,如果没有则为 null
。
Fmi2RealVariable.unit
如果为变量定义了,则此只读属性持有 Fmi2Unit
对象,否则为 null
。
Fmi2RealVariable.displayUnit
如果为变量定义了,则此只读属性持有 Fmi2DisplayUnit
对象,否则为 null
。
Fmi2Type 类
Fmi2Type
类包含有关 FMI 类型定义的信息。它仅充当信息角色。
Fmi2Type.name
此只读属性持有类型定义的名称。
Fmi2Type.description
此只读属性持有类型定义的描述。
Fmi2Type.baseType
此只读属性持有类型定义的基本类型。此值的含义与 Fmi2Variable.baseType 相同。
Fmi2Type.quantity
此只读属性持有描述类型定义数量的一串字符。
Fmi2RealType Fmi2Type.asReal()
如果其 baseType
是 Real
,则此方法将类型定义强制转换为 Fmi2RealType 对象,否则为 null
。
Fmi2IntegerType Fmi2Type.asInteger()
此方法如果类型定义的 baseType
为 Real
,则将其转换为 Fmi2ItegerType 对象;否则为 null
。
Fmi2EnumType Fmi2Type.asEnum()
如果类型定义的 baseType
为 Enum
,则将类型定义为 Fmi2EnumType 对象;否则为 null
。
Fmi2Unit 类
Fmi2Unit
类包含有关 FMI 单位定义的信息。每个 Fmi2Unit
类可以有一个或多个相关的 Fmi2DisplayUnit
对象。显示单位用于以用户友好的格式显示值。这两个类都仅具有信息作用。
Fmi2Unit.name
此只读属性保存了单位定义的名称。
Fmi2Unit.displayUnits
此只读属性保存了与单位定义相对应的 Fmi2DisplayUnit
对象数组。
Fmi2Unit.SIexponents
此只读属性保存了一个整数数组,描述单位定义的 SI 指数。
Fmi2Unit.SIfactor
Fmi2Unit.SIoffset
这些只读属性保存了一个与相应 SI 单位对应的因子和偏移量。
Fmi2Unit.fromSI(value)
此方法将对应 SI 单位表示的值转换为指定单位中的值。
Fmi2Unit.toSI(value)
此方法将指定单位表示的值转换为对应 SI 单位中的值。
Fmi2DisplayUnit.name
此只读属性保存了显示单位定义的名称。
Fmi2DisplayUnit.baseUnit
此只读属性保存了一个关联的 Fmi2Unit
对象。
Fmi2DisplayUnit.factor
Fmi2DisplayUnit.offset
这些只读属性保存了一个与相应 Fmi2Unit
对应的因子和偏移量。
Fmi2DisplayUnit.fromDisplayUnit(value)
此方法将对应 Fmi2Unit
表示的值转换为显示单位中的值。
Fmi2DisplayUnit.toDisplayUnit(value)
此方法将显示单位表示的值转换为对应 Fmi2Unit
单位中的值。
Fmi2State 类
有些 FMUs 具有存储其当前状态和从之前保存的状态恢复的能力。 Fmi2State
代表一个存储的 FMU 状态。
您可以通过使用带有 Fmi2Import.CS_canGetAndSetFMUstate
标志的 Fmi2Import.getCapability(capability) 方法来查询 FMU 保存和恢复状态的能力。另外,具有 Fmi2Import.CS_canSerializeFMUstate
能力标志设置的 FMUs 可以将此类状态序列化为字节序列,该序列可用于在 FMU 实例之间传输。
Fmi2DisplayUnit.size
这个只读属性包含一个字节数组的容量,该数组可以存储序列化的状态数据。
Fmi2State.serialize()
此方法将表示的状态序列化,并将其作为一个字节数组返回。
示例
运行仿真
以下示例代码展示了如何加载FMU对象、访问其变量并运行仿真过程。
function main() { startFMI(); var fmu = Fmi2Import.create( '/data/deviceModel.fmu' ); // Retrieves model variable called 'varX' var variableX = fmu.getVariable( "varX" ); // An alternative approach var variableY = findObject( "{type='Fmi2Variable' name='varY'}" ); // Set the values of the variables fmu.setValue( [ variableX, variableY, "varZ" ], [ 1, 2, 4 ] ); // Run the simulation in the background at real-time pace. fmu.runDetached( 0.01, 1 ); // Run the simulation for specific time snooze(5); // Compare the value of a variable with expected value test.compare( variableX.value, 1 ); // Destroys the FMI object and terminates 'fmiutil' fmu.destroy(); }
sub main() { startFMI(); my $fmu = Fmi2Import::create( '/data/deviceModel.fmu' ); # Retrieves model variable called 'varX' my $variableX = $fmu->getVariable( "varX" ); # An alternative approach my $variableY = findObject( "{name='varY' type='Fmi2Variable'}" ); # Set the values of the variables @variables = ( "varX", "varY", "varZ" ); @values = ( 1, 2, 4 ); $fmu->setValue( \@variables, \@values ); # Run the simulation in the background at real-time pace. $fmu->runDetached( 0.01, 1 ); # Run the simulation for specific time snooze(5); # Compare the value of a variable with expected value test::compare( $variableX->value, 1 ); # Destroys the FMI object and terminates 'fmiutil' $fmu->destroy(); }
def main(): startFMI() fmu = Fmi2Import.create( '/data/deviceModel.fmu' ) # Retrieves model variable called 'varX' variableX = fmu.getVariable( "varX" ) # An alternative approach variableY = findObject( "{name='varY' type='Fmi2Variable'}" ) # Set the values of the variables fmu.setValue( [ variableX, variableY, "varZ" ], [ 1, 2, 4 ] ) # Run the simulation in the background at real-time pace. fmu.runDetached( 0.01, 1 ) # Run the simulation for specific time snooze(5) # Compare the value of a variable with expected value test.compare( variableX.value, 1 ) # Destroys the FMI object and terminates 'fmiutil' fmu.destroy()
require 'squish' include Squish def main startFMI() fmu = Fmi2Import.create( '/data/deviceModel.fmu' ) # Retrieves model variable called 'varX' variableX = fmu.getVariable( "varX" ) # An alternative approach variableY = findObject( "{name='varY' type='Fmi2Variable'}" ) # Set the values of the variables fmu.setValue( [ "varX", "varY", "varZ" ], [ 1, 2, 4 ] ) # Run the simulation in the background at real-time pace. fmu.runDetached( 0.01, 1 ) # Run the simulation for specific time snooze(5) # Compare the value of a variable with expected value Test.compare( variableX.value, 1 ) # Destroys the FMI object and terminates 'fmiutil' fmu.destroy() end
proc main {} { startFMI set fmu [ invoke Fmi2Import create "/data/deviceModel.fmu" ] # Retrieves model variable called 'varX' set variableX [ invoke $fmu getVariable "varX" ]; # An alternative approach set variableY [ findObject "{name='varY' type='Fmi2Variable'}" ] # Set the values of the variables property set $variableX value 1 property set $variableY value 2 property set [ findObject "{name='varZ' type='Fmi2Variable'}" ] value 4 # Run the simulation in the background at real-time pace. invoke $fmu runDetached 0.01 1 # Run the simulation for specific time snooze 5 # Compare the value of a variable with expected value test compare [ property get $variableX value ] 1 # Destroys the FMI object and terminates 'fmiutil' invoke $fmu destroy }
与 AUT 并行运行的仿真
在工具进程中创建了一个 FMU 对象。如果测试脚本访问 FMU 和 AUT,则必须更改当前上下文以与当前访问的对象匹配,具体描述在 如何在单个测试脚本中启动并访问多个应用被测对象 中。
function main() { var fmictx = startFMI(); var fmu = Fmi2Import.create( '/data/deviceModel.fmu' ); // Run the simulation in the background at real-time pace. fmu.runDetached( 0.01, 1 ); var autctx = startApplication( "/an/aut" ); activateItem( waitForObjectItem( ":_QMenuBar", "Device" ) ); activateItem( waitForObjectItem( ":Device_QMenu", "Start" ) ); setApplicationContext( fmictx ); test.compare( fmu.getVariable( "isStarted" ).value, True ); fmu.setValue( [ "isRunning" ], [ 1 ] ); setApplicationContext( autctx ); test.compare( waitForObject( ":Status_QLabel" ).text, "Running" ); setApplicationContext( fmictx ); fmu.destroy(); }
sub main() { my $fmictx = startFMI(); my $fmu = Fmi2Import::create( '/data/deviceModel.fmu' ); # Run the simulation in the background at real-time pace. $fmu->runDetached( 0.01, 1 ); my $autctx = startApplication( "/an/aut" ); activateItem( waitForObjectItem( ":_QMenuBar", "Device" ) ); activateItem( waitForObjectItem( ":Device_QMenu", "Start" ) ); setApplicationContext( $fmictx ); test::compare( $fmu->getVariable( "isStarted" )->value, True ); @variables = ( "isRunning" ); @values = ( 1 ); $fmu->setValue( \@variables, \@values ); setApplicationContext( $autctx ); test::compare( waitForObject( ":Status_QLabel" )->text, "Running" ); setApplicationContext( $fmictx ); $fmu.destroy(); }
def main(): fmictx = startFMI() fmu = Fmi2Import.create( '/data/deviceModel.fmu' ) // Run the simulation in the background at real-time pace. fmu.runDetached( 0.01, 1 ) autctx = startApplication( "/an/aut" ) activateItem( waitForObjectItem( ":_QMenuBar", "Device" ) ) activateItem( waitForObjectItem( ":Device_QMenu", "Start" ) ) setApplicationContext( fmictx ) test.compare( fmu.getVariable( "isStarted" ).value, 1 ) fmu.setValue( [ "isRunning" ], [ 1 ] ) setApplicationContext( autctx ) test.compare( waitForObject( ":Status_QLabel" ).text, "Running" ) setApplicationContext( fmictx ) fmu.destroy()
require 'squish' include Squish def main() { fmictx = startApplication( "fmiutil" ) fmu = Fmi2Import.create( '/data/deviceModel.fmu' ) # Run the simulation in the background at real-time pace. fmu.runDetached( 0.01, 1 ) var autctx = startApplication( "/an/aut" ) activateItem( waitForObjectItem( ":_QMenuBar", "Device" ) ) activateItem( waitForObjectItem( ":Device_QMenu", "Start" ) ) setApplicationContext( fmictx ) test.compare( fmu.getVariable( "isStarted" ).value, True ) fmu.setValue( [ "isRunning" ], [ 1 ] ) setApplicationContext( autctx ) test.compare( waitForObject( ":Status_QLabel" ).text, "Running" ) setApplicationContext( fmictx ) fmu.destroy() }
proc main {} { set fmictx [ startFMI ] set fmu [ invoke Fmi2Import create "/data/deviceModel.fmu" ] # Run the simulation in the background at real-time pace. invoke $fmu runDetached 0.01 1 set autctx [ startApplication "/an/aut" ] invoke activateItem [waitForObjectItem ":_QMenuBar" "Device" ] invoke activateItem [waitForObjectItem ":Device_QMenu" "Start" ] setApplicationContext $fmictx test compare [ property get [ invoke $fmu getVariable "isStarted" ] value ] 1 set isRunning [ invoke $fmu getVariable "isRunning" ]; property set $isRunning value 1 setApplicationContext $autctx test compare [ property get [ waitForObject ":Status_QLabel" ] text ] "Running" setApplicationContext $fmictx invoke $fmu destroy
等待仿真结果
要等待仿真变量达到特定值,请使用 Object waitForObject(objectOrName)。如果指定了 value
属性,它将仅查找指定值的变量,并在没有此类变量的情况下等待。
// will wait until variable 'varY' has a value of 1. var variableY = waitForObject( "{type='Fmi2Variable' name='varY' value='1'}" );
// will wait until variable 'varY' has a value of 1. my $variableY = waitForObject( "{type='Fmi2Variable' name='varY' value='1'}" );
// will wait until variable 'varY' has a value of 1. variableY = waitForObject( "{type='Fmi2Variable' name='varY' value='1'}" )
// will wait until variable 'varY' has a value of 1. variableY = waitForObject( "{type='Fmi2Variable' name='varY' value='1'}" );
// will wait until variable 'varY' has a value of 1. set variableY [ waitForObject "{type='Fmi2Variable' name='varY' value='1'}" ]
如果等待的条件更复杂,可以使用 Boolean waitFor(condition) 函数。
var variableY = findObject( "{type='Fmi2Variable' name='varY'}" ); waitFor( function() { return variableY.value < 1; } );
my $variableY = findObject( "{type='Fmi2Variable' name='varY'}" ); waitFor( function() { return $variableY->value < 1; } );
variableY = findObject( "{type='Fmi2Variable' name='varY'}" ) waitFor( lambda: variableY.value < 1 )
var variableY = findObject( "{type='Fmi2Variable' name='varY'}" ) waitFor( lambda { return variableY.value < 1 } )
set variableY [ findObject "{type='Fmi2Variable' name='varY'}" ] waitFor [ proc "" {} { expr [ property get $variableY value ] < 1 } ]
如果感兴趣的变量在相对较短的时间内具有预期值,由于测试脚本执行的并行性质,有可能会完全错过该值。为了获得仿真过程的精细控制,请直接从测试脚本运行该变量。
setApplicationContext( fmictx ); // Stops background execution of the simulation process (if started). fmu.sync(); var variableY = findObject( "{type='Fmi2Variable' name='varY'}" ); for ( var i=0; i<1000; ++i ) { fmu.doStep( 0.01 ); if ( variableY.value < 1 ) break; } test.verify( variableY.value < 1 ); // Re-start detahed execution ( if required ) fmu.runDetached( 0.01, 1 );
setApplicationContext( $fmictx ); // Stops background execution of the simulation process (if started). $fmu->sync(); my $variableY = findObject( "{type='Fmi2Variable' name='varY'}" ); for ( my $i=0; $i<1000; $i++ ) { $fmu->doStep( 0.01 ); if ( $variableY->value < 1 ) { last; } } test::verify( $variableY->value < 1 ); // Re-start detahed execution ( if required ) $fmu->runDetached( 0.01, 1 );
setApplicationContext( fmictx ) // Stops background execution of the simulation process (if started). fmu.sync() variableY = findObject( "{type='Fmi2Variable' name='varY'}" ) for x in range(0, 1000): fmu.doStep( 0.01 ) if variableY.value < 1: break test.verify( variableY.value < 1 ) // Re-start detahed execution ( if required ) fmu.runDetached( 0.01, 1 )
setApplicationContext( fmictx ) // Stops background execution of the simulation process (if started). fmu.sync() variableY = findObject( "{type='Fmi2Variable' name='varY'}" ) for x in 1..1000: fmu.doStep( 0.01 ) if variableY.value < 1 then break end end test.verify( variableY.value < 1 ) // Re-start detahed execution ( if required ) fmu.runDetached( 0.01, 1 )
setApplicationContext $fmictx # Stops background execution of the simulation process (if started). invoke fmu sync set variableY [ findObject "{type='Fmi2Variable' name='varY'}" ] for {set i 0} {$i < 1000} {incr i} { invoke $fmu doStep 0.01 if { expr [ property get $variableY value ] < 1 } { break } } invoke test verify [ expr [ property get $variableY value ] < 1 ] # Re-start detached execution ( if required ) invoke fmu runDetached 0.01 1
©2024 The Qt Company Ltd. 本文档的贡献权属于各自的拥有者。
提供的文档根据 Free Software Foundation 发布的 GNU Free Documentation License 1.3 版本的条款许可。
Qt 和相关的标志是 The Qt Company Ltd. 在芬兰和/或其他国家/地区的商标。所有其他商标归各自的所有者所有。