Main Content

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:

  1. Identify algorithm components for deployment — Review the test bench model with signals and identify the algorithm components in the test bench model.

  2. Add Simulink message interfaces to algorithm components — Review the test bench model with Simulink messages. Simulate the model and examine the results.

  3. Generate C++ code — Configure the algorithm components with Simulink messages to generate C++ code.

  4. 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®. The 3D simulation environment requires a Windows® 64-bit platform.

if ~ispc
    error(['3D simulation 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, open a working copy of the project example files. MATLAB copies the files to an example folder so that you can edit them.

addpath(fullfile(matlabroot,"toolbox","driving","drivingdemos"))
helperDrivingProjectSetup("HLFControlsSensorFusion.zip",workDir=pwd)

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 channel #3.
-->Assuming output disturbance added to measured output channel #2 is integrated white noise.
   Assuming no disturbance added to measured output channel #1.
-->Assuming output disturbance added to measured output channel #4 is integrated white noise.
-->The "Model.Noise" property of the "mpc" object is empty. Assuming white noise on each measured output channel.

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");
### 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

Code generation targets built:

Model                       Action          Rebuild Reason  
============================================================
ForwardVehicleSensorFusion  Code generated                  

Top model targets built:

Model                          Action          Rebuild Reason                   
================================================================================
SOAForwardVehicleSensorFusion  Code generated  Referenced models were updated.  

2 of 2 models built (0 models already up to date)
Build duration: 0h 2m 57.083s

Generate code for the Lane Following Decision Logic component.

slbuild("SOALaneFollowingDecisionLogic");
### Starting serial model reference code generation build
### Checking the status of model reference code generation target for model 'LaneFollowingDecisionLogic' used in 'SOALaneFollowingDecisionLogic'
### Checking for structural changes in LaneFollowingDecisionLogic because the model reference rebuild option is set to 'If any changes detected'. Structural changes cause the model reference code generation target to be rebuilt.
### Starting build procedure for: LaneFollowingDecisionLogic
### Generating code and artifacts to 'Model specific' folder structure
### Code for the model reference code generation target for model LaneFollowingDecisionLogic is up to date because no functional changes were found in the referenced model.
### Model reference code generation target for LaneFollowingDecisionLogic is up to date.
### Starting build procedure for: SOALaneFollowingDecisionLogic
### Generating code and artifacts to 'Model specific' folder structure
### Generating code into build folder: C:\Local\Examples\autonomous_control-ex39999976\SOALaneFollowingDecisionLogic_ert_rtw
### Generated code for 'SOALaneFollowingDecisionLogic' is up to date because no structural, parameter or code replacement library changes were found.
### Saving binary information cache.
### Skipping makefile generation and compilation because C:\Local\Examples\autonomous_control-ex39999976\slprj\ert\_sharedutils\rtwshared.lib is up to date
### Skipping makefile generation and compilation because C:\Local\Examples\autonomous_control-ex39999976\SOALaneFollowingDecisionLogic.exe is up to date
### Successful completion of code generation for: SOALaneFollowingDecisionLogic

Build Summary

Top model targets built:

Model                          Action                                Rebuild Reason  
=====================================================================================
SOALaneFollowingDecisionLogic  Binary information cache regenerated                  

1 of 2 models built (1 models already up to date)
Build duration: 0h 0m 6.126s

Generate code for the Lane Following Controller component.

slbuild("SOALaneFollowingController");
### Starting serial model reference code generation build
### Checking the status of model reference code generation target for model 'LaneFollowingController' used in 'SOALaneFollowingController'
### Checking for structural changes in LaneFollowingController because the model reference rebuild option is set to 'If any changes detected'. Structural changes cause the model reference code generation target to be rebuilt.
### Starting build procedure for: LaneFollowingController
### Generating code and artifacts to 'Model specific' folder structure
   Assuming no disturbance added to measured output channel #3.
-->Assuming output disturbance added to measured output channel #2 is integrated white noise.
   Assuming no disturbance added to measured output channel #1.
-->Assuming output disturbance added to measured output channel #4 is integrated white noise.
-->The "Model.Noise" property of the "mpc" object is empty. Assuming white noise on each measured output channel.
### Code for the model reference code generation target for model LaneFollowingController is up to date because no functional changes were found in the referenced model.
### Model reference code generation target for LaneFollowingController is up to date.
### Starting build procedure for: SOALaneFollowingController
### Generating code and artifacts to 'Model specific' folder structure
### Generating code into build folder: C:\Local\Examples\autonomous_control-ex39999976\SOALaneFollowingController_ert_rtw
### Generated code for 'SOALaneFollowingController' is up to date because no structural, parameter or code replacement library changes were found.
### Saving binary information cache.
### Skipping makefile generation and compilation because C:\Local\Examples\autonomous_control-ex39999976\slprj\ert\_sharedutils\rtwshared.lib is up to date
### Skipping makefile generation and compilation because C:\Local\Examples\autonomous_control-ex39999976\SOALaneFollowingController.exe is up to date
### Successful completion of code generation for: SOALaneFollowingController

Build Summary

Top model targets built:

Model                       Action                                Rebuild Reason  
==================================================================================
SOALaneFollowingController  Binary information cache regenerated                  

1 of 2 models built (1 models already up to date)
Build duration: 0h 0m 25.77s

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 the Simulation 3D Scenario subsystem.

  • VisionRecvData.RecvData — Receives vision detections from the Simulation 3D Scenario subsystem.

  • RadarRecvData.RecvData — Receives radar detections from the Simulation 3D Scenario subsystem.

  • TracksSendData.SendData — Sends confirmed tracks detected by this component to the Lane 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 Between Simulink and an Operating System or Middleware (Embedded Coder) and Use Handwritten Code to Integrate C++ Messages with POSIX (Embedded Coder).

Related Topics