Запустите быстрые симуляции в области значений значений параметров

Этот пример показывает, как использовать цель RSim, чтобы запустить симуляции в области значений значений параметров. Пример использует Осциллятор Ван дер Поля и выполняет развертку параметра в области значений значений начального состояния, чтобы получить схему фазы нелинейной системы.

Очень легко настроить этот пример для вашего собственного приложения путем изменения скрипта MATLAB®, используемого, чтобы создать этот пример. Щелкните по ссылке в левом верхнем угле этой страницы, чтобы отредактировать скрипт MATLAB®. Щелкните по ссылке в правом верхнем углу, чтобы запустить этот пример от MATLAB®. При выполнении этого примера убедитесь, что вы находитесь в перезаписываемой директории. Пример создает файлы, которые можно хотеть исследовать позже.

В данном примере поведение параметра По умолчанию установлено в Inlined. В примере вы создаете объекты Simulink.Parameter как настраиваемые параметры. Чтобы использовать RSim с набором поведения параметра По умолчанию к Tunable, и явным образом не объявляя настраиваемые параметры, смотрите Симуляции Пакета Выполнения, Не Перекомпилировав Сгенерированный код (Simulink Coder).

Чтобы быстро запустить несколько симуляций в окружении Simulink, рассмотрите использование быстрого акселератора вместо RSim. Для получения информации о быстром акселераторе смотрите то, Что Ускорение? (Simulink). Чтобы развернуть значения параметров, смотрите, Оптимизируют, Оценка и Значения Параметров блоков Развертки (Simulink).

Шаг 1. Подготовка

Убедитесь, что текущий каталог перезаписываем, потому что этот пример будет создавать файлы.

[stat, fa] = fileattrib(pwd);
if ~fa.UserWrite
    disp('This script must be run in a writable directory');
    return
end

Откройте модель и сконфигурируйте ее, чтобы использовать цель RSim. Для получения дополнительной информации о выполнении этого графически и подготовке другие связанные с целью опции RSim, посмотрите здесь.

mdlName = 'rtwdemo_rsim_vdp';
open_system(mdlName);
cs = getActiveConfigSet(mdlName);
cs.switchTarget('rsim.tlc',[]);

Задайте как Настраиваемые переменные INIT_X1 (начальное условие для состояния x1), INIT_X2 (начальное условие для состояния x2), и MU (значение усиления). Чтобы создать настраиваемые параметры, преобразуйте переменные в объекты Simulink.Parameter и используйте класс памяти кроме Auto для каждого объекта. В этом примере мы будем заниматься расследованиями, как траектории состояния развиваются из различных начальных значений для состояний x1 и x2 в модели.

INIT_X1 = Simulink.Parameter(INIT_X1);
INIT_X1.StorageClass = 'Model default';

INIT_X2 = Simulink.Parameter(INIT_X2);
INIT_X2.StorageClass = 'Model default';

MU = Simulink.Parameter(MU);
MU.StorageClass = 'Model default';

Задайте имена файлов, которые будут созданы во время этого примера.

prmFileName = [mdlName, '_prm_sets.mat'];
logFileName = [mdlName, '_run_scr.log'];
batFileName = [mdlName, '_run_scr'];
exeFileName = mdlName;
if ispc
    exeFileName = [exeFileName, '.exe'];
    batFileName = [batFileName, '.bat'];
end
aggDataFile = [mdlName, '_results'];
startTime = cputime;

Шаг 2. Создайте модель

Создайте исполняемый файл RSim для модели. Во время процесса сборки структурная контрольная сумма вычисляется для модели и встраивается в сгенерированный исполняемый файл. Эта контрольная сумма используется, чтобы проверять, что набор параметра, переданный исполняемому файлу, совместим с нею.

rtwbuild(mdlName);
### Starting build procedure for model: rtwdemo_rsim_vdp
### Successful completion of build procedure for model: rtwdemo_rsim_vdp

Шаг 3. Установите параметр по умолчанию для модели

