MATLAB Examples

Aircraft Position Radar Model

This model shows the code generated for a Simulink model containing a MATLAB script.

The model contains an Extended Kalman Filter that estimates aircraft position from radar measurements. The MATLAB script rtwdemo_eml_aero_radar.m contains data for running the model. The estimated and actual positions are saved to the workspace and are plotted at the end of the simulation by the program rtwdemo_aero_radplot (called from the simulation automatically).

Contents

Review and Simulate the Model

In this section you should review the model and perform a simulation.

Open the Simulink model.

model='rtwdemo_eml_aero_radar';
open_system(model)
rtwdemo_eml_aero_radar([],[],[],'compile');
rtwdemo_eml_aero_radar([],[],[],'term');

Open the MATLAB Function block RadarTracker in the MATLAB Editor.

open_system([model,'/RadarTracker'])

Simulate the model and review the results (displayed automatically.)

sim(model)

Generate Code for the Model

In this section you will generate code for the Kalman Filter portion of the model using the subsystem build functionality provided by Simulink Coder. In the first build, the model is configured to generate code using Simulink Coder. In the second build, the model is configured to generate code using Embedded Coder.

% Create a temporary folder (in your system's temporary folder) for the
% build and inspection process.
currentDir = pwd;
[~,cgDir] = rtwdemodir();

Configure and build the model using Simulink Coder.

rtwconfiguredemo(model,'GRT')
rtwbuild([model,'/RadarTracker'])
### Starting build procedure for model: RadarTracker
### Successful completion of build procedure for model: RadarTracker

Configure and build the model using Embedded Coder.

rtwconfiguredemo(model,'ERT')
rtwbuild([model,'/RadarTracker'])
### Starting build procedure for model: RadarTracker
### Successful completion of build procedure for model: RadarTracker

A portion of RadarTracker.c is listed below.

cfile = fullfile(cgDir,'RadarTracker_ert_rtw','RadarTracker.c');
rtwdemodbtype(cfile,'/* Model step', '/* Model initialize', 1, 0);
/* Model step function */
void RadarTracker_step(void)
{
  int8_T Phi[16];
  real_T Q[16];
  real_T Rangehat;
  real_T Bearinghat;
  real_T M[8];
  real_T W[8];
  int32_T j;
  real_T x[4];
  real_T r;
  static const real_T d[4] = { 0.0, 0.005, 0.0, 0.005 };

  static const real_T R[4] = { 90000.0, 0.0, 0.0, 1.0E-6 };

  real_T Phi_0[16];
  real_T Phi_1[4];
  real_T M_0[8];
  real_T Phi_2[16];
  real_T Q_0[16];
  int32_T i;
  real_T M_tmp;
  real_T M_tmp_0;

  /* MATLAB Function: '<Root>/RadarTracker' incorporates:
   *  Inport: '<Root>/meas'
   */
  Phi[0] = 1;
  Phi[4] = 1;
  Phi[8] = 0;
  Phi[12] = 0;
  Phi[2] = 0;
  Phi[6] = 0;
  Phi[10] = 1;
  Phi[14] = 1;
  Phi[1] = 0;
  Phi[3] = 0;
  Phi[5] = 1;
  Phi[7] = 0;
  Phi[9] = 0;
  Phi[11] = 0;
  Phi[13] = 0;
  Phi[15] = 1;
  memset(&Q[0], 0, sizeof(real_T) << 4U);
  for (j = 0; j < 4; j++) {
    Q[j + (j << 2)] = d[j];
    for (i = 0; i < 4; i++) {
      Phi_0[j + (i << 2)] = 0.0;
      Phi_0[j + (i << 2)] += rtDW.P_c[i << 2] * (real_T)Phi[j];
      Phi_0[j + (i << 2)] += rtDW.P_c[(i << 2) + 1] * (real_T)Phi[j + 4];
      Phi_0[j + (i << 2)] += rtDW.P_c[(i << 2) + 2] * (real_T)Phi[j + 8];
      Phi_0[j + (i << 2)] += rtDW.P_c[(i << 2) + 3] * (real_T)Phi[j + 12];
    }
  }

  for (i = 0; i < 4; i++) {
    Phi_1[i] = 0.0;
    for (j = 0; j < 4; j++) {
      rtDW.P_c[i + (j << 2)] = (((Phi_0[i + 4] * (real_T)Phi[j + 4] + Phi_0[i] *
        (real_T)Phi[j]) + Phi_0[i + 8] * (real_T)Phi[j + 8]) + Phi_0[i + 12] *
        (real_T)Phi[j + 12]) + Q[(j << 2) + i];
      Phi_1[i] += (real_T)Phi[(j << 2) + i] * rtDW.xhat[j];
    }
  }

  rtDW.xhat[0] = Phi_1[0];
  rtDW.xhat[1] = Phi_1[1];
  rtDW.xhat[2] = Phi_1[2];
  rtDW.xhat[3] = Phi_1[3];
  Rangehat = sqrt(rtDW.xhat[0] * rtDW.xhat[0] + rtDW.xhat[2] * rtDW.xhat[2]);
  Bearinghat = atan2(rtDW.xhat[2], rtDW.xhat[0]);
  M_tmp_0 = cos(Bearinghat);
  M[0] = M_tmp_0;
  M[2] = 0.0;
  M_tmp = sin(Bearinghat);
  M[4] = M_tmp;
  M[6] = 0.0;
  M[1] = -M_tmp / Rangehat;
  M[3] = 0.0;
  M[5] = M_tmp_0 / Rangehat;
  M[7] = 0.0;
  rtY.residual[0] = rtU.meas[0] - Rangehat;
  rtY.residual[1] = rtU.meas[1] - Bearinghat;
  for (i = 0; i < 2; i++) {
    for (j = 0; j < 4; j++) {
      M_0[i + (j << 1)] = 0.0;
      M_0[i + (j << 1)] += rtDW.P_c[j << 2] * M[i];
      M_0[i + (j << 1)] += rtDW.P_c[(j << 2) + 2] * M[i + 4];
    }

    for (j = 0; j < 2; j++) {
      x[i + (j << 1)] = (M_0[i + 4] * M[j + 4] + M_0[i] * M[j]) + R[(j << 1) + i];
    }
  }

  if (fabs(x[1]) > fabs(x[0])) {
    r = x[0] / x[1];
    Rangehat = 1.0 / (r * x[3] - x[2]);
    Bearinghat = x[3] / x[1] * Rangehat;
    M_tmp_0 = -Rangehat;
    M_tmp = -x[2] / x[1] * Rangehat;
    Rangehat *= r;
  } else {
    r = x[1] / x[0];
    Rangehat = 1.0 / (x[3] - r * x[2]);
    Bearinghat = x[3] / x[0] * Rangehat;
    M_tmp_0 = -r * Rangehat;
    M_tmp = -x[2] / x[0] * Rangehat;
  }

  for (i = 0; i < 4; i++) {
    for (j = 0; j < 2; j++) {
      M_0[i + (j << 2)] = 0.0;
      M_0[i + (j << 2)] += rtDW.P_c[i] * M[j];
      M_0[i + (j << 2)] += rtDW.P_c[i + 8] * M[j + 4];
    }

    W[i] = 0.0;
    W[i] += M_0[i] * Bearinghat;
    W[i] += M_0[i + 4] * M_tmp_0;
    r = W[i] * rtY.residual[0];
    W[i + 4] = 0.0;
    W[i + 4] += M_0[i] * M_tmp;
    W[i + 4] += M_0[i + 4] * Rangehat;
    r += W[i + 4] * rtY.residual[1];
    rtDW.xhat[i] += r;
  }

  memset(&Q[0], 0, sizeof(real_T) << 4U);
  for (i = 0; i < 16; i++) {
    Phi[i] = 0;
  }

  Phi[0] = 1;
  Phi[5] = 1;
  Phi[10] = 1;
  Phi[15] = 1;
  for (j = 0; j < 4; j++) {
    Q[j + (j << 2)] = 1.0;
    for (i = 0; i < 4; i++) {
      Phi_0[j + (i << 2)] = (real_T)Phi[(i << 2) + j] - (M[(i << 1) + 1] * W[j +
        4] + M[i << 1] * W[j]);
    }

    for (i = 0; i < 4; i++) {
      Phi_2[j + (i << 2)] = 0.0;
      Phi_2[j + (i << 2)] += rtDW.P_c[i << 2] * Phi_0[j];
      Phi_2[j + (i << 2)] += rtDW.P_c[(i << 2) + 1] * Phi_0[j + 4];
      Phi_2[j + (i << 2)] += rtDW.P_c[(i << 2) + 2] * Phi_0[j + 8];
      Phi_2[j + (i << 2)] += rtDW.P_c[(i << 2) + 3] * Phi_0[j + 12];
    }
  }

  for (i = 0; i < 4; i++) {
    for (j = 0; j < 4; j++) {
      Q_0[i + (j << 2)] = Q[(i << 2) + j] - (M[(i << 1) + 1] * W[j + 4] + M[i <<
        1] * W[j]);
    }

    M_0[i] = 0.0;
    M_0[i] += W[i] * 90000.0;
    M_0[i + 4] = 0.0;
    M_0[i + 4] += W[i + 4] * 1.0E-6;
  }

  for (i = 0; i < 4; i++) {
    for (j = 0; j < 4; j++) {
      Phi_0[i + (j << 2)] = 0.0;
      Phi_0[i + (j << 2)] += Q_0[j << 2] * Phi_2[i];
      Phi_0[i + (j << 2)] += Q_0[(j << 2) + 1] * Phi_2[i + 4];
      Phi_0[i + (j << 2)] += Q_0[(j << 2) + 2] * Phi_2[i + 8];
      Phi_0[i + (j << 2)] += Q_0[(j << 2) + 3] * Phi_2[i + 12];
      Q[i + (j << 2)] = 0.0;
      Q[i + (j << 2)] += M_0[i] * W[j];
      Q[i + (j << 2)] += M_0[i + 4] * W[j + 4];
    }
  }

  for (i = 0; i < 4; i++) {
    rtDW.P_c[i << 2] = Phi_0[i << 2] + Q[i << 2];
    rtDW.P_c[1 + (i << 2)] = Phi_0[(i << 2) + 1] + Q[(i << 2) + 1];
    rtDW.P_c[2 + (i << 2)] = Phi_0[(i << 2) + 2] + Q[(i << 2) + 2];
    rtDW.P_c[3 + (i << 2)] = Phi_0[(i << 2) + 3] + Q[(i << 2) + 3];

    /* Outport: '<Root>/xhatOut' */
    rtY.xhatOut[i] = rtDW.xhat[i];
  }

  /* End of MATLAB Function: '<Root>/RadarTracker' */
}

You can view the entire generated code in a detailed HTML report, with bi-directional traceability between model and code.

web(fullfile(cgDir,'RadarTracker_ert_rtw','html','RadarTracker_codegen_rpt.html'))

Close the model and cleanup.

bdclose(model)
rtwdemoclean;
cd(currentDir)