В этом примере показано, как создать код C для функции MATLAB, которая обрабатывает обнаруженные и выводимые дорожки. Функция содержит trackerGNN, но вместо него можно использовать любой трекер.
Автоматическое создание кода из кода MATLAB имеет два ключевых преимущества:
Прототипы могут быть разработаны и отлажены в среде MATLAB. После выполнения работы MATLAB автоматическое формирование кода C делает алгоритмы развертываемыми для различных целей. Кроме того, код C может быть дополнительно протестирован путем запуска скомпилированного файла MEX в среде MATLAB с использованием тех же средств визуализации и анализа, которые были доступны на этапе прототипирования.
После генерации кода C можно создать исполняемый код, который во многих случаях выполняется быстрее, чем код MATLAB. Улучшенное время работы может быть использовано для разработки и развертывания систем слияния и отслеживания датчиков в реальном времени. Это также обеспечивает лучший способ пакетного тестирования систем отслеживания на большом количестве наборов данных.
В примере поясняется, как изменить код MATLAB в примере управления воздушным движением для поддержки генерации кода. В этом примере для создания кода C требуется лицензия кодера MATLAB.
Для генерации кода C кодер MATLAB требует, чтобы код MATLAB имел форму функции. Кроме того, аргументами функции не могут быть классы MATLAB.
В этом примере код для примера управления воздушным движением (УВД) был реструктурирован таким образом, что trackerGNN который выполняет слияние датчиков и отслеживание находится в отдельном файле, называемом tracker_kernel.m. Просмотрите этот файл для получения важной информации о выделении памяти для создания кода.
Сохранение состояния trackerGNN между вызовами tracker_kernel.m, трекер определяется как persistent переменная.
Эта функция принимает массив ячеек objectDetection объекты, сгенерированные fusionRadarSensor объект и время в качестве входных аргументов.
Аналогично, выходные данные функции, поддерживающей генерацию кода, не могут быть объектами. Выходные данные tracker_kernel.m являются:
Подтвержденные треки - A 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] = helperTrackerCGExample('Create Display',scenario); helperTrackerCGExample('Update Display',theater,scenario,tower);
![]()
Теперь выполните пример, вызвав 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(2020) % 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) % Generate detections on targets in the radar's current field of view. [dets,config] = detect(scenario); 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,scenario.SimulationTime); 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. helperTrackerCGExample('Update Display',theater,scenario,tower,scanBuffer,tracks); end
![]()
Используйте codegen для компиляции tracker_kernel в файл MEX. Можно указать -report используется для создания отчета о компиляции, в котором отображается исходный код MATLAB и связанные файлы, созданные во время создания кода C. Рекомендуется создать временный каталог, в котором кодер MATLAB может хранить созданные файлы. Обратите внимание, что, если вы не используете -o для указания имени исполняемого файла созданный файл MEX имеет то же имя, что и исходный файл MATLAB с _mex прилагается.
Для кодера MATLAB необходимо указать свойства всех входных аргументов. Входные данные используются трекером для создания правильных типов данных и размеров для объектов, используемых в трекинге. Типы и размеры данных не должны изменяться между кадрами данных. Один простой способ сделать это - определить входные свойства на примере в командной строке с помощью -args вариант. Дополнительные сведения см. в разделе Спецификация ввода (кодер MATLAB).
% 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 scenario.SimulationTime}; % 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
Code generation successful.
После создания кода выполните тот же сценарий с созданным файлом 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(2020) while advance(scenario) && ishghandle(fig) % Generate detections on targets in the radar's current field of view. [dets,config] = detect(scenario); 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,scenario.SimulationTime); 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. helperTrackerCGExample('Update Display',theater,scenario,tower,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-кодом шага обновления, измеряется за несколько миллисекунд.
В этом примере показано, как генерировать код C из кода MATLAB для слияния и отслеживания датчиков.
Основными преимуществами автоматического создания кода являются возможность создания прототипа в среде MATLAB и создание файла MEX, который может выполняться в среде MATLAB. Сгенерированный код C можно развернуть на целевом объекте. В большинстве случаев генерируемый код быстрее кода MATLAB и может использоваться для пакетного тестирования алгоритмов и создания систем слежения в реальном времени.