如何在Matlab中进行循环时响应和绘制数据?

如何在Matlab中进行循环时响应和绘制数据?,matlab,matlab-figure,Matlab,Matlab Figure,我试图模拟两颗卫星的位置,并确定它们是否会碰撞。为此,我使用了Rk4方法。如您所见,在循环中,我使用了drawnow命令,在avery迭代之后在3d图形上添加一个点。我感兴趣的是找到一种方法来表示3d绘图,直到碰撞条件满足为止(在我有消息的地方),并在循环中而不是在外部时获取.txt文件上的值。当我使用return命令,并尝试打印或添加文本时,我有一个错误“向量必须是相同长度的”,并且不允许我获取数据。这是因为sat1=1X200,而tspan=1X201。有没有其他命令可以代替return或更

我试图模拟两颗卫星的位置,并确定它们是否会碰撞。为此,我使用了Rk4方法。如您所见,在循环中,我使用了
drawnow
命令,在avery迭代之后在3d图形上添加一个点。我感兴趣的是找到一种方法来表示3d绘图,直到碰撞条件满足为止(在我有消息的地方),并在循环中而不是在外部时获取
.txt
文件上的值。当我使用return命令,并尝试打印或添加文本时,我有一个错误“向量必须是相同长度的”,并且不允许我获取数据。这是因为sat1=1X200,而tspan=1X201。有没有其他命令可以代替return或更好的解决方案

这是我的密码:

clear; close all; clc;
figure(1);
orbitsat1 = animatedline('Color','r');

msat1 = 124;
msat2 = 234;
Asat1 = 2.2;
Asat2 = 3.2;

sat10(1) = 453322.3616;
sat10(2) = -2346021.219;
sat10(3) = -7894131.349;
sat10(4) = 2142.38067;
sat10(5) = 7487.44895;
sat10(6) = -9864.00872;
sat10 = sat10';

sat20(1) = 543322.3616;
sat20(2) = -3246021.219;
sat20(3) = -8794131.349;
sat20(4) = 1242.38067;
sat20(5) = 4787.44895;
sat20(6) = -8964.00872;
sat20 = sat20';

tspan = 0:200;
secpday = 60*60*24;
a1 = 2018;
la1 = 1;
z1 = 2;
o1 = 12;
m1 = 0;
s1 = 0;
n1 = datenum(a1,la1,z1,o1,m1,s1);

n1 = n1 + tspan/secpday;

[an,luna,zi,ora,min,sec] = datevec(n1);

h = 1;
sat1 = zeros(6, tspan(end)/h);
sat1(:,1) = sat10;

sat2 = zeros(6, tspan(end)/h);
sat2(:,1) = sat20;

for i = 1:tspan(end)/h
    k_1 = simsat1(tspan(i), sat1(:,i), msat1, Asat1, sat1(4:6,i));
    k_2 = simsat1(tspan(i)+0.5*h, sat1(:,i)+0.5*h*k_1,msat1, Asat1, sat1(4:6,i));
    k_3 = simsat1(tspan(i)+0.5*h, sat1(:,i)+0.5*h*k_2,  msat1, Asat1, sat1(4:6,i));
    k_4 = simsat1(tspan(i)+h, sat1(:,i)+k_3*h, msat1, Asat1, sat1(4:6,i));

    k_12 = simsat2(tspan(i), sat2(:,i),  msat2, Asat2, sat2(4:6,i));
    k_22 = simsat2(tspan(i)+0.5*h, sat2(:,i)+0.5*h*k_12,  msat2, Asat2, sat2(4:6,i));
    k_32 = simsat2(tspan(i)+0.5*h, sat2(:,i)+0.5*h*k_22, msat2, Asat2, sat2(4:6,i));
    k_42 = simsat2(tspan(i)+h, sat2(:,i)+k_32*h, msat2, Asat2, sat2(4:6,i));

    sat2(:,i+1) = sat2(:,i) + (1/6)*(k_12+2*k_22+2*k_32+k_42)*h;
    sat1(:,i+1) = sat1(:,i) + (1/6)*(k_1+2*k_2+2*k_3+k_4)*h;
    addpoints(orbitsat1, sat1(1,i), sat1(2,i), sat1(3,i));
    drawnow update;
    hold off;

    Rorb = sqrt(sum(sat1(1:3,i).^2));
    Rcsc = sqrt(sum(sat2(1:3,i).^2));
    dif = Rorb-Rcsc;

    if (dif >0.5e10 && dif < 2e5) && i>350
        Message = sprintf('Data:\nan:%d\nluna:%d\nzi:%d\nora:%d\nminut:%d\nsecunda:%d',an(i),luna(i),zi(i),ora(i),min(i),sec(i));
        msgbox(Message)
        msgbox('Coliziune!','Coliziune','warn',Message);
        return
    end
