Клиначёв Николай Васильевич

Пример проектирования дискретного ПИД-регулятора с применением инструментария моделирующих пакетов

Задачи проектирования дискретных ПИД-регулятора и коррекции подобны. В непрерывном варианте между устройствами есть отличие: регулятор должен содержать активные элементы – операционные усилители (ОУ), позволяющие усиливать сигналы, а коррекция может быть выполнена на пассивных элементах (RC-цепи). В дискретном же варианте устройства неразличимы – могут состоять из трех микросхем включенных последовательно (АЦП, цифровой сигнальный процессор (DSP), ЦАП). И регулятор и четыре основные вида последовательных корректирующих устройств описываются передаточной функцией (ПФ) не выше второго порядка. Следовательно, достаточно составить одну программу цифрового рекурсивного фильтра второго порядка для DSP и менять в зависимости от задачи пять – семь констант программы – коэффициентов z-ПФ. Для более качественного восприятия дальнейшего изложения вы можете посмотреть небольшие теоретические пояснения, а так же вашему вниманию предлагается методика составления разностных уравнений (РУ) и программ, реализующих z-ПФ на ЦВМ.

ЭТАП 1 – Синтез ПФ непрерывного ПИД-регулятора

Пусть имеется модель объекта (Plant, рис. 1) и звена обратной связи (Woc) параметры которых нам заданы. Задача синтеза непрерывного ПИД-регулятора сводится к настройке его параметров – коэффициента усиления пропорционального канала и сопрягающих частот интегрального и дифференциального каналов. Для ее решения следует использовать инструментарий итерационного подбора параметров программы VisSim – блоки "parametrUnknown" и "cost". Для сравнения результатов итераций следует составить функцию из блоков программы VisSim, которая представляет собой классическую улучшенную интегральную оценку качества переходного процесса (составной блок "Cost_Function – I^2").

ЭТАП 1 – Синтез ПФ непрерывного ПИД-регулятора

На графике демонстрируются переходные процессы системы без регулятора и при настроенных его параметрах (начальные настройки ПИД-регулятора не оказывают влияния на вид ЛАЧХ объекта)

Рис. 1

ЭТАП 2 – Переход к эквивалентной дискретной ПФ ПИД-регулятора

Осуществим замену модели непрерывного ПИД-регулятора (построенного на элементарных блоках) одним эквивалентным блоком "transferFunction". Для выполнения этой операции надо знать коэффициенты полиномов числителя и знаменателя его ПФ, а так же коэффициент усиления (семь цифр). Для этого выделим настроенный блок непрерывного ПИД-регулятора и воспользуемся инструментарием пакета VisSim для получения информации о ПФ (Menu -> Analyz -> Transfer Function Info). В результате будут показаны два окна (см. рис. 2 и 3). В первом окне – все требуемые коэффициенты.

Transfer Function
Gain 47.6
s^n Numerator Denumerator
s^1
s^2
s^3
63.5
21.2
1
0
2000
1

Рис. 2

Во втором окне – корни полиномов числителя и знаменателя – нули и полюсы соответственно (корни квадратных уравнений). Заметим, что появление комплексных корней возможно, но не необходимо для регуляторов и всех основных видов коррекции. В дальнейшем может потребоваться разложение z-ПФ на элементарные дроби (для написания программ функционирующих на параллельно работающих ЦВМ) или на элементарные дроби (для контроля промежуточных координат). В этих случаях комплексные корни могут помешать. Те эту ситуацию вы должны предвидеть и при необходимости вам следует вернуться к первому этапу синтеза.

Zeros and Poles
Zeros Poles
(-3.605,0)
(-17.62,0)
(0,0)
(-2000,0)

Рис. 3

Промежуточный итог второго этапа продемонстрирован на рис. 4. Сравните с рисунком 2. Данный блок включите вместо регулятора, установите метод интегрирования – Euler и подберите минимальную частоту моделирования по существенному визуальному ухудшению переходного процесса. Для данной системы это 2000 Гц.

непрерывная ПФ

Рис. 4

Откройте окно свойств блока "transferFunction" (рис. 4) и выполните преобразование ПФ к дискретной форме (Convert S->Z). Вам будет предложено выбрать период дискретизации. Установите его равным шагу моделирования или меньшим в 2..6 раз (потом не забудьте и свойства симуляции привести в соответствие). Результат преобразования показан на рис. 5. Проконтролируйте неизменность вида переходного процесса.

