- •1.Постановка задачи.
- •2. Исходные данные.
- •3.Математическая модель.
- •4. Листинг программы
- •5.Расчёт номинальной траектории.
- •6.Расчет отклонений координат точек падения по дальности стрельбы при действии возмущений
- •Расчёт отклонений координат точек падения по дальности стрельбы при наличии ветра.
- •8.Выводы
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. |
