Управление в режиме реального времени с OPC Toolbox

Этот пример показывает, как реализовать онлайновое образцовое прогнозирующее приложение контроллера с помощью OPC-клиента, предоставленного OPC Toolbox™.

Пример использует Сервер OPC Симуляции Matrikon™, чтобы моделировать поведение производственного процесса на операционной системе Windows®.

Загрузите сервер симуляции Matrikon™ OPC с "www.matrikon.com"

Загрузите и установите сервер и установите его запускающийся или как сервис или как приложение.

Для этого примера нужен OPC Toolbox™.

if ~mpcchecktoolboxinstalled('opc')
    disp('The example needs OPC Toolbox(TM).')
end
The example needs OPC Toolbox(TM).

Установите связь с сервером OPC

Используйте команды OPC Toolbox, чтобы соединиться с Сервером Симуляции Matrikon OPC.

if mpcchecktoolboxinstalled('opc')
    % Clear any existing opc connections.
    opcreset
    % Flush the callback persistent variables.
    clear mpcopcPlantStep;
    clear mpcopcMPCStep;
    try
        h = opcda('localhost','Matrikon.OPC.Simulation.1');
        connect(h);
    catch ME
        disp('The Matrikon(TM) OPC Simulation Server must be running on the local machine.')
        return
    end
end

Настройте Объект ввод-вывод OPC

На практике объект был бы физическим процессом, и теги OPC, которые задают его ввод-вывод, были бы уже созданы на Сервере OPC. Однако, поскольку в этом случае Сервер OPC симуляции используется, поведение объекта должно быть моделировано. Это достигается путем определения тегов для объекта которыми управляют и измеренные переменные и создания коллбэка (mpcopcPlantStep), чтобы моделировать ответ объекта на изменения в переменных, которыми управляют. Две группы OPC требуются, один, чтобы представлять две переменные, которыми управляют, которые будут считаны средством моделирования объекта и другим, чтобы записать два измеренных объекта обратно выходные параметры, хранящие результаты симуляции объекта.

if mpcchecktoolboxinstalled('opc')
    % Build an opc group for 2 plant inputs and initialize them to zero.
    plant_read = addgroup(h,'plant_read');
    imv1 = additem(plant_read,'Bucket Brigade.Real8', 'double');
    writeasync(imv1,0);
    imv2 = additem(plant_read,'Bucket Brigade.Real4', 'double');
    writeasync(imv2,0);
    % Build an opc group for plant outputs.
    plant_write = addgroup(h,'plant_write');
    opv1 = additem(plant_write,'Bucket Brigade.Time', 'double');
    opv2 = additem(plant_write,'Bucket Brigade.Money', 'double');
    plant_write.WriteAsyncFcn = []; % Suppress command line display.
end

Задайте контроллер MPC, который будет управлять моделируемым объектом

Создайте модель объекта управления.

plant_model = ss([-.2 -.1; 0 -.05],eye(2,2),eye(2,2),zeros(2,2));
disc_plant_model = c2d(plant_model,1);
% We assume no model mismatch, a control horizon 6 samples and
% prediction horizon 20 samples.
mpcobj = mpc(disc_plant_model,1,20,6);
mpcobj.weights.ManipulatedVariablesRate = [1 1];
% Build an internal MPC object structure so that the MPC object
% is not rebuilt each callback execution.
state = mpcstate(mpcobj);
y1 = mpcmove(mpcobj,state,[1;1]',[1 1]');
-->The "Weights.ManipulatedVariables" property of "mpc" object is empty. Assuming default 0.00000.
-->The "Weights.ManipulatedVariablesRate" property of "mpc" object is empty. Assuming default 0.10000.
-->The "Weights.OutputVariables" property of "mpc" object is empty. Assuming default 1.00000.
-->Assuming output disturbance added to measured output channel #1 is integrated white noise.
-->Assuming output disturbance added to measured output channel #2 is integrated white noise.
-->The "Model.Noise" property of the "mpc" object is empty. Assuming white noise on each measured output channel.

Создайте ввод-вывод OPC для Контроллера MPC

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

if mpcchecktoolboxinstalled('opc')
    % Build an opc group for MPC inputs.
    mpc_read = addgroup(h,'mpc_read');
    impcpv1 = additem(mpc_read,'Bucket Brigade.Time', 'double');
    writeasync(impcpv1,0);
    impcpv2 = additem(mpc_read,'Bucket Brigade.Money', 'double');
    writeasync(impcpv2,0);
    impcref1 = additem(mpc_read,'Bucket Brigade.Int2', 'double');
    writeasync(impcref1,1);
    impcref2 = additem(mpc_read,'Bucket Brigade.Int4', 'double');
    writeasync(impcref2,1);
    % Build an opc group for mpc outputs.
    mpc_write = addgroup(h,'mpc_write');
    additem(mpc_write,'Bucket Brigade.Real8', 'double');
    additem(mpc_write,'Bucket Brigade.Real4', 'double');
    % Suppress command line display.
    mpc_write.WriteAsyncFcn = [];
end

Создайте группы OPC, чтобы инициировать выполнение Plant Simulator & Controller

Создайте две opc группы на основе того же внешнего opc таймера, чтобы инициировать выполнение и симуляции объекта и выполнения MPC когда содержимое изменений тега времени OPC.

if mpcchecktoolboxinstalled('opc')
    gtime = addgroup(h,'time');
    time_tag = additem(gtime,'Triangle Waves.Real8');
    gtime.UpdateRate = 1;
    gtime.DataChangeFcn = {@mpcopcPlantStep plant_read plant_write disc_plant_model};
    gmpctime = addgroup(h,'mpctime');
    additem(gmpctime,'Triangle Waves.Real8');
    gmpctime.UpdateRate = 1;
    gmpctime.DataChangeFcn = {@mpcopcMPCStep mpc_read mpc_write mpcobj};
end

Данные логов от объекта измеренные Выходные параметры

Регистрируйте объект, измеренный выходные параметры от тегов 'Бригада Блока. Деньги' и 'Бригада Блока. Деньги'.

if mpcchecktoolboxinstalled('opc')
    mpc_read.RecordsToAcquire = 40;
    start(mpc_read);
    while mpc_read.RecordsAcquired < mpc_read.RecordsToAcquire
       pause(3)
       fprintf('Logging data: Record %d / %d',mpc_read.RecordsAcquired,mpc_read.RecordsToAcquire)
    end
    stop(mpc_read);
end

Извлеките и постройте записанные данные

if mpcchecktoolboxinstalled('opc')
    [itemID, value, quality, timeStamp, eventTime] = getdata(mpc_read,'double');
    plot((timeStamp(:,1)-timeStamp(1,1))*24*60*60,value)
    title('Measured Outputs Logged from Tags Bucket Brigade.Time,Bucket Brigade.Money')
    xlabel('Time (secs)');
end