文章目录
前言
《深入拆解Simulink自动生成代码(一)——数据流处理》
一、Simulink实现数据统计算法
用Simulink实现求极值统计算法的一个最简单编程举例如下:
二、自动生成C代码
上述Matlab Function的Simulink自动生成的对应C代码如下:
int32_T idx;
int32_T k;
boolean_T exitg1;
/* MATLAB Function: '<S2>/MATLAB Function' */
if (!rtIsNaN(CodeGenerate_ConstB.VectorConcatenate[0])) {
idx = 1;
} else {
idx = 0;
k = 2;
exitg1 = false;
while ((!exitg1) && (k < 104)) {
if (!rtIsNaN(CodeGenerate_ConstB.VectorConcatenate[k - 1])) {
idx = k;
exitg1 = true;
} else {
k++;
}
}
}
if (idx == 0) {
/* Outport: '<Root>/y4' */
CodeGenerate_Y.y4 = CodeGenerate_ConstB.VectorConcatenate[0];
} else {
CodeGenerate_Y.y4 = CodeGenerate_ConstB.VectorConcatenate[idx - 1];
while (idx + 1 <= 103) {
if (CodeGenerate_Y.y4 < CodeGenerate_ConstB.VectorConcatenate[idx]) {
CodeGenerate_Y.y4 = CodeGenerate_ConstB.VectorConcatenate[idx];
}
idx++;
}
}
/* End of MATLAB Function: '<S2>/MATLAB Function' */
三、变式1
基于上述举例,把最大值求解结果再加上最大值位置,生成的对应代码如下所示:
real_T b_ex;
int32_T idx;
int32_T k;
boolean_T exitg1;
/* MATLAB Function: '<S3>/MATLAB Function1' */
if (!rtIsNaN(CodeGenerate_ConstB.VectorConcatenate2[0])) {
idx = 1;
} else {
idx = 0;
k = 2;
exitg1 = false;
while ((!exitg1) && (k < 104)) {
if (!rtIsNaN(CodeGenerate_ConstB.VectorConcatenate2[k - 1])) {
idx = k;
exitg1 = true;
} else {
k++;
}
}
}
if (idx == 0) {
b_ex = CodeGenerate_ConstB.VectorConcatenate2[0];
idx = 1;
} else {
b_ex = CodeGenerate_ConstB.VectorConcatenate2[idx - 1];
for (k = idx; k < 103; k++) {
if (b_ex < CodeGenerate_ConstB.VectorConcatenate2[k]) {
b_ex = CodeGenerate_ConstB.VectorConcatenate2[k];
idx = k + 1;
}
}
}
四、变式2
基于上述举例,把最大值求解变成次大值求解,生成的对应代码如下所示:
static void CodeGenerate_maximum(const real_T x[103], real_T *ex, int32_T *idx)
{
int32_T k;
boolean_T exitg1;
if (!rtIsNaN(x[0])) {
*idx = 1;
} else {
*idx = 0;
k = 2;
exitg1 = false;
while ((!exitg1) && (k < 104)) {
if (!rtIsNaN(x[k - 1])) {
*idx = k;
exitg1 = true;
} else {
k++;
}
}
}
if (*idx == 0) {
*ex = x[0];
*idx = 1;
} else {
*ex = x[*idx - 1];
for (k = *idx; k < 103; k++) {
if (*ex < x[k]) {
*ex = x[k];
*idx = k + 1;
}
}
}
}
real_T u[103];
real_T ex;
int32_T idx;
/* MATLAB Function: '<S3>/MATLAB Function3' */
memcpy(&u[0], &CodeGenerate_ConstB.VectorConcatenate3[0], 103U * sizeof(real_T));
CodeGenerate_maximum(CodeGenerate_ConstB.VectorConcatenate3, &ex, &idx);
u[idx - 1] = 0.0;
CodeGenerate_maximum(u, &ex, &idx);
五、变式3
基于上述举例,把最大值求解变成去掉最大值的方差求解,生成的对应代码如下所示:
real_T u_[10];
real_T absdiff;
real_T j;
real_T scale;
real_T t;
real_T xbar;
int32_T idx;
int32_T k;
boolean_T exitg1;
/* MATLAB Function: '<S4>/MATLAB Function2' */
j = 1.0;
memset(&u_[0], 0, 10U * sizeof(real_T));
if (!rtIsNaN(CodeGenerate_ConstB.VectorConcatenate1[0])) {
idx = 1;
} else {
idx = 0;
k = 2;
exitg1 = false;
while ((!exitg1) && (k < 12)) {
if (!rtIsNaN(CodeGenerate_ConstB.VectorConcatenate1[k - 1])) {
idx = k;
exitg1 = true;
} else {
k++;
}
}
}
if (idx == 0) {
idx = 1;
} else {
xbar = CodeGenerate_ConstB.VectorConcatenate1[idx - 1];
for (k = idx; k < 11; k++) {
if (xbar < CodeGenerate_ConstB.VectorConcatenate1[k]) {
xbar = CodeGenerate_ConstB.VectorConcatenate1[k];
idx = k + 1;
}
}
}
for (k = 0; k < 11; k++) {
if (k + 1 != idx) {
u_[(int32_T)j - 1] = CodeGenerate_ConstB.VectorConcatenate1[k];
j++;
}
}
xbar = u_[0];
for (idx = 0; idx < 9; idx++) {
xbar += u_[idx + 1];
}
xbar /= 10.0;
j = 0.0;
scale = 3.3121686421112381E-170;
for (idx = 0; idx < 10; idx++) {
absdiff = fabs(u_[idx] - xbar);
if (absdiff > scale) {
t = scale / absdiff;
j = j * t * t + 1.0;
scale = absdiff;
} else {
t = absdiff / scale;
j += t * t;
}
}
j = scale * sqrt(j);
j /= 3.1622776601683795;
/* End of MATLAB Function: '<S4>/MATLAB Function2' */
总结
以上就是本人拆解Simulink模块自动生成代码时,讲解的最后一部分。主要针对Simulink的Matlab Function模块,展示了这类模块的使用方法,并对比了相应的C代码。
欢迎评论区留言、点赞、收藏和关注,这些鼓励和支持都将成为笔者持续分享的动力。
另外,上述例程使用的Demo工程可以到笔者的主页查找和下载。
版权声明:原创文章,转载和引用请注明出处和链接,侵权必究!