可以通过两种方法以编程方式仿真模型:
-
通过 sim 命令。
-
通过运行按钮
使用 sim 命令执行仿真时,可以使用命令行对仿真执行操作。使用运行按钮执行仿真意味着您可以使用 Simulink® UI 与仿真进行交互,以执行任何其他操作。下表详细说明了这两种方法之间的差异。
操作 | 非交互式仿真(sim 命令仿真) | 交互式仿真(“运行”按钮仿真) |
允许的交互级别 | 低 | 高/set_param(mdl,'SimulationCommand','Start') |
开始仿真。 | sim 命令 | Run |
停止仿真 | 在命令行中执行 Ctrl-C | set_param(mdl,'SimulationCommand','Stop')/ Stop |
暂停仿真 | 否 | 是。set_param(mdl,'SimulationCommand','Pause') / 暂停 |
当仿真运行时,MATLAB® 提示符可用 | 否 | 是 |
仿真运行时示波器更新 | 是,但在快速加速模式下除外 | 是 |
仿真步进器 | 否 | 是,但在快速加速模式下除外 |
条件暂停 | 否 | 是,但在快速加速模式下除外 |
仿真运行时端口值显示可用? | 否 | 是 |
支持仿真调速 | 是 | 是 |
支持 TimeOut 选项 | 是 | 否 |
错误处理 | MATLAB 异常,除非 CaptureErrors 为 on | 向诊断查看器报告 |
sim
命令仿真
通过使用指定的方法来指定参数值,可以用 sim 函数以编程方式仿真模型。除运行模型仿真外,还可以使用 sim 命令来启用仿真超时、捕获仿真错误并在仿真完成时访问仿真元数据。
指定参数名称-值对组
此示例说明如何以名称-值对组形式指定模型参数,从而以编程方式进行模型仿真。
使用指定为连续的名称-值对组的参数值进行 vdp 模型仿真。
simOut = sim('vdp','SimulationMode','normal',...'SaveState','on','StateSaveName','xout',...'SaveOutput','on','OutputSaveName','yout',...'SaveFormat', 'Dataset');
outputs = simOut.yout
outputs = Simulink.SimulationData.DatasetPackage: Simulink.SimulationDataCharacteristics:Name: 'yout'Total Elements: 2Elements:1 : 'x1'2 : 'x2'-Use get or getElement to access elements by index or name.-Use addElement or setElement to add or modify elements.
在 Normal 模式下进行模型仿真,并为求解器误差指定绝对容差。sim 函数返回 SimOut,它是一个 Simulink.SimulationOutput 对象,其中包含所有的仿真输出(记录的时间、状态和信号)。
绘制输出信号值对时间的图。
x1 = (outputs.get('x1').Values);
x2 = (outputs.get('x2').Values);
plot(x1); hold on;
plot(x2);
title('VDP States')
xlabel('Time'); legend('x1','x2')
启用仿真超时
如果在一个循环中运行多个仿真并使用变步长求解器,可以考虑使用 sim 的 timeout 参数。如果某个仿真因为某种原因中止或开始执行非常小的时间步,该仿真将超时。然后,可以运行下一个仿真。
N = 100;
simOut = repmat(Simulink.SimulationOutput, N, 1);
for i = 1:NsimOut(i) = sim('vdp', 'timeout', 1000);
end
捕获仿真错误
如果发生错误导致仿真停止,您可以在仿真元数据中查看错误。在这种情况下,sim 会在仿真输出对象中捕获遇到错误之前的仿真数据,以便您对仿真进行某些调试,而不用重新运行仿真。要启用此功能,请使用 sim 函数的 CaptureErrors 参数。
这种方法的另一个好处是仿真错误不会导致 sim
停止。因此,假设您在 for
循环中使用 sim
,此循环中的后续迭代仍会继续运行。
simOut = sim('my_model', 'CaptureErrors', 'on');
simOut.getSimulationMetadata.ExecutionInfo
ans = struct with fields:StopEvent: 'DiagnosticError'StopEventSource: []StopEventDescription: 'Division by zero in 'my_model/Divide''ErrorDiagnostic: [1×1 struct]WarningDiagnostics: [0×1 struct]
访问仿真元数据
此示例说明如何在仿真完成之后访问仿真元数据。可以运行任何类型的仿真并访问其元数据。
此示例对采用名称-值对组形式指定参数值的模型进行仿真。运行仿真。
simOut = sim('vdp','SimulationMode','normal','AbsTol','1e-5',...'SaveState','on','StateSaveName','xoutNew',...'SaveOutput','on','OutputSaveName','youtNew',...'SaveFormat', 'StructureWithTime');
访问 ModelInfo 属性,其中包含有关模型和求解器的基本信息。
simOut.getSimulationMetadata.ModelInfo
ans = struct with fields:ModelName: 'vdp'ModelVersion: '1.6'ModelFilePath: 'C:\MyWork'UserID: 'User'MachineName: 'MyMachine'Platform: 'PCWIN64'ModelStructuralChecksum: [4×1 uint32]SimulationMode: 'normal'StartTime: 0StopTime: 20SolverInfo: [1×1 struct]SimulinkVersion: [1×1 struct]LoggingInfo: [1×1 struct]
检查求解器信息。
simOut.getSimulationMetadata.ModelInfo.SolverInfo
ans = struct with fields:Type: 'Variable-Step'Solver: 'ode45'MaxStepSize: 0.4000
查看仿真的时间信息,例如仿真的开始时间和完成时间,以及仿真初始化、执行和终止所用的时间。
simOut.getSimulationMetadata.TimingInfo
ans = struct with fields:WallClockTimestampStart: '2016-06-17 10:26:58.433686'WallClockTimestampStop: '2016-06-17 10:26:58.620687'InitializationElapsedWallTime: 0.1830ExecutionElapsedWallTime: 1.0000e-03TerminationElapsedWallTime: 0.0030TotalElapsedWallTime: 0.1870
为仿真添加说明。
simOut=simOut.setUserString('Results from simulation 1 of 10');
simOut.getSimulationMetadata
ans = SimulationMetadata with properties:ModelInfo: [1×1 struct]TimingInfo: [1×1 struct]ExecutionInfo: [1×1 struct]UserString: 'Results from simulation 1 of 10'UserData: []
还可以使用 UserData 属性添加您自己的自定义数据。
“运行”按钮仿真
对于交互式仿真,可以使用 set_param 和 get_param。使用 set_param 和 get_param,可以检查正在运行的仿真的状态,并通过使用模块回调来控制仿真的执行。
控制和检查仿真的状态
以下示例说明如何使用 set_param 来控制仿真的状态。set_param 允许您动态更新变量以及将数据记录变量写入工作区。
开始仿真。
set_param('vdp','SimulationCommand','start')
如果使用 set_param 和 'start' 参数启动仿真,则必须使用 'stop' 参数来停止仿真。不使用 'stop' 参数会导致仿真仅在完成后才停止。
暂停、继续和停止仿真。
set_param('vdp','SimulationCommand','pause')
set_param('vdp','SimulationCommand','continue')
set_param('vdp','SimulationCommand','stop')
当使用 set_param 暂停或停止仿真时,仿真不会立即执行命令。可以使用 set_param 在 stop 命令后开始仿真以及在暂停命令后继续进行仿真。Simulink 首先完成不可中断的工作,例如求解器的求解步骤以及 set_param 命令之前的其他命令。然后才会按照 set_param 命令的指示启动、暂停、继续或停止仿真。
检查仿真的状态。
get_param('vdp','SimulationStatus')
软件将返回
'stopped'、'initializing'、'running'、'paused'、'compiled'、'updating'、'terminating' 或 'external'(与 Simulink Coder™ 产品一起使用)。
要在仿真运行时动态更新已更改的工作区变量,请使用 update 命令。
set_param('vdp','SimulationCommand','update')
将所有数据记录变量写入基础工作区。
set_param('vdp','SimulationCommand','WriteDataLogs')
使用回调自动执行仿真任务
当对模型执行各种操作(例如启动、暂停或停止仿真)时,将执行回调。您可以使用回调来执行 MATLAB 脚本或其他 MATLAB 命令。。
此示例说明如何使用模型 StartFcn 回调在仿真开始之前自动执行 MATLAB 代码。
编写在模型中查找 Scope 模块的 MATLAB 脚本,并在仿真模型时在前台打开这些模块。将脚本保存在当前文件夹中。
% openscopes.m
% Brings scopes to forefront at beginning of simulation.blocks = find_system(bdroot,'BlockType','Scope');% Finds all of the scope blocks in the top level of your% model. To find scopes in subsystems, provide the subsystem% names. Type help find_system for more on this command.for i = 1:length(blocks)set_param(blocks{i},'Open','on')
end% Loops through all of the scope blocks and brings them% to the forefront.
为模型设置 StartFcn 参数以调用 openscopes 脚本。
set_param('my_model','StartFcn','openscopes')