В этом примере показано, как протестировать детектор маркера полосы движения на основе монокулярной камеры и сгенерировать код C++ для приложений реального времени на заранее созданной сцене 3D из среды моделирования вождения Unreal Engine ®. В этом примере проверяется алгоритм детектора маркера полосы движения с помощью метрик и генерируемый код C++ с помощью программного моделирования в контуре.
Детектор маркера полосы движения является фундаментальным компонентом восприятия автоматизированного применения вождения. Детектор анализирует изображения дорог, захваченные с помощью датчика монокулярной камеры, и возвращает информацию о кривизне и типе разметки каждой полосы. Можно разработать и смоделировать алгоритм детектора маркера полосы движения с помощью MATLAB ® или Simulink ® и оценить его точность, используя известную достоверность. Для интеграции детектора во внешнюю программную среду и развертывания на транспортном средстве можно создать код C++. Выполнение генерации кода и верификации модели Simulink обеспечивает функциональную эквивалентность между моделированием и реализацией в реальном времени.
Сведения о проектировании детектора обозначения полосы движения см. в примере «Проектирование детектора обозначения полосы движения с использованием среды моделирования нереального двигателя». В этом примере показано, как протестировать детектор маркера полосы движения в среде моделирования 3D и создать код C++ для реализации в реальном времени. В этом примере будут выполнены следующие действия:
Изучите и смоделируйте модель детектора маркера полосы движения.
Оцените точность алгоритма детектора маркера полосы движения путем сравнения с достоверностью на земле.
Создайте код C++ из модели алгоритма.
Проверьте реализацию с помощью программного моделирования в цикле (SIL).
Оцените время выполнения и выполните анализ покрытия кода. Для выполнения анализа покрытия кода необходимо использовать Simulink Coverage™.
В этом примере проверяется алгоритм детектора маркера полосы движения в среде моделирования 3D, в которой используется Unreal Engine ® от Epic Games ®. Для среды моделирования вождения Unreal Engine требуется 64-разрядная платформа Windows ®.
if ~ispc error(['Unreal driving simulation environment is only supported on Microsoft', char(174), ' Windows', char(174), '.']); end
Чтобы обеспечить воспроизводимость результатов моделирования, задайте случайное начальное число.
rng(0);
Система детектора маркера полосы движения в этом примере имеет стенд для испытания детектора маркера полосы движения и эталонную модель.
Модель испытательного стенда: модель испытательного стенда моделирует и тестирует поведение алгоритма детектора маркера полосы движения в разомкнутом контуре.
Эталонная модель: Блок детектора маркера полосы движения в модели испытательного стенда вызывает LaneMarkerDetector ссылочная модель. Эталонная модель реализует алгоритм обнаружения маркера полосы движения и генерирует код C++ алгоритма. Эта эталонная модель может быть интегрирована с системами с замкнутым контуром.
Откройте модель испытательного стенда.
open_system('LaneMarkerDetectorTestBench');

При открытии этой модели запускается helperSLLaneMarkerDetectorSetup сценарий, который инициализирует сценарий дороги с помощью drivingScenario в базовой рабочей области. Он также конфигурирует параметры детектора маркера полосы движения, параметры модели транспортного средства и сигналы шины Simulink, необходимые для определения входов и выходов для LaneMarkerDetectorTestBench модель. Модель испытательного стенда содержит следующие подсистемы:
Сценарий 3D моделирования: определяет сцену, транспортные средства и датчик камеры, используемые для моделирования.
Детектор маркера полосы движения: реализует алгоритм детектора маркера полосы движения.
Оценка метрик: оценивает поведение алгоритма детектора маркера полосы движения с помощью метрик, включающих истинные положительные, ложные положительные и ложные отрицательные значения.
Визуализация: Отображает кадр, захваченный датчиком камеры, и накладывает обнаруженные полосы во время моделирования.
Подсистема моделирования 3D сценария конфигурирует дорожную сеть, устанавливает положение транспортного средства и синтезирует датчики. Это аналогично подсистеме моделирования 3D сценария в следующем примере полосы движения. Однако используемая в этом примере подсистема моделирования 3D сценария не имеет радиолокационного датчика. Откройте подсистему моделирования 3D сценария.
open_system('LaneMarkerDetectorTestBench/Simulation 3D Scenario');

