Этот пример показывает, как использовать цель RSim, чтобы запустить симуляции в области значений значений параметров. Пример использует Осциллятор Ван дер Поля и выполняет развертку параметра в области значений значений начального состояния, чтобы получить схему фазы нелинейной системы.
Очень легко настроить этот пример для вашего собственного приложения путем изменения скрипта MATLAB®, используемого, чтобы создать этот пример. Щелкните по ссылке в левом верхнем угле этой страницы, чтобы отредактировать скрипт MATLAB®. Щелкните по ссылке в правом верхнем углу, чтобы запустить этот пример от MATLAB®. При выполнении этого примера убедитесь, что вы находитесь в перезаписываемой директории. Пример создает файлы, которые можно хотеть исследовать позже.
В данном примере поведение параметра По умолчанию установлено в Inlined
. В примере вы создаете объекты Simulink.Parameter
как настраиваемые параметры. Чтобы использовать RSim с набором поведения параметра По умолчанию к Tunable
, и явным образом не объявляя настраиваемые параметры, смотрите Симуляции Пакета Выполнения, Не Перекомпилировав Сгенерированный код.
Чтобы быстро запустить несколько симуляций в окружении Simulink, рассмотрите использование быстрого акселератора вместо RSim. Для получения информации о быстром акселераторе смотрите то, Что Ускорение? (Simulink). Чтобы развернуть значения параметров, смотрите, Оптимизируют, Оценка и Значения Параметров блоков Развертки (Simulink).
Убедитесь, что текущий каталог перезаписываем, потому что этот пример будет создавать файлы.
[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;
Создайте исполняемый файл RSim для модели. Во время процесса сборки структурная контрольная сумма вычисляется для модели и встраивается в сгенерированный исполняемый файл. Эта контрольная сумма используется, чтобы проверять, что набор параметра, переданный исполняемому файлу, совместим с нею.
rtwbuild(mdlName);
### Starting build procedure for model: rtwdemo_rsim_vdp ### Successful completion of build procedure for model: rtwdemo_rsim_vdp
Получите значение по умолчанию 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]
Используя 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');
Мы создаем файл пакета/скрипта, чтобы запустить исполняемый файл 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®) вместо того, чтобы вызвать системную команду в цикле для каждой симуляции. Это приводит к повышению производительности, потому что системная команда имеет значительные издержки.
Запустите файл пакета/скрипта, который запускает исполняемый файл RSim однажды для каждого набора параметра и сохраняет результаты в различный MAT-файл каждый раз. Обратите внимание на то, что этот пакетный файл может быть запущен от вне MATLAB®.
[stat, res] = system(['.' filesep batFileName]); if stat ~= 0 error(['Error running batch file ''', batFileName, ''' :', res]); end
В этом примере мы помещаем симуляцию, сталкивается с одним пакетным файлом, запустил пакетный файл, чтобы последовательно запустить 'n' симуляции по 'n' наборам параметра. Для вашего приложения этот скрипт может быть изменен, чтобы сгенерировать несколько пакетных файлов, и эти пакетные файлы запущены параллельно путем распределения их на нескольких компьютерах. Также пакетные файлы могут быть запущены, не запуская MATLAB®.
Здесь мы собираем результаты симуляции из выходных 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).
У нас теперь есть данные, чтобы построить схему фазы (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');