Contenuto principale

Aircraft Position Radar Model

R2026b

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 AircraftPositionData.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 AircraftPositionPlot.m (called from the simulation automatically).

Review and Simulate the Model

Review the model and perform a simulation.

Open the Simulink model.

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

Open the MATLAB Function block RadarTrackerFcn in the MATLAB Editor.

open_system([model,'/RadarTrackerFcn'])

Simulate the model and review the results.

sim(model)

Generate Code for the Model

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®.

Configure and build the model using Simulink Coder.

set_param(model, "SystemTargetFile", "grt.tlc");
slbuild([model,'/RadarTrackerFcn'])
### Searching for referenced models in model 'RadarTrackerFcn'.
### Total of 1 models to build.
### Starting top model code generation target build for: RadarTrackerFcn
### Successful completion of build procedure for: RadarTrackerFcn

Build Summary

Top model targets:

Model            Build Reason                               Status                        Build Duration
========================================================================================================
RadarTrackerFcn  Target (RadarTrackerFcn.c) did not exist.  Code generated and compiled.  0h 0m 14.998s

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

Configure and build the model using Embedded Coder.

set_param(model, "SystemTargetFile", "ert.tlc");
slbuild([model,'/RadarTrackerFcn'])
### Searching for referenced models in model 'RadarTrackerFcn'.
### Total of 1 models to build.
### Starting top model code generation target build for: RadarTrackerFcn
### Successful completion of build procedure for: RadarTrackerFcn

Build Summary

Top model targets:

Model            Build Reason                               Status                        Build Duration
========================================================================================================
RadarTrackerFcn  Target (RadarTrackerFcn.c) did not exist.  Code generated and compiled.  0h 0m 12.03s

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

A portion of RadarTrackerFcn.c is listed below.