z-ПФ – аналог непрерывной

Рис. 5

Калькулятор Билинейного Преобразования  
Параметры передаточной функции              

   k:                             s-mantissa: 
Числ: 
Знам: 

  dT:                           

ЭТАП 3 – Выбор структурной схемы (алгоритма программы) и получение РУ цифрового ПИД-регулятора

В этом, демонстрационном примере не будем проектировать регулятор, реализуемый на параллельно функционирующих ЦВМ (для быстродействия) или адаптированный для независимого подбора полюсов и нулей (настраиваемый). Таким образом, из трех широко распространённых алгоритмов программ реализующих z-ПФ мы выбрали "непосредственный". Определимся с его модификацией, использующей два буфера, как наиболее наглядной. Поскольку непосредственный алгоритм не требует разложений z-ПФ, сразу запишем РУ для оригиналов.

(*)

y[n] = [ 31.9016459416667
       (1 x[n] - 1.9894401341982 x[n-1] + 0.98945592544195 x[n-2]) -
       (-1.3333333333333 y[n-1] + 0.33333333333333 y[n-2]) ] / 1

Сравните это уравнение с z-ПФ на рис. 5 и со структурной схемой на рис. 6 (K=1), по которой можно построить z-ПФ любого порядка.

Структурная схема рекурсивного цифрового фильтара

Рис. 6

При манипуляциях с коэффициентами полиномов числителя и знаменателя дискретных фильтров следует воздержаться от округлений – переход от изображения Лапласа к Z-изображению описывается свертыванием правой полуплоскости "устойчивых" корней в несравнимо малую окружность единичного радиуса, т.е. точность позиционирования корней должна быть эквивалентно выше.

Следует отметить, что наиболее дешевые DSP – с фиксированной точкой (целочисленной математикой). При подобном ограничении можно увеличить все коэффициенты z-ПФ так, чтобы вес дробных остатков коэффициентов был незначителен, и корни остались прежними. Среди примеров программы VisSim вы найдете решение этой локальной задачи.

Если вами будет выбран другой алгоритм программной реализации z-ПФ и потребуется разложение последней на множители или на элементарные дроби, не обязательно его выполнять для дискретной ПФ. Разложить можно и непрерывную ПФ (нули и полюсы известны – рис. 3), а потом уже следует перейти к дискретным фильтрам первого порядка. При этом вы будете освобождены от расчетов и избежите неприятных манипуляций с "неокругляемыми" коэффициентами.

ЭТАП 4 – Написание программы ПИД-регулятора для ЦВМ

Не затрагивая вопрос выбора ЦВМ, скажем, что это может быть периферийный контроллер (PIC), микроЭВМ (8051, AVR, ...), ЭВМ (x86, ...), промышленный контроллер, DSP (ADSP-21xxx, TMS320, ...) или схема на жесткой логике. Составление программы выполняющей расчет рекурсивного уравнения (*) обычно не вызывает затруднений, если ЦВМ имеет команды деления и умножения чисел (желательно с большой мантиссой и плавающей точкой).

В табл. 1 и 2 представлены программы рекурсивного цифрового фильтра второго порядка. Они написаны на языках C++ и Паскале в средах разработки Borland C++Builder 4 и Borland Delphi 4 в соответствии с технологией создания моделей пользователя для программы VisSim. При трансляции получается файл pid.dll, главная функция которого "zW" может быть включена в модель программы VisSim с помощью блока "userFunction" (см. рис. 7). При записи коэффициентов РУ (*) в параметры блока и стробировании частотой 2000 Гц – это и будет модель искомого дискретного ПИД-регулятора.

Блок "userFunction", с помощью которого подключена библиотека pid.dll

Рис. 7

Таблица 1. Файл pid.cpp
#include <math.h>
#include <condefs.h>
#pragma hdrstop
#define EXPORT32 __declspec(dllexport)

//---------------------------------------------------------------------------
struct z_TF_INFO {
  double k;        // коэффициент усиления
  double b0,b1,b2; // коэффициенты полинома числителя
  double a0,a1,a2; // коэффициенты полинома знаменателя
};

