Project 2 Adaptive Cruise Control
STUDENT OF ONLINE EV BATCH 16
ANS :
OBJECTIVE :
- Developing Adaptive Cruise Control feature as per the Requirement Document using MATLAB Simulink.
- Following all the MBD related processes: Requirement Tagging & Traceability, SLDD creation, Configuration Parameter changes, Model Advisor check & Code Generation.
- In Configuration Parameters: enable “Support Floating Numbers” under Code Generation settings.
- Use Embedded Coder to generate the code.
- If choosing code generation, Storage class for Input signals: ImportedExtern; Storage class for Output signal: Export to File; Storage class for local signals: localizable; Storage class for calibration signals: Const.
- Choose sample time for all signals as 0.01s.
MATLAB FUNCTIONAL MODEL :
- CHANGE SOLVER SETTING.
- CHANGE CODE GENERATION SETTING.
- CREATE SLDD FILE.
- CREATE REQUIREMENT 1 SUBSYSTEM.
- CREATE REQUIREMENT 2 SUBSYSTEM.
- CREATE REQUIREMENT 3 SUBSYSTEM.
- CREATE SUBSYSTEM.
- TAG THE SUBSYSTEM'S.
- RESOLVE AND PROPOGATE THE SIGNAL.
- GO FOR MODEL ADVISOR TEST.
- GO FOR CODE GENERATION.
CHANGE SOLVER SETTING :

CHANGE CODE GENERTION SETTING :

CREATE SLDD FILE :

Requirement 1– Lead Vehicle :
- 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.

REQUIREMENT-1 SUBSYSTEM :

Requirement 2 – Drive Vehicle :
- 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.

REQUIREMENT-2 SUBSYSTEM :

Requirement 3 – Adaptive Cruise Control Algorithm :
- 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.
ACC LOGIC :

- MOVE TO SYMBOL PANE OPTION AND DEFINE 'INPUTS' AND 'OUTPUTS'.
- MOVE FOR MODEL EXPLORER.
- CHANGE THE DATA TYPE.


REQUIREMENT-3 SUBSYSTEM :


CREATED SUBSYSTEM :

TAG ALL THREE SUBSYSTEM'S :
- RIGHT CLICK ON SUBSYSTEM.
- MOVE TO REQUIREMENT.
- LINK TO SELECTION IN WORD.
- REPEAT SAME BELOW PROCESS FOR ALL THREE SUBSYSTEM'S TO TAG THE SUBSYSTEM.

RESOLVE AND PROPOGATE THE SIGNAL'S :
- DOUBLE CLICK ON SIGNAL.
- THEN, RIGHT CLICK.
- MOVE TO PROPERTIES.
- PUT THE SIGNAL NAME.
- ENABLE 'SIGNAL NAME MUST RESOLVE TO SIMULINK SIGNAL OBJECT'.
- FOR PROPOGATION JUST DOUBLE TAP ON LINE.
- USE THIS SYMBOL '<>'.
- PUT ENTER INSIDE THIS.
STEP-1 :

STEP-2 :

ACC MODEL :

MODEL ADVISOR :
- GO TO MODELING OPTION.
- MOVE TO MODEL ADVISOR.
- TAP ON THAT.
- MOVE TO BY TASK OPTION.
- ENABLE ONLY MODELING SIMULINK FOR MAB.
- RUN SELECTED CHECKS.
- REDUCE WARNINGS.
- GENERATE REPORT.
STEP-1 :

STEP-2 :

STEP-3 :

C-CODE GENERATION :
- MOVE TO APPS OPTION.
- GO FOR EMBEDDED CODER.
- TAP ON THAT.
- GO TO BUILD OPTION.
- GENERATE THE CODE.
STEP-1 :

STEP-2 :

