2016-06-22 2 views
3

Есть ли способ определить рабочую область источника в Matlab для «линеаризации» при использовании внутри функции?Как изменить исходное рабочее пространство в 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. Однако в параметрах линеаризации я не нашел ничего подобного.

Большое спасибо за любую помощь или предложение!

ответ

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, который присутствует в базовой рабочей области в то время ... В качестве альтернативы, я предлагаю с помощью следующей функции

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. - Не очень элегантный, но безопасный.

+0

Спасибо за ваше предложение. Но изменение переменной в базовом рабочем пространстве - это то, чего я бы хотел избежать этой функцией. Поскольку это возможно для команды sim, я надеюсь, что есть также решение для команды линеаризации. –

+0

Я включил обход, который сохраняет и восстанавливает любую переменную 'A', которая присутствует в базовом рабочем пространстве до вызова функции. Не изящное решение, но выполняет эту работу. Может быть (надеюсь!) Кто-то придумает встроенный, простой способ сделать это - мне тоже не нравится это решение. – hbaderts

+0

Большое спасибо за ваши усилия! Но опять же: вопрос заключается в том, как перейти к «текущему» рабочему пространству, а не как манипулировать базовым рабочим пространством :-) Надеюсь, у кого-то есть идея. –

1

В различных файлах в MATLABROOT \ инструментарии \ 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 Workspace не вариант, потому что это было бы предположить Caller функция формы, где sim вызывается, а не от того, где вы звоните linearize.

Возможно, вам удастся установить данные из Model Workspace, и в этом случае вам нужно будет заполнить и установить это рабочее пространство перед вызовом linearize.