//---------------------------------------------------------------------------
extern "C" {
  double buffer_x[2]={0,0}, buffer_y[]={0,0};
  double c, help_y;
//************ Функция размещения параметров ********************************
//************ Вызывается VisSim-ом при создании блока **********************
EXPORT32 long WINAPI zWPA(short FAR *ppCount){
  *ppCount=7; // число записываемых в файл vsm параметров модели пользователя
  return sizeof(z_TF_INFO);
}
//************ Процедура инициализации параметров ***************************
//************ Вызывается VisSim-ом после PA функции ************************
EXPORT32 void WINAPI zWPI(z_TF_INFO *zTF){
  zTF->k=31.9016459416667;
  zTF->b0=1;
  zTF->b1=-1.9894401341982;
  zTF->b2=0.98945592544195;
  zTF->a0=1;
  zTF->a1=-1.3333333333333;
  zTF->a2=0.33333333333333;
}
//************ Функция изменения параметров *********************************
//************ Вызывается VisSim-ом при нажатии правой клавиши мыши *********
EXPORT32 LPSTR WINAPI zWPC(z_TF_INFO *zTF){
  return "k;b0;b1;b2;a0;a1;a2";
}
//************ Процедура Simulation Start ***********************************
//************ Вызывается VisSim-ом на первом шаге моделирования ************
EXPORT32 long WINAPI zWSS(z_TF_INFO *zTF, long *runCount){
  buffer_x[0]=0; buffer_x[1]=0;
  buffer_y[0]=0; buffer_y[1]=0;
  help_y=0; c=0;
  return 0;
}
//************ Процедура Simulation End *************************************
//************ Вызывается VisSim-ом на последнем шаге моделирования *********
EXPORT32 long WINAPI zWSE(z_TF_INFO *zTF, long *runCount){
  return 0;
}
//************ Это базовая процедура в DLL **********************************
//************ Вызывается VisSim-ом на каждом шаге моделирования ************
EXPORT32 void WINAPI zW(z_TF_INFO *zTF, double FAR x[], double FAR y[]){
  if (x[0]==1 && c==0) {
  // Непосредственный алгоритм с двумя буферами
    help_y=(zTF->k*(x[1]*zTF->b0+buffer_x[0]*zTF->b1+buffer_x[1]*zTF->b2)
           -(buffer_y[0]*zTF->a1+buffer_y[1]*zTF->a2)) / zTF->a0;
    buffer_x[1]=buffer_x[0]; buffer_x[0]=x[1];
    buffer_y[1]=buffer_y[0]; buffer_y[0]=help_y;
  // Непосредственный алгоритм с одним буфером
  /* double help;
    help=(x[1]-(buffer_x[0]*zTF->a1+buffer_x[1]*zTF->a2))/zTF->a0;
    help_y=(help*zTF->b0+buffer_x[0]*zTF->b1+buffer_x[1]*zTF->b2)*zTF->k;
    buffer_x[1]=buffer_x[0]; buffer_x[0]=help;*/
  }
  y[0]=help_y;
  c=x[0]; // организованна синхронизация блока по фронту
};
//---------------------------------------------------------------------------
}// end extern "C" {
//---------------------------------------------------------------------------
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*){
  return 1;
}

Таблица 2. Файл pid.dpr
library PID;

type
  InVector  = array [0..9] of Double; { тип входной переменной:  входов  - 10 }
  OutVector = array [0..9] of Double; { тип выходной переменной: выходов - 10 }
  Global = record { запись параметров, и координат "dll"-модели }
    k : double;
    b0, b1, b2 : double;
    a0, a1, a2 : double;
end;