STEP-3 :
/*
* File: ACC.c
*
* Code generated for Simulink model 'ACC'.
*
* Model version : 1.36
* Simulink Coder version : 9.3 (R2020a) 18-Nov-2019
* C/C++ source code generated on : Wed Jun 15 11:49:15 2022
*
* Target selection: ert.tlc
* Embedded hardware selection: Intel->x86-64 (Windows64)
* Code generation objectives: Unspecified
* Validation result: Not run
*/
#include "ACC.h"
#include "ACC_private.h"
/* Named constants for Chart: '/Chart' */
#define ACC_IN_ACC_OFF_MODE ((uint8_T)1U)
#define ACC_IN_ACC_ON_MODE ((uint8_T)2U)
#define ACC_IN_ACC_STANDBY_MODE ((uint8_T)3U)
#define ACC_IN_LeadVehicle_Not_Detected ((uint8_T)3U)
#define ACC_IN_NO_ACTIVE_CHILD ((uint8_T)0U)
#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)
/* Exported data definition */
/* Definition for custom storage class: ExportToFile */
uint8_T Acceleration_Mode; /* '/Unit Delay' */
/* Definition for custom storage class: Localizable */
static uint8_T DriveVehicle_Speed; /* '/Add' */
static uint8_T LeadVehicle_Detected; /* '/Signal Conversion' */
static uint8_T LeadVehicle_Speed; /* '/Add' */
/* Block states (default storage) */
DW_ACC_T ACC_DW;
/* External outputs (root outports fed by signals with default storage) */
ExtY_ACC_T ACC_Y;
/* Real-time model */
RT_MODEL_ACC_T ACC_M_;
RT_MODEL_ACC_T *const ACC_M = &ACC_M_;
/* Forward declaration for local functions */
static void ACC_ACC_ON_MODE(void);
real_T rt_roundd_snf(real_T u)
{
real_T y;
if (fabs(u) < 4.503599627370496E+15) {
if (u >= 0.5) {
y = floor(u + 0.5);
} else if (u > -0.5) {
y = u * 0.0;
} else {
y = ceil(u - 0.5);
}
} else {
y = u;
}
return y;
}
/* Function for Chart: '/Chart' */
static void ACC_ACC_ON_MODE(void)
{
int32_T tmp;
int32_T tmp_0;
uint8_T tmp_1;
uint8_T tmp_2;
/* Inport: '/SetSwitch' incorporates:
* Inport: '/CruiseSwitch'
*/
if (!SetSwitch) {
ACC_DW.is_ACC_ON_MODE = ACC_IN_NO_ACTIVE_CHILD;
ACC_DW.is_c3_ACC = ACC_IN_ACC_STANDBY_MODE;
/* Outport: '/Acceleration_Mode' */
ACC_Y.Acceleration_Mode_a = 1U;
} else if (!CruiseSwitch) {
ACC_DW.is_ACC_ON_MODE = ACC_IN_NO_ACTIVE_CHILD;
ACC_DW.is_c3_ACC = ACC_IN_ACC_OFF_MODE;
/* Outport: '/Acceleration_Mode' */
ACC_Y.Acceleration_Mode_a = 0U;
} else {
switch (ACC_DW.is_ACC_ON_MODE) {
case IN_LeadVehicle_Detected_Follow:
/* Outport: '/Acceleration_Mode' */
/* Inport: '/Set_Gap' incorporates:
* Inport: '/Set_Speed'
* Inport: '/Time_Gap'
*/
ACC_Y.Acceleration_Mode_a = 2U;
if (LeadVehicle_Detected == 0) {
ACC_DW.is_ACC_ON_MODE = ACC_IN_LeadVehicle_Not_Detected;
/* Outport: '/Acceleration_Mode' */
ACC_Y.Acceleration_Mode_a = 1U;
} else {
if (((LeadVehicle_Detected == 1) && (LeadVehicle_Speed < Set_Speed)) ||
(Time_Gap < Set_Gap)) {
ACC_DW.is_ACC_ON_MODE = IN_LeadVehicle_Speed_lessthan_S;
/* Outport: '/Acceleration_Mode' */
ACC_Y.Acceleration_Mode_a = 4U;
}
}
break;
case IN_LeadVehicle_Detected_Resume:
/* Outport: '/Acceleration_Mode' */
ACC_Y.Acceleration_Mode_a = 3U;
/* Inport: '/Set_Speed' incorporates:
* Inport: '/Set_Gap'
* Inport: '/Time_Gap'
*/
if ((DriveVehicle_Speed == Set_Speed) && (LeadVehicle_Speed >= Set_Speed) &&
(Time_Gap >= Set_Gap)) {
ACC_DW.is_ACC_ON_MODE = IN_LeadVehicle_Detected_Follow;
/* Outport: '/Acceleration_Mode' */
ACC_Y.Acceleration_Mode_a = 2U;
} else if (LeadVehicle_Detected == 0) {
ACC_DW.is_ACC_ON_MODE = IN_LeadVehicle_Not_Detected_Res;
/* Outport: '/Acceleration_Mode' */
ACC_Y.Acceleration_Mode_a = 1U;
} else {
if ((DriveVehicle_Speed < Set_Speed) && (LeadVehicle_Speed >
DriveVehicle_Speed) && (Time_Gap >= Set_Gap)) {
ACC_DW.is_ACC_ON_MODE = IN_LeadVehicle_Speed_equal_Set_;
/* Outport: '/Acceleration_Mode' */
ACC_Y.Acceleration_Mode_a = 5U;
}
}
break;
case ACC_IN_LeadVehicle_Not_Detected:
/* Outport: '/Acceleration_Mode' */
ACC_Y.Acceleration_Mode_a = 1U;
/* Inport: '/Set_Speed' incorporates:
* Inport: '/Set_Gap'
* Inport: '/Time_Gap'
*/
if ((LeadVehicle_Detected == 1) && (DriveVehicle_Speed == Set_Speed) &&
(LeadVehicle_Speed >= Set_Speed) && (Time_Gap >= Set_Gap)) {
ACC_DW.is_ACC_ON_MODE = IN_LeadVehicle_Detected_Follow;
/* Outport: '/Acceleration_Mode' */
ACC_Y.Acceleration_Mode_a = 2U;
} else {
if (((LeadVehicle_Detected == 1) && (LeadVehicle_Speed < Set_Speed)) ||
(Time_Gap < Set_Gap)) {
ACC_DW.is_ACC_ON_MODE = IN_LeadVehicle_Speed_lessthan_S;
/* Outport: '/Acceleration_Mode' */
ACC_Y.Acceleration_Mode_a = 4U;
}
}
break;
case IN_LeadVehicle_Not_Detected_Res:
/* Outport: '/Acceleration_Mode' */
ACC_Y.Acceleration_Mode_a = 1U;
break;
case IN_LeadVehicle_Speed_equal_Set_:
/* Outport: '/Acceleration_Mode' */
ACC_Y.Acceleration_Mode_a = 5U;
/* Inport: '/Set_Speed' incorporates:
* Inport: '/Set_Gap'
* Inport: '/Time_Gap'
*/
if (((DriveVehicle_Speed < Set_Speed) && (LeadVehicle_Speed >
DriveVehicle_Speed)) || (Time_Gap >= Set_Gap)) {
ACC_DW.is_ACC_ON_MODE = IN_LeadVehicle_Detected_Resume;
/* Outport: '/Acceleration_Mode' */
ACC_Y.Acceleration_Mode_a = 3U;
} else if ((LeadVehicle_Detected == 0) || (DriveVehicle_Speed <= Set_Speed))
{
ACC_DW.is_ACC_ON_MODE = IN_LeadVehicle_Not_Detected_Res;
/* Outport: '/Acceleration_Mode' */
ACC_Y.Acceleration_Mode_a = 1U;
} else {
if (((LeadVehicle_Speed < Set_Speed) && (LeadVehicle_Speed <
DriveVehicle_Speed)) || ((int32_T)rt_roundd_snf(0.75 * (real_T)
Set_Gap) == Time_Gap)) {
ACC_DW.is_ACC_ON_MODE = IN_LeadVehicle_Speed_lessthan_S;
/* Outport: '/Acceleration_Mode' */
ACC_Y.Acceleration_Mode_a = 4U;
}
}
break;
default:
/* Outport: '/Acceleration_Mode' */
/* case IN_LeadVehicle_Speed_lessthan_Set_Speed: */
ACC_Y.Acceleration_Mode_a = 4U;
/* Inport: '/Set_Speed' */
if ((LeadVehicle_Detected == 0) && (DriveVehicle_Speed == Set_Speed)) {
ACC_DW.is_ACC_ON_MODE = ACC_IN_LeadVehicle_Not_Detected;
/* Outport: '/Acceleration_Mode' */
ACC_Y.Acceleration_Mode_a = 1U;
} else {
tmp = (int32_T)rt_roundd_snf((real_T)LeadVehicle_Speed * 1.25);
/* Inport: '/Set_Gap' */
tmp_0 = (int32_T)rt_roundd_snf(1.25 * (real_T)Set_Gap);
if (tmp < 256) {
tmp_1 = (uint8_T)tmp;
} else {
tmp_1 = MAX_uint8_T;
}
if (tmp_0 < 256) {
tmp_2 = (uint8_T)tmp_0;
} else {
tmp_2 = MAX_uint8_T;
}
/* Inport: '/Time_Gap' incorporates:
* Inport: '/Set_Gap'
*/
if ((tmp_1 >= DriveVehicle_Speed) && ((int32_T)rt_roundd_snf((real_T)
LeadVehicle_Speed * 0.75) <= DriveVehicle_Speed) &&
(DriveVehicle_Speed < Set_Speed) && (Time_Gap <= tmp_2) && (Time_Gap
>= (int32_T)rt_roundd_snf(0.75 * (real_T)Set_Gap))) {
ACC_DW.is_ACC_ON_MODE = IN_LeadVehicle_Speed_equal_Set_;
/* Outport: '/Acceleration_Mode' */
ACC_Y.Acceleration_Mode_a = 5U;
}
}
break;
}
}
/* End of Inport: '/SetSwitch' */
}
/* Model step function */
void ACC_step(void)
{
/* Sum: '/Add' incorporates:
* Inport: '/CameraInput_LeadVehicle'
* Inport: '/RadarInput_LeadVehicle'
*/
LeadVehicle_Speed = (uint8_T)((uint32_T)CameraInput_LeadVehicle +
RadarInput_LeadVehicle);
/* UnitDelay: '/Unit Delay' */
Acceleration_Mode = ACC_DW.UnitDelay_DSTATE;
/* Sum: '/Add' incorporates:
* Inport: '/CameraInput_DriveVehicle'
* Inport: '/RadarInput_DriveVehicle'
*/
DriveVehicle_Speed = (uint8_T)((uint32_T)(uint8_T)((uint32_T)
CameraInput_DriveVehicle + Acceleration_Mode) + RadarInput_DriveVehicle);
/* SignalConversion: '/Signal Conversion' incorporates:
* Inport: '/RadarInput_DriveVehicle'
*/
LeadVehicle_Detected = RadarInput_DriveVehicle;
/* Chart: '/Chart' incorporates:
* Inport: '/CruiseSwitch'
* Inport: '/SetSwitch'
*/
if (ACC_DW.is_active_c3_ACC == 0U) {
ACC_DW.is_active_c3_ACC = 1U;
ACC_DW.is_c3_ACC = ACC_IN_ACC_OFF_MODE;
/* Outport: '/Acceleration_Mode' */
ACC_Y.Acceleration_Mode_a = 0U;
} else {
switch (ACC_DW.is_c3_ACC) {
case ACC_IN_ACC_OFF_MODE:
/* Outport: '/Acceleration_Mode' */
ACC_Y.Acceleration_Mode_a = 0U;
if (CruiseSwitch) {
ACC_DW.is_c3_ACC = ACC_IN_ACC_STANDBY_MODE;
/* Outport: '/Acceleration_Mode' */
ACC_Y.Acceleration_Mode_a = 1U;
}
break;
case ACC_IN_ACC_ON_MODE:
ACC_ACC_ON_MODE();
break;
default:
/* Outport: '/Acceleration_Mode' */
/* case IN_ACC_STANDBY_MODE: */
ACC_Y.Acceleration_Mode_a = 1U;
if (!CruiseSwitch) {
ACC_DW.is_c3_ACC = ACC_IN_ACC_OFF_MODE;
/* Outport: '/Acceleration_Mode' */
ACC_Y.Acceleration_Mode_a = 0U;
} else {
if (SetSwitch) {
ACC_DW.is_c3_ACC = ACC_IN_ACC_ON_MODE;
ACC_DW.is_ACC_ON_MODE = IN_LeadVehicle_Detected_Follow;
/* Outport: '/Acceleration_Mode' */
ACC_Y.Acceleration_Mode_a = 2U;
}
}
break;
}
}
/* End of Chart: '/Chart' */
/* Update for UnitDelay: '/Unit Delay' incorporates:
* Outport: '/Acceleration_Mode'
*/
ACC_DW.UnitDelay_DSTATE = ACC_Y.Acceleration_Mode_a;
}
/* Model initialize function */
void ACC_initialize(void)
{
/* (no initialization code required) */
}
/* Model terminate function */
void ACC_terminate(void)
{
/* (no terminate code required) */
}
/*
* File trailer for generated code.
*
* [EOF]
*/