Получите значение по умолчанию rtP структура (набор параметра) для модели. modelChecksum поле в rtP структуре является структурной контрольной суммой модели. Это должно совпадать с контрольной суммой, встроенной в исполняемый файл RSim (сгенерированный на шаге 2 выше). Если эти две контрольных суммы не будут соответствовать, исполняемый файл сгенерирует ошибку. rsimgetrtp генерирует rtP структуру с записями для именованных настраиваемых переменных INIT_X1, INIT_X2 и MU в модели.

rtp = rsimgetrtp(mdlName)
rtp = 

  struct with fields:

          modelChecksum: [1.7672e+09 23113875 4.2337e+09 2.4106e+09]
             parameters: [1x1 struct]
    globalParameterInfo: [1x1 struct]

Шаг 4. Создайте наборы параметра

Используя rtp структуру от шага 4, мы создаем массив структур с различными значениями для настраиваемых переменных в модели. Как отмечалось ранее, в этом примере мы хотим, чтобы видеть, как траектории состояния развиваются для различных начальных значений для состояний x1 и x2 в модели. Следовательно мы генерируем различные наборы параметра с различными значениями для INIT_X1 и INIT_X2 и оставляем настраиваемую переменную MU в значении по умолчанию.

INIT_X1_vals = -5:1:5;
INIT_X2_vals = -5:1:5;
MU_vals = 1;
nPrmSets = length(INIT_X1_vals)*length(INIT_X2_vals)*length(MU_vals)
nPrmSets =

   121

Обратите внимание на то, что в этом примере у нас есть nPrmSets наборы параметра, т.е. мы должны запустить это много симуляций. Инициализируйте aggData, который является массивом структур, используемым, чтобы содержать набор параметра и соответствующие результаты.

aggData = struct('tout', [], 'yout', [], ...
                'prms', struct('INIT_X1',[],'INIT_X2',[], 'MU', []))
aggData = repmat(aggData, nPrmSets, 1);
aggData = 

  struct with fields:

    tout: []
    yout: []
    prms: [1x1 struct]

Служебная функция rsimsetrtpparam является удобным способом создать rtP структуру путем добавления наборов параметра по одному с различными значениями параметров.

idx = 1;
for iX1 = INIT_X1_vals
    for iX2 = INIT_X2_vals
        for iMU = MU_vals
            rtp = rsimsetrtpparam(rtp,idx,'INIT_X1',iX1,'INIT_X2',iX2,'MU',iMU);
            aggData(idx).prms.INIT_X1 = iX1;
            aggData(idx).prms.INIT_X2 = iX2;
            aggData(idx).prms.MU      = iMU;
            idx = idx + 1;
        end
    end
end

Сохраните rtP массив структур с наборами параметра к MAT-файлу.

save(prmFileName,'rtp');

Шаг 5. Создайте пакетный файл

Мы создаем файл пакета/скрипта, чтобы запустить исполняемый файл RSim по наборам параметра. Каждое выполнение читает заданный набор параметра из MAT-файла параметра и пишет результаты в заданный выходной MAT-файл. Обратите внимание на то, что мы используем время опция так, чтобы, если конкретное выполнение должно было зависнуть (потому что модель может иметь особенность, для которой конкретный параметр установил), мы прервали выполнявшийся, предел требуемого времени превышен, и перейдите к следующему запуску.

Например, команда (на Windows®)

  model.exe -p prm.mat@3 -o run3.mat -L 3600 2>&1>> run.log

задает использование третьего набора параметра от rtP структуры в prm.mat, запись результатов к run3.mat и прерывания выполнения, если выполнение занимает больше времени, чем 3 600 секунд процессорного времени. Кроме того, сообщения из model.exe, в то время как это запускается, передаются по каналу к run.log. В случае проблем мы можем посмотреть на run.log, чтобы помочь отладить.

fid = fopen(batFileName, 'w');
idx = 1;
for iX1 = INIT_X1_vals
    for iX2 = INIT_X2_vals
        for iMU = MU_vals
            outMatFile = [mdlName, '_run',num2str(idx),'.mat'];
            cmd = [exeFileName, ...
                   ' -p ', prmFileName, '@', int2str(idx), ...
                   ' -o ', outMatFile, ...
                   ' -L 3600'];
            if ispc
                cmd  = [cmd, ' 2>&1>> ', logFileName];
            else % (unix)
                cmd  = ['.' filesep cmd, ' 1> ', logFileName, ' 2>&1'];
            end
            fprintf(fid, ['echo "', cmd, '"\n']);
            fprintf(fid, [cmd, '\n']);
            idx = idx + 1;
        end
    end
