Эта модель показывает код, сгенерированный для модели Simulink, содержащей скрипт MATLAB.
Модель содержит Расширенный Фильтр Калмана, который оценивает положение самолета от радарных измерений. Скрипт MATLAB rtwdemo_eml_aero_radar.m содержит данные для выполнения модели. Предполагаемые и фактические положения сохранены в рабочую область и построены в конце симуляции программой rtwdemo_aero_radplot (названный от симуляции автоматически).
В этом разделе необходимо рассмотреть модель и выполнить симуляцию.
Откройте модель Simulink.
model='rtwdemo_eml_aero_radar'; open_system(model) rtwdemo_eml_aero_radar([],[],[],'compile'); rtwdemo_eml_aero_radar([],[],[],'term');

Откройте блок MATLAB function RadarTracker в редакторе MATLAB.
open_system([model,'/RadarTracker'])

Симулируйте модель и рассмотрите результаты (отображенный автоматически).
sim(model)

В этом разделе вы сгенерируете код для фрагмента Фильтра Калмана модели с помощью функциональности сборки подсистемы, обеспеченной Simulink Coder. В первой сборке модель сконфигурирована, чтобы сгенерировать код с помощью Simulink Coder. Во второй сборке модель сконфигурирована, чтобы сгенерировать код с помощью Embedded Coder.
% Create a temporary folder (in your system's temporary folder) for the % build and inspection process. currentDir = pwd; [~,cgDir] = rtwdemodir();
Сконфигурируйте и создайте модель с помощью Simulink Coder.
rtwconfiguredemo(model,'GRT') rtwbuild([model,'/RadarTracker'])
### Starting build procedure for model: RadarTracker ### Successful completion of build procedure for model: RadarTracker
Сконфигурируйте и создайте модель с помощью Embedded Coder.
rtwconfiguredemo(model,'ERT') rtwbuild([model,'/RadarTracker'])
### Starting build procedure for model: RadarTracker ### Successful completion of build procedure for model: RadarTracker
Фрагмент RadarTracker.c описан ниже.
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 r;
real_T M_tmp;
real_T M_tmp_0;
real_T x_tmp[8];
real_T P_m_tmp[16];
real_T Phi_0[16];
real_T Phi_1[4];
real_T M_0[8];
real_T Q_0[16];
int32_T i;
real_T tmp;
int32_T Phi_tmp;
int32_T Phi_tmp_tmp;
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 };
/* 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_tmp_tmp = i << 2;
Phi_tmp = j + Phi_tmp_tmp;
Phi_0[Phi_tmp] = 0.0;
Phi_0[Phi_tmp] += rtDW.P_m[Phi_tmp_tmp] * (real_T)Phi[j];
Phi_0[Phi_tmp] += rtDW.P_m[Phi_tmp_tmp + 1] * (real_T)Phi[j + 4];
Phi_0[Phi_tmp] += rtDW.P_m[Phi_tmp_tmp + 2] * (real_T)Phi[j + 8];
Phi_0[Phi_tmp] += rtDW.P_m[Phi_tmp_tmp + 3] * (real_T)Phi[j + 12];
}
}
for (i = 0; i < 4; i++) {
Phi_1[i] = 0.0;
for (j = 0; j < 4; j++) {
Phi_tmp_tmp = (j << 2) + i;
rtDW.P_m[Phi_tmp_tmp] = (((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[Phi_tmp_tmp];
Phi_1[i] += (real_T)Phi[Phi_tmp_tmp] * 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 = sin(Bearinghat);
M_tmp_0 = cos(Bearinghat);
M[0] = M_tmp_0;
M[2] = 0.0;
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++) {
Phi_tmp_tmp = (j << 1) + i;
x_tmp[j + (i << 2)] = M[Phi_tmp_tmp];
M_0[Phi_tmp_tmp] = 0.0;
Phi_tmp = j << 2;
M_0[Phi_tmp_tmp] += rtDW.P_m[Phi_tmp] * M[i];
M_0[Phi_tmp_tmp] += rtDW.P_m[Phi_tmp + 2] * M[i + 4];
}
}
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
Phi_tmp_tmp = i << 2;
Phi_tmp = (i << 1) + j;
Phi_1[Phi_tmp] = (((x_tmp[Phi_tmp_tmp + 1] * M_0[j + 2] +
x_tmp[Phi_tmp_tmp] * M_0[j]) + x_tmp[Phi_tmp_tmp + 2] *
M_0[j + 4]) + x_tmp[Phi_tmp_tmp + 3] * M_0[j + 6]) +
R[Phi_tmp];
}
}
if (fabs(Phi_1[1]) > fabs(Phi_1[0])) {
r = Phi_1[0] / Phi_1[1];
Rangehat = 1.0 / (r * Phi_1[3] - Phi_1[2]);
Bearinghat = Phi_1[3] / Phi_1[1] * Rangehat;
M_tmp = -Rangehat;
M_tmp_0 = -Phi_1[2] / Phi_1[1] * Rangehat;
Rangehat *= r;
} else {
r = Phi_1[1] / Phi_1[0];
Rangehat = 1.0 / (Phi_1[3] - r * Phi_1[2]);
Bearinghat = Phi_1[3] / Phi_1[0] * Rangehat;
M_tmp = -r * Rangehat;
M_tmp_0 = -Phi_1[2] / Phi_1[0] * Rangehat;
}
for (i = 0; i < 4; i++) {
for (j = 0; j < 2; j++) {
Phi_tmp_tmp = j << 2;
Phi_tmp = i + Phi_tmp_tmp;
M_0[Phi_tmp] = 0.0;
M_0[Phi_tmp] += x_tmp[Phi_tmp_tmp] * rtDW.P_m[i];
M_0[Phi_tmp] += x_tmp[Phi_tmp_tmp + 1] * rtDW.P_m[i + 4];
M_0[Phi_tmp] += x_tmp[Phi_tmp_tmp + 2] * rtDW.P_m[i + 8];
M_0[Phi_tmp] += x_tmp[Phi_tmp_tmp + 3] * rtDW.P_m[i + 12];
}
W[i] = 0.0;
W[i] += M_0[i] * Bearinghat;
r = M_0[i + 4];
W[i] += r * M_tmp;
tmp = W[i] * rtY.residual[0];
W[i + 4] = 0.0;
W[i + 4] += M_0[i] * M_tmp_0;
W[i + 4] += r * Rangehat;
tmp += W[i + 4] * rtY.residual[1];
rtDW.xhat[i] += tmp;
}
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_tmp_tmp = j + (i << 2);
P_m_tmp[Phi_tmp_tmp] = 0.0;
Phi_tmp = i << 1;
P_m_tmp[Phi_tmp_tmp] += M[Phi_tmp] * W[j];
P_m_tmp[Phi_tmp_tmp] += M[Phi_tmp + 1] * W[j + 4];
}
}
for (i = 0; i < 16; i++) {
Q_0[i] = Q[i] - P_m_tmp[i];
}
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
Phi_tmp_tmp = j << 2;
Phi_tmp = i + Phi_tmp_tmp;
Q[Phi_tmp] = 0.0;
Q[Phi_tmp] += rtDW.P_m[Phi_tmp_tmp] * Q_0[i];
Q[Phi_tmp] += rtDW.P_m[Phi_tmp_tmp + 1] * Q_0[i + 4];
Q[Phi_tmp] += rtDW.P_m[Phi_tmp_tmp + 2] * Q_0[i + 8];
Q[Phi_tmp] += rtDW.P_m[Phi_tmp_tmp + 3] * Q_0[i + 12];
Phi_0[j + (i << 2)] = (real_T)Phi[Phi_tmp] - P_m_tmp[Phi_tmp];
}
M[i] = 0.0;
M[i] += W[i] * 90000.0;
M[i + 4] = 0.0;
M[i + 4] += W[i + 4] * 1.0E-6;
}
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
Phi_tmp_tmp = j << 2;
Phi_tmp = i + Phi_tmp_tmp;
Q_0[Phi_tmp] = 0.0;
Q_0[Phi_tmp] += Phi_0[Phi_tmp_tmp] * Q[i];
Q_0[Phi_tmp] += Phi_0[Phi_tmp_tmp + 1] * Q[i + 4];
Q_0[Phi_tmp] += Phi_0[Phi_tmp_tmp + 2] * Q[i + 8];
Q_0[Phi_tmp] += Phi_0[Phi_tmp_tmp + 3] * Q[i + 12];
P_m_tmp[Phi_tmp] = 0.0;
P_m_tmp[Phi_tmp] += M[i] * W[j];
P_m_tmp[Phi_tmp] += M[i + 4] * W[j + 4];
}
}
for (i = 0; i < 16; i++) {
rtDW.P_m[i] = Q_0[i] + P_m_tmp[i];
}
/* Outport: '<Root>/xhatOut' incorporates:
* MATLAB Function: '<Root>/RadarTracker'
*/
rtY.xhatOut[0] = rtDW.xhat[0];
rtY.xhatOut[1] = rtDW.xhat[1];
rtY.xhatOut[2] = rtDW.xhat[2];
rtY.xhatOut[3] = rtDW.xhat[3];
}
Можно просмотреть целый сгенерированный код в подробном отчете HTML с двусторонней отслеживаемостью между моделью и кодом.
web(fullfile(cgDir,'RadarTracker_ert_rtw','html','RadarTracker_codegen_rpt.html'))
Закройте модель и очистку.
bdclose(model) rtwdemoclean; cd(currentDir)