Challenge

Project 2 Adaptive Cruise Control

SOLUTION -

Steps to model the Adaptive cruise control algorithm:

Create a blank Simulink model and save it.

Create SLDD:

Create a new SLDD file and link it to the model by saving it in the same directory as of the model

Go to model explorer > Open design data from model folders and subfolders > create signals and constants required

Requirement1 :

Lead_Vehicle subsystem: The camera and radar inputs values are taken as inputs and Lead vehicle speed will be the output as specified in requirement1

  • Lead Vehicle is a vehicle which is driving in the road ahead of our drive vehicle. Two input signals (Signal Name: CameraInput_LeadVehicle & RadarInput_LeadVehicle).
  • Ideally sensor fusion techniques will be deployed to process & analyze data from camera & radar. For complexity reasons, let’s not adapt to any such algorithms.
  • We can simply add both the radar & camera inputs & the corresponding output is read as Speed profile output (Signal Name: LeadVehicle_Speed).
  • Speed data of the lead vehicle is critical in implementing the Adaptive Cruise Control algorithm.

Requirement2

Drive vehicle subsystem: This block follows the conditions of Requirement2 and takes 3 input values for Camera input, radar input, and acceleration mode. There will be 2 outputs of drive vehicle speed and lead vehicle detection signal

  • Drive Vehicle is the vehicle driven by the user & this is the vehicle which has ACC algorithm in it.
  • Like the Lead Vehicle, Drive Vehicle algorithm also has 2 input signals (Signal Name: CameraInput_DriveVehicle, RadarInput_DriveVehicle) & one signal coming as an Input to this subsystem (Signal Name: Acceleration_Mode) – three inputs into this requirement in total.
  • Like the above requirement, sensor fusion techniques will also be deployed here, for complexity reasons we are ignoring them.
  • Two output signals come from this subsystem (Signal Name: DriveVehicle_Speed & LeadVehicle_Detected).
  • Signal DriveVehicle_Speed is summation of three input signals mentioned above & LeadVehicle_Detected is renamed from Input Signal RadarInput_DriveVehicle by mere use of Signal Conversion block.

Requirement3

ACCAlgorithm Stateflow diagram: The Stateflow chart is developed based on the 6 sub-requirements specified in Requirement3.

  • Adaptive Cruise Control feature has 3 major modes of operation: OFF Mode, STANDBY Mode & ON Mode. This particular requirement has to be implemented as state machine logic in Simulink.
  • The input signals to this state machine system are (Signal Name: Time_Gap, Set_Speed, Set_Gap, CruiseSwitch, SetSwitch).
  • Also, the output signals (Signal Name: DriveVehicle_Speed & LeadVehicle_Detected) from requirement-2 is fed back as an input signal into this state machine block.
  • Additionally, output signal (Signal Name: LeadVehicle_Speed) from requirement-1 is given as an input signal to this state machine block as well.
  • Output from this subsystem is a signal (Signal Name: Acceleration_Mode) which governs the vehicular speed of the drive vehicle which automatically adjusts its speed & velocity to match the lead vehicle.

Statlow symbol pane:

ACC subsystem:

This subsystem is developed on the Requirement3 and is made using the concept of stateflow. It takes 8 inputs and gives the acceleration mode as the final output.

Three more subsystems are created for the three provided requirements namely Lead_Vehicle, Drive_Vehicle, and ACC:

Requirement tagging

  • Require tagging is the process of linking the model with a document or a file that explains the model requirements by just clicking on the name
  • The word document with requirement details is opened.
  • Select the heading and highlight it.

Configuration of Solver settings and Code generation

  • Go to model settings > Solver > select type: Fixed step ; solver: discrete (no continuous states) ;Fixed step size:0.01 > OK

Go to code generation > system target file:select ert.tlc >OK

Code generation:

  • Once the warnings are reduced to the maximum, we can generate a C code for the model created
  • Go to model explorer > open requirement 2 > set the parameters
  • Go to APPS tab > Embedded Coder > Select the model name >Gerate code /Build

