3

在函数中使用时,有没有办法在 Matlab 中为“线性化”定义源工作区?

这是一个简短的最小工作示例:

clear all
sys = 'watertank';
open(sys)
sys_io(1)   = linio('watertank/PID Controller',1,'input');
sys_io(2)   = linio('watertank/Water-Tank System',1,'openoutput');
linsys      = GetLinsys(sys,sys_io);
disp(linsys.a)

功能是:

function linsys = GetLinsys(sys,sys_io)
A       = 10;
linsys  = linearize(sys,sys_io);
end

输出是

-0.0500

因为linearize在“基本”工作区 (A=20) 中使用 A 的初始值,而不是在“当前”工作区 (A=10) 中的值。

但是,我希望

-0.1000

如果函数的代码包含在脚本中,则会获得此信息:

clear all
sys = 'watertank';
open(sys)
sys_io(1)   = linio('watertank/PID Controller',1,'input');
sys_io(2)   = linio('watertank/Water-Tank System',1,'openoutput');
A           = 10;
linsys      = linearize(sys,sys_io);
disp(linsys.a)

因此,问题是:如何使用该函数获得相同的结果?

对于sim命令,这可以通过选项来完成:

options = simset('SrcWorkspace','current');
sim('modelname',[],options)

这里。但是,我在线性化选项中找不到类似的东西。

非常感谢您的任何帮助或建议!

4

2 回答 2

1

在 MATLABROOT\toolbox\slcontrol\slcontrol 中与线性化相关的各种文件中,在调用之前有以下注释sim

    % Run the simulation.  Do not need to simulate past
    % the final specified time.  Use the base workspace to write
    % variables and simulate.  This will be consistent with all
    % linearization functions that require the model parameters be
    % defined in the base workspace.
    S = simset('DstWorkspace','base');
    pmgr.sim([Tstart Tfinal],S);

我认为没有简单/透明(甚至可能不是困难)的方式来linearize使用Caller Workspace.

将上述调用更改sim为使用CallerWorkspace 不是一种选择,因为它假定Caller是正在调用的函数形式,sim而不是从你正在调用的位置linearize

您可能可以进行设置以从 获取数据Model Workspace,在这种情况下,您需要在调用之前填充和设置该工作区linearize

于 2016-06-23T00:28:07.817 回答
1

似乎将参数传递给 Simulink 的标准方法是通过 MATLAB 的基础工作区。要从函数传递A=10到 Simulink,即在基础工作区中创建一个变量,您可以使用该assignin函数:

function linsys = GetLinsys(sys,sys_io)
    assignin('base','A',10);
    linsys  = linearize(sys,sys_io);
end

然后,调用

sys = 'watertank';
open(sys)
sys_io(1)   = linio('watertank/PID Controller',1,'input');
sys_io(2)   = linio('watertank/Water-Tank System',1,'openoutput');
linsys      = GetLinsys(sys,sys_io);
disp(linsys.a)

产量

-0.1000

正如预期的那样。

请注意,这有点危险,因为您覆盖A了当时存在于基础工作区中的 any ......作为替代方案,我建议使用以下函数

function linsys = GetLinsys(sys,sys_io)

% Save old 'A', if exists
if evalin('base', 'exist(''A'',''var'')');
    baseA = evalin('base','A');
end
assignin('base','A',10)

% Function call
linsys  = linearize(sys,sys_io);

% Clean up
evalin('base', 'clear(''A'')');
if exist('baseA', 'var')
    assignin('base','A',baseA)
end

end

这将检查基础工作区中是否存在名为的变量A并将其值保存在baseA. 然后您可以安全地分配 newA和 call linearize。最后,我们clear A再次(如果需要)重新分配旧的baseA. - 不是很优雅,但更安全。

于 2016-06-22T11:16:15.073 回答