rcksim.m

来自「航天工程工具箱」· M 代码 · 共 302 行

M
302
字号
function [flight_,t,x]=rcksim(name,eng,Cd,Dr,mr,dt)
%RCKSIM  Simulation of rocket trajectory.
%   [DATA,T,X] = RCKSIM(NAME,ENG,CD,DR,MR,DT) simulates the trajectory
%   of a multi staged rocket with name NAME, having for each stage
%   a motor ENG given by LOADENG, an overall "static" subsonic drag
%   coefficient CD (for current stage and upper stages),
%   a body diameter DR, an empty mass MR (without the motor) and a
%   separation delay (burnout-separation) DT. It is assumed that the delay
%   for separation-ignition equals zero.
%
%   [...] = RCKSIM(ROCKET) does the same as above but for a rocket
%   definition structure ROCKET given by RCKTOOL.
%
%   LENGTH(DT)+1 = LENGTH(MR) = LENGTH(DR) = LENGTH(CD) = LENGTH(ENG)
%                = # stages
%
%   The returned structure DATA contains information about the
%   simulation results. The format for DATA will be:
%
%      DATA.name         : Name of rocket
%      DATA.Cd           : Drag coefficient for each stage
%      DATA.Dr           : Diameter of each stage
%      DATA.mass.mr      : Mass of each stage w/o motor
%      DATA.mass.mf      : Fuel mass for each stage
%      DATA.mass.mm      : Motor mass for each stage
%      DATA.mass.m[0-3]  : Total mass of rocket at event
%      DATA.alt.h[0-3]   : Altitude at event
%      DATA.vel.ve       : Exhaust velocity for each stage
%      DATA.vel.v[0-3]   : Velocity at event
%      DATA.acc.amax     : Maximum acceleration
%      DATA.acc.a[0-3]   : Acceleration at event
%
%   where an event is associated with each index 0-3 as:
%      0 : ignition for each stage
%      1 : burn-out for each stage
%      2 : turning point (maximum altitude)
%      3 : impact
%
%   T is the sampled time points and X is:
%
%      X(:,1) = altitude
%      X(:,2) = velocity
%      X(:,3) = acceleration
%      X(:,4) = mass
%
%   See also RCKMOD, LOADENG, RCKTOOL, MOTORCLASS.

% Copyright (c) 2002-02-09, B. Rasmus Anthin.
% Revisited 2003-06-11,
%           2003-06-14 - 2003-06-15,
%           2003-06-18 - 2003-06-19.

g=constant('g');

if nargin==1 & isempty(name), return,end

if isstruct(name)
   r=name;
   name=r.name;
   slen=r.stages;
   eng=r.eng;
   Cd=r.Cd;
   Dr=r.Dr;
   mr=r.mr;
   dt=r.dt;
else
   slen=length(eng);
end

%name=[];
for i=1:slen
%   name=[name ' - ' eng(i).name];
   mf(i)=eng(i).mf;
   mm(i)=eng(i).mm;
end
%name=name(4:end);

for i=1:slen
   m0(i)=sum(mr(i:end))+sum(mm(i:end))+sum(mf(i:end));   %start
   m1(i)=m0(i)-mf(i);                                    %burnout   
end

t0=0;t1=eng(1).thrust(end,1);
for i=2:slen
   t0(i)=t1(i-1)+dt(i-1);                                %start
   t1(i)=t0(i)+eng(i).thrust(end,1);                     %burnout
end

for i=1:slen
   Ar(i)=pi*max(Dr(i:end))^2/4;

   thrust(i).t=[t0(i);t0(i)+eng(i).thrust(:,1)];
   thrust(i).F=[0;eng(i).thrust(:,2)];

   ve(i)=trapz(thrust(i).t,thrust(i).F)/mf(i);
end

atmmodel='US';    %alter to change to another model.
switch(atmmodel)
case 'MSIS-E-90'
   %MSIS-E-90 (up to 1000 km)
   %http://nssdc.gsfc.nasa.gov/space/model/models/msis_n.html#height
   load atmdata
   atmos.h=atm(:,1)*1e3; %km -> m.
   atmos.rho=atm(:,5)*1e3; %g/cm^3 -> kg/m^3.
   atmos.T=atm(:,6);
