Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АрхитектураБиологияГеографияДругоеИностранные языки
ИнформатикаИсторияКультураЛитератураМатематика
МедицинаМеханикаОбразованиеОхрана трудаПедагогика
ПолитикаПравоПрограммированиеПсихологияРелигия
СоциологияСпортСтроительствоФизикаФилософия
ФинансыХимияЭкологияЭкономикаЭлектроника

Модернизация S-функций, созданных с помощью S-Function Builder

Callback-методы S-функции | Создание S-функций на языке MATLAB | Простейшая S-функция | Модель непрерывной системы | Модель дискретнойной системы | Модель гибридной системы | Модель дискретной системы с переменным шагом расчета | Математическое описание ДПТ НВ | Пример S-функции для ДПТ НВ | Создание S-функций на языке C с помощью S-Function Builder |


Читайте также:
  1. GELLED BUILDER ALLABELLA - КОНСТРУИРУЮЩИЙ ГЕЛЬ НОВОГО ПОКОЛЕНИЯ
  2. Архивация. Архиваторы, их универсальные опции. Работа с архивными файлами с помощью архиватора Winrar.
  3. Блок-схема процедуры обработки данных с помощью одномерного массива
  4. БЫЛИ ЛИ БЕЛЫЕ ВЫВЕДЕНЫ ЯКУБОМ С ПОМОЩЬЮ ИСКУССТВЕННОГО ОТБОРА?
  5. Ватерпасовка обрывистого клифа производится с помощью двух ватерпасовочных реек.
  6. ВОСПОЛЬЗУЙТЕСЬ ПОМОЩЬЮ ДРУГИХ
  7. Вход в область священного с помощью молитв рейки и мантр Рейки

S-функции, созданные с помощью S-Function Builder обладают одним существенным недостатком. В большинстве случаев при расчете переменных состояния, выходных сигналов либо производных непрерывных переменных состояния должны использоваться некоторые ранее вычисленные константы. В задаче моделирования двигателя постоянного тока - это элементы матриц A, B, С уравнений пространства-состояния, рассчитываемые через параметры двигателя (сопротивление, индуктивность и т.п.). В примере на языке MATLAB (см. п. 16.7.6) расчет матриц выполняется в методе mdlInitializeSizes, благодаря чему этот расчет производится только один раз - на этапе инициализации модели. Далее рассчитанные матрицы только используются для вычисления производных переменных состояния в методе mdlDerivatives и выходных сигналов в методе mdlOutputs. Такая компоновка S-функции обеспечивает наибольшую скорость вычислений. К сожалению, в S-Function Builder отсутствует возможность ввести фрагмент кода на вкладке Initialization, а также скрыты заголовки методов, что делает невозможным добавление новых параметров, которые могли бы передаваться в эти методы. Такая ситуация приводит к тому, что константы, которые можно было бы вычислить всего один раз и, затем лишь использовать, вычисляются вновь и вновь на каждом шаге расчета (в примере с двигателем постоянного тока п.16.6 - это A00, A01, B00 и т.д.). И, если в относительно простых моделях с эти еще можно смириться, то для сложных моделей с большим объемом предварительных вычислений такая ситуация приведет к существенному замедлению процесса расчета.

Выходом из сложившейся ситуации может явиться редактирование автоматически сгенерированного кода S-функции. Редактирование должно обеспечить вычисление констант один раз на этапе инициализации и передачу их в нужные методы. В рассматриваемом примере модели двигателя постоянного тока на этапе инициализации должны вычисляться константы A00, A01, B00 и т.д., а затем, передаваться в методы для расчета производных и выходных переменных. Для реализации поставленной задачи следует проанализировать полученные с помощью S-Function Builder файлы DPT_Sfunc_1_C.c и DPT_Sfunc_1_C_wrapper.c. Первый файл содержит исходный текст S-функции, а второй текст методов этой S-функции.

Текст файла DPT_Sfunc_1_C.c приведен ниже:

