Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
51
Добавлен:
22.02.2014
Размер:
417.28 Кб
Скачать

6. Список использованной литературы.

1. Основы теории многосвязных систем автоматического управления летательными аппаратами: Учеб. Пособие / С. Ф. Бабак, В.И. Васильев, Б.Г. Ильясов и др. ; Под ред. М.Н. Красильщикова. – М.: Изд-во МАИ, 1995. – 188 с.

2. Смит Дж. М. Математическое и цифровое моделирование для инженеров и исследователей. М., Машиностроение, 1980.

3. Изерман Р. Цифровые системы управления. Пер. с англ. М.: Мир, 1984. 541 с.

4. Многоуровневое управление динамическими объектами / В.И. Васильев, Ю.М. Гусев, В.Н. Ефанов и др. Под ред. В.Ю. Рутковского и С.Д. Землякова. – М.: Наука, 1987. 309 с.

5. Теория линейных систем автоматического регулирования и управления

Попов Е.П. М.: Наука 1989

Приложение Листинг программы.

Текст программы на языке Turbo Pascal для построения переходных процессов САУ.

UNIT MDrawFun;

INTERFACE

USES Graph;

TYPE

Float=Single;

PROCEDURE DrawFun(N:Integer;VAR x,y:ARRAY OF Float;

WMinX,WMinY,WMaxX,WMaxY:Integer;Text:STRING;Color:Integer);

IMPLEMENTATION

CONST

{Максимальные высота и ширина одной буквы шрифта графика}

CharMaxWidth=8;

CharMaxHeight=8;

MaxStringChars=5;

Delta:Float=0.000001;

VAR

xScale,yScale,xOrigin,yOrigin:Float;

WindowMinX,WindowMinY,WindowMaxX,WindowMaxY:Integer;

xMin,yMin,xMax,yMax:Extended;

{Специальное округление, для выбора шага масштабной сетки}

FUNCTION MyRound(x:Float):Float;

BEGIN

IF x>0.0

THEN MyRound:=Trunc(x+0.9)

ELSE MyRound:=Trunc(x-0.1)

END;

{Выбор масштаба графика,

Ввод:

координаты окна (WindowMinX,WindowMinY,WindowMaxX,WindowMaxY:Integer;)

минимумы и максимумы функции (xMin,yMin,xMax,yMax:Extended)

Вывод:

множители и смещения (xScale,yScale,xOrigin,yOrigin:Extended;)

}

PROCEDURE DrawFunZoom;

BEGIN

IF xMax-xMin>Delta THEN xScale:=(WindowMaxX-WindowMinX)/(xMax-xMin);

IF yMax-yMin>Delta THEN yScale:=(WindowMaxY-WindowMinY)/(yMax-yMin);

IF xScale<Delta THEN xScale:=yScale;

IF yScale<Delta THEN yScale:=xScale;

IF (yScale<Delta) AND (xScale<Delta)

THEN

BEGIN

xScale:=1.0;

yScale:=1.0

END;

{Закоментирован выбор одинакового масштаба по осям.}

{IF xScale<yScale

THEN yScale:=xScale

ELSE xScale:=yScale;}

xOrigin:=(WindowMinX+WindowMaxX-(xMax+xMin)*xScale)/2.0;

yOrigin:=(WindowMinY+WindowMaxY+(yMax+yMin)*yScale)/2.0

END;

{Расчёт экранной координаты точки по X,

ввод:

координата X точки (параметр x:Extended)

вывод:

экранная координата X точки

}

FUNCTION DrawFunX(x:Extended):Integer;

BEGIN

DrawFunX:=Round(xOrigin+x*xScale)

END;

{Расчёт экранной координаты точки по Y,

ввод:

координата Y точки (параметр y:Extended)

вывод:

экранная координата Y точки

}

FUNCTION DrawFunY(y:Extended):Integer;

BEGIN

DrawFunY:=Round(yOrigin-y*yScale)

END;

PROCEDURE DrawFun(N:Integer;VAR x,y:ARRAY OF Float;

WMinX,WMinY,WMaxX,WMaxY:Integer;Text:STRING;Color:Integer);

VAR

I:Integer;

yStep,yStepCur,yStepMin,yStepMax:Float;

xStep,xStepCur,xStepMin,xStepMax:Float;

xText,yText:Integer;

S:STRING;

BEGIN

xMin:=x[0];

xMax:=x[0];

yMin:=y[0];

yMax:=y[0];

FOR I:=1 TO N-1 DO

BEGIN

IF x[I]<xMin

THEN xMin:=x[I];