end
if isunix,
    system(['touch ', logFileName]);
    system(['chmod +x ', batFileName]);
end
fclose(fid);

Создание пакетного файла, чтобы запустить симуляции позволяет нам вызвать системную команду однажды, чтобы запустить симуляции (или даже запустить сценарий пакетной обработки вне MATLAB®) вместо того, чтобы вызвать системную команду в цикле для каждой симуляции. Это приводит к повышению производительности, потому что системная команда имеет значительные издержки.

Шаг 6. Выполните пакетный файл, чтобы запустить симуляции

Запустите файл пакета/скрипта, который запускает исполняемый файл RSim однажды для каждого набора параметра и сохраняет результаты в различный MAT-файл каждый раз. Обратите внимание на то, что этот пакетный файл может быть запущен от вне MATLAB®.

[stat, res] = system(['.' filesep batFileName]);
if stat ~= 0
    error(['Error running batch file ''', batFileName, ''' :', res]);
end

В этом примере мы помещаем симуляцию, сталкивается с одним пакетным файлом, запустил пакетный файл, чтобы последовательно запустить 'n' симуляции по 'n' наборам параметра. Для вашего приложения этот скрипт может быть изменен, чтобы сгенерировать несколько пакетных файлов, и эти пакетные файлы запущены параллельно путем распределения их на нескольких компьютерах. Также пакетные файлы могут быть запущены, не запуская MATLAB®.

Шаг 7. Загрузите Выходные MAT-файлы и сопоставьте результаты

Здесь мы собираем результаты симуляции из выходных MAT-файлов в aggData структуру. Если выходной MAT-файл, соответствующий конкретному выполнению, не найден, мы устанавливаем результаты, соответствующие тому выполнению быть NaN (не номер). Эта ситуация может произойти, если симуляция, запущенная с определенным набором параметров, сталкивается с особенностями в модели.

idx = 1;
for iX1 = INIT_X1_vals
    for iX2 = INIT_X2_vals
        for iMU = MU_vals
            outMatFile = [mdlName, '_run',num2str(idx),'.mat'];
            if exist(outMatFile,'file')
                load(outMatFile);
                aggData(idx).tout = rt_tout;
                aggData(idx).yout = rt_yout;
            else
                aggData(idx).tout = nan;
                aggData(idx).yout = nan;
            end
            idx = idx + 1;
        end
    end
end

Сохраните aggData структуру в MAT-файл результатов. На данном этапе можно удалить другие MAT-файлы, когда aggData структура данных содержит агрегацию входа (наборы параметров) и выходные данные (результаты симуляции).

save(aggDataFile,'aggData');
disp(['Took ', num2str(cputime-startTime), ...
      ' seconds to generate results from ', ...
      num2str(nPrmSets), ' simulation runs (Steps 2 to 7).']);
Took 19.93 seconds to generate results from 121 simulation runs (Steps 2 to 7).

Шаг 8. Анализируйте результаты симуляции

У нас теперь есть данные, чтобы построить схему фазы (X2 по сравнению с X1) с различными начальными значениями для x1 и x2. Схема показывает, что независимо от начального условия Осциллятор Ван дер Поля сходится к своему естественному режиму осциллятора.

colors = {'b','g','r','c','m','y','k'}; nColors = length(colors);
for idx = 1:nPrmSets
    col = colors{idx - nColors*floor(idx/nColors) + 1};
    plot(aggData(idx).prms.INIT_X1, aggData(idx).prms.INIT_X2, [col,'x'], ...
         aggData(idx).yout(:,1), aggData(idx).yout(:,2),col);
    hold on
end
grid on
xlabel('X1');
ylabel('X2');
axis('square');
title('Phase diagram for Van der Pol equation');