MATLAB.Exponenta
–Û·Ë͇ Matlab&Toolboxes

Simulink

Работы-участники конкурса Simulink-моделей.

Синхронизатор времени

архив работы zip-файл

Погожев Сергей Владимирович, старший преподаватель кафедры Компьютерных технологий и систем факультета прикладной математики - процессов управления (ПМ-ПУ) Санкт-Петербургского государственного университета (СПбГУ), pogojev@vrm.apmath.spbu.ru

Назначение разработки.

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

Текст S-функции "synchronizer.c"

#define S_FUNCTION_NAME  synchronizer
#define S_FUNCTION_LEVEL 2
#include "simstruc.h"
#include "matlab.h"
#include 
#include 
//=====================================================
static clock_t StartTime;
#define DISCRETE_STEP 0.1

#define SYNCHR_R_IDX 0
#define SYNCHR_R_PARAM(S) ssGetSFcnParam(S,SYNCHR_R_IDX)
//=====================================================
//Проверка правильности задания параметров блока S-function
//Должен быть указан 1 параметр - положительное число
static void mdlCheckParameters(SimStruct *S)
{ const mxArray *para = (const mxArray *) SYNCHR_R_PARAM(S);
  real_T *N= mxGetPr(para);
  if ((mxGetM(SYNCHR_R_PARAM(S)) > 1) || (mxGetN(SYNCHR_R_PARAM(S)) > 1)) {
        ssSetErrorStatus(S,"Parameter to S-function must be a scalar.");
       return;
  }
  if (N[0]<=0){ ssSetErrorStatus(S,"Parameter to S-function must be positive!");  return;  }
}
//=====================================================
//Инициализация блока S-function
static void mdlInitializeSizes(SimStruct *S)
{ ssSetNumSFcnParams(S, 1);  
#if defined(MATLAB_MEX_FILE)
  if (ssGetNumSFcnParams(S) == ssGetSFcnParamsCount(S)) {
     mdlCheckParameters(S);
     if (ssGetErrorStatus(S) != NULL) return;
  } else  return;
#endif
  ssSetNumContStates( S, 0); 
  ssSetNumDiscStates( S, 0); 
  if (!ssSetNumInputPorts(S, 0)) return;
  if (!ssSetNumOutputPorts(S, 0)) return;
  ssSetNumSampleTimes( S, 1);
  ssSetOptions( S, 0); 
}
//=====================================================
//Установка временных харастерисик блока S-function 
static void mdlInitializeSampleTimes(SimStruct *S)
{ ssSetSampleTime(S, 0, DISCRETE_STEP);
   ssSetOffsetTime(S, 0, 0.0);
}
//=====================================================
//Функция, которая выполняется при запуске имитационного моделирования
static void mdlStart(SimStruct *S)
{ StartTime=clock(); }
//=====================================================
//Вычисление выхода блока S-function
static void mdlOutputs(SimStruct *S, int_T tid)
{ const mxArray *para = (const mxArray *) SYNCHR_R_PARAM(S);
  double *N= mxGetPr(para);
  clock_t NowTime;
  DWORD diff_M_PC;
  real_T InTime=(real_T)ssGetT(S); //Имитационное время модели
  long Tr_Hold = 1000*DISCRETE_STEP/N[0];
  NowTime=clock(); // Реальное (машинное) время
  diff_M_PC=NowTime-StartTime;
  if ((diff_M_PC>=0) && (diff_M_PC<Tr_Hold))
     Sleep(Tr_Hold-diff_M_PC);
  StartTime=clock();
}
//=====================================================
static void mdlTerminate(SimStruct *S) {}
//=====================================================
#ifdef  MATLAB_MEX_FILE 
#include "simulink.c"   
#else
#include "cg_sfun.h" 
#endif

Использование S-функции "synchronizer.c". Данную функцию необходимо откомпилировать при помощи команды mex synchronizer.c . В случае успешного выполнения команды будет получен файл с именем synchronizer.dll, представляющий собой динамическую библиотеку функций, вызываемых из Simulink.

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

Для использования полученной функции в качестве синхронизатора в сетевых комплексах необходимо подобрать такое значение параметра, которое позволит всем компьютерам комплекса справляться с требуемым объемом вычислений.

Пример использования S-функции synchronizer и пример межMATLABового обмена данными.

Рассмотрим объект управления, который описывается системой уравнений:

(1)