end

Pozx = sat1(1,:);
Pozy = sat1(2,:);
Pozz = sat1(3,:);

Tbody = [an luna zi ora min sec Pozx Pozy Pozz]';
twobody = fopen('nobody.txt','w');
fprintf(twobody,'Rezultate Twobody (metri) \n\n');
fprintf(twobody,'  An  luna  zi   ora min sec            pozitia pe  x     pozitia pe  y      pozitia pe  z       viteza pe  x    viteza pe  y    viteza pe  z\n\n');
fprintf(twobody,'---------------------------------------------------------------------------------------------------------------------------------------------\n%6d-%3d-%3d\t%3d:%3d:%3d\t\t\t\t%12.6f\t%12.6f\t\t%12.6f\t\t%12.6f\t%\n',Tbody);
fclose(twobody);
和模拟人生2

function sat2prim = simsat2(t,sat2,msat2,Asat2,vit)
miu = 398600.4418e9;
magn = sum(sat2(1:3).^2)^(3/2);
sat2prim = zeros(6,1);
sat2prim(1:3) = sat2(4:6);
sat2prim(4:6) = -miu.*sat2(1:3)./magn;
end

好的;如果我理解正确,这应该是你想要的

我已经将
Tbody
变量移到了'for'循环中,并且我正在将每个timestep写入文件。另外,您搜索的关键字是
break
,而不是
return
break
只是将您从当前的for或while循环中分离出来(仅上升一级),而
return
将控件返回给调用函数

我稍微改变了初始化时间向量的方式,使它更清晰。“sat1=1X200而tspan=1X201”的问题来自这样一个事实,即您的
tspan=0:200
201点,而
tpsan(end)
值仅为200。这很好,并且在向量中包含初始位置时很有意义。基本上确保他们都有正确的分数。为此,我定义了一个timestep
dt=1
hour,然后定义了timestep
nt=200
。这样,我的时间向量变成
tspan=0:nt*dt
,它将有
nt+1
点。然后,我可以像您一样迭代I=1:(nt-1)

我已经添加了一些注释,鼓励您在代码中也这样做。无论如何这是:

clear; close all; clc;
warning('on'); % Turn on warnings (Because they may be off)

figure(1);
orbitsat1 = animatedline('Color','r');

%% Initial conditions
msat1 = 124; msat2 = 234; Asat1 = 2.2; Asat2 = 3.2;

% Initialise satellites
sat10 = [453322.3616 -2346021.219 -7894131.349 2142.38067 7487.44895 -9864.00872];
sat20 = [543322.3616 -3246021.219 -8794131.349 1242.38067 4787.44895 -8964.00872];

dt = 1; % On hour timestep
nt = 200; % Number of timesteps
tspan = (0:nt)*dt; % Time from 0 to 200 timesteps in hours

% Make the time vectors
n1 = datenum(2018,1,2,12,0,0); % Starting point (serial date number in days)
n1 = n1 + tspan/24; % Timespan from hours -> days
[an,luna,zi,ora,min,sec] = datevec(n1);

%% Initialise containers
% Satelites
% nt+1 points because (:,1) is the initial condition
sat1 = zeros(6,nt+1); sat1(:,1) = sat10;
sat2 = zeros(6,nt+1); sat2(:,1) = sat20;

% Initialise Tbody here
Tbody = zeros(9,nt+1); Tbody(1:6,:) = [an; luna; zi; ora; min; sec];

%% Open the file
f_twobody = fopen('nobody.txt','w');
fprintf2(f_twobody,'Rezultate Twobody (metri)\n');
fprintf2(f_twobody,'Numar\tAn\tluna\tzi\tora\tmin\tsec\tpozitia_pe_x\tpozitia_pe_y\tpozitia_pe_z\n');
fprintf2(f_twobody,'%06d\t%6d\t%3d\t%3d\t%3d\t%3d\t%3d\t%12.6f\t%12.6f\t%12.6f\n',0,Tbody(:,1));