IF x[I]>xMax

THEN xMax:=x[I];

IF y[I]<yMin

THEN yMin:=y[I];

IF y[I]>yMax

THEN yMax:=y[I]

END;

{Теперь найдём область окна, где будет нарисован сам график.}

WindowMinX:=WMinX;

WindowMaxX:=WMaxX;

WindowMinY:=WMinY;

WindowMaxY:=WMaxY;

{Над графиком может быть надпись. Если она есть, отсекаем

верхнюю прямоугольную область окна на высоту шрифта.}

IF Text<>''

THEN WindowMinY:=WindowMinY+CharMaxHeight;

{Если ось X проходит в верхней части графика, значения X

будем проставлять наверху и т.д.}

IF (Abs(yMin)>Abs(yMax))

THEN WindowMinY:=WindowMinY+MaxStringChars*CharMaxHeight

ELSE WindowMaxY:=WindowMaxY-MaxStringChars*CharMaxHeight;

{Если ось Y проходит в правой части графика, значения Y

будем проставлять справа и т.д.}

IF (Abs(xMin)<Abs(xMax))

THEN WindowMinX:=WindowMinX+MaxStringChars*CharMaxWidth

ELSE WindowMaxX:=WindowMaxX-MaxStringChars*CharMaxWidth;

DrawFunZoom;

SetColor(White);

xStep:=CharMaxWidth/xScale;

xStep:=exp(MyRound(ln(xStep)/ln(10.0))*ln(10.0));

xStepMin:=Trunc(xMin/xStep)*xStep;

xStepMax:=Trunc(xMax/xStep+1.0-delta)*xStep;

xStepCur:=xStepMin;

SetTextStyle(0,1,1);

{Если ось Y проходит в правой части графика, значения Y

будем проставлять справа и т.д.}

IF (Abs(yMin)>Abs(yMax))

THEN

BEGIN

SetTextJustify(CenterText,BottomText);

yText:=DrawFunY(yMax)

END

ELSE

BEGIN

SetTextJustify(CenterText,TopText);

yText:=DrawFunY(yMin)

END;

WHILE (xStepCur<xStepMax) DO

BEGIN

IF (Abs(xStepCur)<Delta)

THEN SetLineStyle(SolidLn,0,NormWidth)

ELSE SetLineStyle(DottedLn,0,NormWidth);

Line(DrawFunX(xStepCur),DrawFunY(yMin),

DrawFunX(xStepCur),DrawFunY(yMax));

Str(xStepCur:0:2,S);

OutTextXY(DrawFunX(xStepCur),yText,S);

xStepCur:=xStepCur+xStep

END;

yStep:=CharMaxHeight/yScale;

yStep:=exp(MyRound(ln(yStep)/ln(10.0))*ln(10.0));

yStepMin:=Trunc(yMin/yStep)*yStep;

yStepMax:=Trunc(yMax/yStep+1.0-delta)*yStep;

yStepCur:=yStepMin;

SetTextStyle(0,0,1);

{Если ось X проходит в верхней части графика, значения X

будем проставлять наверху и т.д.}

IF (Abs(xMin)>Abs(xMax))

THEN

BEGIN

SetTextJustify(LeftText,CenterText);

xText:=DrawFunX(xMax)

END

ELSE

BEGIN

SetTextJustify(RightText,CenterText);

xText:=DrawFunX(xMin)

END;

WHILE (yStepCur<yStepMax) DO

BEGIN

IF (Abs(yStepCur)<Delta)

THEN SetLineStyle(SolidLn,0,NormWidth)

ELSE SetLineStyle(DottedLn,0,NormWidth);

Line(DrawFunX(xMin),DrawFunY(yStepCur),

DrawFunX(xMax),DrawFunY(yStepCur));

Str(yStepCur:0:2,S);

OutTextXY(xText,DrawFunY(yStepCur),S);

yStepCur:=yStepCur+yStep

END;

SetColor(Color);

SetTextStyle(0,0,1);

SetTextJustify(CenterText,TopText);

OutTextXY((WMaxX+WMinX) DIV 2,WMinY,Text);

SetLineStyle(SolidLn,0,ThickWidth);

MoveTo(DrawFunX(x[0]),DrawFunY(y[0]));

FOR I:=1 TO N-1 DO

LineTo(DrawFunX(x[I]),DrawFunY(y[I]))

END;

BEGIN

WriteLn('MDrawFun 19-05-2003 by Stupin W.A.');

END.

Исходный текст программы на языке Pascal для моделирования САУ.

PROGRAM TAUKurs;