case 'US'
   %US Standard Atmosphere (up to 65 km)
   %http://dss.ucar.edu/docs/equations/std.atmos.html
   stdatm
   atmos.h=atm(:,2);
   atmos.rho=atm(:,5);
   atmos.T=convert(atm(:,4),'oC','K'); %K -> oC
end

tic
optn=odeset('refine',2,'reltol',1e-6,'abstol',1e-5,'stats','off','events','on');
tt=[]; xx=[];
tj=NaN; xj=NaN*ones(1,3);
init=[0 0];
for i=1:slen
   %IGNITION #I -> BURN-OUT #I
   [t,x]=ode15s('rckmod',[t0(i) t1(i)],[init m0(i)],optn,thrust(i),atmos,Ar(i),Cd(i),m1(i),ve(i));
   tt=[tt;t]; xx=[xx;x];
   init=x(end,1:2);
   if i<slen
      if t1(i)<t0(i+1)          %BURN-OUT #I -> IGNITION #I+1
         [t,x]=ode15s('rckmod',[t1(i) t0(i+1)],[init m1(i)],optn,thrust(i),atmos,Ar(i),Cd(i),m1(i),ve(i));
         tt=[tt;t]; xx=[xx;x];
         init=x(end,1:2);
      end
      null.t=0; null.F=0;       %BURN-OUT #I -> IMPACT #I
      [t,x]=ode15s('rckmod',[t0(i+1) inf],[init mr(i)+mm(i)],optn,null,atmos,Ar(i),Cd(i),m1(i),ve(i));
      tj=[tj;t;NaN]; xj=[xj;x;NaN*ones(1,3)];
   end
end
%BURN-OUT #I+N -> IMPACT #I+N
[t,x]=ode15s('rckmod',[t(end) inf],x(end,:),optn,thrust(end),atmos,Ar(end),Cd(end),m1(end),ve(end));
tt=[tt;t]; xx=[xx;x];
t=tt;x=xx;
tsim=toc;

for i=1:slen
   i0(i)=min(find(t==t0(i)));  %ignition
   i1(i)=min(find(t==t1(i)));  %burn-out
end
i2=min(find(x(:,1)==max(x(:,1))));      %coast
i3=length(t);

t0=t(i0);
t1=t(i1);
t2=t(i2);
t3=t(i3);
h0=x(i0,1);
h1=x(i1,1);
h2=x(i2,1);
h3=x(i3,1);
v0=x(i0,2);
v1=x(i1,2);
v2=x(i2,2);
v3=x(i3,2);

m=x(:,3);
f=-gradient(x(:,3),t);
a=gradient(x(:,2),t);
x(:,3)=a;
x(:,4)=m;
m=x(:,4);    % mass
a=x(:,3);    % acceleration
v=x(:,2);    % velocity
h=x(:,1);    % height

gh=figure;set(gh,'name',name,'numbertitle','off')
subplot(4,1,1), hold on
plot(tj,xj(:,1),'g')
plot(t,x(:,1))
ax=axis; axis tight
events(t0,t1,t2,ax)
xlabel t,ylabel h
grid, set(gca,'xgrid','off')

subplot(4,1,2), hold on
plot(tj,xj(:,2),'g')
plot(t,x(:,2))
ax=axis; axis tight
events(t0,t1,t2,ax)
xlabel t,ylabel('h''')
grid, set(gca,'xgrid','off')