%% Go though all the timesteps
for i = 1:(nt-1)
    % Calculate timestep
    k_1 = simsat1(tspan(i), sat1(:,i), msat1, Asat1, sat1(4:6,i));
    k_2 = simsat1(tspan(i)+0.5*dt, sat1(:,i)+0.5*dt*k_1,msat1, Asat1, sat1(4:6,i));
    k_3 = simsat1(tspan(i)+0.5*dt, sat1(:,i)+0.5*dt*k_2,  msat1, Asat1, sat1(4:6,i));
    k_4 = simsat1(tspan(i)+dt, sat1(:,i)+k_3*dt, msat1, Asat1, sat1(4:6,i));

    k_12 = simsat2(tspan(i), sat2(:,i),  msat2, Asat2, sat2(4:6,i));
    k_22 = simsat2(tspan(i)+0.5*dt, sat2(:,i)+0.5*dt*k_12,  msat2, Asat2, sat2(4:6,i));
    k_32 = simsat2(tspan(i)+0.5*dt, sat2(:,i)+0.5*dt*k_22, msat2, Asat2, sat2(4:6,i));
    k_42 = simsat2(tspan(i)+dt, sat2(:,i)+k_32*dt, msat2, Asat2, sat2(4:6,i));

    sat2(:,i+1) = sat2(:,i) + (1/6)*(k_12+2*k_22+2*k_32+k_42)*dt;
    sat1(:,i+1) = sat1(:,i) + (1/6)*(k_1+2*k_2+2*k_3+k_4)*dt;

    % Put the calculated positions into Tbody
    Tbody(7:9,i+1) = [sat1(1,i+1) sat1(2,i+1) sat1(3,i+1)]';

    % Write next line to the file
    fprintf2(f_twobody,'%06d\t%6d\t%3d\t%3d\t%3d\t%3d\t%3d\t%12.6f\t%12.6f\t%12.6f\n',i,Tbody(:,i+1));

    % Update plot
    addpoints(orbitsat1, sat1(1,i), sat1(2,i), sat1(3,i));
    drawnow update; hold off;

    % Check for collision
    Rorb = sqrt(sum(sat1(1:3,i+1).^2));
    Rcsc = sqrt(sum(sat2(1:3,i+1).^2));
    dif = abs(Rorb-Rcsc);
    %if (dif >0.5e10 && dif < 2e5) && i>350
    if sat1(1,i)>sat2(1,i) % Some kindof collision condition
        warning('Coliziune! %d/%d/%d %d:%d:%d',Tbody(1:6,i+1));
        fprintf(f_twobody,'Coliziune!\n');
        break % Break out of the for loop (use this instead of 'return')
    end
end

fclose(f_twobody); % Close the file



如果它们只有1个元素不同,为什么不排除绘图的最终
tspan
值呢?这只在发生碰撞的情况下有效,但如果卫星在一段时间内不会碰撞,那就不正确了。这是因为sat1=201(在没有碰撞的情况下)和tspan=201;您建议tspan=tspan-1;我会得到同样的错误。你的代码示例不起作用。它缺少
secundePeZi
msat1
Asat1
,然后在索引
simsat1
时抛出错误。之后可能会有错误,但我在这一点上放弃了尝试。执行以下操作;添加
全部关闭;清楚的clc行位于代码的最顶端。然后确保它运行并更新您的问题。我猜这段代码对您有效,因为您的工作区中已经有了所有这些变量。为了避免脚本之间的这种“串扰”,我建议总是将
全部关闭;清楚的clc在每段代码的开头。您是wright。我刚刚用A、m和函数对代码进行了改进。我不明白您的碰撞情况:
dif>0.5*10^10&&dif<2*10^5)&&I>350
dif
如何同时大于5e9和小于2e5??你确定你的
符号正确吗。也;您是否确定在前一行中不应该说
dif=abs(Rorb-Rcsc)?2.您提供的代码实际上不会产生您所说的冲突(也不会产生关于该问题的错误)。3.您的函数接受5个输入参数,但只使用一个参数--
sat1
sat2
。其他的显然是多余的,但是在您的代码中使用和变化…(?)工作得非常好。但是如果我想每秒钟积分一次,假设Tspan=200秒呢?另外,我在.txt文件中看到秒(second)是从秒+24s开始的,它在第一个时间步从0开始。有没有办法在第一步将init cond和seconds sec=sec+1的值改为0?我不确定你的算法是否适用于此,但原则上,您可以只设置
dt=1/3600
hours(即1s)。至于文件中的“sec”条目,它是由
datevec
生成的。文件中的第一个条目实际上是初始条件(有一个
fprintf
将其放在循环之前)。我还注意到我的代码中有一些错误(我假设
datevec
有秒的单位,但实际上它有天的单位。括号也是硬的…),所以我已经纠正了这些错误(参见上面的代码)。现在试一试。txt中的条目应该更有意义。
clear; close all; clc;
warning('on'); % Turn on warnings (Because they may be off)

figure(1);
orbitsat1 = animatedline('Color','r');

%% Initial conditions
msat1 = 124; msat2 = 234; Asat1 = 2.2; Asat2 = 3.2;

% Initialise satellites
sat10 = [453322.3616 -2346021.219 -7894131.349 2142.38067 7487.44895 -9864.00872];
sat20 = [543322.3616 -3246021.219 -8794131.349 1242.38067 4787.44895 -8964.00872];

dt = 1; % On hour timestep
nt = 200; % Number of timesteps
tspan = (0:nt)*dt; % Time from 0 to 200 timesteps in hours

