Challenge

Project 2 Adaptive Cruise Control

STUDENT OF ONLINE EV BATCH 16

ANS :

OBJECTIVE :

  1. Developing Adaptive Cruise Control feature as per the Requirement Document using MATLAB Simulink.
  2. Following all the MBD related processes: Requirement Tagging & Traceability, SLDD creation, Configuration Parameter changes, Model Advisor check & Code Generation.
  3. In Configuration Parameters: enable “Support Floating Numbers” under Code Generation settings.
  4. Use Embedded Coder to generate the code.
  5. 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.
  6. 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]
 */
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.

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.