subplot(4,1,3), hold on
%plot(tj,gradient(xj(:,2)),'g')
plot(t,x(:,3))
ax=axis; axis tight
events(t0,t1,t2,ax)
xlabel t,ylabel('h''''')
grid, set(gca,'xgrid','off')

subplot(4,1,4), hold on
plot(t,x(:,4))
ax=axis; axis tight
events(t0,t1,t2,ax)
xlabel t,ylabel m
grid, set(gca,'xgrid','off')

   disp(' ')
   disp(['Simulation time : ' num2str(tsim) ' s'])
   disp(['# samples       : ' num2str(size(x,1))])

   disp(' ')
   disp( 'MASS---------------------------------')
for i=1:slen
   disp(['  Rocket     ' int2str(i) '    : ' num2mass(mr(i),6)])
   disp(['  Propellant ' int2str(i) '    : ' num2mass(mf(i),6)])
   disp(['  Motor      ' int2str(i) '    : ' num2mass(mm(i),6)])
end
for i=1:slen
   disp(['  Ignition   ' int2str(i) '    : ' num2mass(m0(i),6)])
   disp(['  Burn-out   ' int2str(i) '    : ' num2mass(m1(i),6)])
end
   disp(' ')
   disp( 'ALTITUDE-----------------------------')
for i=1:slen
   disp(['  Ignition   ' int2str(i) '    : ' num2sci(h0(i)) 'm'])
   disp(['  Burn-out   ' int2str(i) '    : ' num2sci(h1(i)) 'm'])
end
   disp(['  Turning         : ' num2sci(h2) 'm'])
   disp(' ')
   disp( 'VELOCITY-----------------------------')
for i=1:slen
   disp(['  Exit       ' int2str(i) '    : ' num2sci(ve(i)) 'm/s'])
end
for i=1:slen
   disp(['  Ignition   ' int2str(i) '    : ' num2sci(v0(i)) 'm/s'])
   disp(['  Burn-out   ' int2str(i) '    : ' num2sci(v1(i)) 'm/s'])
end
   disp(['  Impact          : ' num2sci(v3) 'm/s'])
   disp(' ')
   disp( 'ACCELERATION-------------------------')
   disp(['  Maximum         : ' num2sci(max(abs(a))/g) 'g'])
for i=1:slen
   disp(['  Ignition   ' int2str(i) '    : ' num2sci(a(i0(i))/g) 'g'])
   disp(['  Burn-out   ' int2str(i) '    : ' num2sci(a(i1(i))/g) 'g'])
end
   disp(['  Turning         : ' num2sci(a(i2)/g) 'g'])
   disp(['  Impact          : ' num2sci(a(i3)/g) 'g'])
   disp(' ')
   disp( 'TIME---------------------------------')
for i=1:slen
   tm0=sec2hms(t0(i));
   tm1=sec2hms(t1(i));
   disp(['  Ignition   ' int2str(i) '    : ' num2str(tm0(1)) ' h, ' num2str(tm0(2)) ' m, ' num2str(tm0(3)) ' s'])
   disp(['  Burn-out   ' int2str(i) '    : ' num2str(tm1(1)) ' h, ' num2str(tm1(2)) ' m, ' num2str(tm1(3)) ' s'])
end
   tm2=sec2hms(t2);
   tm3=sec2hms(t3);
   disp(['  Turning         : ' num2str(tm2(1)) ' h, ' num2str(tm2(2)) ' m, ' num2str(tm2(3)) ' s'])
   disp(['  Impact          : ' num2str(tm3(1)) ' h, ' num2str(tm3(2)) ' m, ' num2str(tm3(3)) ' s'])
   disp(' ')
   disp( 'OTHER--------------------------------')
for i=1:slen
   disp(['  Diameter   ' int2str(i) '    : ' num2sci(Dr(i)) 'm'])
end
   disp(['  Impact energy   : ' num2sci(m1(end)*v3^2/2) 'J'])
   disp(' ')
   
flight.name=name;
flight.Cd=Cd;
flight.Dr=Dr;
flight.mass.mr=mr;
flight.mass.mf=mf;
flight.mass.mm=mm;
flight.mass.m0=m0;
flight.mass.m1=m1;
flight.mass.m2=m(i2);
flight.mass.m3=m(i3);
flight.alt.h0=h0;
flight.alt.h1=h1;
flight.alt.h2=h2;
flight.alt.h3=h3;
flight.vel.ve=ve;
flight.vel.v0=v0;
flihgt.vel.v1=v1;
flight.vel.v2=v2;
flight.vel.v3=v3;
flight.acc.max=max(a);
flight.acc.a0=a(i0);
flight.acc.a1=a(i1);
flight.acc.a2=a(i2);
flight.acc.a3=a(i3);


if nargout, flight_=flight;end


%%%%%%%%%%%%%%%%%%%%

function events(t0,t1,t2,ax)
for i=1:length(t0)
   plot([t0(i) t0(i)],ax(3:4),'r:')
   plot([t1(i) t1(i)],ax(3:4),'m:')
end
plot([t2 t2],ax(3:4),'b:')

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?