Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
КП Скубицкий v1.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
1.49 Mб
Скачать

4. Листинг программы

Листинг программы

unit main;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls, XPMan, Math, RK_Method, St_Atmosphere, ComObj;

type

TMainForm = class(TForm)

Label1: TLabel;

Label2: TLabel;

Edit1: TEdit;

Label3: TLabel;

Edit2: TEdit;

Label4: TLabel;

Edit3: TEdit;

Label5: TLabel;

Edit4: TEdit;

Label6: TLabel;

Edit5: TEdit;

Label7: TLabel;

Edit6: TEdit;

Label8: TLabel;

Edit7: TEdit;

Label9: TLabel;

Edit8: TEdit;

Button1: TButton;

XPManifest1: TXPManifest;

Edit9: TEdit;

Label10: TLabel;

CheckAYT: TCheckBox;

CheckPYT: TCheckBox;

Label11: TLabel;

procedure Button1Click(Sender: TObject);

procedure CheckAYTClick(Sender: TObject);

procedure CheckPYTClick(Sender: TObject);

procedure FormCreate(Sender: TObject);

private

{ Private declarations }

Procedure ShowExcel;

public

{ Public declarations }

end;

Const g=9.80665;

var

MainForm: TMainForm;

// Переменные, используемые в программе

// Исходные данные

Dmid,Sm:Extended; // Диаметр (площадь) миделевого сечения

Da,Sa:Extended; // Диаметр (площадь) выходного сечения сопла двигателя

m0:Extended; // Начальная масса ракеты

mk:Extended; // Конечная масса ракеты

tk:Extended; // Время работы двигателя

We:Extended; // Эффективная скорость истечения газов

Vk0:Extended; // Начальная траекторная скорость

Teta0:Extended; // Начальный угол наклона траекторной скорости

Wx_:Extended; // Скорость продольного горизонтального ветра

dmc:Extended; // Секундный расход массы топлива

dt:Extended=0.1; // Шаг интегрирования

// Переменные для интегрирования методом Рунге-Кутта

FunArray: TFunArray; // массив функций

InitArray:TInitArray;// вектор начальных значений

implementation

{$R *.dfm}

{ TMainForm }

Function CxAYT(Max: Extended):Extended; // Линейная интерполяция Сх(АУТ)

begin

IF ((Max>0 ) and (Max<=0.25)) then Result:=0.3

Else IF ((Max>0.25) and (Max<=0.50)) then Result:=0.3 +(0.31-0.3 )/(0.50-0.25)*(Max-0.25)

Else IF ((Max>0.50) and (Max<=0.75)) then Result:=0.31+(0.38-0.31)/(0.75-0.50)*(Max-0.50)

Else IF ((Max>0.75) and (Max<=0.90)) then Result:=0.38+(0.51-0.38)/(0.90-0.75)*(Max-0.75)

Else IF ((Max>0.90) and (Max<=1.00)) then Result:=0.51+(0.56-0.51)/(1.00-0.90)*(Max-0.90)

Else IF ((Max>1.00) and (Max<=1.10)) then Result:=0.56+(0.59-0.56)/(1.10-1.00)*(Max-1.00)

Else IF ((Max>1.10) and (Max<=1.25)) then Result:=0.59+(0.58-0.59)/(1.25-1.10)*(Max-1.10)

Else IF ((Max>1.25) and (Max<=1.50)) then Result:=0.58+(0.52-0.58)/(1.50-1.25)*(Max-1.25)

Else IF ((Max>1.50) and (Max<=2.00)) then Result:=0.52+(0.44-0.52)/(2.00-1.50)*(Max-1.50)

Else IF ((Max>2.00) and (Max<=3.00)) then Result:=0.44+(0.42-0.44)/(3.00-2.00)*(Max-2.00)

Else Result:=0.42;

end;

Function CxPYT(Max: Extended):Extended; // Линейная интерполяция Сх(ПУТ)

begin

IF ((Max>0 ) and (Max<=0.25)) then Result:=0.32

Else IF ((Max>0.25) and (Max<=0.50)) then Result:=0.32+(0.33-0.32)/(0.50-0.25)*(Max-0.25)

Else IF ((Max>0.50) and (Max<=0.75)) then Result:=0.33+(0.41-0.33)/(0.75-0.50)*(Max-0.50)

Else IF ((Max>0.75) and (Max<=0.90)) then Result:=0.41+(0.54-0.41)/(0.90-0.75)*(Max-0.75)

Else IF ((Max>0.90) and (Max<=1.00)) then Result:=0.54+(0.60-0.54)/(1.00-0.90)*(Max-0.90)