Детектор маркеров полос - это ссылочная модель, определяющая границы полос в рамах. Откройте ссылочную модель «Детектор маркеров полос движения».
open_system('LaneMarkerDetector');

Блок «Детектор маркеров полосы движения» использует системный Object™, HelperLaneDetectorWrapper, который конфигурирует и реализует алгоритм обнаружения маркера полосы движения. Блок принимает кадры, захваченные датчиком камеры, в качестве входных данных и выводит обнаруженные границы полосы с помощью LaneSensor Автобус для симулинков.
Подсистема Metrics Assessment оценивает точность результатов обнаружения с использованием информации о истинности земли. Откройте подсистему оценки метрик.
open_system('LaneMarkerDetectorTestBench/Metrics Assessment');

Подсистема Metrics Assessment сравнивает обнаруженные границы полосы движения и границы полосы движения с истинной землей с помощью evaluateLaneBoundaries функция. Функция вычисляет боковое расстояние между обнаруженными границами полосы движения и данными истинности земли. Если вычисленное расстояние находится в пределах определенного порога, то обнаруженная граница рассматривается как допустимое совпадение (истинно положительное) и соответствующий статус полосы движения устанавливается равным 1. В противном случае функция вычисляет, является ли граница ложноотрицательной или ложноположительной, а затем устанавливает статус полосы в 0. Подсистема соединяет выходы left_lane_status и right_lane_status к лампам на приборной панели. Лампы идут green когда полоса имеет статус 1, и перейти red когда состояние полосы равно 0. Продукция left_lane_metrics и right_lane_metrics это массивы 1 на 3, содержащие совпадения полос (истинные положительные значения), промахи (ложные отрицательные значения) и ложные положительные значения для левой и правой полос соответственно. Средние отклонения левой и правой полос, вычисленные по обнаруженным границам полос, возвращаются на выходе left_lane_distance и right_lane_distance соответственно. Эти значения отклонения используются в модели для проверки точности алгоритма во время моделирования с использованием блоков Check Static Range (Simulink): Verify Left Lane Deviation и Verify Right Lane Deviation.
Сконфигурируйте LaneMarkerDetectorTestBench модель для моделирования в scenario_LD_02_SixVehicles сценарий. Этот сценарий содержит шесть транспортных средств, включая эго-транспортное средство, и определяет их траектории.
helperSLLaneMarkerDetectorSetup("scenario_LD_02_SixVehicles");
Смоделировать модель испытательного стенда. Используйте окно визуализации и индикаторы состояния на инструментальной панели для просмотра результатов обнаружения во время выполнения моделирования.
sim('LaneMarkerDetectorTestBench');
Можно также визуализировать границы полосы движения истинного грунта, включив EnableTruthDisplay параметр маски в блоке «Визуализация».
Проанализируйте результаты обнаружения и проверьте общую производительность алгоритма.
Во время моделирования модель выводит три параметра, характеризующих границу полосы движения: кривизну, угол курса и боковое смещение. Модель регистрирует эти параметры для обнаруженных границ полосы движения и истинности грунта в базовой переменной рабочего пространства. logsout. Можно распечатать значения в logsout с помощью helperLaneBoundaryParams функция.
helperPlotLaneBoundaryParams(logsout);


