Generate C++ Message Interfaces for Lane Following Controls and Sensor Fusion
This example shows how to generate C++ code that supports message-based communication between components of a highway lane following system. Generating code with message interfaces enables your application to communicate in a distributed system that uses an external message protocol service.
Introduction
Next generation autonomous vehicles (AVs) run highly complex algorithms to perform perception, planning, and control. Service-oriented architecture (SOA) is becoming a prevalent means of dealing with this increasing complexity. SOA promotes a distributed approach to implementing perception, planning, and control algorithms using local computing units. These units can exchange information with each other using message-based communication services such as Robot Operating System (ROS), Data Distribution Services (DDS), and the AUTOSAR Adaptive Platform.
This example focuses on modeling message-based communication between sensor fusion and controls components of a highway lane-following application. The example uses the Send (Simulink) and Receive (Simulink) blocks from the Simulink Messages and Events library to model the message-passing interface between the components of this system. This example also uses the HLFControlsWithSensorFusionTestBench
model from the Automate Testing for Highway Lane Following Controls and Sensor Fusion example. In this example, you:
Identify algorithm components for deployment — Review the test bench model with signals and identify the algorithm components in the test bench model.
Add Simulink message interfaces to algorithm components — Review the test bench model with Simulink messages. Simulate the model and examine the results.
Generate C++ code — Configure the algorithm components with Simulink messages to generate C++ code.
Explore generated code — Explore the generated code and observe message interfaces.
In this example, you enable system-level simulation through integration with the Unreal Engine® from Epic Games®.
if ~ispc error(['This example is supported only on Microsoft',char(174),' Windows',char(174),'.']) end
Identify Algorithm Components for Deployment
This example uses a system-level simulation test bench model to interface with Simulink messages. To explore the test bench model, load highway lane following controls with sensor fusion project.
openProject("HLFControlsSensorFusion");
Open the test bench model and highlight the model components for deployment.
open_system("HLFControlsWithSensorFusionTestBench") hilite_system("HLFControlsWithSensorFusionTestBench/Forward Vehicle Sensor Fusion") hilite_system("HLFControlsWithSensorFusionTestBench/Lane Following Decision Logic") hilite_system("HLFControlsWithSensorFusionTestBench/Lane Following Controller")
The test bench model contains these subsystems:
Simulation 3D Scenario
— Specifies the road, vehicles, vision detection generator, and radar sensors used for the simulation.Forward Vehicle Sensor Fusion
— Fuses the vision and radar sensor detections of vehicles in front of the ego vehicle.Lane Following Decision Logic
— Algorithm model that specifies the lateral and longitudinal decision logic, and provides lane center information and most important object (MIO) related information to the controller.Lane Following Controller
— Algorithm model that specifies the controller.Vehicle Dynamics
— Specifies the dynamic model for the ego vehicle.Metrics Assessment
— Assesses system-level behavior.
This example configures the Forward Vehicle Sensor Fusion
, Lane Following Decision Logic
, and Lane Following Controller
components using Simulink messages.
Add Simulink Message Interfaces to Algorithm Components
To model a message passing interface for algorithm components, add Send and Receive blocks at the output and input ports, respectively, of the algorithm components. Open the test bench model that contains message interfaces.
open_system("SOAHLFControlsWithSensorFusionTestBench")
Observe the message interfaces between the components of the model. To explore the modeling pattern for the message Send and Receive interfaces, open each component model.
Open the Forward Vehicle Sensor Fusion
component.
open_system("SOAForwardVehicleSensorFusion")
Open the Lane Following Decision Logic
component.
open_system("SOALaneFollowingDecisionLogic")
Open the Lane Following Controller
component.
open_system("SOALaneFollowingController")
Observe the Simulink message Send and Receive blocks connected to the Lane Following Controller
reference component. Simulate the model and examine the results.
sim("SOAHLFControlsWithSensorFusionTestBench");
Assuming no disturbance added to measured output #3. -->Assuming output disturbance added to measured output #2 is integrated white noise. Assuming no disturbance added to measured output #1. -->Assuming output disturbance added to measured output #4 is integrated white noise. -->"Model.Noise" is empty. Assuming white noise on each measured output.
Plot performance metrics for the lateral controller.
hFigLatResults = helperPlotLFLateralResults(logsout);
Close the figure.
close(hFigLatResults)
Plot performance metrics for the longitudinal controller. For more information about the lateral and longitudinal controller metrics, see Highway Lane Following.
hFigLongResults = helperPlotLFLongitudinalResults(logsout,time_gap, ...
default_spacing);
Close the figure.
close(hFigLongResults)
Generate C++ Code
Generate C++ code for the Forward Vehicle Sensor Fusion
, Lane Following Decision Logic
, and Lane Following Controller
algorithm components.
Configure the reference model parameters for code generation support.
helperSetModelParametersForCodeGeneration({'SOAForwardVehicleSensorFusion', ... 'SOALaneFollowingDecisionLogic', ... 'SOALaneFollowingController'}); save_system("SOAForwardVehicleSensorFusion"); save_system("SOALaneFollowingDecisionLogic"); save_system("SOALaneFollowingController");
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' } {'off' } {'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' }
Generate code for the Forward Vehicle Sensor Fusion
component.
slbuild("SOAForwardVehicleSensorFusion");
### Searching for referenced models in model 'SOAForwardVehicleSensorFusion'. ### Found 1 model reference targets to update. ### Starting serial model reference code generation build. ### Starting build procedure for: ForwardVehicleSensorFusion ### Successful completion of code generation for: ForwardVehicleSensorFusion ### Starting build procedure for: SOAForwardVehicleSensorFusion ### Successful completion of code generation for: SOAForwardVehicleSensorFusion Build Summary Model reference code generation targets: Model Build Reason Status Build Duration =================================================================================================================== ForwardVehicleSensorFusion Target (ForwardVehicleSensorFusion.cpp) did not exist. Code generated. 0h 5m 19.496s Top model targets: Model Build Reason Status Build Duration =================================================================================================================== SOAForwardVehicleSensorFusion Information cache folder or artifacts were missing. Code generated. 0h 0m 15.385s 2 of 2 models built (0 models already up to date) Build duration: 0h 5m 43.973s
Generate code for the Lane Following Decision Logic
component.
slbuild("SOALaneFollowingDecisionLogic");
### Searching for referenced models in model 'SOALaneFollowingDecisionLogic'. ### Found 1 model reference targets to update. ### Starting serial model reference code generation build. ### Starting build procedure for: LaneFollowingDecisionLogic ### Successful completion of code generation for: LaneFollowingDecisionLogic ### Starting build procedure for: SOALaneFollowingDecisionLogic ### Successful completion of code generation for: SOALaneFollowingDecisionLogic Build Summary Model reference code generation targets: Model Build Reason Status Build Duration =================================================================================================================== LaneFollowingDecisionLogic Target (LaneFollowingDecisionLogic.cpp) did not exist. Code generated. 0h 0m 18.362s Top model targets: Model Build Reason Status Build Duration =================================================================================================================== SOALaneFollowingDecisionLogic Information cache folder or artifacts were missing. Code generated. 0h 0m 14.061s 2 of 2 models built (0 models already up to date) Build duration: 0h 0m 33.819s
Generate code for the Lane Following Controller
component.
slbuild("SOALaneFollowingController");
### Searching for referenced models in model 'SOALaneFollowingController'. ### Found 1 model reference targets to update. ### Starting serial model reference code generation build. ### Starting build procedure for: LaneFollowingController Assuming no disturbance added to measured output #3. -->Assuming output disturbance added to measured output #2 is integrated white noise. Assuming no disturbance added to measured output #1. -->Assuming output disturbance added to measured output #4 is integrated white noise. -->"Model.Noise" is empty. Assuming white noise on each measured output. ### Successful completion of code generation for: LaneFollowingController ### Starting build procedure for: SOALaneFollowingController ### Successful completion of code generation for: SOALaneFollowingController Build Summary Model reference code generation targets: Model Build Reason Status Build Duration ============================================================================================================= LaneFollowingController Target (LaneFollowingController.cpp) did not exist. Code generated. 0h 1m 15.455s Top model targets: Model Build Reason Status Build Duration ================================================================================================================ SOALaneFollowingController Information cache folder or artifacts were missing. Code generated. 0h 0m 12.437s 2 of 2 models built (0 models already up to date) Build duration: 0h 1m 29.69s
Explore Generated Code
Explore the generated code for the Forward Vehicle Sensor Fusion
component and verify the message interfaces.
Open the SOAForwardVehicleSensorFusion.cpp
file and view these message interfaces:
TimeRecvData.RecvData
— Receives system time from theSimulation 3D Scenario
subsystem.VisionRecvData.RecvData
— Receives vision detections from theSimulation 3D Scenario
subsystem.RadarRecvData.RecvData
— Receives radar detections from theSimulation 3D Scenario
subsystem.TracksSendData.SendData
— Sends confirmed tracks detected by this component to theLane Following Decision Logic
component.
You can also use this process to verify the message classes for the Lane Following Decision Logic
and Lane Following Controller
components from their generated code.
For information about how to integrate the generated code with external message protocols, see Generate C++ Messages to Communicate Data Between Simulink and an Operating System or Middleware (Embedded Coder) and Model Message-Based Communication Integrated with POSIX Message Queues (Embedded Coder).