Else IF ((Max>1.00) and (Max<=1.10)) then Result:=0.60+(0.63-0.60)/(1.10-1.00)*(Max-1.00)

Else IF ((Max>1.10) and (Max<=1.25)) then Result:=0.63+(0.62-0.63)/(1.25-1.10)*(Max-1.10)

Else IF ((Max>1.25) and (Max<=1.50)) then Result:=0.62+(0.56-0.62)/(1.50-1.25)*(Max-1.25)

Else IF ((Max>1.50) and (Max<=2.00)) then Result:=0.56+(0.49-0.56)/(2.00-1.50)*(Max-1.50)

Else IF ((Max>2.00) and (Max<=3.00)) then Result:=0.49+(0.46-0.49)/(3.00-2.00)*(Max-2.00)

Else Result:=0.46;

end;

// Состав координат вектора переменных:

// 0 = t

// 1 = Vk

// 2 = Teta

// 3 = y

// 4 = x

// 5 = m

// Вспомогательные функции

function Wx(VarArray: TVarsArray): Extended;

begin

Result:=0;

If (Res[0,High(Res[0])]) <(tk-dt) then

Begin

IF MainForm.CheckAYT.Checked then Result:=Wx_; // VarArray[0]

end

Else

IF MainForm.CheckPYT.Checked then Result:=Wx_;

end;

function P(VarArray: TVarsArray): Extended;

begin

If (Res[0,High(Res[0])]) <(tk-dt) then // VarArray[0]

Result:=We*dmc-Patm(VarArray[3])*Sa

Else Result:=0;

end;

function V(VarArray: TVarsArray): Extended;

begin

Result:=Sqrt( Sqr(VarArray[1])+Sqr(Wx(VarArray))-2*VarArray[1]*Wx(VarArray)*cos(VarArray[2]) );

end;

function Aw(VarArray: TVarsArray): Extended;

begin

Result:=Arctan( Wx(VarArray)*sin(VarArray[2]) / ( VarArray[1]-Wx(VarArray)*cos(VarArray[2]) ) );

end;

function Max(VarArray: TVarsArray): Extended;

begin

Result:=V(VarArray)/a(VarArray[3]);

end;

function X(VarArray: TVarsArray): Extended;

begin

If (Res[0,High(Res[0])])<(tk-dt) then // VarArray[0]

Result:=CxAYT(Max(VarArray))*po(VarArray[3])*Sqr(V(VarArray))/2*Sm

Else

Result:=CxPYT(Max(VarArray))*po(VarArray[3])*Sqr(V(VarArray))/2*Sm;

end;

// Функции составляющие вектор правых частей ДУ движения

function dVk(VarArray: TVarsArray): Extended;

begin

Result:=( P(VarArray)-X(VarArray) )*cos(Aw(VarArray))/VarArray[5] - g*sin(VarArray[2]);

end;

function dTeta(VarArray: TVarsArray): Extended;

begin

Result:=( P(VarArray)-X(VarArray) )*sin(Aw(VarArray))/(VarArray[5]*VarArray[1]) - g*cos(VarArray[2])/VarArray[1];

end;

function dx(VarArray: TVarsArray): Extended;

begin

Result:=VarArray[1]*cos(VarArray[2]);

end;

function dy(VarArray: TVarsArray): Extended;

begin

Result:=VarArray[1]*sin(VarArray[2]);

end;

function dm(VarArray: TVarsArray): Extended;

begin

If (Res[0,High(Res[0])])<(tk-dt) then // VarArray[0]

Result:=-dmc

Else

Result:=0;

end;

function Nx(VarArray: TVarsArray): Extended;

begin

Result:=dVk(VarArray)/g+sin(VarArray[2]);

end;

// Функция возвращает истину при окончании интегрирования

// Условие окончания интегрирования: Y<=0

function Stop(VarArray: TVarsArray): Boolean;

begin

Result:=(VarArray[3]<0);

end;

procedure TMainForm.Button1Click(Sender: TObject);

begin

// Ввод данных

Button1.Enabled:=False;

MainForm.CheckAYT.Enabled:=False;

MainForm.CheckPYT.Enabled:=False;

Try

Dmid:= StrToFloat(Edit1.Text);

Da:= StrToFloat(Edit2.Text);

m0:= StrToFloat(Edit3.Text);

mk:= StrToFloat(Edit4.Text);

tk:= StrToFloat(Edit5.Text);

We:= StrToFloat(Edit6.Text);