USES CRT,Graph,MDrawFun;

CONST

TimeStep=0.001; {Шаг времени}

NumberPoints=3000; {Число шагов}

T0=0.01; {Период дискретизации для цифровых САУ}

VAR

GD,GM,Method,I:Integer;

time,g,e,v,u,x:Float;

KUX0,KUX1,KUTime,

IMX,IMXDot,

OUX,OUXDot:Float;

AnalogXVector,

TastinXVector,

RectangleXVector,

StandartZXVector,

TimeVector:ARRAY [0..NumberPoints-1] OF Float;

PROCEDURE TrapeziodalIntegral(VAR X,XDot:Float;NextXDot,step:Float);

BEGIN

X:=X+(XDot+NextXDot)*step/2.0;

XDot:=NextXDot

END;

{PROCEDURE RectangularIntegral(VAR X:Float;XDot,step:Float);

BEGIN

X:=X+XDot*step;

END;}

{Инерционное звено. (Апериодическое звено 1-го порядка.)

K

W(S)=-----

T*S+1

. K*Int-Out

Out=---------

T

=>

. K*Int-Out

X=---------

T

Out=X

K и T - параметры звена,

X, XDot - текущее состояние звена

(производная нужна для вычисления интеграла методом трапеций),

Int - значение входного сигнала.

Функция вычисляет новое внутреннее состояние звена

и сигнал на выходе.

Шаг интегрирования общий для всей программы - TimeStep.

}

FUNCTION Inertion(K,T:Float;

VAR X,XDot:Float;

Int:Float):Float;

BEGIN

TrapeziodalIntegral(X,XDot,(K*Int-X)/T,timeStep);

Inertion:=X

END;

{Изодромное звено.

T*S+1

W(S)=K*-----

S

.

Out=K*(T*IntDot+Int)

=>

.

X=Int

Out=K*(T*Int+X)

K и T - параметры звена,

X, XDot - текущее состояние звена

(производная нужна для вычисления интеграла методом трапеций),

Int - значение входного сигнала.

Функция вычисляет новое внутреннее состояние звена

и сигнал на выходе.

Шаг интегрирования общий для всей программы - TimeStep.

}

FUNCTION Isodrome(K,T:Float;

VAR X,XDot:Float;

Int:Float):Float;

BEGIN

TrapeziodalIntegral(X,XDot,Int,timeStep);

Isodrome:=K*(T*Int+X)

END;

{Цифровой аналог изодромного звена (преобразование Тастина).

T0 z+1

W(z)=K*T+K*--*---

2 z-1

Out=PrevOut+K*(T0/2+T)*Int+K*(T0/2-T)*PrevInt

K и T - параметры звена,

PrevInt, PrevOut - предыдущие значения входа и выхода,

PrevTime - время предыдущего срабатывания звена,

Int - текущее значение сигнала на входе.

Функция запоминает значения сигналов на входе и выходе

и вычисляет новое значение сигнала на выходе.

Текущее время общее для всей программы - time.

}

FUNCTION TastinIsodrome(K,T,T0:Float;

VAR PrevInt,PrevOut,PrevTime:Float;

Int:Float):Float;

VAR

Out:Float;

BEGIN

IF (time>=PrevTime+T0)

THEN

BEGIN

Out:=PrevOut+K*(T0/2.0+T)*Int+K*(T0/2.0-T)*PrevInt;

PrevInt:=Int;

PrevOut:=Out;

PrevTime:=PrevTime+T0;

TastinIsodrome:=PrevOut

END

ELSE

TastinIsodrome:=PrevOut

END;

{Цифровой аналог изодромного звена (преобразование прямоугольников).

Функция вычисляет новое внутреннее состояние звена

и сигнал на выходе.

z

W(z)=K*T+K*T0*---

z-1

Out=PrevOut+K*(T+T0)*Int-K*T*PrevInt

K и T - параметры звена,

PrevInt, PrevOut - предыдущие значения входа и выхода,

PrevTime - время предыдущего срабатывания звена,

Int - текущее значение сигнала на входе.

Функция запоминает значения сигналов на входе и выходе

и вычисляет новое значение сигнала на выходе.

Текущее время общее для всей программы - time.

}

FUNCTION RectangleIsodrome(K,T,T0:Float;

VAR PrevInt,PrevOut,PrevTime:Float;

Int:Float):Float;

VAR

Out:Float;

BEGIN

IF (time>=PrevTime+T0)

THEN

BEGIN

Out:=PrevOut+K*(T+T0)*Int-K*T*PrevInt;

PrevInt:=Int;