Будем считать, что стабилизация объекта осуществляется регулятором вида

где - заданная величина (2)

Предположим, что измерения в алгоритм управления поступают с периодом 0.1 секунды.

На рис. 1 представлена блок-схема Simulink-модели (model.mdl) объекта управления, описываемого уравнениями (1). На рис. 2 приведена блок-схема Simulink-модели (control.mdl) алгоритма управления вида (2).

На рис. 3 приведено диалоговое окно для настройки параметров блока S-Function synchronizer, входящего в состав модели объекта управления и алгоритмов управления.

Блоки S-функций get_control, save_state, from_model, to_model являются маскированными. Их диалоговые окна выглядят аналогично (почти совпадают) (рис. 4). В них указываются имена переменных, в которых сохраняются те или иные данные, а также их размеры (длины). Тесты данных функции приведены ниже.

Для работы с моделью необходимо выполнить следующие действия:

  • Запустить Simulink-модель control.mdl

  • Дважды щелкнуть по блоку Double click to connect to model (в свойствах этого блока (подсистемы) при открытии (OnOpen) вызывается функция control_connect.m). При этом возникнет диалоговое окно, в котором необходимо указать IP адрес компьютера, на котором будет моделироваться модель model.mdl. Можно указать адрес 127.0.0.1, при этом моделирование будет осуществляться на этом же компьютере, но в другом экземпляре Matlab.

  • После установления удачного соединения необходимо запусти Simulink-модель control.mdl на моделирование (Simulation/Start). При этом произойдет запуск и модели model.mdl, поскольку у модели control.mdl в свойстве Simulation start function (StartFcn) указана функция control_start.

Замечания.

  1. В Matlab, в котором моделируется модель объекта управления, должны быть доступны файлы model.mdl, get_control.m, save_state.m, synchronizer.dll. В Matlab, в котором моделируется алгоритм управления, должны быть доступны файлы control.mdl, control_connect.m, control_start.m, from_model.m, synchronizer.dll, to_model.m.
  2. S-функция synchronizer работает и в более ранних версиях Simulink, старше, чем Simulink 2.2.1 (должно работать и на еще более ранних версиях, однако этот факт не проверен).
  3. В Matlab версии менее чем 6.0 не работает метод GetFullMatrix, поэтому пример будет выполняться только в версиях Matlab 6.0 и старше. В Matlab 5.0 межсетевой обмен был реализован с использованием только метода PutFullMatrix. В данном случае все компоненты сетевого комплекса помещали свои данные непосредственно в рабочую область соответствующего экземпляра Matlab, используя метод PutFullMatrix (все экземпляры Matlab должны являться при этом серверами автоматизации, т.е. они должны быть запущены на различных машинах в сети и при их запуске необходимо указать ключ "/Automation"). Следует отметить, что реализовать такую схему (достаточно удобную) в Matlab версии 6.0 и старше не получилось, поскольку если Matlab данных версий является сервером автоматизации, т.е. при запуске указан ключ "/Automation", то при попытке установить связь с сервером автоматизации Matlab, запущенным на другой машине сети, Matlab подсоединяется сам к себе.

Рис. 1. Блок-схема Simulink-модели объекта управления (model.mdl).

Рис. 2. Блок-схема Simulink-модели объекта управления (control.mdl).

Рис. 3.

Рис. 4.

Текст S-функции from_model.m

function [sys,x0,str,ts] = from_model(t,x,u,flag,STATE_NAME,STATE_LEN)
switch flag,
  case 0,  % Initialization %
     sizes = simsizes;
     sizes.NumContStates  = 0;     sizes.NumDiscStates  = 0;
     sizes.NumInputs      = 0;     sizes.NumOutputs     =-1;% dynamically sized
     sizes.DirFeedthrough = 1;     sizes.NumSampleTimes = 1;
     sys = simsizes(sizes);        str=[]; 
     ts  = [0.1 0];
  case 3,  % Outputs %
       global MODEL_PC;
sys=invoke(MODEL_PC,'GetFullMatrix',STATE_NAME,'global',zeros(1,STATE_LEN), zeros(1,STATE_LEN));
   case {1,2,4,9},
     sys=[];
  otherwise
     error(['Unhandled flag = ',num2str(flag)]);
end
% end from_model

Текст S-функции to_model.m