Vk0:= StrToFloat(Edit7.Text);

Teta0:= StrToFloat(Edit8.Text);

Wx_:= StrToFloat(Edit9.Text);

Except

ShowMessage('Ошибка при вводе данных!'+#13+'Возможно данные были введены некорректно');

exit;

end;

Sm:=Pi*Sqr(Dmid)/4;

Sa:=Pi*Sqr(Da)/4;

dmc:=(m0-mk)/tk;

Teta0:=DegToRad(Teta0);

// Интегрирование методом Рунге-Кутта

// Создаем вектор функций правых частей системы ДУ:

SetLength(FunArray,7);

FunArray[0]:=dVk;

FunArray[1]:=dTeta;

FunArray[2]:=dy;

FunArray[3]:=dx;

FunArray[4]:=dm;

FunArray[5]:=Nx;

FunArray[6]:=Aw;

// Задаем начальные условия:

SetLength(InitArray,5);

InitArray[0]:=Vk0;

InitArray[1]:=Teta0;

InitArray[2]:=0;

InitArray[3]:=0;

InitArray[4]:=m0;

// Интегрируем

IF Runge_Kutt(FunArray, 0, dt, Stop, 5, InitArray) =0 then

ShowExcel; // Выводим в Excel

end;

// Функция для вывода данных в Excel

procedure TMainForm.ShowExcel;

Var XLApp,Sheet,Colum: Variant; // Переменные для вывода данных в MS Excel

i:integer;

Xm:Extended;

begin

DecimalSeparator := '.';// Вместо запятой используем точку

// Открываем Excel

XLApp:= CreateOleObject('Excel.Application');

XLApp.Visible:=False;

XLApp.Workbooks.Add(-4167);

XLApp.Workbooks[1].WorkSheets[1].Name:='Результаты расчёта';

Sheet:=XLApp.Workbooks[1].WorkSheets['Результаты расчёта'];

i:=High(Res[0]);

Xm:=Res[4,i]-Res[3,i]/tan(Res[2,i]);

Sheet.Cells[2,9]:='Дальность: '+FloatToStrf(Xm,ffFixed,6 ,1)+' м';

// Выводим названия столбцов

Sheet.Cells[3,1]:= 't,c';

Sheet.Cells[3,2]:= 'Vk, м/с';

Sheet.Cells[3,3]:= 'Teta, рад';

Sheet.Cells[3,4]:= 'y, м';

Sheet.Cells[3,5]:= 'x, м';

Sheet.Cells[3,6]:= 'm, кг';

Sheet.Cells[3,7]:= 'Nx';

Sheet.Cells[3,8]:= 'Aw';

For i:=0 to High(Res[0]) do

Begin

Sheet.Cells[4+i,1]:=FloatToStrf(Res[0,i],ffFixed,6 ,1);

Sheet.Cells[4+i,2]:=FloatToStrf(Res[1,i],ffFixed,6 ,1);

Sheet.Cells[4+i,3]:=FloatToStrf(RadToDeg(Res[2,i]),ffFixed,6 ,2);

Sheet.Cells[4+i,4]:=FloatToStrf(Res[3,i],ffFixed,6 ,1);

Sheet.Cells[4+i,5]:=FloatToStrf(Res[4,i],ffFixed,6 ,1);

Sheet.Cells[4+i,6]:=FloatToStrf(Res[5,i],ffFixed,6 ,3);

Sheet.Cells[4+i,7]:=FloatToStrf(Res[6,i],ffFixed,6 ,3);

Sheet.Cells[4+i,8]:=FloatToStrf(RadToDeg(Res[7,i]),ffFixed,6 ,3);

End;

XLApp.Visible:=True;

end;

procedure TMainForm.CheckAYTClick(Sender: TObject);

begin

If (CheckPYT.Checked)then EXIT;

If (CheckAYT.Checked) Then

Begin

Label10.Visible:= True;

Edit9.Visible:= True;

end

Else

Begin

Label10.Visible:= False;

Edit9.Visible:= False;

end;

end;

procedure TMainForm.CheckPYTClick(Sender: TObject);

begin

If (CheckAYT.Checked)then EXIT;

If (CheckPYT.Checked) Then

Begin

Label10.Visible:= True;

Edit9.Visible:= True;

end

Else

Begin

Label10.Visible:= False;

Edit9.Visible:= False;

end;

end;

procedure TMainForm.FormCreate(Sender: TObject);

begin

Application.Title:='Динамика полета';

end;

end.

unit RK_Method;

interface

type

TVarsArray = array of Extended; // вектор переменных включая независимую

TInitArray = array of Extended; // вектор начальных значений

TFunArray = array of function(VarsArray: TVarsArray ):Extended;

TCondition = function(VarsArray: TVarsArray ): Boolean;// вектор функций

TResArray = array of TVarsArray; // матрица результатов

TCoefsArray = array of Extended; // вектор коэффициетов метода

function Runge_Kutt( // метод Рунге-Кутта

FunArray: TFunArray; // массив функций

First: Extended; // начальная точка по независимой координате

Delt: Extended; // шаг разбиения

Condition: TCondition; // условие окончания интегрирования

Num: Word; // число интегрируемых уравнений

InitArray: TInitArray // вектор начальных значений

):Word; // возвращаемое значение - код ошибки

Var

Res: TResArray; // матрица результатов включая независимую переменную

implementation

Function Runge_Kutt( // метод Рунге-Кутта

FunArray: TFunArray; // массив функций

First: Extended; // начальная точка по независимой координате

Delt: Extended; // шаг разбиения

Condition: TCondition; // условие окончания интегрирования

Num: Word; // число интегрируемых уравнений

InitArray: TInitArray // вектор начальных значений

):Word; // возвращаемое значение - код ошибки

var

NumFunc:Word; // Общее число уравнений (интегрируемые и нет)

NumInit: Word; // число начальных условий

Vars: TVarsArray; // вектор переменных включая независимую

Vars2,Vars3,Vars4: TVarsArray; // значения перем. для 2-4 коэф.

Coefs1: TCoefsArray; // вектор 1-ыx коэффициентов в методе

Coefs2: TCoefsArray; // вектор 2 коэффициентов в методе

Coefs3: TCoefsArray; // вектор 3 коэффициентов в методе

Coefs4: TCoefsArray; // вектор 4 коэффициентов в методе

J: Word; // индекс коэф.-тов метода

I: Integer; // счетчик цикла по иттерациям

K: Integer; // счетчик прочих циклов

begin

NumFunc:=Length(FunArray); // узнаем общее число уравнений (интегрируемые и нет)

NumInit:=Length(InitArray); // узнаем число начальных условий

If (NumInit<>Num) or (NumFunc<Num) then

begin

Result:=100; // код ошибки 100: число интегрирумых уравнений не равно числу нач. усл.

Exit;

end;

SetLength(Vars,Num+1); // число переменных включая независимую

SetLength(Vars2,Num+1); // число переменных для 2-го коэф. включая независимую

SetLength(Vars3,Num+1); // число переменных для 3-го коэф. включая независимую

SetLength(Vars4,Num+1); // число переменных для 4-го коэф. включая независимую

SetLength(Coefs1,Num); // число 1-ыx коэф. метода по числу уравнений

SetLength(Coefs2,Num); // число 2-ыx коэф. метода по числу уравнений

SetLength(Coefs3,Num); // число 3-иx коэф. метода по числу уравнений

SetLength(Coefs4,Num); // число 4-ыx коэф. метода по числу уравнений

// Начальные значения переменных:

Vars[0]:=First;

For K:=0 to NumInit-1 do Vars[K+1]:=InitArray[K];

SetLength(Res,NumFunc+1,1); // задаем первоначальный размер матрицы ответов с незав. перем.

For J:=0 to Num do Res[J,0]:=Vars[J]; // первая точка результата

For J:=Num+1 to NumFunc do Res[J,0]:=FunArray[J-1](Vars);

{Res[Num+1,0]:=FunArray[0](Vars)/9.80665+sin(Vars[2]);

Res[Num+2,0]:=Aw(Vars);}

I:=1;

While NOT(Condition(Vars)) do // начало цикла иттераций

begin

For J:=0 to Num-1 do Coefs1[J]:=FunArray[J](Vars)*delt; // 1-й коэфф.

// Находим значения переменных для второго коэф.

Vars2[0]:=Vars[0]+delt/2;

For K:=1 to Num do Vars2[K]:=Vars[K]+Coefs1[K-1]/2;

For J:=0 to Num-1 do Coefs2[J]:=FunArray[J](Vars2)*delt; // 2-й коэф.

// Находим значения переменных для третьго коэф.

Vars3[0]:=Vars[0]+delt/2;

For K:=1 to Num do Vars3[K]:=Vars[K]+Coefs2[K-1]/2;

For J:=0 to Num-1 do Coefs3[J]:=FunArray[J](Vars3)*delt; // 3 коэфф.

// Находим значения переменных для 4 коэф.

Vars4[0]:=Vars[0]+delt;

For K:=1 to Num do Vars4[K]:=Vars[K]+Coefs3[K-1];

For J:=0 to Num-1 do Coefs4[J]:=FunArray[J](Vars4)*delt; // 4 коэфф.

// Находим новые значения переменных включая независимую

Vars[0]:=Vars[0]+delt;

For K:=1 to Num do

Vars[K]:=Vars[K]+(1/6)*(Coefs1[K-1]+2*(Coefs2[K-1]+Coefs3[K-1])+Coefs4[K-1]);

SetLength(Res,NumFunc+1,I+1); // увеличиваем размер матрицы ответов с незав. перем.

// Результат иттерации:

For J:=0 to Num do Res[J,I]:=Vars[J];

For J:=Num+1 to NumFunc do Res[J,I]:=FunArray[J-1](Vars);

{ Res[Num+1,i]:=FunArray[0](Vars)/9.80665+sin(Vars[2]);

Res[Num+2,i]:=Aw(Vars);}

I:=I+1;

end; // конец итераций

Result:=0; // код ошибки 0 - нет ошибок

end;

end.

unit St_Atmosphere;

interface

Uses Math;

Function T(Y:Extended):Extended;

Function Patm(Y:Extended):Extended;

Function Po(Y:Extended):Extended;

Function a(Y:Extended):Extended;

implementation

Function T(Y:Extended):Extended; // Температура на высоте У (Кельвин)

Var Ts,Ps,Hs : Extended; // Температура, Давление и Высота базового уровня

Beta: Extended; // Градиент температуры

Begin

Case Trunc(Y/1000) of // Выбираем базовый уровень в зависимости от текущей высоты, выраженной в КМ

-2..10: Begin Beta:=-6.5*0.001; Ts:=301.150; Ps:= 0127774; Hs:=-2000; end;

11..19: Begin Beta:= 0; Ts:=216.650; Ps:= 22632.0; Hs:=11000; end;

20..31: Begin Beta:= 1*0.001; Ts:=216.650; Ps:= 5474.87; Hs:=20000; end;

32..46: Begin Beta:= 2.8*0.001; Ts:=228.650; Ps:= 868.014; Hs:=32000; end;

47..50: Begin Beta:= 0; Ts:=270.650; Ps:= 110.906; Hs:=47000; end;

51..70: Begin Beta:=-2.8*0.001; Ts:=270.650; Ps:= 66.9385; Hs:=51000; end;

71..85: Begin Beta:=-2.0*0.001; Ts:=214.650; Ps:= 3.95639; Hs:=71000; end;

end;

Result:=Ts+Beta*(Y-Hs);

end;

Function Patm(Y:Extended):Extended; // Давление на высоте У (Паскаль)

Const g=9.80665; R=287.05287;

Var Ts,Ps,Hs : Extended; // Температура, Давление и Высота базового уровня

T:Extended; // Температура на высоте У

Beta: Extended; // Градиент температуры

Begin

Case Trunc(Y/1000) of // Выбираем базовый уровень в зависимости от текущей высоты, выраженной в КМ

-2..10: Begin Beta:=-6.5*0.001; Ts:=301.150; Ps:= 0127774; Hs:=-2000; end;

11..19: Begin Beta:= 0; Ts:=216.650; Ps:= 22632.0; Hs:=11000; end;

20..31: Begin Beta:= 1*0.001; Ts:=216.650; Ps:= 5474.87; Hs:=20000; end;

32..46: Begin Beta:= 2.8*0.001; Ts:=228.650; Ps:= 868.014; Hs:=32000; end;

47..50: Begin Beta:= 0; Ts:=270.650; Ps:= 110.906; Hs:=47000; end;

51..70: Begin Beta:=-2.8*0.001; Ts:=270.650; Ps:= 66.9385; Hs:=51000; end;

71..85: Begin Beta:=-2.0*0.001; Ts:=214.650; Ps:= 3.95639; Hs:=71000; end;

end;

T:=Ts+Beta*(Y-Hs);

IF Beta=0 then

Result:=Ps*exp(-g*(Y-Hs)/(R*T))

Else

Result:=Ps*Power(1+Beta*(Y-Hs)/Ts , -g/(R*Beta) );

end;

Function po(Y:Extended):Extended; // Плотность на высоте У (кг/м^3)

Const R=287.05287;

Begin

Result:=Patm(y)/(R*T(y));

end;

Function a(Y:Extended):Extended; // Скорость звука на высоте У (м/с)

Begin

Result:=20.046796*Sqrt(T(y));

end;

end.