На графиках можно вывести отклонения между истинностью земли и обнаруженными границами полос. Большое отклонение между графиками указывает на то, что обнаруженная граница полосы значительно удалена от истинного положения земли.
Можно также проверить производительность алгоритма детектора маркера полосы, проверив и выведя метрики отдельно для левой и правой полосы. Модель также регистрирует результаты обнаружения левой и правой полос, вычисленные подсистемой метрической оценки, в базовой переменной рабочего пространства. logsout . Подсистема метрической оценки выводит:
Метрики левой полосы: Возвращается в виде массива, который содержит количество совпадений (истинных срабатываний), промахов (ложных срабатываний) и ложных срабатываний, вычисленных по обнаружениям для левой полосы дороги.
Состояние левой полосы: возвращено как true или false. Значение true для совпадений в левой полосе и false для промахов и ложных срабатываний в левой полосе.
Расстояние между левыми полосами движения: скаляр, задающий среднее значение расстояний между обнаруженными точками границы левой полосы движения и истинностью земли для левой полосы движения.
Метрики правой полосы: Возвращается в виде массива, который содержит количество совпадений (истинных срабатываний), промахов (ложных срабатываний) и ложных срабатываний, вычисленных по обнаружениям для правой полосы дороги.
Состояние правой полосы: возвращено как true или false. Значение true для совпадений в правой полосе и false для промахов и ложных срабатываний в правой полосе.
Расстояние между правыми полосами: скаляр, задающий среднее значение расстояний между обнаруженными граничными точками правых полос и истинностью земли для правой полосы.
Постройте график результатов обнаружения для левой и правой полос движения с помощью helperPlotLaneMetrics сценарий:
[numLaneMatches, numLaneMisses, numFalsePositives] = helperPlotLaneMetrics(logsout);


Из графиков можно сделать вывод о том, что все обнаруженные границы левой и правой полос совпадают с истинностью земли и что нет ложных срабатываний или ложных негативов.
Во время моделирования модель записывает выходной сигнал датчика камеры в forwardFacingCamera.mp4. Можно наложить результаты отклонения на полосы, обнаруженные в кадрах, и записать в видеофайл с помощью helperPlotLaneDetectionResults функция.
hVideoViewer = helperPlotLaneDetectionResults(... logsout, "forwardFacingCamera.mp4" , scenario, camera,scenarioFcnName,... "RecordVideo", true,"RecordVideoFileName", scenarioFcnName,... "OpenRecordedVideoInVideoViewer", true,"VideoViewerJumpToTime", 9.3);

