125 Использование пакета SIMULINK/MATLAB для построения S-функций систем управления - Страница 4

Эту инструкцию можно записать и так:

*x=0;

Вызов callback-функции

mdlOutputs(SimStruct * S, int_T tid)

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

Макрокоманды ssGetСontStates(S) и ssGetOutputPortSignal(S,0) возвращают соответственно адреса x и y ячеек памяти, в которых хранятся значения вектора состояния и векторного выходного сигнала соответственно. Полученная на основе уравнения выхода создаваемого блока инструкция С-кода

y[0]=x[0];

позволяет вычислить единственный выходной сигнал и предусматривает сначала извлечение из блока памяти значения вектора состояния и затем  запись последнего в память по адресу, определяемому указателем y. Отметим, что данное выражение также может быть записано в виде:

*y=*x;

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

#define MDL_DERIVATIVES

callback-функцию mdlDerivatives (вычисление производных состояния непрерывного блока). При этом условный оператор компиляции #if defined(MDL_DERIVATIVES) передает программный код данной callback-функции на компиляцию. Макрокоманды ssGetdx(S) и ssGetСontStates(S) возвращают соответственно адреса (указатели) dx и x ячеек памяти в структуре SimStruct, которые выделены для хранения вектора производных состояния и вектора состояния соответственно. Область памяти для вектора состояния уже хранит вычисленные значения вектора состояния, полученные на предыдущем шаге интегрирования.

На следующих двух инструкциях остановимся более подробно. Прежде всего отметим, что макрокоманда ssGetSFcnParam(S, 0) (возвратить указатель на диалоговый параметр S-функции с индексом 0), второй аргумент которой равен порядковому номеру параметра минус единица, возвращает указатель (адрес) типа mxArray* на область памяти, выделенной для хранения диалогового параметра А. При этом инструкция для получения значения диалогового параметра А должна была бы выглядеть следующим образом:

const mxArray* A = ssGetSFcnParam(S,0);

где указатель А является константой для данной S-функции на весь период ее действия вплоть до изменения этого параметра с помощью диалогового окна параметров. Однако S-функция не оперирует с типами данных mxArray и их применение приводит к ошибкам смешения типов данных [2]. Для того чтобы преобразовать указатель типа const mxArray* в указатель типа const real_T, являющийся одним из базовых типов данных S-функции, используется функция mxGetPr, входящих в набор функций MATLAB API. Последняя функция в качестве аргумента имеет константу-указатель типа const mxArray* и возвращает преобразованный указатель типа const real_T*. Следовательно, инструкция для получения диалогового параметра А должна иметь вид:

const real_T* A = mxGetPr(ssGetSFcnParam(S,0));

В данном случае заявлены два диалоговых параметра А и В, первый из которых имеет индекс 0, а второй индекс 1. Отсюда в исходный файл включена еще одна инструкция

const real_T* B = mxGetPr(ssGetSFcnParam(S,1));

позволяющая получить доступ ко второму диалоговому параметру В.

И, наконец, макрокоманда

ssGetInputPortRealSignalPtrs(S, 0);

возвращает указатель (адрес) на первый элемент векторного входного сигнала, причем этот указатель имеет тип данных InputPortRealPtrsType, аналогичный типу данных const real_T *. Отсюда инструкция для получения значения входного сигнала выглядит так:

InputPortRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S, 0);

Выражение

dx[0]=A[0]*x[0]+B[0]*U(0);

является С-кодом уравнения состояния апериодического звена. В принципе, его можно записать следующим образом:

*dx=(*A)*(*x)+(*B)*U(0);

Результатом вычисления правой части этого выражения является производная состояния , помещаемая затем для хранения в область памяти с адресом, определяемым указателем dx.

В процессе работы пакета Simulink/MATLAB информация о производной состояния  используется для ее интегрирования с помощью выбранного решателя. Тем самым вычисляется само состояние x и осуществляется его размещение по адресу, определенному указателем x=ssGetСontStates(S).

Заметим, что необходимо возвращать все указатели, которые фигурируют в С-кодах для вычисления векторов выхода и производных состояния, расположенных соответственно в callback-функциях mdlOutputs и mdlDerivatives. Поэтому в данном случае инструкция

real_T *x = ssGetСontStates(S);

фигурирует как в mdlOutputs, так и в mdlDerivatives.

Callback-функция

static void mdlTerminate(SimStruct * S);

является обязательной даже тогда, когда, как и в данном случае, не содержит никаких инструкций.

Последняя часть исходного файла включает условные директивы препроцессора. Нас в данном учебном пособии интересует лишь случай, когда выражение MATLAB_MEX_FILE, говорящее о том, что данный исходный файл компилируется как С MEX-файл, является истинным. При этом в соответствии с директивой #includesimulink.c” файл simulink.c, представляющий собой интерфейсный механизм С MEX-файла, включается в исходный файл.

 

3.3.Построение S-функции для гибридной системы управления

Рассмотрим гибридную (цифровую) систему управления с обратной связью (рис. 5), которая включает в себя:

1) непрерывный объект управления ОУ 2-го порядка (непрерывный динамический блок), описываемый уравнениями в переменных состояния

(8)

(9)

 

где ,  - переменные состояния ОУ,  - скалярная управляемая величина (выход системы), - скалярное управляющее воздействие. Заданы матричный  и  векторный   параметры объекта управления:

 

(10)

 

2) дискретный регулятор ДР 2-го порядка (дискретный динамический блок), описываемый разностным уравнением состояния

 

 

где  ,  - переменные состояния ДР, - задающая последовательность, - управляемая последовательность {причем  и     образуются     путем     дискретизации   с      периодом       TD =0.1 с соответственно скалярного задающего воздействия   и управляемой величины } и   разностным   уравнением    выхода

 

