概述
我在个人博客 F-16飞行器非线性Simulink模型 中,简单介绍了该F-16模型的主要情况、各个文件的功能等。
其中模型中的 F16_dyn.c 是最主要的调试文件,该文件由C语言完成,搭配S-Function使用,难点在于对C Mex S函数的理解和应用。在此对S函数进行一些简单的归纳分析:
首先看一下S函数的简介:
下面看一下该文件,其中有较详细的注释,程序以以下定义开头:
#define S_FUNCTION_NAME F16_dyn
#define S_FUNCTION_LEVEL 2
第一条指定了 S-function 的名字(F16_dyn),第二条指定了该 S-function 是按照 level 2 的格式进行编写的。
在定义了这两条之后,该程序包含了 simstruc.h 文件,这是一个头文件,它给出了SimStruct 数据结构的访问通道,以及MATLAB 应用程序接口(API)函数。
/* include files */
#include <math.h>
#include "simstruc.h"
#include "aerodata/mexndinterp.c"
#include "aerodata/hifi_f16_aerodata.c" /* hifi lookup tables */
#include "aerodata/lofi_f16_aerodata.c" /* lofi lookup tables */
#include "aerodata/ISA_atmos.c" /* ISA atmosphere model */
#include "aerodata/engine_model.c" /*engine model */
接下来是各种宏定义:包括输入量、状态量、状态量导数、系数、参数、常量。
下面看一下模型运行的过程:
下图所示为 Simulink 调用S-function 回调函数的顺序。实线框部分表示在模型初始化和/或每个仿真步长内需使用的回调函数;虚线框部分表示在初始化阶段和/或在仿真循环的一些或所有采样步长内使用的回调函数。
这里摘出几个需要特别注意的模块:
Simulink 调用 mdlInitializeSizes 来获取输入端口和输出端口的数量、端口宽度、以及S-function 所需的任何其它对象(诸如状态数量)等有关信息。
/*=============================*/
/* Function: mdlInitalizeSizes */
/*=============================*/
static void mdlInitializeSizes(SimStruct *S)
{
ssSetNumSFcnParams(S, 1); /* Number of expected parameters */
ssSetNumContStates(S, 20);
ssSetNumDiscStates(S, 0);
ssSetNumInputPorts(S, 2);
ssSetInputPortWidth(S, 0, 4);
ssSetInputPortWidth(S, 1, 1);
// ssSetInputPortWidth(S, 2, 1);
/* ssSetInputPortDirectFeedThrough(S, 1, 1); */
ssSetNumOutputPorts(S, 2);
ssSetOutputPortWidth(S, 0, 23);
ssSetOutputPortWidth(S, 1, 3);
ssSetNumSampleTimes(S, 1);
ssSetNumRWork(S, 23);
ssSetNumIWork(S, 0);
ssSetNumPWork(S, 0);
ssSetNumModes(S, 0);
ssSetNumNonsampledZCs(S, 0);
ssSetOptions(S, 0);
}
在每个采样时间步长内,Simulink 调用mdlOutputs 来计算块的输出。 其中利用 data_output[i] 增加了变量的输出。
/*======================*/
/* Function: mdlOutputs */
/*======================*/
static void mdlOutputs(SimStruct *S, int_T tid)
{
real_T *x = ssGetContStates(S);
real_T *y = ssGetOutputPortRealSignal(S, 0);
int i;
for (i = 0; i < ssGetNumContStates(S); i++)
{
y[i] = x[i]; /* outputs are the states */
}
for(i=0; i<3; i++)
{
y[i+ssGetNumContStates(S)] = data_output[i];
}
real_T *y1 = ssGetOutputPortRealSignal(S, 1);
y1[0] = X_output;
y1[1] = Y_output;
y1[2] = Z_output;
}
其次是变量的定义:
注意开始有输入端口的定义,需与 mdlInitializeSizes 中对应。
/*==========================*/
/* Function: mdlDerivatives */
/*==========================*/
#define MDL_DERIVATIVES
#if defined(MDL_DERIVATIVES)
static void mdlDerivatives(SimStruct *S)
{
real_T *x = ssGetContStates(S);
real_T *dx = ssGetdX(S);
InputRealPtrsType u = ssGetInputPortRealSignalPtrs(S, 0);
InputRealPtrsType u1 = ssGetInputPortRealSignalPtrs(S, 1);
// InputRealPtrsType u3 = ssGetInputPortRealSignalPtrs(S, 2);
/* Declare a lot of variables */
变量定义
/* end mdlDerivatives */
#endif
最后
以上就是端庄朋友为你收集整理的MATLAB S函数 之 C Mex S函数结构分析的全部内容,希望文章能够帮你解决MATLAB S函数 之 C Mex S函数结构分析所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复