var buffer_x, buffer_y : array [0..1] of double;
    c, help_y : double;
{/************ Это базовая процедура в DLL ****************************/}
{/************ Вызывается VisSim-ом на каждом шаге моделирования ******/}
procedure zW(var zTF:Global; var x:InVector; var y:OutVector); export; stdcall;
var help : double;
begin
  if (x[0]=1)and(c=0) then
  begin
  { Непосредственный алгоритм с двумя буферами }
    help_y:=(zTF.k*(x[1]*zTF.b0+buffer_x[0]*zTF.b1+buffer_x[1]*zTF.b2)
           -(buffer_y[0]*zTF.a1+buffer_y[1]*zTF.a2))/zTF.a0;
    buffer_x[1]:=buffer_x[0]; buffer_x[0]:=x[1];
    buffer_y[1]:=buffer_y[0]; buffer_y[0]:=help_y;{}
  { Непосредственный алгоритм с одним буфером }
  { help:=(x[1]-(buffer_x[0]*zTF.a1+buffer_x[1]*zTF.a2))/zTF.a0;
    help_y:=(help*zTF.b0+buffer_x[0]*zTF.b1+buffer_x[1]*zTF.b2)*zTF.k;
    buffer_x[1]:=buffer_x[0]; buffer_x[0]:=help;{}
   end;
  y[0]:=help_y;
  c:=x[0]; { организованна синхронизация блока по фронту }
end;

{/************ Функция размещения параметров **************************/}
{/************ Вызывается VisSim-ом при создании блока ****************/}
function zWPA( var pCount:integer):Longint; export; stdcall;
begin
  pCount := 7;  { число записываемых в файл параметров диалогового окна }
  zWPA := sizeof(Global);     { размер памяти необходимый под параметры }
end;

{/************ Процедура инициализации параметров *********************/}
{/************ Вызывается VisSim-ом после PA функции ******************/}
procedure zWPI( var zTF:Global ); export; stdcall;
begin
  zTF.k:=31.9016459416667;
  zTF.b0:=1;
  zTF.b1:=-1.9894401341982;
  zTF.b2:=0.98945592544195;
  zTF.a0:=1;
  zTF.a1:=-1.3333333333333;
  zTF.a2:=0.33333333333333;
end;

{/************ Функция изменения параметров ***************************/}
{/************ Вызывается VisSim-ом при нажатии правой клавиши мыши ***/}
function zWPC( var zTF:Global ):Pchar; export; stdcall;
begin
  zWPC :='k;b0;b1;b2;a0;a1;a2'; { названия могут быть любые }
end;

{/************ Процедура Simulation Start *****************************/}
{/************ Вызывается VisSim-ом на первом шаге моделирования ******/}
procedure zWSS( var zTF:Global; var runCount:longint); export; stdcall;
begin
  buffer_x[0]:=0; buffer_x[1]:=0;
  buffer_y[0]:=0; buffer_y[1]:=0;
  help_y:=0;      c:=0;
end;

{/************ Процедура Simulation End *******************************/}
{/************ Вызывается VisSim-ом на последнем шаге моделирования ***/}
procedure zWSE( var zTF:Global; var runCount:longint); export; stdcall;
begin
end;

exports
  zW index 1,{ Имя базовой процедуры в DLL Его нужно будет указать в блоке userFunction }
  zWPA index 2,{ Список вспомогательных процедур и функций для экспорта. Они будут      }
  zWPI index 3,{ вызываться Vissim-ом по окончаниям PA,PI,PC,SS,SE для базового имени.  }
  zWPC index 4,
  zWSS index 5,
  zWSE index 6;
begin

end.

ЭТАП 5 – Проверка работоспособности спроектированного цифрового ПИД-регулятора

Успех любого проекта основан на проверке технических решений. На этом этапе сказывается нехватка инструментария пакета VisSim. Для моделей пользователя недоступны все выды анализа (возможна только симуляция движения). Можно включить дискретный ПИД-регулятор (рис. 7) в контур модели и проверить схожесть переходного процесса с исходным, но этого не достаточно. В опыте будет подтверждено относительное соответствие высокочастотной части ЛАЧХ, те работоспособность П & Д-каналов регулятора, но не интегрального, который при наличии в системе статических звеньев с большими коэффициентами усиления не определяет заметные глазу изменения вида переходного процесса. Можно конечно проверить, как регулятор отрабатывает ошибку в установившихся режимах движения при изменении задания с постоянной скоростью, ускорением, приращением ускорения, но мы поступим иначе – используем возможность пакета VisSim включать в модель блоки пользователя. Библиотека AzFqRsp.dll позволяет выполнить виртуальные измерения ЧХ систем (блоки "PGL 01" & "Lfi 021" на рис. 8). Частотные характеристики разработанной программы ПИД-регулятора (блок "pid.dll.zW") приведены на верхних графиках. ЛАЧХ & ЛФЧХ исходного непрерывного ПИД-регулятора получены с помощью инструментария программы VisSim и демонстрируются на нижних графиках. Результаты вполне удовлетворительны.

Схема измерения ЧХ программы ПИД-регулятора

Рис. 8

8.02.2001