Можно также вычислить общую точность и чувствительность алгоритма обнаружения маркера полосы движения, как показано ниже:
Точность: вычислить как процент истинных положительных результатов от общего числа обнаруженных границ полосы движения.
precision = (numLaneMatches./(numLaneMatches+numFalsePositives))*100; disp(precision);
100
Чувствительность: вычислить как процент истинных положительных результатов от общего числа фактических границ полосы движения.
sensitivity = (numLaneMatches./(numLaneMatches+numLaneMisses))*100; disp(sensitivity);
100
Точность и чувствительность надежного детектора маркера полосы движения должны быть близки к 100 для различных сценариев испытаний и условий испытаний.
Теперь можно создать код C++ для алгоритма, применить общие оптимизации и создать отчет, чтобы облегчить изучение созданного кода.
Сконфигурируйте LaneMarkerDetector модель для генерации кода C++ для реализации алгоритма в реальном времени. Задайте параметры модели, чтобы включить генерацию кода и отобразить значения конфигурации.
Задайте и просмотрите параметры модели, чтобы включить генерацию кода C++.
helperSetModelParametersForCodeGeneration('LaneMarkerDetector'); save_system('LaneMarkerDetector');
Model configuration parameters:
Parameter Value Description
___________________________________ _______________ ______________________________________________________________________________________________________________________
{'SystemTargetFile' } {'ert.tlc' } {'Code Generation>System target file' }
{'TargetLang' } {'C++' } {'Code Generation>Language' }
{'SolverType' } {'Fixed-step' } {'Solver>Type' }
{'FixedStep' } {'auto' } {'Solver>Fixed-step size (fundamental sample time)' }
{'EnableMultiTasking' } {'on' } {'Solver>Treat each discrete rate as a separate task' }
{'ProdLongLongMode' } {'on' } {'Hardware Implementation>Support long long' }
{'BlockReduction' } {'on' } {'Simulation Target>Block reduction' }
{'MATLABDynamicMemAlloc' } {'on' } {'Simulation Target>Simulation Target>Dynamic memory allocation in MATLAB functions' }
{'OptimizeBlockIOStorage' } {'on' } {'Simulation Target>Signal storage reuse' }
{'InlineInvariantSignals' } {'on' } {'Simulation Target>Inline invariant signals' }
{'BuildConfiguration' } {'Faster Runs'} {'Code Generation>Build configuration' }
{'RTWVerbose' } {'of' } {'Code Generation>Verbose build' }
{'CombineSignalStateStructs' } {'on' } {'Code Generation>Interface>Combine signal/state structures' }
{'SupportVariableSizeSignals' } {'on' } {'Code Generation>Interface>Support variable-size signals' }
{'CodeInterfacePackaging' } {'C++ class' } {'Code Generation>Interface>Code interface packaging' }
{'GenerateExternalIOAccessMethods'} {'Method' } {'Code Generation>Interface>Data Member Visibility>External I/O access' }
{'EfficientFloat2IntCast' } {'on' } {'Code Generation>Optimization>Remove code from floating-point to integer conversions that wraps out-of-range values'}
{'ZeroExternalMemoryAtStartup' } {'off' } {'Code Generation>Optimization>Remove root level I/O zero initialization (inverse logic)' }
{'CustomSymbolStrGlobalVar' } {'$N$M' } {'Code Generation>Symbols>Global variables' }
{'CustomSymbolStrType' } {'$N$M_T' } {'Code Generation>Symbols>Global types' }
{'CustomSymbolStrField' } {'$N$M' } {'Code Generation>Symbols>Field name of global types' }
{'CustomSymbolStrFcn' } {'APV_$N$M$F' } {'Code Generation>Symbols>Subsystem methods' }
{'CustomSymbolStrTmpVar' } {'$N$M' } {'Code Generation>Symbols>Local temporary variables' }
{'CustomSymbolStrMacro' } {'$N$M' } {'Code Generation>Symbols>Constant macros' }
Создайте код и просмотрите отчет о создании кода из ссылочной модели.
slbuild('LaneMarkerDetector');
### Starting build procedure for: LaneMarkerDetector ### Successful completion of build procedure for: LaneMarkerDetector Build Summary Top model targets built: Model Action Rebuild Reason ================================================================================== LaneMarkerDetector Code generated and compiled Generated code was out of date. 1 of 1 models built (0 models already up to date) Build duration: 0h 1m 15.75s