где - скалярная управляющая последовательность (выход дискретного регулятора).

 

Рис. 5

 

Параметры дискретного регулятора, а именно матрица , векторы  и , скаляр , которые можно записать в общем виде:

 

должны быть выбраны в процессе параметрического синтеза системы управления, другими словами, в процессе синтеза нужно опеределить элементы матрицы , векторов  и , скаляр , обеспечивающие заданное качество работы этой системы;

3) формирователь Ф, преобразующий управляющую последовательность  в непрерывный, кусочно-постоянный управляющий сигнал  в соответствии с формулой

 

Директивы препроцессора вида

#define PARAM_AD(S) ssGetSFcnParam(S, 0);

позволяют связать значения параметров, которые вводятся в диалоговое окно блока S-Function, с названиями этих параметров. В данном случае при выполнении моделирования надо ввести четыре параметра в диалоговое окно этого блока, причем первый – матричный PARAM_AD для матрицы  , второй и третий – векторные PARAM_BD и PARAM_CD для векторов  и , четвертый – скалярный PARAM_dD для скаляра . Доступ к диалоговым параметрам обеспечивается макрокомандой ssGetSFcnParam(S, ind). Второй аргумент ind этой мкрокоманды определяет относительную позицию параметра в списке, введенном в диалоговое окно, причем 0 – первая позиция, 1- вторая позиция и т.д. Как видим, первому параметру  в макрокоманде ssGetSFcnParam(S, 0) соответствует аргумент 0, второму параметру  соответствует аргумент 1 и т.д. Забегая вперед, отметим, что второй аргумент макрокоманды ssSetNumSFcnParams(S, 4), сообщающий Simulink, сколько диалоговых параметров должна ожидать S-функция, в данном случае равен 4.

Следующие за директивами препроцессора директивы объявления и определения относятся к массивам параметров объекта управления. В языке С признаком массива являются квадратные скобки, в которых записаны константные выражения, определяющие число элементов в массиве [6,7]. В данном случае массивом, состоящим из двух элементов, является массив BС [2], соотвествующий параметру  объекта управления. Индексация элементов массива начинается с нуля. Таким образом, последний элемент массива имеет индекс на единицу меньше, чем число элементов в массиве. В данном случае элемент BС[0] массива BС соответствует элементу BС1 векторного параметра , элемент BС[1] массива BС - элементу BС2 векторного параметра .

Многомерный массив объявляется путем задания константных выражений в нескольких последовательно расположенных квадратных скобках,

следующих за описателем. В данном случае двухмерный массив с именем АС, представляющий собой матрицу размерностью 2х2, объявляется как real_T AС[2][2]. Этот массив соответствует матричному параметру  объекта управления. Строго говоря, АС представляет собой массив, состоящий из двух элементов, каждый из которых является массивом из двух элементов. Элементы массива запоминаются построчно. Так, массив AС будет храниться следующим образом: сначала в памяти запоминаются два элемента AС[0][0] и AС[0][1] первой строки, затем два элемента АС[1][0] и AС[1][1] второй строки. Инициализация массивов, т.е. присваивание элементам массива числовых значений, производится с помощью списка инициализаторов. В данном случае двухмерный массив АС объявляется так:

static real_T AС [2][2] = {{0,1},{-2,-3}};

Элементами первой строки этого массива являются значения 0 и 1, соответствущие элементам первой строки матрицы  объекта управления, элементами второй строки -  значения -2 и -3, соответствующие элементам второй строки этой матрицы.

Из текста файла видно, каким образом инициализируется массив BС[2] по заданным значениям элементов векторного параметра  объекта управления.

Макрокоманды, входящие в callback–функцию mdlInitialization, позволяют определить число переменных состояния непрерывного (СontStates) и дискретного (DiskStates) блоков (в данном случае  2 для каждого из них), а также число сигналов, т. е. одного входного и двух выходных сигналов. Кроме того, с помощью макрокоманд ssSetInputPortWidth и ssSetOutputPortWidth определяется, что все эти сигналы являются скалярными, другими словами, векторными с размерностью (PortWidth), равной 1. Входящие
в условные операторы if макрокоманды ssSetNumInputPorts(S,1) и ssSetNumOutInputPorts(S,2) как раз служат для определения числа входов и выходов блока S-Function.

Особо следует остановиться на определении вида дискретизации выходных сигналов блока S-Function. Предпринятая нами попытка использовать блок S-Function с одним векторным выходным сигналом,  элементами которого служат выходные сигналы дискретного регулятора и объекта управления, оказалась неудачной. По нашему мнению, это связано  со специфической интерпретацией пакетом Simulink сигнала, снимаемого с выхода дискретного регулятора. Пакет Simulink трактует этот дискретный сигнал как непрерывный с вытекающими отсюда негативными последствиями, проявляющимися при последующей регистрации этого выходного сигнала с помощью блока Scope. С целью избежать недоразумений, вызванных этим обстоятельством, надо сообщить Simulink вид дискретизации, присущий каждому из интересующих нас выходных сигналов моделируемой системы, а также предоставить каждому из них отдельный выход в блоке S-Function. Для спецификации вида дискретизации и значения периода дискретизации (для дискретных сигналов) используются макрокоманды ssSetInputPortSampleTime и  ssSetOutputPortSampleTime.

В данном случае с помощью макрокоманды

ssSetInputPortSampleTime (S,0,СONTINUOUS_SAMPLE_TIME);

и парной ей макрокоманды

ssSetInputPortOffsetTime (S, 0, 0.0);

определяется, что вход проектируемого блока является выходом внешнего проектируемого блока и смещение (Offset) равно нулю.



 
станина от швейной машинки