*
* File: project.c
*
* Code generated for Simulink model 'project'.
*
* Model version : 1.5
* Simulink Coder version : 9.5 (R2021a) 14-Nov-2020
* C/C++ source code generated on : Sat Dec 17 12:03:01 2022
*
* Target selection: ert.tlc
* Embedded hardware selection: Intel->x86-64 (Windows64)
* Code generation objectives: Unspecified
* Validation result: Not run
*/
#include "project.h"
#include "project_private.h"
/* Named constants for Chart: '<S3>/Chart' */
#define IN_LeadVehicle_Detected_Follow ((uint8_T)1U)
#define IN_LeadVehicle_Detected_Resume ((uint8_T)2U)
#define IN_LeadVehicle_Not_Detected_Res ((uint8_T)4U)
#define IN_LeadVehicle_Speed_equal_Set_ ((uint8_T)5U)
#define IN_LeadVehicle_Speed_lessthan_S ((uint8_T)6U)
#define pro_IN_LeadVehicle_Not_Detected ((uint8_T)3U)
#define project_IN_ACC_MODE_OFF ((uint8_T)1U)
#define project_IN_ACC_MODE_ON ((uint8_T)2U)
#define project_IN_ACC_MODE_STANDBY ((uint8_T)3U)
#define project_IN_NO_ACTIVE_CHILD ((uint8_T)0U)
/* Block states (default storage) */
DW_project_T project_DW;
/* External inputs (root inport signals with default storage) */
ExtU_project_T project_U;
/* Real-time model */
static RT_MODEL_project_T project_M_;
RT_MODEL_project_T *const project_M = &project_M_;
/* Model step function */
void project_step(void)
{
real_T rtb_Add;
real_T rtb_Add_a;
/* Sum: '<S1>/Add' incorporates:
* Inport: '<Root>/Input2'
* Inport: '<Root>/Input3'
* UnitDelay: '<Root>/Unit Delay'
*/
rtb_Add = (project_U.CameraInput_DriveVehicle +
project_U.RadarInput_DriveVehicle) + project_DW.UnitDelay_DSTATE;
/* Sum: '<S2>/Add' incorporates:
* Inport: '<Root>/Input'
* Inport: '<Root>/Input1'
*/
rtb_Add_a = project_U.CameraInput_LeadVehicle +
project_U.RadarInput_LeadVehicle;
/* Chart: '<S3>/Chart' incorporates:
* Inport: '<Root>/CruiseSwitch'
* Inport: '<Root>/SetSwitch'
* Inport: '<Root>/Set_Gap'
* Inport: '<Root>/Set_Speed'
* Inport: '<Root>/Time_Gap'
*/
if (project_DW.is_active_c3_project == 0U) {
project_DW.is_active_c3_project = 1U;
project_DW.is_c3_project = project_IN_ACC_MODE_OFF;
/* UnitDelay: '<Root>/Unit Delay' */
project_DW.UnitDelay_DSTATE = 0.0;
} else {
switch (project_DW.is_c3_project) {
case project_IN_ACC_MODE_OFF:
if (project_U.CruiseSwitch == 1.0) {
project_DW.is_c3_project = project_IN_ACC_MODE_STANDBY;
/* UnitDelay: '<Root>/Unit Delay' */
project_DW.UnitDelay_DSTATE = 1.0;
} else {
/* UnitDelay: '<Root>/Unit Delay' */
project_DW.UnitDelay_DSTATE = 0.0;
}
break;
case project_IN_ACC_MODE_ON:
if (project_U.SetSwitch == 0.0) {
project_DW.is_ACC_MODE_ON = project_IN_NO_ACTIVE_CHILD;
project_DW.is_c3_project = project_IN_ACC_MODE_STANDBY;
/* UnitDelay: '<Root>/Unit Delay' */
project_DW.UnitDelay_DSTATE = 1.0;
} else {
switch (project_DW.is_ACC_MODE_ON) {
case IN_LeadVehicle_Detected_Follow:
if (project_DW.UnitDelay_DSTATE == 0.0) {
project_DW.is_ACC_MODE_ON = pro_IN_LeadVehicle_Not_Detected;
/* UnitDelay: '<Root>/Unit Delay' */
project_DW.UnitDelay_DSTATE = 1.0;
} else if (((project_DW.UnitDelay_DSTATE == 1.0) && (rtb_Add_a <
project_U.Set_Speed)) || (project_U.Time_Gap <
project_U.Set_Gap)) {
project_DW.is_ACC_MODE_ON = IN_LeadVehicle_Speed_lessthan_S;
/* UnitDelay: '<Root>/Unit Delay' */
project_DW.UnitDelay_DSTATE = 4.0;
} else {
/* UnitDelay: '<Root>/Unit Delay' */
project_DW.UnitDelay_DSTATE = 2.0;
}
break;
case IN_LeadVehicle_Detected_Resume:
if (project_DW.UnitDelay_DSTATE == 0.0) {
project_DW.is_ACC_MODE_ON = IN_LeadVehicle_Not_Detected_Res;
/* UnitDelay: '<Root>/Unit Delay' */
project_DW.UnitDelay_DSTATE = 1.0;
} else if ((rtb_Add < project_U.Set_Speed) && (rtb_Add_a > rtb_Add) &&
(project_U.Time_Gap >= project_U.Set_Gap)) {
project_DW.is_ACC_MODE_ON = IN_LeadVehicle_Speed_equal_Set_;
/* UnitDelay: '<Root>/Unit Delay' */
project_DW.UnitDelay_DSTATE = 5.0;
} else if ((rtb_Add == project_U.Set_Speed) && (rtb_Add_a >=
project_U.Set_Speed) && (project_U.Time_Gap >=
project_U.Set_Gap)) {
project_DW.is_ACC_MODE_ON = IN_LeadVehicle_Detected_Follow;
/* UnitDelay: '<Root>/Unit Delay' */
project_DW.UnitDelay_DSTATE = 2.0;
} else {
/* UnitDelay: '<Root>/Unit Delay' */
project_DW.UnitDelay_DSTATE = 3.0;
}
break;
case pro_IN_LeadVehicle_Not_Detected:
if ((project_DW.UnitDelay_DSTATE == 1.0) && (rtb_Add ==
project_U.Set_Speed) && (rtb_Add_a >= project_U.Set_Speed) &&
(project_U.Time_Gap >= project_U.Set_Gap)) {
project_DW.is_ACC_MODE_ON = IN_LeadVehicle_Detected_Follow;
/* UnitDelay: '<Root>/Unit Delay' */
project_DW.UnitDelay_DSTATE = 2.0;
} else if (((project_DW.UnitDelay_DSTATE == 1.0) && (rtb_Add_a <
project_U.Set_Speed)) || (project_U.Time_Gap <
project_U.Set_Gap)) {
project_DW.is_ACC_MODE_ON = IN_LeadVehicle_Speed_lessthan_S;
/* UnitDelay: '<Root>/Unit Delay' */
project_DW.UnitDelay_DSTATE = 4.0;
} else {
/* UnitDelay: '<Root>/Unit Delay' */
project_DW.UnitDelay_DSTATE = 1.0;
}
break;
case IN_LeadVehicle_Not_Detected_Res:
/* UnitDelay: '<Root>/Unit Delay' */
project_DW.UnitDelay_DSTATE = 1.0;
break;
case IN_LeadVehicle_Speed_equal_Set_:
if ((project_DW.UnitDelay_DSTATE == 0.0) || (rtb_Add <=
project_U.Set_Speed)) {
project_DW.is_ACC_MODE_ON = IN_LeadVehicle_Not_Detected_Res;
/* UnitDelay: '<Root>/Unit Delay' */
project_DW.UnitDelay_DSTATE = 1.0;
} else if (((rtb_Add < project_U.Set_Speed) && (rtb_Add_a > rtb_Add)) ||
(project_U.Time_Gap >= project_U.Set_Gap)) {
project_DW.is_ACC_MODE_ON = IN_LeadVehicle_Detected_Resume;
/* UnitDelay: '<Root>/Unit Delay' */
project_DW.UnitDelay_DSTATE = 3.0;
} else if (((rtb_Add_a < project_U.Set_Speed) && (rtb_Add_a < rtb_Add))
|| (0.75 * project_U.Set_Gap == project_U.Time_Gap)) {
project_DW.is_ACC_MODE_ON = IN_LeadVehicle_Speed_lessthan_S;
/* UnitDelay: '<Root>/Unit Delay' */
project_DW.UnitDelay_DSTATE = 4.0;
} else {
/* UnitDelay: '<Root>/Unit Delay' */
project_DW.UnitDelay_DSTATE = 5.0;
}
break;
default:
/* case IN_LeadVehicle_Speed_lessthan_Set_Speed: */
if ((project_DW.UnitDelay_DSTATE == 0.0) && (rtb_Add ==
project_U.Set_Speed)) {
project_DW.is_ACC_MODE_ON = pro_IN_LeadVehicle_Not_Detected;
/* UnitDelay: '<Root>/Unit Delay' */
project_DW.UnitDelay_DSTATE = 1.0;
} else if ((rtb_Add_a * 1.25 >= rtb_Add) && (rtb_Add_a * 0.75 <=
rtb_Add) && (rtb_Add < project_U.Set_Speed) &&
(project_U.Time_Gap <= 1.25 * project_U.Set_Gap) &&
(project_U.Time_Gap >= 0.75 * project_U.Set_Gap)) {
project_DW.is_ACC_MODE_ON = IN_LeadVehicle_Speed_equal_Set_;
/* UnitDelay: '<Root>/Unit Delay' */
project_DW.UnitDelay_DSTATE = 5.0;
} else {
/* UnitDelay: '<Root>/Unit Delay' */
project_DW.UnitDelay_DSTATE = 4.0;
}
break;
}
}
break;
default:
/* case IN_ACC_MODE_STANDBY: */
if (project_U.CruiseSwitch == 0.0) {
project_DW.is_c3_project = project_IN_ACC_MODE_OFF;
/* UnitDelay: '<Root>/Unit Delay' */
project_DW.UnitDelay_DSTATE = 0.0;
} else if (project_U.SetSwitch == 1.0) {
project_DW.is_c3_project = project_IN_ACC_MODE_ON;
project_DW.is_ACC_MODE_ON = IN_LeadVehicle_Detected_Follow;
/* UnitDelay: '<Root>/Unit Delay' */
project_DW.UnitDelay_DSTATE = 2.0;
} else {
/* UnitDelay: '<Root>/Unit Delay' */
project_DW.UnitDelay_DSTATE = 1.0;
}
break;
}
}
/* End of Chart: '<S3>/Chart' */
}
/* Model initialize function */
void project_initialize(void)
{
/* (no initialization code required) */
}
/* Model terminate function */
void project_terminate(void)
{
/* (no terminate code required) */
}
/*
* File trailer for generated code.
*
* [EOF]
*/
Your portfolio, next

Ship work like this
in your own course.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.