С помощью определенных функций Simulink Compiler можно регистрировать обратные вызовы во время моделирования. simulink.compiler.setExternalInputsFcn и simulink.compiler.setExternalOutputsFcn функции позволяют задавать значения в корневых блоках ввода и получать значения в корневых блоках вывода на каждом шаге моделирования. С помощью simulink.compiler.setPostStepFcn можно зарегистрировать обратный вызов, вызываемый после каждого шага моделирования, используя его для постобработки выходных данных.
В следующем примере используется simulink.compiler.setExternalOutputsFcn и simulink.compiler.setPostStepFcn, для обеспечения текущего отслеживания результатов моделирования.
В этом примере показано приложение, которое использует обратные вызовы для входных и выходных данных моделирования для просмотра моделирования модели Simulink системы Lorenz, а затем развертывается с помощью компилятора Simulink
Открытие и проверка файла проекта
В этом примере мы используем Simulink Project, который содержит все файлы, необходимые для выполнения этого примера. Проект содержит модель Simulink системы Лоренца и приложение MATLAB, созданное в App Designer, которое моделирует модель с различными входными и выходными значениями. Дополнительные сведения о создании приложения с помощью App Designer см. в разделе Создание и запуск простого приложения с помощью App Designer.
simulink.compiler.example.LorenzSystem


Сведения о приложении
Откройте окно mlapp файл. Код, написанный для создания этого приложения, можно просмотреть в разделе «Просмотр кода» конструктора приложений. Важной частью этого приложения является поведение кнопки Simulate. Он имеет следующие важные детали: создание SimulationInput объект, конфигурируя его для развертывания, используя обратные вызовы моделирования для считывания данных выходного порта и построения графика данных на каждом шаге времени. В следующем разделе объясняется, как эти три функции используются для просмотра результатов моделирования в развернутом приложении
Создание Simulink.SimulationInput объект
В функции createSimulationInput, мы определяем пустой Simulink.SimulationInput объект для модели. Мы используем это Simulink.SimulationInput установка обратных вызовов моделирования и переменных для моделирования модели.
Функции имитационного обратного вызова используются для регистрации обратного вызова. simulink.compiler.setPostStepFcn регистрирует обратный вызов, вызываемый после каждого шага моделирования. simulink.compiler.setExternalOuputsFcn регистрирует обратный вызов, который динамически обрабатывает значения для каждого выходного порта на корневом уровне модели во время моделирования.
Мы используем setVariable способ Simulink.SimulationInput объект для предоставления значений параметров приложению. Эти значения для моделирования получены из полей редактирования пользовательского интерфейса приложения. Чтобы включить развертывание приложения, мы используем simulink.compiler.configureForDeployment функция. (Комментировать строку кода, которая вызывает simulink.compiler.configureForDeployment функция для более быстрой отладки)
function simInp = createSimulationInput(app) % Create an empty SimulationInput object simInp = Simulink.SimulationInput('LorenzSystemModel'); % Specify the simulation callbacks simInp = simulink.compiler.setPostStepFcn(simInp, @app.postStepFcn); simInp = simulink.compiler.setExternalOutputsFcn(simInp, @app.processOutputs); % Load the parameters values from the ui edit fields simInp = simInp.setVariable('rho',app.rhoUIC.Value); simInp = simInp.setVariable('beta',app.betaUIC.Value); simInp = simInp.setVariable('sigma',app.sigmaUIC.Value); simInp = simInp.setVariable('x0',app.x0UIC.Value); simInp = simInp.setVariable('y0',app.y0UIC.Value); simInp = simInp.setVariable('z0',app.z0UIC.Value); % Configure simInp for deployment % DEBUG TIP: Comment out the line below for % faster/easier debugging when runnng in MATLAB simInp = simulink.compiler.configureForDeployment(simInp); end % createSimulationInput
Функции имитационного обратного вызова
Функции имитационного обратного вызова регистрируют обратные вызовы, что позволяет считывать значения из выходных портов и записывать значения в корневые входные порты. Эти функции регистрируют обратные вызовы на каждом этапе моделирования, позволяя просматривать результаты моделирования в реальном времени.
Обратный вызов processOutputs
simulink.compiler.setExternalOutputsFcn строка относится к функции postprocressOuputs. Это функция обратного вызова, которая обрабатывает значения для каждого корневого блока выходного порта модели во время моделирования. postprocressOuputs вызывается один раз для каждого порта и по времени выборки порта. Когда postprocressOuputs вызывается функция, считывает значения для каждого корневого блока исходящего трафика и кэширует эти значения. postStepFcn получает кэшированные значения для обновления графика.
function processOutputs(app, opIdx, ~, data) % Called during sim to process the external output port data, % will be called once per port per its sample hit. switch opIdx case 1 app.txyzBuffer.x = data; case 2 app.txyzBuffer.y = data; case 3 app.txyzBuffer.z = data; otherwise error(['Invalid port index: ', num2str(opIdx)]); end end
Обратный вызов PostStepFcn
postStepFcn является функцией обратного вызова, которая вызывается после каждого шага моделирования. Аргумент time - это время для предыдущего этапа моделирования. Эта функция получает кэшированные значения блоков исходящего трафика для каждого time, и передает эти значения в updateTrace для построения графика кэшированных значений во время моделирования.
function postStepFcn(app, time) % Called during sim after each simulation time step app.updateSimStats(time); if app.status == AppStatus.Starting app.switchStatus(AppStatus.Running); app.simStats.WallClockTimeAfterFirstStep = tic; end if app.stopRequested app.switchStatus(AppStatus.Stopping); stopRequestedID = [mfilename('class'), ':StopRequested']; throw(MException(stopRequestedID, 'Stop requested')); end %-------------------------------------------------------------- app.txyzBuffer.t = time; x = [app.txyzBuffer.x]; y = [app.txyzBuffer.y]; z = [app.txyzBuffer.z]; app.updateTrace(x, y, z); app.updateMarker('head', x, y, z); %-------------------------------------------------------------- drawnow limitrate; end % postStepFcn
Тестирование приложения в App Designer
Перед развертыванием приложения убедитесь, что оно работает в App Designer. Щелкните Смоделировать (Simulate), чтобы проверить работу приложения путем моделирования модели для различных значений.
Скомпилировать приложение для развертывания
. Для компиляции и развертывания приложения можно использовать конструктор приложений MATLAB. deploytool. Дополнительные сведения о компиляции и развертывании с помощью App Designer см. в разделе Разработка приложений с помощью App Designer, Web Apps и компилятора приложений.
В этом примере мы компилируем приложение с помощью mcc за командой следует имя приложения.
mcc -m LorenzSystemApp
configureForDeployment | deploytool | mcc | sim | simulink.compiler.genapp | simulink.compiler.setExternalInputsFcn | simulink.compiler.setExternalOutputsFcn | simulink.compiler.setPostStepFcn | Simulink.SimulationInput