/* * File: DPT_Sfunc_1_C.c * * * * --- THIS FILE GENERATED BY S-FUNCTION BUILDER: BASIC, 1.0 --- * * This file is an S-function produced by the Basic S-Function * Builder which only recognizes certain fields. Changes made * outside these fields will be lost the next time the block is * used to load, edit, and resave this file. This file will be overwritten * by the S-function Builder block. If you want to edit this file by hand, * you must change it only in the area defined as: * * %%%-SFUNWIZ_defines_Changes_BEGIN * #define NAME 'replacement text' * %%% SFUNWIZ_defines_Changes_END * * DO NOT change NAME--Change te 'replacement text' only. * * For better compatibility with the Real-Time Workshop, the * "wrapper" S-function technique is used. This is discussed * in the Real-Time Workshop User's Manual in the Chapter titled, * "Wrapper S-functions". * * ------------------------------------------------------------------------ *| See matlabroot/simulink/src/sfuntmpl_doc.c for a more detailed template | * ------------------------------------------------------------------------ * Created: Sun Mar 30 13:07:10 2003 * * */#define S_FUNCTION_NAME DPT_Sfunc_1_C#define S_FUNCTION_LEVEL 2/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*//* %%%-SFUNWIZ_defines_Changes_BEGIN --- EDIT HERE TO _END */#define NUM_INPUTS 1 #define INPUT_0_WIDTH 2#define INPUT_0_FEEDTHROUGH 0#define NUM_OUTPUTS 1#define OUTPUT_0_WIDTH 2#define NPARAMS 6#define SAMPLE_TIME_0 INHERITED_SAMPLE_TIME#define NUM_DISC_STATES 0#define DISC_STATES_IC [0]#define NUM_CONT_STATES 2#define CONT_STATES_IC [0,0]#define SFUNWIZ_GENERATE_TLC 1#define SOURCEFILES "//my_lib.lib"#define PANELINDEX 5#define SFUNWIZ_REVISION 1.0/* %%%-SFUNWIZ_defines_Changes_END --- EDIT HERE TO _BEGIN *//*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/#include "simstruc.h"#define PARAM_DEF0(S) ssGetSFcnParam(S, 0)#define PARAM_DEF1(S) ssGetSFcnParam(S, 1)#define PARAM_DEF2(S) ssGetSFcnParam(S, 2)#define PARAM_DEF3(S) ssGetSFcnParam(S, 3)#define PARAM_DEF4(S) ssGetSFcnParam(S, 4)#define PARAM_DEF5(S) ssGetSFcnParam(S, 5)extern void DPT_Sfunc_1_C_Outputs_wrapper(const real_T *u, real_T *y, const real_T *xC, const real_T *param0, const int_T p_width0, const real_T *param1,
const int_T p_width1, const real_T *param2, const int_T p_width2, const real_T *param3, const
int_T p_width3, const real_T *param4, const int_T p_width4, const real_T *param5, const int_T
p_width5);extern void DPT_Sfunc_1_C_Update_wrapper(const real_T *u, const real_T *y, const real_T *param0, const int_T p_width0,const real_T *param1, const
int_T p_width1,const real_T *param2, const int_T p_width2,const real_T *param3, const int_T
p_width3,const real_T *param4, const int_T p_width4, const real_T *param5, const int_T p_width5);extern void DPT_Sfunc_1_C_Derivatives_wrapper(const real_T *u, const real_T *y, real_T *dx, real_T *xC, const real_T *param0, const int_T p_width0,const real_T *param1, const
int_T p_width1,const real_T *param2, const int_T p_width2,const real_T *param3, const int_T
p_width3,const real_T *param4, const int_T p_width4, const real_T *param5, const int_T p_width5);/*====================* * S-function methods * *====================*/#define MDL_CHECK_PARAMETERS#if defined(MDL_CHECK_PARAMETERS) && defined(MATLAB_MEX_FILE) /* Function: mdlCheckParameters========================================== * Abstract: * Validate our parameters to verify they are okay. */ static void mdlCheckParameters(SimStruct *S) { int i; bool validParam = false;/* All parameters must be scalar */ for (i = 0; i < ssGetSFcnParamsCount(S); i++) { const mxArray *pVal = ssGetSFcnParam(S,i); if (!mxIsNumeric(pVal) ||!mxIsDouble(pVal) || mxIsLogical(pVal) || mxIsComplex(pVal) || mxIsSparse(pVal) ||!mxIsFinite(mxGetPr(pVal)[0])) { validParam = true; break; } } if (validParam) { ssSetErrorStatus(S,"All parameters must be a scalar or vectors"); return; } } #endif /* MDL_CHECK_PARAMETERS */ /* Function: mdlInitializeSizes =========================================== * Abstract: * Setup sizes of the various vectors. */static void mdlInitializeSizes(SimStruct *S){ DECL_AND_INIT_DIMSINFO(inputDimsInfo); DECL_AND_INIT_DIMSINFO(outputDimsInfo); ssSetNumSFcnParams(S, NPARAMS); /* Number of expected parameters */#if defined(MATLAB_MEX_FILE) if (ssGetNumSFcnParams(S) == ssGetSFcnParamsCount(S)) { mdlCheckParameters(S); if (ssGetErrorStatus(S)!= NULL) { return; } } else { return; /* Parameter mismatch will be reported by Simulink */ }#endif ssSetNumContStates(S, NUM_CONT_STATES); ssSetNumDiscStates(S, NUM_DISC_STATES); if (!ssSetNumInputPorts(S, 1)) return; inputDimsInfo.width = INPUT_0_WIDTH; ssSetInputPortDimensionInfo(S, 0, &inputDimsInfo); ssSetInputPortFrameData(S, 0, FRAME_INHERITED); ssSetInputPortDirectFeedThrough(S, 0, INPUT_0_FEEDTHROUGH); ssSetInputPortRequiredContiguous(S, 0, 1); /*direct input signal access*/ if (!ssSetNumOutputPorts(S,1)) return; outputDimsInfo.width = OUTPUT_0_WIDTH; ssSetOutputPortDimensionInfo(S, 0, &outputDimsInfo); ssSetOutputPortFrameData(S, 0, FRAME_INHERITED); ssSetNumSampleTimes(S, 1); ssSetNumRWork(S, 0); ssSetNumIWork(S, 0); ssSetNumPWork(S, 0); ssSetNumModes(S, 0); ssSetNumNonsampledZCs(S, 0); /* Take care when specifying exception free code - see sfuntmpl_doc.c */ ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE | SS_OPTION_USE_TLC_WITH_ACCELERATOR);}/* Function: mdlInitializeSampleTimes ====================================== * Abstract: * Specifiy the sample time. */static void mdlInitializeSampleTimes(SimStruct *S){ ssSetSampleTime(S, 0, SAMPLE_TIME_0); ssSetOffsetTime(S, 0, 0.0);}#define MDL_INITIALIZE_CONDITIONS/* Function: mdlInitializeConditions ====================================== * Abstract: * Initialize the states */static void mdlInitializeConditions(SimStruct *S){ real_T *xC = ssGetContStates(S); xC[0] = 0; xC[1] = 0;}/* Function: mdlOutputs =================================================== **/static void mdlOutputs(SimStruct *S, int_T tid){ const real_T *u = (const real_T*) ssGetInputPortSignal(S,0); real_T *y = ssGetOutputPortRealSignal(S,0); const real_T *xC = ssGetContStates(S); const real_T *param0 = mxGetPr(PARAM_DEF0(S)); const real_T *param1 = mxGetPr(PARAM_DEF1(S)); const real_T *param2 = mxGetPr(PARAM_DEF2(S)); const real_T *param3 = mxGetPr(PARAM_DEF3(S)); const real_T *param4 = mxGetPr(PARAM_DEF4(S)); const real_T *param5 = mxGetPr(PARAM_DEF5(S)); const int_T p_width0 = mxGetNumberOfElements(PARAM_DEF0(S)); const int_T p_width1 = mxGetNumberOfElements(PARAM_DEF1(S)); const int_T p_width2 = mxGetNumberOfElements(PARAM_DEF2(S)); const int_T p_width3 = mxGetNumberOfElements(PARAM_DEF3(S)); const int_T p_width4 = mxGetNumberOfElements(PARAM_DEF4(S)); const int_T p_width5 = mxGetNumberOfElements(PARAM_DEF5(S)); DPT_Sfunc_1_C_Outputs_wrapper(u, y, xC, param0, p_width0, param1, p_width1, param2, p_width2,
param3, p_width3, param4, p_width4, param5, p_width5);}#undef MDL_UPDATE /* Change to #define to use the function */#if defined(MDL_UPDATE) /* Function: mdlUpdate ================================================== * Abstract:* This function is called once for every major integration time step.* Discrete states are typically updated here, but this function is useful * for performing any tasks that should only take place once per * integration step. */ static void mdlUpdate(SimStruct *S, int_T tid) { const real_T *u = (const real_T *) ssGetInputPortSignal(S,0); real_T *xD = ssGetDiscStates(S); const real_T *y = ssGetOutputPortSignal(S,0); const real_T *param0 = mxGetPr(PARAM_DEF0(S)); const int_T p_width0 = mxGetNumberOfElements(PARAM_DEF0(S)); const real_T *param1 = mxGetPr(PARAM_DEF1(S)); const int_T p_width1 = mxGetNumberOfElements(PARAM_DEF1(S)); const real_T *param2 = mxGetPr(PARAM_DEF2(S)); const int_T p_width2 = mxGetNumberOfElements(PARAM_DEF2(S)); const real_T *param3 = mxGetPr(PARAM_DEF3(S)); const int_T p_width3 = mxGetNumberOfElements(PARAM_DEF3(S)); const real_T *param4 = mxGetPr(PARAM_DEF4(S)); const int_T p_width4 = mxGetNumberOfElements(PARAM_DEF4(S)); const real_T *param5 = mxGetPr(PARAM_DEF5(S)); const int_T p_width5 = mxGetNumberOfElements(PARAM_DEF5(S)); DPT_Sfunc_1_C_Update_wrapper(u, y, param0, p_width0, param1, p_width1, param2, p_width2, param3,
p_width3, param4, p_width4, param5, p_width5); } #endif /* MDL_UPDATE */#define MDL_DERIVATIVES /* Change to #undef to remove function */#if defined(MDL_DERIVATIVES) /* Function: mdlDerivatives ============================================== * Abstract: * In this function, you compute the S-function block's derivatives. * The derivatives are placed in the derivative vector, ssGetdX(S). */ static void mdlDerivatives(SimStruct *S) { const real_T *u = (const real_T *) ssGetInputPortSignal(S,0); real_T *dx = ssGetdX(S); real_T *xC = ssGetContStates(S); const real_T *y = ssGetOutputPortSignal(S,0); const real_T *param0 = mxGetPr(PARAM_DEF0(S)); const int_T p_width0 = mxGetNumberOfElements(PARAM_DEF0(S)); const real_T *param1 = mxGetPr(PARAM_DEF1(S)); const int_T p_width1 = mxGetNumberOfElements(PARAM_DEF1(S)); const real_T *param2 = mxGetPr(PARAM_DEF2(S)); const int_T p_width2 = mxGetNumberOfElements(PARAM_DEF2(S)); const real_T *param3 = mxGetPr(PARAM_DEF3(S)); const int_T p_width3 = mxGetNumberOfElements(PARAM_DEF3(S)); const real_T *param4 = mxGetPr(PARAM_DEF4(S)); const int_T p_width4 = mxGetNumberOfElements(PARAM_DEF4(S)); const real_T *param5 = mxGetPr(PARAM_DEF5(S)); const int_T p_width5 = mxGetNumberOfElements(PARAM_DEF5(S)); DPT_Sfunc_1_C_Derivatives_wrapper(u, y, dx, xC, param0, p_width0, param1, p_width1, param2, p_width2,
param3, p_width3, param4, p_width4, param5, p_width5); }#endif /* MDL_DERIVATIVES *//* Function: mdlTerminate ================================================== * Abstract: * No termination needed, but we are required to have this routine. */static void mdlTerminate(SimStruct *S){}#ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */#include "simulink.c" /* MEX-file interface mechanism */#else#include "cg_sfun.h" /* Code generation registration function */#endif

