exponenta event banner

Советы по работе с несколькими моделированиями

Цель этой демонстрации - предоставить полезные советы по выполнению нескольких симуляций с помощью инструментов параллельного моделирования. Этот пример будет работать, даже если Toolbox™ параллельных вычислений недоступен, но моделирование будет выполняться последовательно. Для этого примера мы будем использовать sldemo_suspn_3dof модели.

mdl = 'sldemo_suspn_3dof';
isModelOpen = bdIsLoaded(mdl);
open_system(mdl);

Инициализация множества Simulink. Объекты SimulationInput

Как правило, для выполнения нескольких моделирований создается массив объектов Simulink.ImentionInput. Существует несколько способов инициализации массива перед его заполнением данными.

numSims = 5;
Cf_sweep = Cf*linspace(.05,.95, numSims);

Метод 1: Инициализация массива перед циклом

in(numSims) = Simulink.SimulationInput;
for idx = 1:numSims
    % Need to populate the model name since we get any empty array by default
    in(idx).ModelName = 'sldemo_suspn_3dof';
    in(idx) = in(idx).setVariable('Cf', Cf_sweep(idx));
end

Метод 2: Инициализация массива в цикле

Обратите внимание, что переменная цикла idx начинается с наибольшего значения, чтобы весь массив был предварительно выделен.

for idx = numSims:-1:1
    % Since we are indexing from 5 to 1, the first iteration will
    % initialize the array.
    in(idx) = Simulink.SimulationInput('sldemo_suspn_3dof');
    in(idx) = in(idx).setVariable('Cf', Cf_sweep(idx));
end

Настройка параметров модели и блока

setModelParameter и setBlockParameter методы используют тот же синтаксис пары параметр-значение, что и set_param API использует. Это означает, что большинство значений, передаваемых этим методам, должны быть массивами символов, а не их литеральными значениями.

for idx = numSims:-1:1
    in(idx) = Simulink.SimulationInput('sldemo_suspn_3dof');

    % Incorrect
    in(idx) = in(idx).setModelParameter('StartTime', 5);

    % Correct
    in(idx) = in(idx).setModelParameter('StartTime', '3');
end

Установка переменных

setVariable метод ожидает, что значение литерала будет передано переменной. Идея в том, что это близко отражает assignin синтаксис.

for idx = numSims:-1:1
    in(idx) = Simulink.SimulationInput('sldemo_suspn_3dof');

    % Incorrect, Cf is expected to be a double, not a character array
    in(idx) = in(idx).setVariable('Cf', '2500');

    % Correct, Cf is a scalar double
    in(idx) = in(idx).setVariable('Cf', 2500);
end

Диагностика ошибок во время выполнения

Предположим, что вы случайно настроили массив объектов Simulink.Input с неверным значением.

Mb_sweep = linspace(0, 1500, numSims);
for idx = numSims:-1:1
    in(idx) = Simulink.SimulationInput('sldemo_suspn_3dof');

    % Accidentally set the Mass to 0 on the first iteration
    in(idx) = in(idx).setVariable('Mb', Mb_sweep(idx));

    % Shorten the stop time
    in(idx) = in(idx).setModelParameter('StopTime','1');
end

Их моделирование приведет к ошибке во время выполнения

out = sim(in);
[05-May-2020 13:22:50] Running simulations...
[05-May-2020 13:22:51] Completed 1 of 5 simulation runs. Run 1 has errors.
[05-May-2020 13:22:52] Completed 2 of 5 simulation runs
[05-May-2020 13:22:53] Completed 3 of 5 simulation runs
[05-May-2020 13:22:54] Completed 4 of 5 simulation runs
[05-May-2020 13:22:55] Completed 5 of 5 simulation runs
Warning: Simulation(s) with indices listed below completed with errors. Please
inspect the corresponding SimulationOutput to get more details about the error:
[1] 

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

out(1).ErrorMessage
ans =

    'Derivative of state '1' in block '<a href="matlab:open_and_hilite_hyperlink ('sldemo_suspn_3dof/Body Dynamics/Vertical (Z) dynamics/Zdot','error')">sldemo_suspn_3dof/Body Dynamics/Vertical (Z) dynamics/Zdot</a>' at time 0.0 is not finite. The simulation will be stopped. There may be a singularity in the solution.  If not, try reducing the step size (either by reducing the fixed step size or by tightening the error tolerances)'

Это также работает для отладки проблем на параллельных рабочих.

for idx = numSims:-1:1
    in(idx) = Simulink.SimulationInput('sldemo_suspn_3dof');

    % Accidentally set the Mass to 0 on the first iteration
    in(idx) = in(idx).setVariable('Mb', Mb_sweep(idx));

    % Shorten the stop time
    in(idx) = in(idx).setModelParameter('StopTime','1');
end

out = parsim(in);
[05-May-2020 13:22:55] Checking for availability of parallel pool...
Starting parallel pool (parpool) using the 'local' profile ...
Connected to the parallel pool (number of workers: 6).
[05-May-2020 13:23:24] Starting Simulink on parallel workers...
[05-May-2020 13:23:47] Configuring simulation cache folder on parallel workers...
[05-May-2020 13:23:48] Loading model on parallel workers...
[05-May-2020 13:24:04] Running simulations...
[05-May-2020 13:24:10] Completed 1 of 5 simulation runs. Run 1 has errors.
[05-May-2020 13:24:12] Completed 2 of 5 simulation runs
[05-May-2020 13:24:12] Completed 3 of 5 simulation runs
[05-May-2020 13:24:12] Completed 4 of 5 simulation runs
[05-May-2020 13:24:12] Completed 5 of 5 simulation runs
Warning: Simulation(s) with indices listed below completed with errors. Please
inspect the corresponding SimulationOutput to get more details about the error:
[1] 
[05-May-2020 13:24:12] Cleaning up parallel workers...

При осмотре Simulink.ColeOutput обнаруживается ошибка неокончательной производной.

out(1).ErrorMessage
ans =

    'Derivative of state '1' in block 'sldemo_suspn_3dof/Body Dynamics/Vertical (Z) dynamics/Zdot' at time 0.0 is not finite. The simulation will be stopped. There may be a singularity in the solution.  If not, try reducing the step size (either by reducing the fixed step size or by tightening the error tolerances)'

applyToModel будет выполнена настройка модели с настройками на панели ввода, чтобы можно было выполнить локальную отладку проблемы.

in(1).applyToModel;

Обратите внимание, что значение переменной Mb в базовой рабочей области изменяется на 0, чтобы отразить значение, которое было использовано в моделировании, соответствующем первому объекту Input в in.

Закрыть работников MATLAB

Наконец, закройте параллельный пул и модель, если они не были открыты ранее.

if(~isModelOpen)
    close_system(mdl, 0);
end
delete(gcp('nocreate'));