PrevOut:=Out;

PrevTime:=PrevTime+T0;

RectangleIsodrome:=PrevOut

END

ELSE

RectangleIsodrome:=PrevOut

END;

{Цифровой аналог изодромного звена (стандартное z-преобразование).

K*T0

W(z)=K*T+----

z-1

Out=PrevOut+K*T*Int+K*(T0-T)*PrevInt

K и T - параметры звена,

PrevInt, PrevOut - предыдущие значения входа и выхода,

PrevTime - время предыдущего срабатывания звена,

Int - текущее значение сигнала на входе.

Функция запоминает значения сигналов на входе и выходе

и вычисляет новое значение сигнала на выходе.

Текущее время общее для всей программы - time.

}

FUNCTION StandartZIsodrome(K,T,T0:Float;

VAR PrevInt,PrevOut,PrevTime:Float;

Int:Float):Float;

VAR

Out:Float;

BEGIN

IF (time>=PrevTime+T0)

THEN

BEGIN

Out:=PrevOut+K*T*Int+K*(T0-T)*PrevInt;

PrevInt:=Int;

PrevOut:=Out;

PrevTime:=PrevTime+T0;

StandartZIsodrome:=PrevOut

END

ELSE

StandartZIsodrome:=PrevOut

END;

{--------------Начало программы------------------}

BEGIN

WriteLn('TAUKurs 27,29,30-05-2003, 1-06-2003 by Stupin W.A.');

GD:=Detect;

InitGraph(GD,GM,'d:\bp\bgi');

IF GraphResult<>GrOk

THEN

BEGIN

WriteLn('Ошибка инициализации графики.');

Exit;

END;

FOR Method:=0 TO 3 DO

BEGIN

{Задаём начальное состояние "линий",

т.е. входов и выходов звеньев}

g:=0.0;

e:=0.0;

v:=0.0;

u:=0.0;

x:=0.0;

{Задаём начальное состояние звеньев}

KUX0:=0.0; KUX1:=0.0; {аналоговое или цифровое}

KUTime:=-T0; {корректирующее устройство}

IMX:=0.0; IMXDot:=0.0; {исполнительный механизм}

OUX:=0.0; OUXDot:=0.0; {объект управления}

FOR I:=0 TO NumberPoints-1 DO

BEGIN

time:=I*TimeStep;

TimeVector[I]:=time;

{Порядок вычисления соответствует "течению" сигнала по системе}

{Единичное ступенчатое воздействие}

g:=1.0;

{Сравнивающий элемент}

e:=g-x;

{Корректирующее устройство}

CASE Method OF

0: BEGIN

AnalogXVector[I]:=x;

v:=Isodrome(133.0,0.2,KUX0,KUX1,e)

END;

1: BEGIN

TastinXVector[I]:=x;

v:=TastinIsodrome(133.0,0.2,T0,KUX0,KUX1,KUTime,e)

END;

2: BEGIN

RectangleXVector[I]:=x;

v:=RectangleIsodrome(133.0,0.2,T0,KUX0,KUX1,KUTime,e)

END;

3: BEGIN

StandartZXVector[I]:=x;

v:=StandartZIsodrome(133.0,0.2,T0,KUX0,KUX1,KUTime,e)

END

END;

{Исполнительный механизм}

u:=Inertion(0.1,0.1,IMX,IMXDot,v);

{Объект управления}

x:=Inertion(0.5,0.2,OUX,OUXDot,u)

END

END;

DrawFun(NumberPoints,TimeVector,AnalogXVector,0,0,GetMaxX,GetMaxY DIV 4,

'Аналоговая система - x(t)',LightRed);

DrawFun(NumberPoints,TimeVector,TastinXVector,0,GetMaxY DIV 4,GetMaxX,GetMaxY DIV 2,

'Аналоговая система с цифровым КУ по преобразованию Тастина - x(t)',Yellow);

DrawFun(NumberPoints,TimeVector,RectangleXVector,0,GetMaxY DIV 2,GetMaxX,3*GetMaxY DIV 4,

'Аналоговая система с цифровым КУ по преобразованию прямоугольников - x(t)',LightGreen);

DrawFun(NumberPoints,TimeVector,StandartZXVector,0,3*GetMaxY DIV 4,GetMaxX,GetMaxY,

'Аналоговая система с цифровым КУ по стандартному z-преобразованию - x(t)',LightBlue);

ReadKey;

CloseGraph

END.

Скажите, большое спасибо Ступину В.

За проделанный столь героический труд.

5

Соседние файлы в папке курсовая работа