Используйте отчет о создании кода для просмотра созданного кода. Дополнительные сведения о отчете по созданию кода см. в разделе Отчеты по созданию кода (встроенный кодер). Используйте ссылку Отчет по кодовому интерфейсу (Code Interface Report) в Отчете по созданию кода (Code Generation Report) для изучения следующих методов:
LaneMarkerDetector_initialize: Однократный вызов при инициализации.
LaneMarkerDetector_stepПериодически звоните на каждый шаг для выполнения алгоритма обнаружения маркера полосы движения.
LaneMarkerDetector_terminate: Звонок один раз при прекращении.
Дополнительные методы получения и установки для сигнального интерфейса объявлены в LaneMarkerDetector.h и определено в LaneMarkerDetector.cpp.
После генерации кода C++ для детектора маркера полосы движения теперь можно оценить функциональность кода с помощью программного моделирования в цикле (SIL). Он обеспечивает раннее понимание поведения развернутого приложения. Дополнительные сведения о моделировании SIL см. в разделе Моделирование SIL и PIL (встроенный кодер).
Моделирование SIL позволяет проверить, что скомпилированный сгенерированный код на хосте функционально эквивалентен обычному режиму.
Сконфигурируйте параметры алгоритма и тестовой модели для поддержки моделирования SIL и профилирования выполнения журнала.
helperSetModelParametersForSIL('LaneMarkerDetector'); helperSetModelParametersForSIL('LaneMarkerDetectorTestBench');
LaneMarkerDetector configuration parameters:
Parameter Value Description
________________________________ ____________________ ____________________________________________________________
{'SystemTargetFile' } {'ert.tlc' } {'Code Generation>System target file' }
{'TargetLang' } {'C++' } {'Code Generation>Language' }
{'CodeExecutionProfiling' } {'on' } {'Code Generation>Verification>Measure task execution time'}
{'CodeProfilingSaveOptions' } {'AllData' } {'Code Generation>Verification>Save options' }
{'CodeExecutionProfileVariable'} {'executionProfile'} {'Code Generation>Verification>Workspace variable' }
LaneMarkerDetectorTestBench configuration parameters:
Parameter Value Description
________________________________ ____________________ ____________________________________________________________
{'SystemTargetFile' } {'ert.tlc' } {'Code Generation>System target file' }
{'TargetLang' } {'C++' } {'Code Generation>Language' }
{'CodeExecutionProfiling' } {'on' } {'Code Generation>Verification>Measure task execution time'}
{'CodeProfilingSaveOptions' } {'AllData' } {'Code Generation>Verification>Save options' }
{'CodeExecutionProfileVariable'} {'executionProfile'} {'Code Generation>Verification>Workspace variable' }
Сконфигурируйте модель стенда для моделирования детектора маркера полосы движения в режиме программного обеспечения в контуре (SIL).
set_param('LaneMarkerDetectorTestBench/Lane Marker Detector','SimulationMode','Software-in-the-loop (SIL)'); sim('LaneMarkerDetectorTestBench');
### Starting build procedure for: LaneMarkerDetector ### Generated code for 'LaneMarkerDetector' is up to date because no structural, parameter or code replacement library changes were found. ### Successful completion of build procedure for: LaneMarkerDetector Build Summary Top model targets built: Model Action Rebuild Reason ============================================================================ LaneMarkerDetector Code compiled Compilation artifacts were out of date. 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 22.046s ### Preparing to start SIL simulation ... Building with 'MinGW64 Compiler (C)'. MEX completed successfully. ### Starting SIL simulation for component: LaneMarkerDetector ### Stopping SIL simulation for component: LaneMarkerDetector ### Completed code coverage analysis
Можно сравнить выходные данные из обычного режима моделирования и режима программного моделирования в цикле (SIL). Можно проверить, находятся ли различия между этими прогонами в пределах допуска, с помощью следующего кода. Постройте график различий обнаруженных параметров границ полосы движения между обычным режимом моделирования и режимом моделирования SIL.
runIDs = Simulink.sdi.getAllRunIDs; normalSimRunID = runIDs(end - 1); SilSimRunID = runIDs(end); diffResult = Simulink.sdi.compareRuns(normalSimRunID ,SilSimRunID);
Постройте график различий между параметрами границ полосы движения, вычисленными из нормального режима и режима SIL.
helperPlotDiffSignals(diffResult);


Обратите внимание, что различия между значениями параметров границы полосы движения между нормальным режимом моделирования и режимом SIL моделирования приблизительно равны нулю. Однако существуют небольшие различия из-за различных методов округления, используемых различными компиляторами.
Во время моделирования программного обеспечения в цикле (SIL) записывайте метрики времени выполнения для сгенерированного кода на хост-компьютере в переменную executionProfile в базовой рабочей области MATLAB. Это время может быть ранним индикатором производительности сгенерированного кода. Для точного измерения времени выполнения выполните профилирование сгенерированного кода при его интеграции во внешнюю среду или при использовании моделирования процессора в цикле (PIL). Дополнительные сведения о профилировании SIL см. в разделе Профилирование выполнения кода с SIL и PIL (встроенный кодер).
Постройте график времени выполнения для LaneMarkerDetector_step функция с использованием helperPlotExecutionProfile функция.
helperPlotExecutionProfile(executionProfile);

