Этот пример показывает, как записать файлы ОДУ для нелинейных моделей серого поля как MATLAB и файлы MEX на C.
Серое моделирование поля концептуально отличается от моделирования черного квадрата, в которое оно вовлекает более всесторонний шаг моделирования. Для IDNLGREY (нелинейный объект модели серого поля; нелинейный дубликат IDGREY), этот шаг состоит из создания файла ОДУ, также названного "образцовым файлом". Файл ОДУ задает правые стороны состояния, и выходные уравнения обычно прибывали в посредством физического первого принципиального моделирования. В этом примере мы сконцентрируемся на общих аспектах реализации его как файл MATLAB или файл MEX на C.
IDNLGREY поддерживает оценку параметров и начальных состояний в нелинейных образцовых структурах, записанных на следующей явной форме пространства состояний (так называемая ошибка на выходе, OE, форма, названная поэтому как шум e (t) только, влияет на вывод образцовой структуры аддитивным способом):
xn(t) = F(t, x(t), u(t), p1, ..., pNpo); x(0) = X0;
y(t) = H(t, x(t), u(t), p1, ..., pNpo) + e(t)
Для структур дискретного времени, xn (t) = x (T+Ts) с Ts, являющимся шагом расчета, и для непрерывно-разовых структур xn (t) = d/dt x (t). Кроме того, F(.) и H(.) являются произвольными линейными или нелинейными функциями с Nx (количество состояний) и Ny (количество выходных параметров) компоненты, соответственно. Любой из параметров модели p1..., pNpo, а также вектор начального состояния X (0) может быть оценен. Стоящий выделения это
моделирование timeseries, т.е. моделирование без внешнего входного сигнала u (t), и
статическое моделирование, т.е. моделирование без любых состояний x (t)
два особых случая, которые поддерживаются IDNLGREY. (См. примеры idnlgreydemo3 и idnlgreydemo5 для примеров этих двух категорий моделирования).
Первый IDNLGREY, моделирующий шаг, чтобы выполнить, должен всегда реализовывать MATLAB или файл модели C MEX, задающий, как обновить состояния и вычислить выходные параметры. Главное, пользователь должен записать образцовый файл, MODFILENAME.m или MODFILENAME.c, заданный со следующими аргументами ввода и вывода (заметьте, что эта форма требуется и для MATLAB и для типа MEX C образцовых файлов),
[дуплекс, y] = MODFILENAME (t, x, u, p1, p2..., pNpo, FileArgument)
MODFILENAME может здесь быть любым пользователем выбранное имя файла MATLAB или файла MEX на C, например, видеть twotanks_m.m, pendulum_c.c и т.д. Этот файл должен быть задан, чтобы возвратить два выходных параметра:
дуплекс: правая сторона (стороны) уравнения (уравнений) пространства состояний (вектор-столбец с Nx действительные записи; [] для статических моделей)
y: правая сторона (стороны) выходного уравнения (уравнений) (вектор-столбец с Ny действительные записи)
и это должно взять 3+Npo (+1) входные параметры, заданные можно следующим образом:
t: текущее время
x: вектор состояния во время t ([] для статических моделей)
u: входной вектор во время t ([] для моделей timeseries)
p1, p2..., pNpo: отдельные параметры (который может быть действительными скалярами, вектор-столбцами или 2-мерными матрицами); Npo является здесь количеством объектов параметра, которые для моделей со скалярными параметрами совпадают с количеством параметров Np
FileArgument: дополнительные входные параметры к образцовому файлу
В прогрессивном обсуждении мы будем фокусироваться на записи модели, использующей или язык MATLAB или использующей файлы MEX на C. Однако IDNLGREY также поддерживает P-файлы (защищенные файлы MATLAB получили использование команды MATLAB "псевдокод"), и указатели на функцию. На самом деле не только возможно использовать файлы модели C MEX, но также и файлы MEX Фортрана. Консультируйтесь с документацией MATLAB относительно Внешних Интерфейсов для получения дополнительной информации о последнем.
Какой образцовый файл должен быть реализован? Ответ на этот вопрос действительно зависит от использования модели.
Реализация с помощью языка MATLAB (приводящий к *.m файлу) имеет некоторые явные преимущества. Во-первых, можно избежать длительного, низкоуровневого программирования и сконцентрироваться больше на аспектах моделирования. Во-вторых, любая функция, доступная в MATLAB и его тулбоксах, может использоваться непосредственно в образцовых файлах. В-третьих, такие файлы будут меньшими и без любых модификаций, вся встроенная проверка ошибок MATLAB будет автоматически осуществлена. Кроме того, это получено без любой компиляции кода.
C моделирование MEX намного более включен и требует элементарных знаний о языке программирования C. Основным преимуществом с файлами модели C MEX является улучшенная скорость выполнения. Наши общие рекомендации должны преследовать моделирование MEX C, когда модель будет используемой много раз, когда большие наборы данных используются, и/или когда образцовая структура содержит много вычислений. Часто стоит запуститься с использования файла MATLAB и позже обратиться к дубликату MEX C.
С этим сказал, давайте затем идти дальше к моделированию файла MATLAB и использовать нелинейную структуру модели второго порядка, описывая две системы корпуса, как пример. См. idnlgreydemo2 для деталей моделирования. Содержимое twotanks_m.m следующие.
type twotanks_m.m
function [dx, y] = twotanks_m(t, x, u, A1, k, a1, g, A2, a2, varargin) %TWOTANKS_M A two tank system. % Copyright 2005-2006 The MathWorks, Inc. % Output equation. y = x(2); % Water level, lower tank. % State equations. dx = [1/A1*(k*u(1)-a1*sqrt(2*g*x(1))); ... % Water level, upper tank. 1/A2*(a1*sqrt(2*g*x(1))-a2*sqrt(2*g*x(2))) ... % Water level, lower tank. ];
В функциональном заголовке мы здесь находим необходимый t, x, и u входные параметры сопровождаемыми шестью скалярными параметрами модели, A1, k, a1, g, A2 и a2. В случае файла MATLAB последний входной параметр должен всегда быть varargin, чтобы поддержать передачу дополнительного образцового входного параметра файла, FileArgument. В объекте модели IDNLGREY FileArgument хранится как массив ячеек, который может содержать любой вид данных. К первому элементу FileArgument здесь получают доступ через varargin {1} {1}.
Переменные и параметры отнесены в стандартном MATLAB путь. Первое состояние является x (1) и вторым x (2), вход является u (1) (или только u в случае, если это - скаляр), и к скалярным параметрам просто получают доступ через их имена (A1, k, a1, g, A2 и a2). К отдельным элементам векторных и параметров матрицы получают доступ как P (i) (элемент i из векторного параметра, названного P) и как P (i, j) (элемент в строке i и столбце j параметра матрицы, названного P), соответственно.
Записывание файла модели C MEX более включено, чем записывание файла модели MATLAB. Чтобы упростить этот шаг, рекомендуется, чтобы доступный шаблон модели IDNLGREY C MEX был скопирован в MODFILENAME.c. Этот шаблон содержит скелетный исходный код, а также подробные инструкции относительно того, как настроить код для конкретного приложения. Местоположение файла шаблона найдено путем ввода следующего в подсказке команды MATLAB.
fullfile(matlabroot, 'toolbox', 'ident', 'nlident', 'IDNLGREY_MODEL_TEMPLATE.c')
Для двух примеров корпуса этот шаблон был скопирован в twotanks_c.c. После некоторых начальных модификаций и настроек (описанный ниже) состояние и выходные уравнения вводились, таким образом, приводя к следующему исходному коду MEX C.
type twotanks_c.c
/* Copyright 2005-2015 The MathWorks, Inc. */ /* Written by Peter Lindskog. */ /* Include libraries. */ #include "mex.h" #include <math.h> /* Specify the number of outputs here. */ #define NY 1 /* State equations. */ void compute_dx(double *dx, double t, double *x, double *u, double **p, const mxArray *auxvar) { /* Retrieve model parameters. */ double *A1, *k, *a1, *g, *A2, *a2; A1 = p[0]; /* Upper tank area. */ k = p[1]; /* Pump constant. */ a1 = p[2]; /* Upper tank outlet area. */ g = p[3]; /* Gravity constant. */ A2 = p[4]; /* Lower tank area. */ a2 = p[5]; /* Lower tank outlet area. */ /* x[0]: Water level, upper tank. */ /* x[1]: Water level, lower tank. */ dx[0] = 1/A1[0]*(k[0]*u[0]-a1[0]*sqrt(2*g[0]*x[0])); dx[1] = 1/A2[0]*(a1[0]*sqrt(2*g[0]*x[0])-a2[0]*sqrt(2*g[0]*x[1])); } /* Output equation. */ void compute_y(double *y, double t, double *x, double *u, double **p, const mxArray *auxvar) { /* y[0]: Water level, lower tank. */ y[0] = x[1]; } /*----------------------------------------------------------------------- * DO NOT MODIFY THE CODE BELOW UNLESS YOU NEED TO PASS ADDITIONAL INFORMATION TO COMPUTE_DX AND COMPUTE_Y To add extra arguments to compute_dx and compute_y (e.g., size information), modify the definitions above and calls below. *-----------------------------------------------------------------------*/ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /* Declaration of input and output arguments. */ double *x, *u, **p, *dx, *y, *t; int i, np; size_t nu, nx; const mxArray *auxvar = NULL; /* Cell array of additional data. */ if (nrhs < 3) { mexErrMsgIdAndTxt("IDNLGREY:ODE_FILE:InvalidSyntax", "At least 3 inputs expected (t, u, x)."); } /* Determine if auxiliary variables were passed as last input. */ if ((nrhs > 3) && (mxIsCell(prhs[nrhs-1]))) { /* Auxiliary variables were passed as input. */ auxvar = prhs[nrhs-1]; np = nrhs - 4; /* Number of parameters (could be 0). */ } else { /* Auxiliary variables were not passed. */ np = nrhs - 3; /* Number of parameters. */ } /* Determine number of inputs and states. */ nx = mxGetNumberOfElements(prhs[1]); /* Number of states. */ nu = mxGetNumberOfElements(prhs[2]); /* Number of inputs. */ /* Obtain double data pointers from mxArrays. */ t = mxGetPr(prhs[0]); /* Current time value (scalar). */ x = mxGetPr(prhs[1]); /* States at time t. */ u = mxGetPr(prhs[2]); /* Inputs at time t. */ p = mxCalloc(np, sizeof(double*)); for (i = 0; i < np; i++) { p[i] = mxGetPr(prhs[3+i]); /* Parameter arrays. */ } /* Create matrix for the return arguments. */ plhs[0] = mxCreateDoubleMatrix(nx, 1, mxREAL); plhs[1] = mxCreateDoubleMatrix(NY, 1, mxREAL); dx = mxGetPr(plhs[0]); /* State derivative values. */ y = mxGetPr(plhs[1]); /* Output values. */ /* Call the state and output update functions. Note: You may also pass other inputs that you might need, such as number of states (nx) and number of parameters (np). You may also omit unused inputs (such as auxvar). For example, you may want to use orders nx and nu, but not time (t) or auxiliary data (auxvar). You may write these functions as: compute_dx(dx, nx, nu, x, u, p); compute_y(y, nx, nu, x, u, p); */ /* Call function for state derivative update. */ compute_dx(dx, t[0], x, u, p, auxvar); /* Call function for output update. */ compute_y(y, t[0], x, u, p, auxvar); /* Clean up. */ mxFree(p); }
Давайте пройдем содержимое этого файла. Как первое наблюдение, мы можем разделить работу записывания файла модели C MEX в четыре отдельных подшага, последний, являющийся дополнительным:
Включение C-библиотек и определения количества выходных параметров.
Пишущий функцию, вычисляя правую сторону (стороны) уравнения (уравнений) состояния, compute_dx.
Пишущий функцию, вычисляя правую сторону (стороны) выходного уравнения (уравнений), compute_y.
Опционально обновляя основную функцию интерфейса, которая включает основную функциональность проверки ошибок, код для создания и обработки аргументов ввода и вывода, и вызывает к compute_dx и compute_y.
Прежде чем мы обратимся к этим подшагам более подробно, давайте кратко прокомментируем несколько общих функций языка программирования C.
Переменные высокой точности (все входные параметры, состояния, выходные параметры и параметры объекта IDNLGREY) должны быть заданы, чтобы быть типа данных "дважды".
Унарный оператор *, помещенный только перед именами переменных или названиями параметра, является так называемым оператором разыменования. C-объявление "дважды *A1"; указывает, что A1 является указателем на двойную переменную. Построение указателя является концепцией в C, который не всегда настолько легко постигать. К счастью, если объявления вывода/входных переменных compute_y и compute_dx не изменяются, и все распакованные параметры модели внутренне объявляются с *, то нет никакой потребности знать больше об указателях от IDNLGREY моделирование точки зрения.
И compute_y и compute_dx сначала объявлены и реализованы, где после того, как они будут названы в основной функции интерфейса. В объявлении ключевое слово "пусто" утверждает явным образом, что никакое значение не должно быть возвращено.
Для получения дальнейшей информации языка программирования C мы обращаемся к книге
B.W. Kernighan and D. Ritchie. The C Programming Language, 2nd
edition, Prentice Hall, 1988.
На первом подшаге мы сначала включаем C-библиотеки "mex.h" (требуемый) и "math.h" (требуемый для более усовершенствованной математики). Количество выходных параметров также объявляется на моделирование файла с помощью стандартного C-define:
/* Include libraries. */
#include "mex.h"
#include "math.h"
/* Specify the number of outputs here. */
#define NY 1
При желании можно также включать больше C-библиотек, чем те выше.
"math.h" библиотека должна быть включена каждый раз, когда любое уравнение состояния или вывода содержит более усовершенствованную математику, как функции тригонометрического и квадратного корня. Ниже выбранный список функций, включенных в "math.h" и дубликат, найденный в MATLAB:
C-function MATLAB function
========================================
sin, cos, tan sin, cos, tan
asin, acos, atan asin, acos, atan
sinh, cosh, tanh sinh, cosh, tanh
exp, log, log10 exp, log, log10
pow(x, y) x^y
sqrt sqrt
fabs abs
Заметьте, что функции MATLAB более универсальны, чем соответствующие C-функции, например, бывшие комплексные числа указателя, в то время как последние не делают.
Затем, в файле мы ищем функции для обновления состояний, compute_dx, и вывод, compute_y. Обе этих функции содержат списки аргументов с выводом, который будет вычислен (дуплекс или y) в положении 1, после которого следует за всеми переменными и параметрами, требуемыми вычислить правую сторону (стороны) состояния и выходных уравнений, соответственно.
Все параметры содержатся в массиве параметров p. Первый шаг в compute_dx и compute_y должен распаковать и назвать параметры, которые будут использоваться в последующих уравнениях. В twotanks_c.c compute_dx объявляет шесть переменных параметра, значения которых определяются соответственно:
/* Retrieve model parameters. */
double *A1, *k, *a1, *g, *A2, *a2;
A1 = p[0]; /* Upper tank area. */
k = p[1]; /* Pump constant. */
a1 = p[2]; /* Upper tank outlet area. */
g = p[3]; /* Gravity constant. */
A2 = p[4]; /* Lower tank area. */
a2 = p[5]; /* Lower tank outlet area. */
compute_y, с другой стороны, не требует никакого параметра для вычисления вывода, и следовательно никакой параметр модели не получен.
Как имеет место в C, первый элемент массива хранится в положении 0. Следовательно, дуплекс [0] в C соответствует дуплексу (1) в MATLAB (или только дуплекс в случае, если это - скаляр), вход u [0] соответствует вам (или u (1)), параметр A1 [0] соответствует A1 и так далее.
В примере выше, мы только используем скалярные параметры, в этом случае общее количество параметров, Np равняется количеству объектов параметра Npo. Если какой-либо векторный или параметр матрицы включен в модель, то Npo <Np.
На скалярные параметры ссылаются как P [0] (P (1) или только P в файле MATLAB) и i:th векторный элемент как P [i-1] (P (i) в файле MATLAB). Матрицы, переданные файлу модели C MEX, отличаются в том смысле, что столбцы сложены друг на друга в очевидном порядке. Следовательно, если P является матрицей 2 на 2, то P (1, 1) отнесен как P [0], P (2, 1) как P[1], P (1, 2) как P[2] и P (2, 2) как P[3]. См. "Примеры на Нелинейной Серой Идентификации Поля: Промышленные Три Робота Степеней свободы: Моделирование Файла MEX на C Системы MIMO Используя Вектор/Параметры матрицы", idnlgreydemo8, для примера, где скаляр, векторные и параметры матрицы используются.
Состояние и выходные функции обновления могут также включать другие вычисления, чем только получение параметров и вычислительных правых выражений стороны. Для скорости выполнения каждый может, например, объявите и используйте промежуточные переменные, значения которых несколько раз используются в ближайших выражениях. Упомянутый выше пример по роботу, idnlgreydemo8, является хорошим примером в этом отношении.
compute_dx и compute_y также могут обработать дополнительный FileArgument. Данные FileArgument передаются этим функциям в auxvar переменной, так, чтобы первый компонент FileArgument (массив ячеек) мог быть получен через
mxArray* auxvar1 = mxGetCell(auxvar, 0);
Здесь, mxArray является определенным типом данных MATLAB, который включает обмен данными между файлом MEX на C и MATLAB. В свою очередь auxvar1 может содержать любые данные. Парсинг, проверка и использование auxvar1 должны быть обработаны только в этих функциях, где это до образцового разработчика файла, чтобы реализовать эту функциональность. Позвольте нам здесь только обратиться к документации MATLAB относительно Внешних Интерфейсов для получения дополнительной информации о функциях, которые работают с mxArrays. Пример того, как использовать дополнительные аргументы файла модели C MEX, обеспечивается в idnlgreydemo6, "Примеры на Нелинейной Серой Идентификации Поля: Система Передачи Сигнала: Моделирование Файла MEX на C Используя Дополнительные Входные параметры".
Основная функция интерфейса должна почти всегда иметь то же содержимое, и для большинства приложений вообще не необходима никакая модификация. В принципе единственная часть, которая может быть рассмотрена для изменений, - то, где вызовы compute_dx и compute_y выполняются. Для статических систем можно не учесть вызов compute_dx. В других ситуациях это может быть желаемо, чтобы только передать переменные и параметры, отнесенные в состоянии и вывести уравнения. Например, в выходном уравнении двух систем корпуса, где только одно состояние используется, можно было очень хорошо сократить список входных параметров к
void compute_y(double *y, double *x)
и вызовите compute_y в основной функции интерфейса как
compute_y(y, x);
Списки входных параметров compute_dx и compute_y силы также быть расширенным, чтобы включать дальнейшие переменные, выведенные в функцию интерфейса. Следующие целочисленные переменные вычисляются и могут поэтому быть переданы: ню (количество входных параметров), nx (количество состояний), и np (здесь количество объектов параметра). Как пример, nx передается compute_y в модели, исследованной в примере idnlgreydemo6.
Завершенный файл модели C MEX должен быть скомпилирован, прежде чем он сможет использоваться для моделирования IDNLGREY. Компиляция может с готовностью быть сделана из командной строки MATLAB как
mex MODFILENAME.c
Заметьте, что mex-команда должна быть сконфигурирована, прежде чем она будет использоваться в самый первый раз. Это также достигается из командной строки MATLAB через
mex -setup
С выполнением готовый образцовый файл это прямо, чтобы создать объекты модели IDNLGREY, для которых и т.д могут быть выполнены симуляции, оценки параметра. Мы иллюстрируем это путем создания двух различных объектов модели IDNLGREY для описания двух систем корпуса, одно использование образцового файла, записанного в MATLAB и одном использовании файла MEX на C, подробно изложенного выше (заметьте здесь, что файл модели C MEX был уже скомпилирован).
Order = [1 1 2]; % Model orders [ny nu nx]. Parameters = [0.5; 0.003; 0.019; ... 9.81; 0.25; 0.016]; % Initial parameter vector. InitialStates = [0; 0.1]; % Initial values of initial states. nlgr_m = idnlgrey('twotanks_m', Order, Parameters, InitialStates, 0)
nlgr_m = Continuous-time nonlinear grey-box model defined by 'twotanks_m' (MATLAB file): dx/dt = F(t, u(t), x(t), p1, ..., p6) y(t) = H(t, u(t), x(t), p1, ..., p6) + e(t) with 1 input(s), 2 state(s), 1 output(s), and 6 free parameter(s) (out of 6). Status: Created by direct construction or transformation. Not estimated.
nlgr_cmex = idnlgrey('twotanks_c', Order, Parameters, InitialStates, 0)
nlgr_cmex = Continuous-time nonlinear grey-box model defined by 'twotanks_c' (MEX-file): dx/dt = F(t, u(t), x(t), p1, ..., p6) y(t) = H(t, u(t), x(t), p1, ..., p6) + e(t) with 1 input(s), 2 state(s), 1 output(s), and 6 free parameter(s) (out of 6). Status: Created by direct construction or transformation. Not estimated.
В этом примере мы обсудили, как записать файлы модели IDNLGREY MATLAB и C MEX. Мы наконец завершаем представление путем листинга в настоящее время доступных файлов модели IDNLGREY и примера/тематического исследования, где они используются. Чтобы упростить дальнейшие сравнения, мы перечисляем обоих MATLAB (соглашение о присвоении имен FILENAME_m.m) и файлы модели C MEX (соглашение о присвоении имен FILENAME_c.c) и указываем в учебном столбце, какой тип моделирования подхода, который используется в примере или тематическом исследовании.
Tutorial/Case study MATLAB file C MEX-file
======================================================================
idnlgreydemo1 (MATLAB) dcmotor_m.m dcmotor_c.c
idnlgreydemo2 (C MEX) twotanks_m.m twotanks_c.c
idnlgreydemo3 (MATLAB) preys_m.m preys_c.c
(C MEX) predprey1_m.m predprey1_c.c
(C MEX) predprey2_m.m predprey2_c.c
idnlgreydemo4 (MATLAB) narendrali_m.m narendrali_c.c
idnlgreydemo5 (MATLAB) friction_m.m friction_c.c
idnlgreydemo6 (C MEX) signaltransmission_m.m signaltransmission_c.c
idnlgreydemo7 (C MEX) twobodies_m.m twobodies_c.c
idnlgreydemo8 (C MEX) robot_m.m robot_c.c
idnlgreydemo9 (MATLAB) cstr_m.m cstr_c.c
idnlgreydemo10 (MATLAB) pendulum_m.m pendulum_c.c
idnlgreydemo11 (C MEX) vehicle_m.m vehicle_c.c
idnlgreydemo12 (C MEX) aero_m.m aero_c.c
idnlgreydemo13 (C MEX) robotarm_m.m robotarm_c.c
Содержимое этих образцовых файлов может быть отображено в окне команды MATLAB посредством команды, "вводят FILENAME_m.m", или "вводят FILENAME_c.c". Все образцовые файлы найдены в директории, возвращенной следующей командой MATLAB.
fullfile(matlabroot, 'toolbox', 'ident', 'iddemos', 'examples')