Тестируйте числовую эквивалентность между компонентами модели и производственным кодом, которые вы генерируете из компонентов с помощью симуляций «цикл» (SIL) и «цикл» (PIL).
С помощью SIL симуляции, вы тестируете исходный код на вашем компьютере разработчика. С помощью PIL симуляции вы тестируете скомпилированный код объекта, который вы намерены развернуть в производстве, запустив код объекта на реальном целевом компьютере или симуляторе процессора. Чтобы определить, являются ли компоненты модели и сгенерированный код численно эквивалентными, сравните результаты SIL и PIL с результатами режима normal mode.
Существует три способа выполнения SIL и PIL симуляций. Можно использовать верхнюю модель, блоки Model или блоки SIL и PIL, которые вы создаете из подсистемы. См. раздел Выбор SIL или PIL-подхода.
Прежде чем вы сможете запустить PIL симуляции, необходимо сконфигурировать целевое подключение. Целевое строение подключения позволяет PIL симуляции:
Создайте целевое приложение.
Загрузите, запустите и остановите приложение на цели.
Поддержка связи между Simulink и целью.
Для создания целевого строения подключения можно использовать поставляемый целевой API подключения. Для получения дополнительной информации смотрите Создание целевого Строения подключения PIL для Simulink.
Для поддерживаемого оборудования можно использовать целевые пакеты поддержки. Для получения дополнительной информации смотрите Embedded Coder Поддерживаемых аппаратных средств.
Протестируйте сгенерированный код модели путем запуска SIL или PIL симуляции верхней модели. С помощью этого подхода:
Вы тестируете код, сгенерированный из верхней модели, которая использует автономный интерфейс кода.
Вы конфигурируете модель, чтобы загрузить тестовые векторы или входные входы стимула из рабочего пространства MATLAB.
Можно легко переключить верхнюю модель между нормальным, SIL и PIL режимами симуляции.
Откройте модель верхней части простого счетчика.
model='rtwdemo_sil_topmodel';
close_system(model,0)
open_system(model)
Чтобы сосредоточиться на численной проверке эквивалентности, отключите:
Покрытие модели
Покрытие кода
Профилирование времени выполнения
set_param(gcs, 'RecordCoverage','off'); coverageSettings = get_param(model, 'CodeCoverageSettings'); coverageSettings.CoverageTool='None'; set_param(model, 'CodeCoverageSettings',coverageSettings); set_param(model, 'CodeExecutionProfiling','off');
Сконфигурируйте входные данные стимула.
[ticks_to_count, reset, counter_mode, count_enable] = ...
rtwdemo_sil_topmodel_data(T);
Сконфигурируйте опции регистрации в модели.
set_param(model, 'LoadExternalInput','on'); set_param(model, 'ExternalInput','ticks_to_count, reset, counter_mode, count_enable'); set_param(model, 'SignalLogging', 'on'); set_param(model, 'SignalLoggingName', 'logsOut'); set_param(model, 'SaveOutput','on')
Запустите симуляцию режима normal mode.
set_param(model,'SimulationMode','normal') sim_output = sim(model,10); yout_normal = [sim_output.yout.signals(1).values sim_output.yout.signals(2).values];
Запустите SIL симуляцию топовой модели.
set_param(model,'SimulationMode','Software-in-the-Loop (SIL)') sim_output = sim(model,10); yout_sil = [sim_output.yout.signals(1).values sim_output.yout.signals(2).values];
### Starting build procedure for: rtwdemo_sil_topmodel ### Successful completion of build procedure for: rtwdemo_sil_topmodel Build Summary Top model targets built: Model Action Rebuild Reason ===================================================================================================== rtwdemo_sil_topmodel Code generated and compiled Code generation information file does not exist. 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 7.7618s ### Preparing to start SIL simulation ... Building with 'gcc'. MEX completed successfully. ### Updating code generation report with SIL files ... ### Starting SIL simulation for component: rtwdemo_sil_topmodel ### Stopping SIL simulation for component: rtwdemo_sil_topmodel
Если актуальный код для этой модели не существует, новый код генерируется и компилируется. Сгенерированный код запускается как отдельный процесс на вашем компьютере.
Постройте и сравните результаты нормали и SIL симуляций. Заметьте, что результаты совпадают.
fig1 = figure; subplot(3,1,1), plot(yout_normal), title('Counter Output for Normal Simulation') subplot(3,1,2), plot(yout_sil), title('Counter Output for SIL Simulation') subplot(3,1,3), plot(yout_normal-yout_sil), ... title('Difference Between Normal and SIL');
Очистить.
close_system(model,0); if ishandle(fig1), close(fig1), end clear fig1 simResults = {'yout_sil','yout_normal','model','T',... 'ticks_to_count','reset'}; save([model '_results'],simResults{:}); clear(simResults{:},'simResults')
Протестируйте сгенерированный код модели с помощью модели тестовой обвязки, которая запускает блок Model в режиме SIL. С помощью этого подхода:
Можно протестировать код, который генерируется из верхней части или модели-ссылки. Код из верхней модели использует автономный интерфейс кода. Код из модели-ссылки использует интерфейс кода модели-ссылки. Для получения дополнительной информации смотрите Интерфейсы кода для SIL и PIL.
Вы используете модель тестовой обвязки или системную модель, чтобы предоставить тестовый вектор или входы стимула.
Можно легко переключить блок Model между нормальным, SIL и PIL симуляция режимами.
Откройте пример модели, которая имеет два блока Model, которые ссылаются на одну и ту же модель. В симуляции вы запускаете один блок Model в режиме SIL и другой блок Model в режим normal mode.
model='rtwdemo_sil_modelblock';
open_system(model);
Выключить:
Покрытие кода
Профилирование времени выполнения
coverageSettings = get_param(model, 'CodeCoverageSettings'); coverageSettings.CoverageTool='None'; set_param(model, 'CodeCoverageSettings',coverageSettings); open_system('rtwdemo_sil_modelblock') set_param('rtwdemo_sil_modelblock', 'CodeExecutionProfiling','off'); open_system('rtwdemo_sil_counter') set_param('rtwdemo_sil_counter', 'CodeExecutionProfiling','off'); currentFolder=pwd; save_system('rtwdemo_sil_counter', fullfile(currentFolder,'rtwdemo_sil_counter.slx'))
Сконфигурируйте логгирование состояний для моделей.
set_param('rtwdemo_sil_counter', 'SaveFormat','Dataset'); save_system('rtwdemo_sil_counter', fullfile(currentFolder,'rtwdemo_sil_counter.slx')) set_param(model, 'SaveFormat','Dataset'); set_param(model, 'SaveState','on'); set_param(model, 'StateSaveName', 'xout');
Тестирование кода верхней модели
Для блока Model в режиме SIL задайте генерацию кода верхней модели, который использует автономный интерфейс кода.
set_param([model '/CounterA'], 'CodeInterface', 'Top model');
Запустите симуляцию модели тестовой обвязки.
out = sim(model,20);
### Starting build procedure for: rtwdemo_sil_counter ### Successful completion of build procedure for: rtwdemo_sil_counter Build Summary Top model targets built: Model Action Rebuild Reason ==================================================================================================== rtwdemo_sil_counter Code generated and compiled Code generation information file does not exist. 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 6.8073s ### Preparing to start SIL simulation ... Building with 'gcc'. MEX completed successfully. ### Updating code generation report with SIL files ... The top model "rtwdemo_sil_modelblock" is configured to load initial state and / or save states (see Data Import/Export configuration parameters). However, the SIL or PIL component "rtwdemo_sil_modelblock/CounterA" does not expose any states to Simulink and therefore cannot participate in state initialization or logging. ### Starting SIL simulation for component: rtwdemo_sil_counter ### Stopping SIL simulation for component: rtwdemo_sil_counter
Блок модели в режиме SIL запускается как отдельный процесс на вашем компьютере. В рабочей папке отображается, что автономный код генерируется для ссылочной модели, если не существует сгенерированного кода из предыдущей сборки.
Сравните поведение блоков Model в режиме normal и SIL. Результаты совпадают.
yout = out.logsOut; yout_sil = yout.get('counterA').Values.Data; yout_normal = yout.get('counterB').Values.Data; fig1 = figure; subplot(3,1,1), plot(yout_normal), title('Counter Output for Normal Simulation') subplot(3,1,2), ... plot(yout_sil), title('Counter Output for Model Block SIL (Top-Model) Simulation') subplot(3,1,3), plot(yout_normal-yout_sil), ... title('Difference Between Normal and SIL');
Сравните записанные состояния блоков Model из симуляций normal и SIL mode.
xout = out.xout; xout_sil = xout{1}.Values.Data; xout_normal = xout{2}.Values.Data; fig1 = figure; subplot(3,1,1), plot(xout_sil), title('State Logging for Normal Simulation') subplot(3,1,2), ... plot(xout_normal), title('State Logging for Model Block SIL (Top-Model) Simulation') subplot(3,1,3), plot(xout_normal-xout_sil), ... title('Difference Between Normal and SIL');
Экспериментальная модель
Для блока Model в режиме SIL задайте генерацию ссылочного кода модели, который использует интерфейс кода модели-ссылки.
set_param([model '/CounterA'], 'CodeInterface', 'Model reference');
Запустите симуляцию модели тестовой обвязки.
out2 = sim(model,20);
### Starting serial model reference code generation build ### Starting build procedure for: rtwdemo_sil_counter ### Successful completion of build procedure for: rtwdemo_sil_counter Build Summary Code generation targets built: Model Action Rebuild Reason ========================================================================================= rtwdemo_sil_counter Code generated and compiled rtwdemo_sil_counter.c does not exist. 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 5.7616s ### Preparing to start SIL simulation ... Building with 'gcc'. MEX completed successfully. ### Updating code generation report with SIL files ... The top model "rtwdemo_sil_modelblock" is configured to load initial state and / or save states (see Data Import/Export configuration parameters). However, the SIL or PIL component "rtwdemo_sil_modelblock/CounterA" does not expose any states to Simulink and therefore cannot participate in state initialization or logging. ### Starting SIL simulation for component: rtwdemo_sil_counter ### Stopping SIL simulation for component: rtwdemo_sil_counter
Блок модели в режиме SIL запускается как отдельный процесс на вашем компьютере. В рабочей папке видно, что модель-ссылка код генерируется, если не существует кода из предыдущей сборки.
Сравните поведение блоков Model в режиме normal и SIL. Результаты совпадают.
yout2 = out2.logsOut; yout2_sil = yout2.get('counterA').Values.Data; yout2_normal = yout2.get('counterB').Values.Data; fig1 = figure; subplot(3,1,1), plot(yout2_normal), title('Counter Output for Normal Simulation') subplot(3,1,2), ... plot(yout2_sil), title('Counter Output for Model Block SIL (Model Reference) Simulation') subplot(3,1,3), plot(yout2_normal-yout2_sil), ... title('Difference Between Normal and SIL');
Сравните записанные состояния блоков Model из симуляций normal и SIL mode.
xout2 = out.xout; xout2_sil = xout2{1}.Values.Data; xout2_normal = xout2{2}.Values.Data; fig1 = figure; subplot(3,1,1), plot(xout2_sil), title('State Logging for Normal Simulation') subplot(3,1,2), ... plot(xout2_normal), title('State Logging for Model Block SIL (Model Reference) Simulation') subplot(3,1,3), plot(xout2_normal-xout2_sil), ... title('Difference Between Normal and SIL');
Очистить.
close_system(model,0); if ishandle(fig1), close(fig1), end, clear fig1 simResults={'out','yout','yout_sil','yout_normal', ... 'out2','yout2','yout2_sil','yout2_normal', ... 'SilCounterBus','T','reset','ticks_to_count','Increment'}; save([model '_results'],simResults{:}); clear(simResults{:},'simResults')
Протестируйте сгенерированный код подсистемы с помощью блока SIL или PIL в симуляции. С помощью этого подхода:
Вы тестируете код, сгенерированный из подсистем, которые используют автономный интерфейс кода.
Вы предоставляете тестовую обвязку или системную модель для подачи тестового вектора или стимулирующих входов.
Исходная подсистема заменяется сгенерированным блоком SIL или PIL.
Откройте простую модель, которая состоит из алгоритма управления и модели объекта управления в замкнутом цикле. Алгоритм управления регулирует выход от объекта управления.
model='rtwdemo_sil_block';
close_system(model,0)
open_system(model)
Запустите симуляцию режима normal mode
out = sim(model,10);
yout_normal = out.yout;
clear out
Сконфигурируйте процесс сборки, чтобы создать блок SIL для проверки.
set_param(model,'CreateSILPILBlock','SIL');
Чтобы протестировать поведение на производственном оборудовании, задайте блок PIL.
Чтобы создать блок SIL, сгенерируйте код для подсистемы алгоритма управления. Блок SIL отображается в конце процесса сборки. Его входные и выходные порты совпадают с портами подсистемы алгоритма управления.
close_system('untitled',0); slbuild([model '/Controller'])
### Starting build procedure for: Controller ### Successful completion of build procedure for: Controller ### Creating SIL block ... Building with 'gcc'. MEX completed successfully. Build Summary Top model targets built: Model Action Rebuild Reason =========================================================================================== Controller Code generated and compiled Code generation information file does not exist. 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 12.063s
Также можно щелкнуть правой кнопкой мыши подсистему и выбрать C/C + + код > Build This Subsystem. В открывшемся диалоговом окне нажмите кнопку «Создать».
Чтобы выполнить SIL симуляцию контроллера и модели объекта управления в закрытом цикле, замените исходный алгоритм управления на новый блок SIL. Чтобы избежать потери исходной подсистемы, не сохраняйте модель в этом состоянии.
controllerBlock = [model '/Controller']; blockPosition = get_param(controllerBlock,'Position'); delete_block(controllerBlock); add_block('untitled/Controller',[controllerBlock '(SIL)'],... 'Position', blockPosition); close_system('untitled',0); clear controllerBlock blockPosition
Запустите SIL симуляцию.
out = sim(model,10);
### Preparing to start SIL block simulation: rtwdemo_sil_block/Controller(SIL) ... ### Starting SIL simulation for component: rtwdemo_sil_block ### Stopping SIL simulation for component: rtwdemo_sil_block
Алгоритм управления использует арифметику с одной точностью и плавающей точкой. Можно ожидать, что порядок величины для различий между SIL и нормальными симуляциями будет близок к точности машины для данных с одной точностью.
Задайте допуск ошибки для результатов SIL симуляции, который основан на точности машины для нормальных результатов симуляции с одной точностью.
machine_precision = eps(single(yout_normal)); tolerance = 4 * machine_precision;
Сравнение результатов моделирования нормали и SIL. На третьем графике различия между симуляциями находятся хорошо в пределах заданного допуска ошибки.
yout_sil = out.yout; tout = out.tout; fig1 = figure; subplot(3,1,1), plot(yout_normal), title('Controller Output for Normal Simulation') subplot(3,1,2), plot(yout_sil), title('Controller Output for SIL Simulation') subplot(3,1,3), plot(tout,abs(yout_normal-yout_sil),'g-', tout,tolerance,'r-'), ... title('Normal and SIL Difference and Error Tolerance');
Очистить.
close_system(model,0); if ishandle(fig1), close(fig1), end clear fig1 simResults={'out','yout_sil','yout_normal','tout','machine_precision'}; save([model '_results'],simResults{:}); clear(simResults{:},'simResults')
Когда вы запускаете SIL симуляцию, необходимо сконфигурировать настройки аппаратной реализации (такие как нативные размеры слов), чтобы разрешить компиляцию для вашего компьютера разработчика. Эти настройки могут отличаться от настроек аппаратной реализации, которые вы используете при построении модели для вашего производственного оборудования. Чтобы избежать необходимости изменения настроек аппаратной реализации между SIL и PIL симуляциями, включите портативные размеры слов. Дополнительные сведения см. в разделе Настройка параметров аппаратной реализации.