Как мне предоставить входные данные для модели Simulink, не помещая ее в рабочую область

У меня есть модель Simulink, которая в настоящее время запускается из сценария (т.е. не функции). Сценарий записывает значения переменных в рабочее пространство MATLAB, запускает симуляцию модели (которая использует эти значения), а затем модель записывает дополнительные значения в рабочее пространство. Если я попытаюсь преобразовать сценарий в функцию (например, поместив function [output] = runSim() в верхнюю часть файла), Simulink жалуется, что не знает о переменных, предположительно потому, что они не находятся в рабочем пространстве MATLAB, а скорее они находятся в объем функции.

Есть ли элегантный способ предоставить модели Simulink входные данные и получить выходы из модели Simulink, кроме как вставлять их в рабочую область?


person JnBrymn    schedule 11.03.2011    source источник


Ответы (4)


Это не очевидно, но вы можете вводить / выводить данные с помощью команды sim() и рабочего пространства вызывающей функции. Я делал это раньше, и у меня есть пример на работе, но я не могу добраться до понедельника, чтобы проверить. Однако попробуйте решение, указанное на сайте Mathworks:

Решение:

При использовании параметров переменной маски в Simulink базовое рабочее пространство является исходным рабочим пространством Simulink по умолчанию. Однако с помощью команды SIMSET это рабочее пространство можно изменить. Затем SIM-карта используется с этой структурой опций, созданной SIMSET. Ниже приводится пример того, как это сделать.

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

... хотя, по-видимому, это стало устаревшим в R2009b из-за несовместимости с Parallel Computing Toolbox> :( Похоже, что правильным решением является явное добавление переменных в рабочее пространство модели моделирования (отличное от базового рабочего пространства), используя assignin().

http://www.mathworks.com/matlabcentral/newsreader/view_thread/292544

У вас есть 2 варианта:

  1. Информацию о выпусках до R2009b см. В документации SIMSET. Он позволяет вам установить для свойства «SrcWorkspace» значение «current», чтобы использовать данные из вашей функции.

http://www.mathworks.com/support/solutions/en/data/1-1BWDA/?solution=1-1BWDA

  1. В более новых выпусках этот параметр не рекомендуется, поскольку он несовместим с Parallel Computing Toolbox и PARFOR. Я рекомендую:

http://www.mathworks.com/support/solutions/en/data/1-ASPEIV/?solution=1-ASPEIV

person Jason S    schedule 12.03.2011
comment
Подойдет ли этот метод для ссылок на модели и компиляции с помощью RTW? - person Miebster; 13.03.2011
comment
что вам придется спросить у сотрудников Mathworks; Я никогда не использовал RTW, и я никогда не углублялся в Simulink, кроме как запускать симуляции из M-файла. - person Jason S; 13.03.2011
comment
Первый вариант работает в 2009a ... так что я буду придерживаться его, пока он меня не укусит. Спасибо! - person JnBrymn; 15.03.2011
comment
@MajorApus Мы используем RTW, и первое решение, похоже, работает. - person JnBrymn; 15.03.2011

Вы можете использовать функцию evalin () для выполнения из вашей собственной функции выражения MATLAB (в виде строки) в определенной рабочей области, в вашем случае это «база» для SIMULINK, чтобы найти их. Однако, если вы не хотите использовать рабочее пространство напрямую, вы можете загружать и сохранять сигналы или переменные из / в файлы MAT с помощью блоков From / To File.

person Mahmoud Kassem    schedule 12.03.2011

Краткий ответ: Нет.

Я могу ошибаться, но позвольте мне дать вам некоторую предысторию. Я работаю над очень большой моделью Simulink, мы работали над ней годами. По сей день мы все еще загружаем все необходимые переменные через рабочую область. Я долгое время жаловался на это настолько, что MathWorks даже решил эту проблему, предоставив функцию Simulink.save_vars. Похоже, вы уже настраиваете переменные с помощью скрипта / функции, поэтому Simulink.save_vars не принесет вам большой пользы.

Вы можете очистить рабочее пространство, используя структуры для некоторых переменных, большинство блоков Simulink не поддерживают структуры, но некоторые поддерживают. Кроме того, избегайте размещения в рабочей области чего-либо, кроме переменных, которые нужны вашей модели.

person Miebster    schedule 12.03.2011

Ну, я не знаю, как это сделать с помощью простой функции, но действительно удобно делать это изнутри функции (метода) класса. Прекрасно работает с версией 2009b.

Поместите код в файл Test.m:

classdef Test < handle
    properties
        mdl
        % Default input signal
        t = [0 1 1 2]'
        u = [0 0 1 1]'
    end

    methods
        function this = Test(mdl)   % Constructor
            this.mdl = mdl;
        end

        function sim(this)
            % Load model
            load_system(this.mdl);
            % Prepare model configuration
            conf = getActiveConfigSet(this.mdl);
            cs = conf.copy();
            set_param(cs, 'StopTime', '4');
            set_param(cs, 'LoadExternalInput', 'on');
            set_param(cs, 'ExternalInput', '[test.t test.u]');  % <-- 1
            % Run simulation
            simout = sim(this.mdl, cs);
            % Plot results
            tout = simout.find('tout');
            yout = simout.find('yout');
            plot(tout, yout(:,1), 'b--');
        end
    end
end

Тогда просто:

>> test = Test('TestSim');
>> test.sim();

Что случается? Вы создаете объект test, в котором определены поля t и u. Затем в методе sim () вы говорите Simulink искать ввод «[test.t test.u]». И Simulink, и метод sim () имеют доступ к этим переменным (я считаю, что это самая важная вещь).

Хорошо, у него все еще есть большой недостаток, отмеченный цифрой 1. Вы должны явно знать, как ссылка на экземпляр класса будет именоваться в рабочей области (в данном случае «test»). Вы можете обойти это, передав имя в конструктор, или вы можете использовать статические переменные и методы, но этот способ не позволит вам динамически изменять входной сигнал.

person Golmar    schedule 03.02.2013
comment
Хм, сначала это выглядит элегантно, но я почти уверен, что объект Test все равно должен находиться в базовой рабочей области - так что это просто меняет местоположение проблемы OP. Также совет: будьте осторожны, называя вещи XXXXtest или textXXXX - вы столкнетесь с проблемами с фреймворком unittest, который подберет файлы классов, названные таким образом, как примеры модульных тестов. - person thclark; 20.08.2016