% Make the time vectors
n1 = datenum(2018,1,2,12,0,0); % Starting point (serial date number in days)
n1 = n1 + tspan/24; % Timespan from hours -> days
[an,luna,zi,ora,min,sec] = datevec(n1);

%% Initialise containers
% Satelites
% nt+1 points because (:,1) is the initial condition
sat1 = zeros(6,nt+1); sat1(:,1) = sat10;
sat2 = zeros(6,nt+1); sat2(:,1) = sat20;

% Initialise Tbody here
Tbody = zeros(9,nt+1); Tbody(1:6,:) = [an; luna; zi; ora; min; sec];

%% Open the file
f_twobody = fopen('nobody.txt','w');
fprintf2(f_twobody,'Rezultate Twobody (metri)\n');
fprintf2(f_twobody,'Numar\tAn\tluna\tzi\tora\tmin\tsec\tpozitia_pe_x\tpozitia_pe_y\tpozitia_pe_z\n');
fprintf2(f_twobody,'%06d\t%6d\t%3d\t%3d\t%3d\t%3d\t%3d\t%12.6f\t%12.6f\t%12.6f\n',0,Tbody(:,1));

%% Go though all the timesteps
for i = 1:(nt-1)
    % Calculate timestep
    k_1 = simsat1(tspan(i), sat1(:,i), msat1, Asat1, sat1(4:6,i));
    k_2 = simsat1(tspan(i)+0.5*dt, sat1(:,i)+0.5*dt*k_1,msat1, Asat1, sat1(4:6,i));
    k_3 = simsat1(tspan(i)+0.5*dt, sat1(:,i)+0.5*dt*k_2,  msat1, Asat1, sat1(4:6,i));
    k_4 = simsat1(tspan(i)+dt, sat1(:,i)+k_3*dt, msat1, Asat1, sat1(4:6,i));

    k_12 = simsat2(tspan(i), sat2(:,i),  msat2, Asat2, sat2(4:6,i));
    k_22 = simsat2(tspan(i)+0.5*dt, sat2(:,i)+0.5*dt*k_12,  msat2, Asat2, sat2(4:6,i));
    k_32 = simsat2(tspan(i)+0.5*dt, sat2(:,i)+0.5*dt*k_22, msat2, Asat2, sat2(4:6,i));
    k_42 = simsat2(tspan(i)+dt, sat2(:,i)+k_32*dt, msat2, Asat2, sat2(4:6,i));

    sat2(:,i+1) = sat2(:,i) + (1/6)*(k_12+2*k_22+2*k_32+k_42)*dt;
    sat1(:,i+1) = sat1(:,i) + (1/6)*(k_1+2*k_2+2*k_3+k_4)*dt;

    % Put the calculated positions into Tbody
    Tbody(7:9,i+1) = [sat1(1,i+1) sat1(2,i+1) sat1(3,i+1)]';

    % Write next line to the file
    fprintf2(f_twobody,'%06d\t%6d\t%3d\t%3d\t%3d\t%3d\t%3d\t%12.6f\t%12.6f\t%12.6f\n',i,Tbody(:,i+1));

    % Update plot
    addpoints(orbitsat1, sat1(1,i), sat1(2,i), sat1(3,i));
    drawnow update; hold off;

    % Check for collision
    Rorb = sqrt(sum(sat1(1:3,i+1).^2));
    Rcsc = sqrt(sum(sat2(1:3,i+1).^2));
    dif = abs(Rorb-Rcsc);
    %if (dif >0.5e10 && dif < 2e5) && i>350
    if sat1(1,i)>sat2(1,i) % Some kindof collision condition
        warning('Coliziune! %d/%d/%d %d:%d:%d',Tbody(1:6,i+1));
        fprintf(f_twobody,'Coliziune!\n');
        break % Break out of the for loop (use this instead of 'return')
    end
end

fclose(f_twobody); % Close the file
function sat1prim = simsat1(t,sat1,msat1,Asat1,vit)
miu = 398600.4418e9;
magn = sum(sat1(1:3).^2)^(3/2);
sat1prim = zeros(6,1);
sat1prim(1:3) = sat1(4:6);
sat1prim(4:6) = -miu.*sat1(1:3)./magn;
end
function sat2prim = simsat2(t,sat2,msat2,Asat2,vit)
miu = 398600.4418e9;
magn = sum(sat2(1:3).^2)^(3/2);
sat2prim = zeros(6,1);
sat2prim(1:3) = sat2(4:6);
sat2prim(4:6) = -miu.*sat2(1:3)./magn;
end
function fprintf2(f,varargin)
% Write both to stdout (console) and file
fprintf(varargin{:}); fprintf(f,varargin{:});
end