Жирным шрифтом в тексте S-функции выделены те строки кода, которые обеспечивают считывание параметров блока S-function, заданных в окне диалога. При инициализации S-функции создается структура с именем S, которая содержит в численном виде все свойства S-функции и из которой, собственно, и происходит извлечение параметров с помощью указанных строк кода. Например, строка const real_T *param0 = mxGetPr(PARAM_DEF0(S));обеспечивает извлечение первого (из списка в окне параметров блока S-function) параметра, а в строке const int_T p_width0 = mxGetNumberOfElements(PARAM_DEF0(S));переменной p_width0 присваивается значение размерности этого же параметра (параметры блока S-function могут быть не только скалярами, но и векторами). Отметим также, что такие строки кода имеются в каждом из методов - mdlDerivatives, mdlOutputs и mdlUpdate, благодаря чему параметры блока S-function являются доступными в каждом из методов. Таким образом, пользователю остается добавить выделенные строки в метод mdlInitializeSizes, записать в этом же методе выражения для вычисления нужных констант и обеспечить передачу рассчитанных значений в методы mdlDerivatives, mdlOutputs и mdlUpdate. Удобнее всего это сделать с помощью специально написанной функции. Ниже приводится текст такой функции (Sfun_Get_Parameters.c) для рассматриваемого примера.

Файл Sfun_Get_Parameters.c:

double A00, A01, A10, B00, B11, C00, C11;void Sfun_Get_Parameters(SimStruct *S){ const real_T *param0 = mxGetPr(PARAM_DEF0(S)); const real_T *param1 = mxGetPr(PARAM_DEF1(S)); const real_T *param2 = mxGetPr(PARAM_DEF2(S)); const real_T *param3 = mxGetPr(PARAM_DEF3(S)); const real_T *param4 = mxGetPr(PARAM_DEF4(S)); const real_T *param5 = mxGetPr(PARAM_DEF5(S)); const int_T p_width0 = mxGetNumberOfElements(PARAM_DEF0(S)); const int_T p_width1 = mxGetNumberOfElements(PARAM_DEF1(S)); const int_T p_width2 = mxGetNumberOfElements(PARAM_DEF2(S)); const int_T p_width3 = mxGetNumberOfElements(PARAM_DEF3(S)); const int_T p_width4 = mxGetNumberOfElements(PARAM_DEF4(S)); const int_T p_width5 = mxGetNumberOfElements(PARAM_DEF5(S)); double L, R, J, Cm, Cw, Fi; L=*param0; R=*param1; J=*param2; Cm=*param3; Cw=*param4; Fi=*param5; A00 = -R/L; A01 = -Cw*Fi/L; A10 = Cm*Fi/J; B00 = 1/L; B11 = -1/J; C00 = Cm*Fi; C11 = 1;}

