Этот пример показывает, как сгенерировать код С для функции MATLAB, которую отслеживают обнаружения процессов и выходные параметры. Функция содержит trackerGNN
, но любое средство отслеживания может использоваться вместо этого.
Автоматическая генерация кода из кода MATLAB обладает двумя ключевыми преимуществами:
Прототипы могут быть разработаны и отлажены в среде MATLAB. Если работа MATLAB сделана, автоматическая генерация кода C делает алгоритмы развертываемыми на различных целях. Кроме того, код С может быть далее протестирован путем выполнения скомпилированного файла MEX в среде MATLAB с помощью тех же инструментов визуализации и анализа, которые были доступны во время фазы прототипирования.
После генерации кода С можно сгенерировать исполняемый код, который во многих случаях запускается быстрее, чем код MATLAB. Улучшенное время выполнения может использоваться, чтобы разработать и развернуть сплав датчика в реальном времени и системы слежения. Это также обеспечивает, лучший способ обработать в пакетном режиме тестируют системы слежения на большом количестве наборов данных.
Пример объясняет, как изменить код MATLAB в примере Управления воздушным движением, чтобы поддержать генерацию кода.
Этот пример требует лицензии MATLAB Coder на генерацию кода С.
Чтобы сгенерировать код С, MATLAB Coder требует, чтобы код MATLAB был в форме функции. Кроме того, аргументы функции не могут быть классами MATLAB.
В этом примере код для примера управления воздушным движением (ATC) был реструктурирован таким образом, что trackerGNN
, который выполняет сплав датчика и отслеживание, находится в отдельном файле, названном tracker_kernel.m
. Рассмотрите этот файл для важной информации о выделении памяти для генерации кода.
Чтобы сохранить состояние trackerGNN
между вызовами tracker_kernel.m
, средство отслеживания задано как переменная persistent
.
Эта функция берет массив ячеек объектов objectDection
, сгенерированных объектом monostaticRadarSensor
, и время как входные параметры.
Точно так же выходные параметры от функции, которая поддерживает генерацию кода, не могут быть объектами. Выходные параметры от tracker_kernel.m
:
Подтвержденные дорожки - массив struct
, который содержит переменное количество дорожек.
Количество дорожек - целочисленный скаляр.
Информация об обработке средства отслеживания при текущем обновлении.
Путем реструктуризации кода этот путь можно снова использовать те же инструменты отображения, используемые в примере ATC. Эти инструменты, все еще запущенные в MATLAB и, не требуют генерации кода.
% If a previous tracker is defined, clear it. clear tracker_kernel % Create the ATC scene with radar and platforms. [scenario,tower,radar] = helperCreateATCScenario; % Create a display to show the true, measured, and tracked positions of the % airliners. [theater,fig] = helperATCExample('Create Display',scenario,tower,radar); helperATCExample('Update Display',theater,scenario,tower,radar);
Теперь запустите пример путем вызывания функции tracker_kernel
в MATLAB. Это начальное выполнение обеспечивает базовую линию, чтобы сравнить результаты и позволяет вам собрать некоторые метрики о производительности средства отслеживания, когда это запускается в MATLAB или как файл MEX.
Следующий цикл совершенствует положения платформы до конца сценария. Для каждого шага вперед в сценарии радар генерирует обнаружения от целей в его поле зрения. Средство отслеживания обновляется с этими обнаружениями после того, как радар завершил 360 сканирований степени в азимуте.
% Set simulation to advance at the update rate of the radar. scenario.UpdateRate = radar.UpdateRate; % Create a buffer to collect the detections from a full scan of the radar. scanBuffer = {}; % Initialize the track array. tracks = []; % Set random seed for repeatable results. rng(2018) % Allocate memory for number of tracks and time measurement in MATLAB. numSteps = 12; numTracks = zeros(1, numSteps); runTimes = zeros(1, numSteps); index = 0; while advance(scenario) && ishghandle(fig) % Current simulation time. simTime = scenario.SimulationTime; % Target poses in the ATC's coordinate frame. targets = targetPoses(tower); % Use the tower's true position as its INS measurement. ins = pose(tower, 'true'); % Generate detections on targets in the radar's current field of view. [dets,~,config] = radar(targets,ins,simTime); scanBuffer = [scanBuffer;dets]; %#ok<AGROW> Allow the buffer to grow. % Update tracks when a 360 degree scan is complete. if config.IsScanDone % Update tracker index = index + 1; tic [tracks, numTracks(index), info] = tracker_kernel(scanBuffer,simTime); runTimes(index) = toc; % Gather MATLAB run time data % Clear scan buffer for next scan. scanBuffer = {}; end % Update display with current beam position, buffered detections, and % track positions. helperATCExample('Update Display',theater,scenario,tower,radar,scanBuffer,tracks); end
Используйте функцию codegen
, чтобы скомпилировать функцию tracker_kernel
в файл MEX. Можно задать опцию -report
, чтобы сгенерировать отчет компиляции, который показывает оригинальный код MATLAB и связанные файлы, которые были созданы во время генерации кода C. Рассмотрите создание временной директории, где MATLAB Coder может хранить сгенерированные файлы. Обратите внимание на то, что, если вы не используете опцию -o
, чтобы задать имя исполняемого файла, сгенерированный файл MEX имеет то же имя как исходный файл MATLAB с добавленным _mex
.
MATLAB Coder требует, чтобы вы задали свойства всех входных параметров. Входные параметры используются средством отслеживания, чтобы создать правильные типы данных и размеры для объектов, используемых в отслеживании. Типы данных и размеры не должны изменяться между кадрами данных. Один простой способ сделать это должно задать входные свойства на примере в командной строке с помощью опции -args
. Для получения дополнительной информации смотрите Входную Спецификацию.
% Define the properties of the input. First define the detections buffer as % a variable-sized cell array that contains objectDetection objects. Then % define the second argument as simTime, which is a scalar double. dets = coder.typeof(scanBuffer(1), [inf 1], [1 0]); compInputs = {dets simTime}; % Code generation may take some time. h = msgbox({'Generating code. This may take a few minutes...';'This message box will close when done.'},'Codegen Message'); % Generate code. try codegen tracker_kernel -args compInputs; close(h) catch ME close(h) delete(videoDisplayHandle.Parent.Parent) throw(ME) end
Теперь, когда код был сгенерирован, запустите тот же самый сценарий со сгенерированным файлом MEX tracker_kernel_mex
. Все остальное остается то же самое.
% If a previous tracker is defined, clear it. clear tracker_kernel_mex % Allocate memory for number of tracks and time measurement numTracksMex = zeros(1, numSteps); runTimesMex = zeros(1, numSteps); % Reset the scenario, data counter, plotters, scanBuffer, tracks, and rng. index = 0; restart(scenario) scanBuffer = {}; clearPlotterData(theater); tracks = []; rng(2018) while advance(scenario) && ishghandle(fig) % Current simulation time. simTime = scenario.SimulationTime; % Target poses in the ATC's coordinate frame. targets = targetPoses(tower); % Use the tower's true position as its INS measurement. ins = pose(tower, 'true'); % Generate detections on targets in the radar's current field of view. [dets,~,config] = radar(targets,ins,simTime); scanBuffer = [scanBuffer;dets]; %#ok<AGROW> Allow the buffer to grow. % Update tracks when a 360 degree scan is complete. if config.IsScanDone % Update tracker. index = index + 1; tic [tracks, numTracksMex(index), info] = tracker_kernel_mex(scanBuffer,simTime); runTimesMex(index) = toc; % Gather MEX run time data % Clear scan buffer for next scan. scanBuffer = {}; end % Update display with current beam position, buffered detections, and % track positions. helperATCExample('Update Display',theater,scenario,tower,radar,scanBuffer,tracks); end
Сравните результаты и производительность сгенерированного кода по сравнению с кодом MATLAB. Следующие графики сравнивают количество дорожек, сохраняемых средствами отслеживания на каждом временном шаге. Они также показывают количество времени, которое это заняло, чтобы обработать каждый вызов функции.
figure(2) subplot(2,1,1) plot(2:numSteps, numTracks(2:numSteps), 's:', 2:numSteps, numTracksMex(2:numSteps), 'x-.') title('Number of Tracks at Each Step'); legend('MATLAB', 'MEX') grid subplot(2,1,2) plot(2:numSteps, runTimesMex(2:numSteps)*1e3); title('MEX Processing Time at Each Step') grid xlabel('Time Step') ylabel('MEX Processing Time [ms]')
Главный график показывает, что количество дорожек, которые сохранялись каждым средством отслеживания, является тем же самым. Это измеряет размер проблемы отслеживания с точки зрения количества дорожек. Даже при том, что было 3 подтвержденных дорожки в примере отслеживания, общее количество всех дорожек, сохраняемых средством отслеживания, отличается на основе количества предварительных дорожек, которые были созданы ложными обнаружениями.
Нижний график показывает время, требуемое для функции сгенерированного кода обработать каждый шаг. Первый шаг был исключен из графика, потому что требуется непропорционально более длительное время, чтобы инстанцировать всех дорожек на первом шаге.
Результаты показывают количество миллисекунд, требуемых кодом MEX выполнять каждый шаг обновления на вашем компьютере. В этом примере время, требуемое для кода MEX запускать шаг обновления, измеряется в нескольких миллисекундах.
Этот пример показал, как сгенерировать код С из кода MATLAB для сплава датчика и отслеживания.
Основные преимущества автоматической генерации кода являются способностью моделировать в среде MATLAB и сгенерировать файл MEX, который может запуститься в среде MATLAB. Сгенерированный код C может быть развернут на цели. В большинстве случаев сгенерированный код быстрее, чем код MATLAB и может использоваться для пакетного тестирования алгоритмов и генерации систем слежения в реальном времени.