function [sys,x0,str,ts] = to_model(t,x,u,flag,CONTROL_NAME,CONTROL_LEN)
switch flag,
 case 0,% Initialization %
     sizes = simsizes;
     sizes.NumContStates  = 0;     sizes.NumDiscStates  = 0;
     sizes.NumOutputs     = 0;     sizes.NumInputs      =-1;% dynamically sized
     sizes.DirFeedthrough = 1;     sizes.NumSampleTimes = 1;
     sys = simsizes(sizes);        str=[];
     ts  = [0.1 0];
  case 3,
       global MODEL_PC;
       if (CONTROL_LEN==1)
           CONTROL_LEN=CONTROL_LEN+1;  u=[u 0];
       end;
invoke(MODEL_PC,'PutFullMatrix',CONTROL_NAME,'global',u,zeros(CONTROL_LEN,1));
       sys=[];
  case {1,2,4,9},
     sys=[];
  otherwise
     error(['Unhandled flag = ',num2str(flag)]);
end
% end to_model

Текст S-функции get_control.m

function [sys,x0,str,ts] = get_control(t,x,u,flag,Control_Name,Control_Len)
switch flag,
 case 0,  % Initialization %
     sizes = simsizes;
     sizes.NumContStates  = 0;          sizes.NumDiscStates  = 0;
     sizes.NumOutputs     =Control_Len; sizes.NumInputs      = 0;
     sizes.DirFeedthrough = 1;          sizes.NumSampleTimes = 1;
     sys = simsizes(sizes);             str=[];
     ts  = [0.1 0];
 case 3,  % Outputs %
     sys=evalin('base',Control_Name);
     sys=sys(1:Control_Len);
 case {1,2,4,9},
    sys=[];
 otherwise
    error(['Unhandled flag = ',num2str(flag)]);
end
% end get_control

Текст S-функции save_state.m

function [sys,x0,str,ts] = save_state(t,x,u,flag,STATE_NAME)
switch flag,
 case 0,% Initialization %
     sizes = simsizes;
     sizes.NumContStates  = 0;     sizes.NumDiscStates  = 0;
     sizes.NumOutputs     = 0;     sizes.NumInputs      =-1;% dynamically sized
     sizes.DirFeedthrough = 1;     sizes.NumSampleTimes = 1;
     sys = simsizes(sizes);        str=[];
     ts  = [0.1 0];
 case 3,
       evalin('base',strcat(STATE_NAME,'=[',num2str(u'),'];'));
       sys=[];
 case {1,2,4,9},
    sys=[];
 otherwise
    error(['Unhandled flag = ',num2str(flag)]);
end
% end save_state

Текст функции control_start.m

function control_start
global MODEL_PC 
invoke(MODEL_PC,'execute', 'Controls=0;');
invoke(MODEL_PC,'execute','set_param(''model'',''simulationcommand'',''start'');');

Текст функции control_connect.m

function control_connect(param)
global MODEL_PC
switch(param)
  case 'connect'
     prompt={'Enter the IP of computer with model:'};
     def={'127.0.0.1'};,  dlgTitle='Input parameters';  lineNo=1;
     answer=inputdlg(prompt,dlgTitle,lineNo,def);
     if(~isempty(answer))
       MODEL_PC=actxserver('Matlab.application',answer{1});
       invoke(MODEL_PC,'execute','model');
       sys=get_param(gcs,'Handle');
a=find_system(sys,'FindAll','on','RegExp','on','type','annotation','Name','IP*');
       if (~isempty(a))
         str1=strcat('IP: ',answer{1});
         set_param(a(1),'Name',strvcat(str1,'Connection: on'));
       end;
     end;
     a=find_system(sys,'FindAll','on','Tag','ConnectionBlock');
     set_param(a,'OpenFcn','control_connect disconnect;');
     set_param(a,'MaskDisplay','disp(''Double click\nto disconnect'')');
  case 'disconnect'
     release(MODEL_PC);
     sys=get_param(gcs,'Handle');        
     a=find_system(sys,'FindAll','on','Tag','ConnectionBlock');
     set_param(a,'OpenFcn','control_connect connect;');
     set_param(a,'MaskDisplay','disp(''Double click\nto connect\nto model'')');
a=find_system(sys,'FindAll','on','RegExp','on','type','annotation','Name','IP*');
     if (~isempty(a))
       set_param(a(1),'Name',strvcat('IP:127.0.0.1','Connection: off'));
     end;
end;


Поиск по сайту:

Система Orphus

Яндекс.Метрика