cfile = fullfile(pwd,'RadarTrackerFcn_ert_rtw','RadarTrackerFcn.c');
coder.example.extractLines(cfile,'/* Model step', '/* Model initialize', 1, 0);
/* Model step function */
void RadarTrackerFcn_step(void)
{
  __m128d tmp_1;
  double P_tmp[16];
  double Phi_0[16];
  double Q[16];
  double Q_0[16];
  double M[8];
  double W[8];
  double tmp[8];
  double x_tmp[8];
  double b[4];
  double x[4];
  double tmp_0[2];
  double Bearinghat;
  double Phi_1;
  double Phi_2;
  double Rangehat;
  int32_t Q_tmp;
  int32_t i;
  int32_t j;
  int32_t x_tmp_tmp;
  int8_t Phi[16];
  static const double e[4] = { 0.0, 0.005, 0.0, 0.005 };

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

  /* MATLAB Function: '<Root>/RadarTrackerFcn' 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(double) << 4U);
  for (j = 0; j < 4; j++) {
    Q_tmp = j << 2;
    Q[j + Q_tmp] = e[j];
    Rangehat = 0.0;
    Bearinghat = 0.0;
    Phi_1 = 0.0;
    Phi_2 = 0.0;
    for (i = 0; i < 4; i++) {
      x_tmp_tmp = i << 2;
      tmp_1 = _mm_set1_pd(RadarTrackerFcn_DW.P[Q_tmp + i]);
      _mm_storeu_pd(&tmp_0[0], _mm_add_pd(_mm_mul_pd(_mm_set_pd(Phi[x_tmp_tmp +
        1], Phi[x_tmp_tmp]), tmp_1), _mm_set_pd(Bearinghat, Rangehat)));
      Rangehat = tmp_0[0];
      Bearinghat = tmp_0[1];
      _mm_storeu_pd(&tmp_0[0], _mm_add_pd(_mm_mul_pd(_mm_set_pd(Phi[x_tmp_tmp +
        3], Phi[x_tmp_tmp + 2]), tmp_1), _mm_set_pd(Phi_2, Phi_1)));
      Phi_1 = tmp_0[0];
      Phi_2 = tmp_0[1];
    }

    Phi_0[Q_tmp + 3] = Phi_2;
    Phi_0[Q_tmp + 2] = Phi_1;
    Phi_0[Q_tmp + 1] = Bearinghat;
    Phi_0[Q_tmp] = Rangehat;
  }

  for (i = 0; i < 4; i++) {
    Rangehat = Phi_0[i + 4];
    Bearinghat = Phi_0[i];
    Phi_1 = Phi_0[i + 8];
    Phi_2 = Phi_0[i + 12];
    for (x_tmp_tmp = 0; x_tmp_tmp <= 2; x_tmp_tmp += 2) {
      j = (x_tmp_tmp << 2) + i;
      Q_tmp = ((x_tmp_tmp + 1) << 2) + i;
      _mm_storeu_pd(&tmp_0[0], _mm_add_pd(_mm_add_pd(_mm_add_pd(_mm_add_pd
        (_mm_mul_pd(_mm_set1_pd(Rangehat), _mm_set_pd(Phi[x_tmp_tmp + 5],
        Phi[x_tmp_tmp + 4])), _mm_mul_pd(_mm_set1_pd(Bearinghat), _mm_set_pd
        (Phi[x_tmp_tmp + 1], Phi[x_tmp_tmp]))), _mm_mul_pd(_mm_set1_pd(Phi_1),
        _mm_set_pd(Phi[x_tmp_tmp + 9], Phi[x_tmp_tmp + 8]))), _mm_mul_pd
        (_mm_set1_pd(Phi_2), _mm_set_pd(Phi[x_tmp_tmp + 13], Phi[x_tmp_tmp + 12]))),
        _mm_set_pd(Q[Q_tmp], Q[j])));
      RadarTrackerFcn_DW.P[j] = tmp_0[0];
      RadarTrackerFcn_DW.P[Q_tmp] = tmp_0[1];
    }
  }

  Rangehat = 0.0;
  Bearinghat = 0.0;
  Phi_1 = 0.0;
  Phi_2 = 0.0;
  for (i = 0; i < 4; i++) {
    x_tmp_tmp = i << 2;
    tmp_1 = _mm_set1_pd(RadarTrackerFcn_DW.xhat[i]);
    _mm_storeu_pd(&tmp_0[0], _mm_add_pd(_mm_mul_pd(_mm_set_pd(Phi[x_tmp_tmp + 1],
      Phi[x_tmp_tmp]), tmp_1), _mm_set_pd(Bearinghat, Rangehat)));
    Rangehat = tmp_0[0];
    Bearinghat = tmp_0[1];
    _mm_storeu_pd(&tmp_0[0], _mm_add_pd(_mm_mul_pd(_mm_set_pd(Phi[x_tmp_tmp + 3],
      Phi[x_tmp_tmp + 2]), tmp_1), _mm_set_pd(Phi_2, Phi_1)));
    Phi_1 = tmp_0[0];
    Phi_2 = tmp_0[1];
  }

  RadarTrackerFcn_DW.xhat[0] = Rangehat;
  RadarTrackerFcn_DW.xhat[1] = Bearinghat;
  RadarTrackerFcn_DW.xhat[2] = Phi_1;
  RadarTrackerFcn_DW.xhat[3] = Phi_2;
  Rangehat = sqrt(RadarTrackerFcn_DW.xhat[0] * RadarTrackerFcn_DW.xhat[0] +
                  RadarTrackerFcn_DW.xhat[2] * RadarTrackerFcn_DW.xhat[2]);
  Bearinghat = rt_atan2d_snf(RadarTrackerFcn_DW.xhat[2],
    RadarTrackerFcn_DW.xhat[0]);
  Phi_1 = sin(Bearinghat);
  Phi_2 = cos(Bearinghat);
  M[0] = Phi_2;
  M[2] = 0.0;
  M[4] = Phi_1;
  M[6] = 0.0;
  M[1] = -Phi_1 / Rangehat;
  M[3] = 0.0;
  M[5] = Phi_2 / Rangehat;
  M[7] = 0.0;
  _mm_storeu_pd(&RadarTrackerFcn_Y.residual[0], _mm_sub_pd(_mm_loadu_pd
    (&RadarTrackerFcn_U.meas[0]), _mm_set_pd(Bearinghat, Rangehat)));
  for (i = 0; i < 2; i++) {
    x_tmp_tmp = i << 2;
    x_tmp[x_tmp_tmp] = M[i];
    x_tmp[x_tmp_tmp + 1] = 0.0;
    x_tmp[x_tmp_tmp + 2] = M[i + 4];
    x_tmp[x_tmp_tmp + 3] = 0.0;
  }

  for (i = 0; i < 4; i++) {
    Rangehat = 0.0;
    Bearinghat = 0.0;
    for (x_tmp_tmp = 0; x_tmp_tmp < 4; x_tmp_tmp++) {
      _mm_storeu_pd(&tmp_0[0], _mm_add_pd(_mm_mul_pd(_mm_loadu_pd(&M[x_tmp_tmp <<
        1]), _mm_set1_pd(RadarTrackerFcn_DW.P[(i << 2) + x_tmp_tmp])),
        _mm_set_pd(Bearinghat, Rangehat)));
      Rangehat = tmp_0[0];
      Bearinghat = tmp_0[1];
    }

    x_tmp_tmp = i << 1;
    W[x_tmp_tmp + 1] = Bearinghat;
    W[x_tmp_tmp] = Rangehat;
  }

  for (i = 0; i < 2; i++) {
    Rangehat = W[i + 2];
    Phi_1 = W[i + 4];
    Phi_2 = W[i + 6];
    j = 0 + i;
    Q_tmp = 2 + i;
    _mm_storeu_pd(&tmp_0[0], _mm_add_pd(_mm_add_pd(_mm_add_pd(_mm_add_pd
      (_mm_mul_pd(_mm_set_pd(x_tmp[5], x_tmp[1]), _mm_set1_pd(Rangehat)),
       _mm_mul_pd(_mm_set_pd(x_tmp[4], x_tmp[0]), _mm_set1_pd(W[i]))),
      _mm_mul_pd(_mm_set_pd(x_tmp[6], x_tmp[2]), _mm_set1_pd(Phi_1))),
      _mm_mul_pd(_mm_set_pd(x_tmp[7], x_tmp[3]), _mm_set1_pd(Phi_2))),
      _mm_set_pd(c_b[Q_tmp], c_b[j])));
    x[0 + i] = tmp_0[0];
    x[2 + i] = tmp_0[1];
  }

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

  for (i = 0; i < 2; i++) {
    Rangehat = 0.0;
    Bearinghat = 0.0;
    Phi_1 = 0.0;
    Phi_2 = 0.0;
    for (x_tmp_tmp = 0; x_tmp_tmp < 4; x_tmp_tmp++) {
      j = x_tmp_tmp << 2;
      Q_tmp = (i << 2) + x_tmp_tmp;
      tmp_1 = _mm_set1_pd(x_tmp[Q_tmp]);
      _mm_storeu_pd(&tmp_0[0], _mm_add_pd(_mm_mul_pd(_mm_loadu_pd
        (&RadarTrackerFcn_DW.P[j]), tmp_1), _mm_set_pd(Bearinghat, Rangehat)));
      Rangehat = tmp_0[0];
      Bearinghat = tmp_0[1];
      _mm_storeu_pd(&tmp_0[0], _mm_add_pd(_mm_mul_pd(_mm_loadu_pd
        (&RadarTrackerFcn_DW.P[j + 2]), tmp_1), _mm_set_pd(Phi_2, Phi_1)));
      Phi_1 = tmp_0[0];
      Phi_2 = tmp_0[1];
      W[Q_tmp] = 0.0;
    }

    x_tmp_tmp = i << 2;
    tmp[x_tmp_tmp + 3] = Phi_2;
    tmp[x_tmp_tmp + 2] = Phi_1;
    tmp[x_tmp_tmp + 1] = Bearinghat;
    tmp[x_tmp_tmp] = Rangehat;
  }

  for (i = 0; i < 2; i++) {
    Q_tmp = i << 2;
    Rangehat = W[Q_tmp];
    Bearinghat = W[Q_tmp + 1];
    Phi_1 = W[Q_tmp + 2];
    Phi_2 = W[Q_tmp + 3];
    for (x_tmp_tmp = 0; x_tmp_tmp < 2; x_tmp_tmp++) {
      j = x_tmp_tmp << 2;
      tmp_1 = _mm_set1_pd(b[(i << 1) + x_tmp_tmp]);
      _mm_storeu_pd(&tmp_0[0], _mm_add_pd(_mm_mul_pd(_mm_loadu_pd(&tmp[j]),
        tmp_1), _mm_set_pd(Bearinghat, Rangehat)));
      Rangehat = tmp_0[0];
      Bearinghat = tmp_0[1];
      _mm_storeu_pd(&tmp_0[0], _mm_add_pd(_mm_mul_pd(_mm_loadu_pd(&tmp[j + 2]),
        tmp_1), _mm_set_pd(Phi_2, Phi_1)));
      Phi_1 = tmp_0[0];
      Phi_2 = tmp_0[1];
    }

    W[Q_tmp + 3] = Phi_2;
    W[Q_tmp + 2] = Phi_1;
    W[Q_tmp + 1] = Bearinghat;
    W[Q_tmp] = Rangehat;
  }

  Rangehat = RadarTrackerFcn_Y.residual[1];
  Bearinghat = RadarTrackerFcn_Y.residual[0];
  for (i = 0; i < 4; i++) {
    RadarTrackerFcn_DW.xhat[i] += W[i + 4] * Rangehat + W[i] * Bearinghat;
  }

  for (i = 0; i < 16; i++) {
    Phi[i] = 0;
  }

  Phi[0] = 1;
  Phi[5] = 1;
  Phi[10] = 1;
  Phi[15] = 1;
  memset(&Q[0], 0, sizeof(double) << 4U);
  for (j = 0; j < 4; j++) {
    Q_tmp = j << 2;
    Q[j + Q_tmp] = 1.0;
    Rangehat = 0.0;
    Bearinghat = 0.0;
    Phi_1 = 0.0;
    Phi_2 = 0.0;
    for (i = 0; i < 2; i++) {
      x_tmp_tmp = i << 2;
      tmp_1 = _mm_set1_pd(M[(j << 1) + i]);
      _mm_storeu_pd(&tmp_0[0], _mm_add_pd(_mm_mul_pd(_mm_loadu_pd(&W[x_tmp_tmp]),
        tmp_1), _mm_set_pd(Bearinghat, Rangehat)));
      Rangehat = tmp_0[0];
      Bearinghat = tmp_0[1];
      _mm_storeu_pd(&tmp_0[0], _mm_add_pd(_mm_mul_pd(_mm_loadu_pd(&W[x_tmp_tmp +
        2]), tmp_1), _mm_set_pd(Phi_2, Phi_1)));
      Phi_1 = tmp_0[0];
      Phi_2 = tmp_0[1];
    }

    P_tmp[Q_tmp + 3] = Phi_2;
    P_tmp[Q_tmp + 2] = Phi_1;
    P_tmp[Q_tmp + 1] = Bearinghat;
    P_tmp[Q_tmp] = Rangehat;
  }

  for (i = 0; i <= 14; i += 2) {
    _mm_storeu_pd(&Q_0[i], _mm_sub_pd(_mm_loadu_pd(&Q[i]), _mm_loadu_pd(&P_tmp[i])));
  }

  for (i = 0; i < 4; i++) {
    Rangehat = 0.0;
    Bearinghat = 0.0;
    Phi_1 = 0.0;
    Phi_2 = 0.0;
    for (x_tmp_tmp = 0; x_tmp_tmp < 4; x_tmp_tmp++) {
      j = x_tmp_tmp << 2;
      Q_tmp = (i << 2) + x_tmp_tmp;
      tmp_1 = _mm_set1_pd(RadarTrackerFcn_DW.P[Q_tmp]);
      _mm_storeu_pd(&tmp_0[0], _mm_add_pd(_mm_mul_pd(_mm_loadu_pd(&Q_0[j]),
        tmp_1), _mm_set_pd(Bearinghat, Rangehat)));
      Rangehat = tmp_0[0];
      Bearinghat = tmp_0[1];
      _mm_storeu_pd(&tmp_0[0], _mm_add_pd(_mm_mul_pd(_mm_loadu_pd(&Q_0[j + 2]),
        tmp_1), _mm_set_pd(Phi_2, Phi_1)));
      Phi_1 = tmp_0[0];
      Phi_2 = tmp_0[1];
      j += i;
      Phi_0[Q_tmp] = (double)Phi[j] - P_tmp[j];
    }

    Q_tmp = i << 2;
    Q[Q_tmp + 3] = Phi_2;
    Q[Q_tmp + 2] = Phi_1;
    Q[Q_tmp + 1] = Bearinghat;
    Q[Q_tmp] = Rangehat;
  }

  for (i = 0; i < 2; i++) {
    Rangehat = 0.0;
    Bearinghat = 0.0;
    Phi_1 = 0.0;
    Phi_2 = 0.0;
    for (x_tmp_tmp = 0; x_tmp_tmp < 2; x_tmp_tmp++) {
      j = x_tmp_tmp << 2;
      tmp_1 = _mm_set1_pd(c_b[(i << 1) + x_tmp_tmp]);
      _mm_storeu_pd(&tmp_0[0], _mm_add_pd(_mm_mul_pd(_mm_loadu_pd(&W[j]), tmp_1),
        _mm_set_pd(Bearinghat, Rangehat)));
      Rangehat = tmp_0[0];
      Bearinghat = tmp_0[1];
      _mm_storeu_pd(&tmp_0[0], _mm_add_pd(_mm_mul_pd(_mm_loadu_pd(&W[j + 2]),
        tmp_1), _mm_set_pd(Phi_2, Phi_1)));
      Phi_1 = tmp_0[0];
      Phi_2 = tmp_0[1];
    }

    Q_tmp = i << 2;
    M[Q_tmp + 3] = Phi_2;
    M[Q_tmp + 2] = Phi_1;
    M[Q_tmp + 1] = Bearinghat;
    M[Q_tmp] = Rangehat;
  }

  for (i = 0; i < 4; i++) {
    Rangehat = 0.0;
    Bearinghat = 0.0;
    Phi_1 = 0.0;
    Phi_2 = 0.0;
    for (x_tmp_tmp = 0; x_tmp_tmp < 4; x_tmp_tmp++) {
      j = x_tmp_tmp << 2;
      Q_tmp = (i << 2) + x_tmp_tmp;
      tmp_1 = _mm_set1_pd(Phi_0[Q_tmp]);
      _mm_storeu_pd(&tmp_0[0], _mm_add_pd(_mm_mul_pd(_mm_loadu_pd(&Q[j]), tmp_1),
        _mm_set_pd(Bearinghat, Rangehat)));
      Rangehat = tmp_0[0];
      Bearinghat = tmp_0[1];
      _mm_storeu_pd(&tmp_0[0], _mm_add_pd(_mm_mul_pd(_mm_loadu_pd(&Q[j + 2]),
        tmp_1), _mm_set_pd(Phi_2, Phi_1)));
      Phi_1 = tmp_0[0];
      Phi_2 = tmp_0[1];
      P_tmp[Q_tmp] = 0.0;
    }

    Q_tmp = i << 2;
    Q_0[Q_tmp + 3] = Phi_2;
    Q_0[Q_tmp + 2] = Phi_1;
    Q_0[Q_tmp + 1] = Bearinghat;
    Q_0[Q_tmp] = Rangehat;
    Rangehat = P_tmp[Q_tmp];
    Bearinghat = P_tmp[Q_tmp + 1];
    Phi_1 = P_tmp[Q_tmp + 2];
    Phi_2 = P_tmp[Q_tmp + 3];
    for (x_tmp_tmp = 0; x_tmp_tmp < 2; x_tmp_tmp++) {
      j = x_tmp_tmp << 2;
      tmp_1 = _mm_set1_pd(W[j + i]);
      _mm_storeu_pd(&tmp_0[0], _mm_add_pd(_mm_mul_pd(_mm_loadu_pd(&M[j]), tmp_1),
        _mm_set_pd(Bearinghat, Rangehat)));
      Rangehat = tmp_0[0];
      Bearinghat = tmp_0[1];
      _mm_storeu_pd(&tmp_0[0], _mm_add_pd(_mm_mul_pd(_mm_loadu_pd(&M[j + 2]),
        tmp_1), _mm_set_pd(Phi_2, Phi_1)));
      Phi_1 = tmp_0[0];
      Phi_2 = tmp_0[1];
    }

    P_tmp[Q_tmp + 3] = Phi_2;
    P_tmp[Q_tmp + 2] = Phi_1;
    P_tmp[Q_tmp + 1] = Bearinghat;
    P_tmp[Q_tmp] = Rangehat;
  }

  for (i = 0; i <= 14; i += 2) {
    _mm_storeu_pd(&RadarTrackerFcn_DW.P[i], _mm_add_pd(_mm_loadu_pd(&Q_0[i]),
      _mm_loadu_pd(&P_tmp[i])));
  }

  /* Outport: '<Root>/xhatOut' incorporates:
   *  MATLAB Function: '<Root>/RadarTrackerFcn'
   */
  RadarTrackerFcn_Y.xhatOut[0] = RadarTrackerFcn_DW.xhat[0];
  RadarTrackerFcn_Y.xhatOut[1] = RadarTrackerFcn_DW.xhat[1];
  RadarTrackerFcn_Y.xhatOut[2] = RadarTrackerFcn_DW.xhat[2];
  RadarTrackerFcn_Y.xhatOut[3] = RadarTrackerFcn_DW.xhat[3];
}

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

web(fullfile(pwd,'RadarTrackerFcn_ert_rtw','html','index.html'))