В этом примере показано, как сгенерировать код С для функции MATLAB, которая обрабатывает данные, записанные с тестового транспортного средства, и отслеживает объекты вокруг него.
Автоматическая генерация кода из кода MATLAB имеет два ключевых преимущества:
Прототипы могут разрабатываться и отлаживаться в среде MATLAB. После выполнения работы MATLAB автоматическая генерация кода C делает алгоритмы развертываемыми для различных целей. Кроме того, код С может быть дополнительно протестирован путем запуска скомпилированного файла MEX в среде MATLAB с помощью тех же инструментов визуализации и анализа, которые были доступны во время фазы прототипирования.
После генерации кода С можно сгенерировать исполняемый код, который во многих случаях запускается быстрее, чем код MATLAB. Улучшенное время запуска может использоваться для разработки и развертывания систем слияния и слежения датчиков в реальном времени. Это также обеспечивает лучший способ пакетного тестирования систем отслеживания на большом количестве наборов данных.
Пример объясняет, как изменить код MATLAB в примере предупреждения прямого столкновения с использованием Sensor Fusion для поддержки генерации кода.
Этот пример требует лицензии Coder™ MATLAB ® для генерации кода С
Об основах генерации кода можно узнать с помощью MATLAB Coder из примера «Введение в генерацию кода» с сопоставлением функций и регистрацией.
Чтобы сгенерировать код С, MATLAB Coder требует, чтобы код MATLAB был в форме функции. Кроме того, аргументы функции не могут быть классами MATLAB.
В этом примере код для примера предупреждения прямого столкновения (FCW) был реструктурирован так, что функции, которые выполняют слияние датчика и отслеживание, находятся в отдельном файле, называемом trackingForFCW_kernel.m
. Проверьте этот файл для получения важной информации о выделении памяти для генерации кода.
Чтобы сохранить состояние multiObjectTracker
между вызовами в trackingForFCW_kernel.m
, трекер определяется как
переменная.persistent
Эта функция принимает за вход систему координат записанных данных, который включает в себя:
Объекты зрения - A struct
который содержит 10 объектов зрения.
Радиолокационные объекты - A struct
который содержит 36 радиолокационных объектов.
Инерционное измерение - A struct
содержащий скорость и скорость рыскания.
Отчеты о маршруте - A struct
массив с параметрами для контуров слева и справа.
Точно так же выходы от функции, которая поддерживает генерацию кода, не могут быть объектами. Выходы trackingForFCW_kernel.m
являются:
Подтвержденные треки - A struct
массив, который содержит переменное количество дорожек.
Ego lane - A struct
массив с параметрами левых и правых контуров маршрута.
Количество треков - Целочисленный скаляр.
Информация о самом важном объекте (MIO) и уровне предупреждения от логики FCW.
При такой реструктуризации кода можно повторно использовать те же инструменты отображения, что и в примере FCW. Эти инструменты все еще работают в MATLAB и не требуют генерации кода.
Запустите следующие строки кода, чтобы загрузить записанные данные и подготовить отображение аналогично примеру FCW.
% If a previous tracker is defined, clear it clear trackingForFCW_kernel % Set up the display videoFile = '01_city_c2s_fcw_10s.mp4'; sensorConfigFile = 'SensorConfigurationData.mat'; [videoReader, videoDisplayHandle, bepPlotters, sensor] = helperCreateFCWDemoDisplay(videoFile,sensorConfigFile); % Read the recorded detections file detfile = '01_city_c2s_fcw_10s_sensor.mat'; [visionObjects, radarObjects, imu, lanes, timeStep, numSteps] = helperReadSensorRecordingsFile(detfile); % An initial ego lane is calculated. If the recorded lane information is % invalid, define the lane boundaries as straight lines half a lane % distance on each side of the car. laneWidth = 3.6; % meters egoLane = struct('left', [0 0 laneWidth/2], 'right', [0 0 -laneWidth/2]); % Prepare some time variables timeStamp = 0; % Time since the beginning of the recording index = 0; % Index into the recorded sensor data % Define the position and velocity selectors: % The state vector is in constant acceleration: [x;vx;ax;y;vy;ay] % Constant acceleration position: [x;y] = [1 0 0 0 0 0; 0 0 0 1 0 0] * State positionSelector = [1 0 0 0 0 0; 0 0 0 1 0 0]; % Constant acceleration velocity: [x;y] = [0 1 0 0 0 0; 0 0 0 0 1 0] * State velocitySelector = [0 1 0 0 0 0; 0 0 0 0 1 0];
Теперь запустите пример, вызвав trackingForFCW_kernel
функция в MATLAB. Этот начальный запуск предоставляет базовую линию для сравнения результатов и позволяет вам собрать некоторые метрики о эффективности трекера, когда он запускается в MATLAB или как файл MEX.
% Allocate memory for number of tracks and time measurement in MATLAB numTracks = zeros(1, numSteps); runTimes = zeros(1, numSteps); while index < numSteps && ishghandle(videoDisplayHandle) % Update scenario counters index = index + 1; timeStamp = timeStamp + timeStep; tic; % Call the MATLAB tracking kernel file to perform the tracking [tracks, egoLane, numTracks(index), mostImportantObject] = trackingForFCW_kernel(... visionObjects(index), radarObjects(index), imu(index), lanes(index), egoLane, timeStamp, positionSelector, velocitySelector); runTimes(index) = toc; % Gather MATLAB run time data % Update video and bird's-eye plot displays frame = readFrame(videoReader); % Read video frame laneBoundaries = [parabolicLaneBoundary(egoLane.left);parabolicLaneBoundary(egoLane.right)]; helperUpdateFCWDemoDisplay(frame, videoDisplayHandle, bepPlotters, laneBoundaries, sensor, ... tracks, mostImportantObject, positionSelector, velocitySelector, visionObjects(index), radarObjects(index)); end
Используйте codegen
функция для компиляции trackingForFCW_kernel
функция в файл MEX. Можно задать -report
опция, чтобы сгенерировать отчет компиляции, который показывает оригинальный код MATLAB и связанные файлы, которые были созданы во время генерации кода C. Рассмотрите создание временной директории, в котором MATLAB Coder может хранить сгенерированные файлы. Обратите внимание, что если вы не используете -o
опция, чтобы задать имя исполняемого файла, сгенерированный файл MEX имеет то же имя, что и исходный файл MATLAB с _mex
приложенный.
MATLAB Coder требует, чтобы вы задали свойства всех входных параметров. Входы используются трекером для создания правильных типов данных и размеров для объектов, используемых в отслеживании. Типы и размеры данных не должны меняться между системами координат данных. Один из простых способов сделать это - задать входные свойства путем примера в командной строке с помощью -args
опция. Для получения дополнительной информации смотрите Задать входные свойства по примеру в командной строке (MATLAB Coder).
% Define the properties of the input based on the data in the first time frame. compInputs = {visionObjects(1), radarObjects(1), imu(1), lanes(1), egoLane, timeStamp, positionSelector, velocitySelector}; % 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 trackingForFCW_kernel -args compInputs; close(h) catch ME close(h) delete(videoDisplayHandle.Parent.Parent) throw(ME) end
Теперь, когда код был сгенерирован, запустите точно такой же сценарий с сгенерированным файлом MEX trackingForFCW_kernel_mex
. Все остальное остается прежним.
% If a previous tracker is defined, clear it clear trackingForFCW_kernel_mex % Allocate memory for number of tracks and time measurement numTracksMex = zeros(1, numSteps); runTimesMex = zeros(1, numSteps); % Reset the data and video counters index = 0; videoReader.CurrentTime = 0; while index < numSteps && ishghandle(videoDisplayHandle) % Update scenario counters index = index + 1; timeStamp = timeStamp + timeStep; tic; % Call the generated MEX file to perform the tracking [tracks, egoLane, numTracksMex(index), mostImportantObject] = trackingForFCW_kernel_mex(... visionObjects(index), radarObjects(index), imu(index), lanes(index), egoLane, timeStamp, positionSelector, velocitySelector); runTimesMex(index) = toc; % Gather MEX run time data % Update video and bird's-eye plot displays frame = readFrame(videoReader); % Read video frame laneBoundaries = [parabolicLaneBoundary(egoLane.left);parabolicLaneBoundary(egoLane.right)]; helperUpdateFCWDemoDisplay(frame, videoDisplayHandle, bepPlotters, laneBoundaries, sensor, ... tracks, mostImportantObject, positionSelector, velocitySelector, visionObjects(index), radarObjects(index)); end
Сравните результаты и эффективность сгенерированного кода с кодом MATLAB. Следующие графики сравнивают количество треков, поддерживаемых трекерами на каждом временном шаге. Они также показывают время, необходимое для обработки каждого вызова функции.
figure(2) subplot(2,1,1) plot(2:numSteps, numTracks(2:end), 'rs-', 2:numSteps, numTracksMex(2:end), 'bx-') title('Number of Tracks at Each Step'); legend('MATLAB', 'MEX') grid subplot(2,1,2) yyaxis left plot(2:numSteps, runTimesMex(2:end)*1e3); ylabel('MEX Processing Time (ms)'); yyaxis right plot(2:numSteps, runTimes(2:end) ./ runTimesMex(2:end)) ylabel('Speed-Up Ratio'); title('MEX Processing Time and Speed-Up Ratio at Each Step') grid xlabel('Time Step')
Верхний график показывает, что количество треков, которые поддерживались каждым трекером, одинаковое. Он измеряет размер задачи отслеживания с точки зрения количества треков.
Нижний график показывает время, необходимое для обработки кода MATLAB и сгенерированного кода функций каждого шага. Обратите внимание, что первый шаг требует непропорционально большего времени, потому что трекеры должны быть построены на первом этапе. Таким образом, первый временной шаг игнорируется.
Результаты показывают, что код MEX намного быстрее, чем код MATLAB. Они также показывают количество миллисекунд, требуемое кодом MEX для выполнения каждого шага обновления на вашем компьютере. Например, на компьютере с тактовой частотой CPU 2,6 ГГц под управлением Windows 7, время, необходимое коду MEX для выполнения шага обновления, составляло менее 4 мс. В качестве ссылки, записанные данные, используемые в этом примере, отбирались каждые 50 мс, таким образом, время выполнения MEX является достаточно коротким, чтобы позволить отслеживать в реальном времени.
Отображение тактовой частоты центральный процессор и среднего коэффициента ускорения.
p = profile('info'); speedUpRatio = mean(runTimes(2:end) ./ runTimesMex(2:end)); disp(['The generated code is ', num2str(speedUpRatio), ' times faster than the MATLAB code.']); disp(['The computer clock speed is ', num2str(p.ClockSpeed / 1e9), ' GHz.']);
The generated code is 43.4007 times faster than the MATLAB code. The computer clock speed is 3.601 GHz.
Этот пример показал, как сгенерировать код С из кода MATLAB для слияния датчиков и отслеживания.
Основными преимуществами автоматической генерации кода являются возможность прототипа в среде MATLAB, генерация файла MEX, который может запускаться в среде MATLAB, и развертывание на целевой объект с помощью кода С В большинстве случаев сгенерированный код быстрее, чем код MATLAB, и может использоваться для пакетной проверки алгоритмов и генерации систем отслеживания в реальном времени.