В первой строке файла выполнено объявление переменных A00, A01, A10, B00, B11, C00, C11. Благодаря тому, что это объявление выполнено вне тела функции указанные переменные являются глобальными. Это облегчает реализацию их передачи в нужные методы. Затем в файле функции следует объявление самой функции, и, несколько строк кода, извлекающие параметры и их размерность из структуры S. Далее идет объявление переменных, являющихся параметрами электродвигателя и расчет значений переменных A00, A01, A10, B00, B11, C00, C11.

Таким образом, исходный файл DPT_Sfunc_1_C.c подвергается модернизации в двух местах:

1. Необходимо вписать строку для подключения файла функции Sfun_Get_Parameters:
#include "Sfun_Get_Parameters.c".
Указанную директиву необходимо записать сразу после всех директив #include и #define.

2. В конце метода mdlInitializeSizes записать вызов функции Sfun_Get_Parameters:
Sfun_Get_Parameters(S);

В результате файл DPT_Sfunc_1_C.c будет выглядеть следующим образом (жирным шрифтом выделены добавления):

/* * File: DPT_Sfunc_1_C.c * * * * --- THIS FILE GENERATED BY S-FUNCTION BUILDER: BASIC, 1.0 --- * * This file is an S-function produced by the Basic S-Function * Builder which only recognizes certain fields. Changes made * outside these fields will be lost the next time the block is * used to load, edit, and resave this file. This file will be overwritten * by the S-function Builder block. If you want to edit this file by hand, * you must change it only in the area defined as: * * %%%-SFUNWIZ_defines_Changes_BEGIN * #define NAME 'replacement text' * %%% SFUNWIZ_defines_Changes_END * * DO NOT change NAME--Change the 'replacement text' only. * * For better compatibility with the Real-Time Workshop, the * "wrapper" S-function technique is used. This is discussed * in the Real-Time Workshop User's Manual in the Chapter titled, * "Wrapper S-functions". * * ------------------------------------------------------------------------- *| See matlabroot/simulink/src/sfuntmpl_doc.c for a more detailed template | * ------------------------------------------------------------------------ * Created: Sun Mar 30 13:07:10 2003 * * */#define S_FUNCTION_NAME DPT_Sfunc_1_C#define S_FUNCTION_LEVEL 2/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*//* %%%-SFUNWIZ_defines_Changes_BEGIN --- EDIT HERE TO _END */#define NUM_INPUTS 1 #define INPUT_0_WIDTH 2#define INPUT_0_FEEDTHROUGH 0#define NUM_OUTPUTS 1#define OUTPUT_0_WIDTH 2#define NPARAMS 6#define SAMPLE_TIME_0 INHERITED_SAMPLE_TIME#define NUM_DISC_STATES 0#define DISC_STATES_IC [0]#define NUM_CONT_STATES 2#define CONT_STATES_IC [0,0]#define SFUNWIZ_GENERATE_TLC 1#define SOURCEFILES "//my_lib.lib"#define PANELINDEX 5#define SFUNWIZ_REVISION 1.0/* %%%-SFUNWIZ_defines_Changes_END --- EDIT HERE TO _BEGIN *//*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/#include "simstruc.h"#define PARAM_DEF0(S) ssGetSFcnParam(S, 0)#define PARAM_DEF1(S) ssGetSFcnParam(S, 1)#define PARAM_DEF2(S) ssGetSFcnParam(S, 2)#define PARAM_DEF3(S) ssGetSFcnParam(S, 3)#define PARAM_DEF4(S) ssGetSFcnParam(S, 4)#define PARAM_DEF5(S) ssGetSFcnParam(S, 5) //=========================NEW CODE================================== #include "Sfun_Get_Parameters.c"//=========================NEW CODE================================== extern void DPT_Sfunc_1_C_Outputs_wrapper(const real_T *u, real_T *y, const real_T *xC, const real_T *param0, const int_T p_width0, const real_T *param1,
const int_T p_width1, const real_T *param2, const int_T p_width2, const real_T *param3, const
int_T p_width3, const real_T *param4, const int_T p_width4, const real_T *param5, const int_T
p_width5);extern void DPT_Sfunc_1_C_Update_wrapper(const real_T *u, const real_T *y, const real_T *param0, const int_T p_width0,const real_T *param1, const
int_T p_width1,const real_T *param2, const int_T p_width2,const real_T *param3, const int_T
p_width3,const real_T *param4, const int_T p_width4, const real_T *param5, const int_T p_width5);extern void DPT_Sfunc_1_C_Derivatives_wrapper(const real_T *u, const real_T *y, real_T *dx, real_T *xC, const real_T *param0, const int_T p_width0,const real_T *param1, const
int_T p_width1,const real_T *param2, const int_T p_width2,const real_T *param3, const int_T
p_width3,const real_T *param4, const int_T p_width4, const real_T *param5, const int_T p_width5);/*====================* * S-function methods * *====================*/#define MDL_CHECK_PARAMETERS#if defined(MDL_CHECK_PARAMETERS) && defined(MATLAB_MEX_FILE) /* Function: mdlCheckParameters ========================================= * Abstract: * Validate our parameters to verify they are okay. */ static void mdlCheckParameters(SimStruct *S) { int i; bool validParam = false; /* All parameters must be scalar */ for (i = 0; i < ssGetSFcnParamsCount(S); i++) { const mxArray *pVal = ssGetSFcnParam(S,i); if (!mxIsNumeric(pVal) ||!mxIsDouble(pVal) || mxIsLogical(pVal) || mxIsComplex(pVal) || mxIsSparse(pVal) ||!mxIsFinite(mxGetPr(pVal)[0])) { validParam = true; break; } } if (validParam) { ssSetErrorStatus(S,"All parameters must be a scalar or vectors"); return; } } #endif /* MDL_CHECK_PARAMETERS *//* Function: mdlInitializeSizes ============================================ * Abstract: * Setup sizes of the various vectors. */static void mdlInitializeSizes(SimStruct *S){ DECL_AND_INIT_DIMSINFO(inputDimsInfo); DECL_AND_INIT_DIMSINFO(outputDimsInfo); ssSetNumSFcnParams(S, NPARAMS); /* Number of expected parameters */#if defined(MATLAB_MEX_FILE) if (ssGetNumSFcnParams(S) == ssGetSFcnParamsCount(S)) { mdlCheckParameters(S); if (ssGetErrorStatus(S)!= NULL) { return; } } else { return; /* Parameter mismatch will be reported by Simulink */ }#endif ssSetNumContStates(S, NUM_CONT_STATES); ssSetNumDiscStates(S, NUM_DISC_STATES); if (!ssSetNumInputPorts(S, 1)) return; inputDimsInfo.width = INPUT_0_WIDTH; ssSetInputPortDimensionInfo(S, 0, &inputDimsInfo); ssSetInputPortFrameData(S, 0, FRAME_INHERITED); ssSetInputPortDirectFeedThrough(S, 0, INPUT_0_FEEDTHROUGH); ssSetInputPortRequiredContiguous(S, 0, 1); /*direct input signal access*/ if (!ssSetNumOutputPorts(S,1)) return; outputDimsInfo.width = OUTPUT_0_WIDTH; ssSetOutputPortDimensionInfo(S, 0, &outputDimsInfo); ssSetOutputPortFrameData(S, 0, FRAME_INHERITED); ssSetNumSampleTimes(S, 1); ssSetNumRWork(S, 0); ssSetNumIWork(S, 0); ssSetNumPWork(S, 0); ssSetNumModes(S, 0); ssSetNumNonsampledZCs(S, 0); /* Take care when specifying exception free code - see sfuntmpl_doc.c */ ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE | SS_OPTION_USE_TLC_WITH_ACCELERATOR); //=========================NEW CODE================================== Sfun_Get_Parameters(S);//=========================NEW CODE================================== }/* Function: mdlInitializeSampleTimes =================================== * Abstract: * Specifiy the sample time. */static void mdlInitializeSampleTimes(SimStruct *S){ ssSetSampleTime(S, 0, SAMPLE_TIME_0); ssSetOffsetTime(S, 0, 0.0);}#define MDL_INITIALIZE_CONDITIONS/* Function: mdlInitializeConditions ==================================== * Abstract: * Initialize the states */static void mdlInitializeConditions(SimStruct *S){ real_T *xC = ssGetContStates(S); xC[0] = 0; xC[1] = 0;}/* Function: mdlOutputs ================================================= **/static void mdlOutputs(SimStruct *S, int_T tid){ const real_T *u = (const real_T*) ssGetInputPortSignal(S,0); real_T *y = ssGetOutputPortRealSignal(S,0); const real_T *xC = ssGetContStates(S); const real_T *param0 = mxGetPr(PARAM_DEF0(S)); const real_T *param1 = mxGetPr(PARAM_DEF1(S)); const real_T *param2 = mxGetPr(PARAM_DEF2(S)); const real_T *param3 = mxGetPr(PARAM_DEF3(S)); const real_T *param4 = mxGetPr(PARAM_DEF4(S)); const real_T *param5 = mxGetPr(PARAM_DEF5(S)); const int_T p_width0 = mxGetNumberOfElements(PARAM_DEF0(S)); const int_T p_width1 = mxGetNumberOfElements(PARAM_DEF1(S)); const int_T p_width2 = mxGetNumberOfElements(PARAM_DEF2(S)); const int_T p_width3 = mxGetNumberOfElements(PARAM_DEF3(S)); const int_T p_width4 = mxGetNumberOfElements(PARAM_DEF4(S)); const int_T p_width5 = mxGetNumberOfElements(PARAM_DEF5(S)); DPT_Sfunc_1_C_Outputs_wrapper(u, y, xC, param0, p_width0, param1, p_width1, param2, p_width2,
param3, p_width3, param4, p_width4, param5, p_width5);}#undef MDL_UPDATE /* Change to #define to use the function */#if defined(MDL_UPDATE) /* Function: mdlUpdate ================================================= * Abstract: * This function is called once for every major integration time step. * Discrete states are typically updated here, but this function is useful * for performing any tasks that should only take place once per * integration step. */ static void mdlUpdate(SimStruct *S, int_T tid) { const real_T *u = (const real_T *) ssGetInputPortSignal(S,0); real_T *xD = ssGetDiscStates(S); const real_T *y = ssGetOutputPortSignal(S,0); const real_T *param0 = mxGetPr(PARAM_DEF0(S)); const int_T p_width0 = mxGetNumberOfElements(PARAM_DEF0(S)); const real_T *param1 = mxGetPr(PARAM_DEF1(S)); const int_T p_width1 = mxGetNumberOfElements(PARAM_DEF1(S)); const real_T *param2 = mxGetPr(PARAM_DEF2(S)); const int_T p_width2 = mxGetNumberOfElements(PARAM_DEF2(S)); const real_T *param3 = mxGetPr(PARAM_DEF3(S)); const int_T p_width3 = mxGetNumberOfElements(PARAM_DEF3(S)); const real_T *param4 = mxGetPr(PARAM_DEF4(S)); const int_T p_width4 = mxGetNumberOfElements(PARAM_DEF4(S)); const real_T *param5 = mxGetPr(PARAM_DEF5(S)); const int_T p_width5 = mxGetNumberOfElements(PARAM_DEF5(S)); DPT_Sfunc_1_C_Update_wrapper(u, y, param0, p_width0, param1, p_width1, param2, p_width2, param3,
p_width3, param4, p_width4, param5, p_width5); } #endif /* MDL_UPDATE */#define MDL_DERIVATIVES /* Change to #undef to remove function */#if defined(MDL_DERIVATIVES) /* Function: mdlDerivatives ============================================= * Abstract: * In this function, you compute the S-function block's derivatives. * The derivatives are placed in the derivative vector, ssGetdX(S). */ static void mdlDerivatives(SimStruct *S) { const real_T *u = (const real_T *) ssGetInputPortSignal(S,0); real_T *dx = ssGetdX(S); real_T *xC = ssGetContStates(S); const real_T *y = ssGetOutputPortSignal(S,0); const real_T *param0 = mxGetPr(PARAM_DEF0(S)); const int_T p_width0 = mxGetNumberOfElements(PARAM_DEF0(S)); const real_T *param1 = mxGetPr(PARAM_DEF1(S)); const int_T p_width1 = mxGetNumberOfElements(PARAM_DEF1(S)); const real_T *param2 = mxGetPr(PARAM_DEF2(S)); const int_T p_width2 = mxGetNumberOfElements(PARAM_DEF2(S)); const real_T *param3 = mxGetPr(PARAM_DEF3(S)); const int_T p_width3 = mxGetNumberOfElements(PARAM_DEF3(S)); const real_T *param4 = mxGetPr(PARAM_DEF4(S)); const int_T p_width4 = mxGetNumberOfElements(PARAM_DEF4(S)); const real_T *param5 = mxGetPr(PARAM_DEF5(S)); const int_T p_width5 = mxGetNumberOfElements(PARAM_DEF5(S)); DPT_Sfunc_1_C_Derivatives_wrapper(u, y, dx, xC, param0, p_width0, param1, p_width1, param2,
p_width2, param3, p_width3, param4, p_width4, param5, p_width5); }#endif /* MDL_DERIVATIVES *//* Function: mdlTerminate ================================================== * Abstract: * No termination needed, but we are required to have this routine. */static void mdlTerminate(SimStruct *S){}#ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */#include "simulink.c" /* MEX-file interface mechanism */#else#include "cg_sfun.h" /* Code generation registration function */#endif