Обратите внимание на то, что на этом графике можно вывести среднее время на кадр для детектора маркера полосы движения. Дополнительные сведения о создании профилей выполнения и их анализе во время моделирования SIL см. в разделе Профилирование времени выполнения для SIL и PIL (встроенный кодер).
При наличии лицензии Simulink Coverage™ можно также выполнить анализ покрытия кода для созданного кода для измерения полноты тестирования. Отсутствующие данные покрытия можно использовать для поиска пробелов в тестировании, отсутствующих требованиях или непреднамеренных функциональных возможностях. Настройте параметры покрытия и смоделируйте модель тестового стенда для создания отчета по анализу покрытия. Поиск созданного отчета CoverageResults/LaneMarkerDetector.html в рабочей папке.
if(license('test','Simulink_Coverage')) helperCoverageSettings('LaneMarkerDetectorTestBench'); cvDataObj = cvsim('LaneMarkerDetectorTestBench'); cvhtml('CoverageResults/LaneMarkerDetector',cvDataObj); end
### Starting build procedure for: LaneMarkerDetector ### Generated code for 'LaneMarkerDetector' is up to date because no structural, parameter or code replacement library changes were found. ### Successful completion of build procedure for: LaneMarkerDetector Build Summary Top model targets built: Model Action Rebuild Reason ============================================================================ LaneMarkerDetector Code compiled Compilation artifacts were out of date. 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 17.364s ### Preparing to start SIL simulation ... ### Starting SIL simulation for component: LaneMarkerDetector ### Stopping SIL simulation for component: LaneMarkerDetector ### Completed code coverage analysis
При моделировании созданного кода для этого сценария тестирования можно найти результаты покрытия решений, покрытия инструкций и покрытия функций. scenario_LD_02_SixVehicles. Можно протестировать эту модель с помощью различных сценариев для получения полного покрытия сгенерированного кода. Для получения дополнительной информации о том, как анализировать результаты покрытия во время моделирования программного обеспечения в цикле, см. Кодовое покрытие для моделей в режиме программного обеспечения в цикле (SIL) и режиме процессора в цикле (PIL) (встроенный кодер).
В этом примере представлены дополнительные сценарии, которые можно использовать с LaneMarkerDetectorTestBench модель:
scenario_LF_01_Straight_RightLane scenario_LF_02_Straight_LeftLane scenario_LF_03_Curve_LeftLane scenario_LF_04_Curve_RightLane scenario_LD_01_ThreeVehicles scenario_LD_02_SixVehicles [Default]
Использовать сценарии с префиксом scenario_LF в имени файла для тестирования алгоритма обнаружения маркера полосы движения без препятствий со стороны других транспортных средств. Транспортные средства все еще существуют в сценарии, но расположены так, что они не находятся в пределах видимого диапазона эго-транспортного средства.
Использовать сценарии с префиксом scenario_LD в имени файла для проверки алгоритма обнаружения маркера полосы движения, в то время как другие транспортные средства на дороге находятся в пределах видимого диапазона эго-транспортного средства.
При разработке и тестировании алгоритма обнаружения маркера полосы движения в разомкнутом контуре полезно начать со сценария, в котором имеется только эго-транспортное средство. Чтобы настроить модель и рабочую область для такого сценария, используйте следующий код.
helperSLLaneMarkerDetectorSetup("scenario_LF_04_Curve_RightLane");
Эту модель можно использовать для интеграции RoadRunner™ сцен в сценарии управления для моделирования и тестирования.