有没有办法在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的初始值。工作空间(A = 20)而不是当前'中的值。工作区(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)
见here。 但是,我无法在线性化选项中找到类似的东西。
非常感谢任何帮助或建议!
答案 0 :(得分: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
...作为替代方案,我建议使用以下函数< / p>
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
中。然后,您可以安全地分配新A
并致电linearize
。最后,我们clear A
再次(如果需要)重新分配旧的baseA
。 - 不是很优雅,但更安全。
答案 1 :(得分: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
以使用Caller
工作区并不是一个选项,因为它会假设Caller
是sim
所在的函数形式叫来,而不是从你打电话的地方linearize
。
您可以设置一些内容以从Model Workspace
获取数据,在这种情况下,您需要在调用linearize
之前填充并设置该工作区。