Следующим шагом является модернизация файла DPT_Sfunc_1_C_wrapper.c, в котором содержится вычислительный код методов mdlDerivatives, mdlOutputs и mdlUpdate. Для рассматриваемого примера модернизация данного файла сводится к следующим шагам:

1. Необходимо добавить объявление глобальных переменных:
double A00, A01, A10, B00, B11, C00, C11;
Это объявление следует сделать сразу же за последней директивой #include.

2. Убрать ("закомментировать") ставшие лишними строки, в которых выполняется объявление и расчет
переменных A00, A01, A10, B00, B11, C00 и C11.

В результате файл DPT_Sfunc_1_C_wrapper.c будет выглядеть следующим образом (жирным шрифтом отмечены изменения в этом файле):

/* * * --- THIS FILE GENERATED BY S-FUNCTION BUILDER: BASIC, 1.0 --- * * This file is a wrapper S-function produced by the S-Function * Builder which only recognizes certain fields. Changes made * outside these fields will be lost the next time the block is * used to load, edit, and resave this file. This file will be overwritten * by the S-function Builder block. If you want to edit this file by hand, * you must change it only in the area defined as: * * %%%-SFUNWIZ_wrapper_XXXXX_Changes_BEGIN * Your Changes go here * %%%-SFUNWIZ_wrapper_XXXXXX_Changes_END * * For better compatibility with the Real-Time Workshop, the * "wrapper" S-function technique is used. This is discussed * in the Real-Time Workshop User's Manual in the Chapter titled, * "Wrapper S-functions". * * Created: Sun Mar 30 13:07:10 2003 *//* * Include Files * */#include "tmwtypes.h"/* %%%-SFUNWIZ_wrapper_includes_Changes_BEGIN --- EDIT HERE TO _END */#include //=========================NEW CODE================================== double A00, A01, A10, B00, B11, C00, C11;//=========================NEW CODE================================== /* %%%-SFUNWIZ_wrapper_includes_Changes_END --- EDIT HERE TO _BEGIN *//* * Create external references here. * *//* %%%-SFUNWIZ_wrapper_externs_Changes_BEGIN --- EDIT HERE TO _END *///extern double func(double a);/* %%%-SFUNWIZ_wrapper_externs_Changes_END --- EDIT HERE TO _BEGIN *//* * Output functions * */void DPT_Sfunc_1_C_Outputs_wrapper(const real_T *u, real_T *y, const real_T *xC, const real_T *param0, const int_T p_width0, const real_T *param1,
const int_T p_width1, const real_T *param2, const int_T p_width2, const real_T *param3, const
int_T p_width3, const real_T *param4, const int_T p_width4, const real_T *param5, const int_T
p_width5){ /* This Outputs function allows for 1 input and 1 output * signal of any width, any number of discrete states and * parameters, all of type real_T. * * If you need the FULL POWER of the S-function interface, * familiarize yourself with the full template file at: * * matlabroot/simulink/src/sfuntmpl_doc.c * * and the "Writing S-functions" manual in the documentation. *//* %%%-SFUNWIZ_wrapper_Outputs_Changes_BEGIN --- EDIT HERE TO _END */ //=========================OLD CODE==================================/* double Cm = param3[0], Fi = param5[0]; double C00=Cm*Fi, C11= 1; *///=========================OLD CODE================================== y[0] = C00*xC[0]; y[1] = C11*xC[1];/* %%%-SFUNWIZ_wrapper_Outputs_Changes_END --- EDIT HERE TO _BEGIN */}/* * Updates function * */void DPT_Sfunc_1_C_Update_wrapper(const real_T *u, const real_T *y, const real_T *param0, const int_T p_width0,const real_T *param1, const
int_T p_width1,const real_T *param2, const int_T p_width2,const real_T *param3, const
int_T p_width3,const real_T *param4, const int_T p_width4, const real_T *param5, const int_T p_width5){/* %%%-SFUNWIZ_wrapper_Update_Changes_BEGIN --- EDIT HERE TO _END *//* * Code example * xD[0] = u[0]; */ /* %%%-SFUNWIZ_wrapper_Update_Changes_END --- EDIT HERE TO _BEGIN */}/* * Derivatives function * */void DPT_Sfunc_1_C_Derivatives_wrapper(const real_T *u, const real_T *y, real_T *dx, real_T *xC, const real_T *param0, const int_T p_width0,const real_T *param1, const
int_T p_width1,const real_T *param2, const int_T p_width2,const real_T *param3, const int_T
p_width3,const real_T *param4, const int_T p_width4, const real_T *param5, const int_T p_width5){/* %%%-SFUNWIZ_wrapper_Derivatives_Changes_BEGIN --- EDIT HERE TO _END */ //=========================OLD CODE==================================/* double L = param0[0], R = param1[0], J =param2[0]; double Cm = param3[0], Cw = param4[0], Fi=param5[0]; double A00 = -R/L, A01 = -Cw*Fi/L, B00 = 1/L; double A10 = Cm*Fi/J, B11 = -1/J; *///=========================OLD CODE================================== dx[0] = A00*xC[0]+A01*xC[1]+B00*u[0]; dx[1] = A10*xC[0]+B11*u[1]; /* %%%-SFUNWIZ_wrapper_Derivatives_Changes_END --- EDIT HERE TO _BEGIN */}

Выполнить сборку S-функции на основе измененных файлов следует командой из рабочего окна MATLAB:
mex DPT_Sfunc_1_C.c DPT_Sfunc_1_C_wrapper.c или mex -g DPT_Sfunc_1_C.c DPT_Sfunc_1_C_wrapper.c.
При этом папка, где находятся исходные файлы, должна быть настроена как текущая. Команда mex с опцией -g создает отладочный вариант S-функции.

В результате использования предложенной методики будет получена S-функция, обеспечивающая наилучшие характеристики по быстродействию. Вносимые в исходные

И.В.Черных. "Simulink: Инструмент моделирования динамических систем": Содержание 1. Общие сведения 2. Запуск Simulink 3. Обозреватель разделов библиотеки Simulink 4. Создание модели 5. Окно модели 6. Основные приемы подготовки и редактирования модели 6.1. Добавление текстовых надписей 6.2. Выделение объектов 6.3. Копирование и перемещение объектов в буфер промежуточного хранения 6.4. Вставка объектов из буфера промежуточного хранения 6.5. Удаление объектов 6.6. Соединение блоков 6.7. Изменение размеров блоков 6.8. Перемещение блоков 6.9. Использование команд Undo и Redo 6.10. Форматирование объектов 7. Установка параметров расчета и его выполнение 7.1. Установка параметров расчета модели 7.1.1. Simulation time (Интервал моделирования или время расчета) 7.1.2. Solver options (Параметры расчета) 7.1.3. Output options (Параметры вывода) 7.2. Установка параметров обмена с рабочей областью 7.3. Установка параметров диагностирования модели 7.4. Выполнение расчета 8. Завершение работы 9. Библиотека блоков Simulink 9.1. Sources - источники сигналов 9.1.1. Источник постоянного сигнала Constant 9.1.2. Источник синусоидального сигнала Sine Wave 9.1.3. Источник линейно изменяющегося воздействия Ramp 9.1.4. Генератор ступенчатого сигнала Step 9.1.5. Генератор сигналов Signal Generator 9.1.6. Источник случайного сигнала с равномерным распределением Uniform Random Number 9.1.7. Источник случайного сигнала с нормальным распределением Random Number 9.1.8. Источник импульсного сигнала Pulse Generator 9.1.9. Генератор линейно-изменяющейся частоты Chirp Generator 9.1.10. Генератор белого шума Band-Limited White Noice 9.1.11. Источник временного сигнала Clock 9.1.12. Цифровой источник времени Digital Clock 9.1.13. Блок считывания данных из файла From File 9.1.14. Блок считывания данных из рабочего пространства From Workspace 9.1.15. Блок сигнала нулевого уровня Ground 9.1.16. Блок периодического сигнала Repeating Sequence 9.1.17. Блок входного порта Inport 9.2. Sinks - приемники сигналов 9.2.1. Осциллограф Scope 9.2.2. Осциллограф Floating Scope 9.2.3. Графопостроитель ХУ Graph 9.2.4. Цифровой дисплей Display 9.2.5. Блок остановки моделирования Stop Simulation 9.2.6. Блок сохранения данных в файле То File 9.2.7. Блок сохранения данных в рабочей области То Workspace 9.2.8. Концевой приемник Terminator 9.2.9. Блок выходного порта Outport 9.3. Continuous – аналоговые блоки 9.3.1. Блок вычисления производной Derivative 9.3.2. Интегрирующий блок lntegrator 9.3.3. Блок Memory 9.3.4. Блок фиксированной задержки сигнала Transport Delay 9.3.5. Блок управляемой задержки сигнала Variable Transport Delay 9.3.6 Блок передаточной функции Transfer Fcn 9.3.7. Блок передаточной функции Zero-Pole 9.3.8. Блок модели динамического объекта State-Space 9.4. Discrete – дискретные блоки 9.4.1. Блок единичной дискретной задержки Unit Delay 9.4.2. Блок экстраполятора нулевого порядка Zero-Order Hold 9.4.3. Блок экстраполятора первого порядка First-Order Hold 9.4.4. Блок дискретного интегратора Discrete-Time Integrator 9.4.5. Дискретная передаточная функция Discrete Transfer Fсn 9.4.6. Блок дискретной передаточной функции Discrete Zero-Pole 9.4.7. Блок дискретного фильтра Discrete Filter 9.4.8. Блок модели динамического объекта Discrete State-Space 9.5. Nonlinear - нелинейные блоки 9.5.1. Блок ограничения Saturation 9.5.2. Блок с зоной нечувствительности Dead Zone 9.5.3. Релейный блок Relay 9.5.4. Блок ограничения скорости изменения сигнала Rate Limiter 9.5.5. Блок квантования по уровню Quantizer 9.5.6. Блок сухого и вязкого трения Coulomb and Viscous Friction 9.5.7. Блок люфта Backlash 9.5.8. Блок переключателя Switch 9.5.9. Блок многовходового переключателя Multiport Switch 9.5.10. Блок ручного переключателя Manual Switch 9.6. Math – блоки математических операций 9.6.1. Блок вычисления модуля Abs 9.6.2. Блок вычисления суммы Sum9.6.3. Блок умножения Product 9.6.4. Блок определения знака сигнала Sign 9.6.5. Усилители Gain и Matrix Gain 9.6.6. Ползунковый регулятор Slider Gain 9.6.7. Блок скалярного умножения Dot Product 9.6.8. Блок вычисления математических функций Math Function 9.6.9. Блок вычисления тригонометрических функций Trigonometric Function 9.6.10. Блок вычисления действительной и (или) мнимой части комплексного числа Complex to Real-Imag 9.6.11. Блок вычисления модуля и (или) аргумена комплексного числа Complex to Magnitude-Angle 9.6.12. Блок вычисления комплексного числа по его действительной и мнимой части Real-Imag to Complex 9.6.13. Блок вычисления комплексного числа по его модулю и аргументу Magnitude-Angle to Complex 9.6.14. Блок определения минимального или максимального значения MinMax 9.6.15. Блок округления числового значения Rounding Function 9.6.16. Блок вычисления операции отношения Relational Operator 9.6.17. Блок логических операций Logical Operation 9.6.18. Блок побитовых логических операций Birwise Logical Operator 9.6.19. Блок комбинаторной логики Gombinatorical Logic 9.6.20. Блок алгебраического контура Algebraic Constraint 9.7. Signal&Systems - блоки преобразования сигналов и вспомогательные блоки 9.7.1. Мультиплексор (смеситель) Mux 9.7.2. Демультиплексор (разделитель) Demux 9.7.3. Блок шинного формирователя Bus Creator 9.7.4. Блок шинного селектора Bus Selector 9.7.5. Блок селектора Selector 9.7.6. Блок присвоения новых значений элементам массива Assignment 9.7.7. Блок объединения сигналов Merge 9.7.8. Блок объединения сигналов в матрицу Matrix Concatenation 9.7.9. Блок передачи сигнала Goto 9.7.10. Блок приема сигнала From 9.7.11. Блок признака видимости сигнала Goto Tag Visibility 9.7.12. Блок создания общей области памяти Data Store Memory 9.7.13. Блок записи данных в общую область памяти Data Store 9.7.14. Блок считывания данных из общей области памяти Data Store 9.7.15. Блок преобразования типа сигнала Data Type Conversion 9.7.16. Блок преобразования размерности сигнала Reshape 9.7.17. Блок определения размерности сигнала Width 9.7.18. Блок определения момента пересечения порогового значения Hit Crossing 9.7.19. Блок установки начального значения сигнала IC 9.7.20. Блок проверки сигнала Signal Specification 9.7.21. Датчик свойств сигнала Probe 9.7.22. Блок, задающий количество итераций Function-Call Generator 9.7.23. Информационный блок Model Info 9.8. Function & Tables – блоки функций и таблиц 9.8.1. Блок задания функции Fcn 9.8.2. Блок задания функции MATLAB Fcn 9.8.3. Блок задания степенного многочлена Polynomial 9.8.4. Блок одномерной таблицы Look-Up Table 9.8.5. Блок двумерной таблицы Look-Up Table(2D) 9.8.6. Блок многомерной таблицы Look-Up Table (n-D) 9.8.7. Блок таблицы с прямым доступом Direct Loop-Up Table (n-D) 9.8.8. Блок работы с индексами PreLook-Up Index Search 9.8.9. Блок интерполяции табличной функции Interpolation (n-D) using PreLook-Up 9.9. Subsystem - подсистемы 9.9.1. Виртуальная и монолитная подсистемы Subsystem и Atomic Subsystem 9.9.2. Управляемая уровнем сигнала подсистема Enabled Subsystem 9.9.3. Управляемая фронтом сигнала подсистема Triggered Subsystem 9.9.4. Управляемая уровнем и фронтом сигнала подсистема Enabled and Triggered Subsystem 9.9.5. Управляемая S-функцией подсистема Function-call subsystem 9.9.6. Блок условного оператора If 9.9.7. Блок переключателя Switch Case 9.9.8. Управляемая по условию подсистема Action Subsystem 9.9.9. Управляемая подсистема For Iterator Subsystem 9.9.10. Управляемая подсистема While Iterator Subsystem 9.9.11. Конфигурируемая подсистема Configurable Subsystem 9.10. Маскирование подсистем 9.10.1. Общие сведения 9.10.2. Создание окна параметров 9.10.3. Создание пиктограммы подсистемы 9.10.3.1. Команды вывода текста 9.10.3.2. Команды построения графиков 9.10.3.3. Команды отображения передаточных функций 9.10.3.4. Команды отображения рисунка из графического файла 9.10.3.5. Использование редактора пиктограмм iconedit 9.10.3.6. Создание автоматически обновляемых пиктограмм 9.10.4. Создание справки маскированной подсистемы 9.10.5. Создание динамически обновляемых окон диалога 9.10.6. Управление портами маскированной подсистемы 10. Редактор дифференциальных уравнений DEE 11. Использование Simulink LTI-Viewer для анализа динамических систем 11.1. Работа с Simulink LTI-Viewer 11.2. Настройка с Simulink LTI-Viewer 11.3. Экспорт модели 12. Основные команды MATLAB для управления Simulink-моделью 12.1. add_block 12.2. add_line 12.3. add_param 12.4. bdclose 12.5. bdroot 12.6. close_system 12.7. delete_block 12.8. delete_line 12.9. delete_param 12.10. gcb 12.11. gcs 12.12. find_system 12.13. get_param 12.14. new_system 12.15. open_system 12.16. replace_block 12.17. save_system 12.18. set_param 12.19. simulink 13. Отладчик Simulink моделей 13.1. Графический интерфейс отладчика Simulink моделей 13.1.1. Панель инструментов 13.1.2. Список контрольных точек Break/Display points 13.1.3. Панель задания точек прерывания по условию Break on conditions 13.1.4. Главное окно отладчика 14. Повышение скорости и точности расчетов 14.1. Повышение скорости расчета 14.2. Повышение точности расчета 15. Обзор набора инструментов Simulink Performance Tools 15.1. Simulink Accelerator 15.2. Simulink Model Profiling 15.3. Simulink Model Coverage 15.4. Simulink Model Differencing 16. Simulink-функции 16.1. Блок S-function 16.2. Математическое описание S-функции 16.3. Этапы моделирования 16.4. Callback-методы S-функции 16.5. Основные понятия S-функции 16.6. Создание S-функций на языке MATLAB 16.7. Примеры S-функций языке MATLAB 16.7.1. Простейшая S-функция 16.7.2. Модель непрерывной системы 16.7.3. Модель дискретнойной системы 16.7.4. Модель гибридной системы 16.7.5. Модель дискретной системы с переменным шагом расчета 16.7.6. Непрерывная модель электродвигателя постоянного тока независимого возбуждения 16.7.6.1. Математическое описание ДПТ НВ 16.7.6.2. Пример S-функции для ДПТ НВ 16.8. Создание S-функций на языке C с помощью S-Function Builder 16.9. Модернизация S-функций, созданных с помощью S-Function Builder 16.10. Создание S-функций на языке Fortran Приложение 1. Система меню обозревателя библиотек программы Simulink Приложение 2. Система меню окна модели  

 


Дата добавления: 2015-09-05; просмотров: 61 | Нарушение авторских прав


<== предыдущая страница | следующая страница ==>
Your machine has a Lcc C compiler located at| Блок единичной дискретной задержки Unit Delay

mybiblioteka.su - 2015-2024 год. (0.011 сек.)