一、背景介绍
在本文介绍一个场景,五颗蓝方卫星和一颗红方卫星,在两个小时之内,使用神经网络等人工智能算法,实现一个轨道追踪的问题,其中接口输入是六颗卫星在J2000坐标系下的坐标,接口输出是该六颗卫星沿着自己速度方向施加的脉冲大小。下面开始创建仿真场景。
二、场景搭建
第一步:搭建STK场景,获取施加脉冲机动的时间片段,本文认为该卫星每5分钟进行一次计算,通过预测5分钟后的位置,来计算需要施加的脉冲。所以,根据(12)的方法,可以通过每5分钟更新一次卫星的MCS序列,来实现实时的控制。所以,首先获取时间片段,也就是每次更新的时间节点。代码如下:
%% 创建六颗卫星,五颗蓝方卫星,一颗红方卫星
clear;clc
uiApplication = actxGetRunningServer('STK12.application');
% Get our IAgStkObjectRoot interface
global root
root = uiApplication.Personality2;
checkempty = root.Children.Count;
if checkempty ~= 0root.CurrentScenario.Unloadroot.CloseScenario;
end
%% 根据你的需要设定场景的名称
root.NewScenario('lanjie');
StartTime = '01 Jan 2024 08:00:00.000'; % 场景开始时间
StopTime = '01 Jan 2024 10:00:00.000'; % 场景结束时间
root.ExecuteCommand(['SetAnalysisTimePeriod * "',StartTime,'" "',StopTime,'"']);
root.ExecuteCommand(' Animate * Reset');
Sat_Name='red';
satellite=root.CurrentScenario.Children.New('eSatellite', Sat_Name);
satellite.Propagator;
sma=7078.637;
Ecc=0;
Inc=20;
w=0;
RAAN=0;
TA=0;
satellite.SetPropagatorType('ePropagatorAstrogator');
satellite.Propagator;
root.ExecuteCommand(['Astrogator */Satellite/',Sat_Name,' SetValue MainSequence.SegmentList Initial_State Propagate']);
%% 初始化卫星参数
root.ExecuteCommand(['Astrogator */Satellite/',Sat_Name,' SetValue MainSequence.SegmentList.Initial_State.CoordinateType Modified Keplerian']);
root.ExecuteCommand(['Astrogator */Satellite/',Sat_Name,' SetValue MainSequence.SegmentList.Initial_State.InitialState.Epoch ',StartTime,' UTCG']);
root.ExecuteCommand(['Astrogator */Satellite/',Sat_Name,' SetValue MainSequence.SegmentList.Initial_State.InitialState.Keplerian.ElementType "Osculating"']);
root.ExecuteCommand(['Astrogator */Satellite/',Sat_Name,' SetValue MainSequence.SegmentList.Initial_State.InitialState.Keplerian.sma ',num2str(sma),' km']);
root.ExecuteCommand(['Astrogator */Satellite/',Sat_Name,' SetValue MainSequence.SegmentList.Initial_State.InitialState.Keplerian.ecc ',num2str(Ecc)]);
root.ExecuteCommand(['Astrogator */Satellite/',Sat_Name,' SetValue MainSequence.SegmentList.Initial_State.InitialState.Keplerian.inc ',num2str(Inc),' deg']);
root.ExecuteCommand(['Astrogator */Satellite/',Sat_Name,' SetValue MainSequence.SegmentList.Initial_State.InitialState.Keplerian.w ',num2str(w),' deg']);
root.ExecuteCommand(['Astrogator */Satellite/',Sat_Name,' SetValue MainSequence.SegmentList.Initial_State.InitialState.Keplerian.TA ',num2str(TA),' deg']);
root.ExecuteCommand(['Astrogator */Satellite/',Sat_Name,' SetValue MainSequence.SegmentList.Initial_State.InitialState.Keplerian.RAAN ',num2str(RAAN),' deg']);
%% 设置时间为2个小时,获取5分钟的时间片段
sat=root.CurrentScenario.Children.Item('red');
Propagate=sat.Propagator.MainSequence.Item(1);
Propagate.StoppingConditions.Item(0).Properties.Trip=7200;
root.ExecuteCommand(['Astrogator */Satellite/',Sat_Name,' RunMCS']);
data=root.ExecuteCommand(['Report_RM */Satellite/',Sat_Name,' Style "J2000 Position Velocity" TimePeriod "',StartTime,'" "',StopTime,'" TimeStep 300']);
Num=data.Count;
for i=1:Num-2struct=regexp(data.Item(i),',','split');Time{i}=struct{1};
end
式子最后获得的Time即为本文中每次更新的时间节点。
第二步:蓝、红方星的轨道高度随机分布在500~2000km的轨道高度,真近地点角随机分布在0~360°。由于人工智能算法还没有搭建起来。目前先固定六颗轨道卫星的轨道六根数。红方星的轨道六根数已经在第一步的代码给出,蓝方星也给出,每一次预报设置的时间为300s
%% 获取完片段后,将时间设置为5分钟
Propagate.StoppingConditions.Item(0).Properties.Trip=300;
root.ExecuteCommand(['Astrogator */Satellite/',Sat_Name,' RunMCS']);SatJ2000=zeros(6,6);%获取六颗卫星在5分钟后的位置
%% 获取5分钟后其在J2000坐标系下的位置
data=root.ExecuteCommand(['Report_RM */Satellite/',Sat_Name,' Style "J2000 Position Velocity" TimePeriod "',StartTime,'" "',Time{2},'" TimeStep 300']);
st=regexp(data.Item(2),',','split');
SatJ2000(6,1)=str2double(st{2});
SatJ2000(6,2)=str2double(st{3});
SatJ2000(6,3)=str2double(st{4});
SatJ2000(6,4)=str2double(st{5});
SatJ2000(6,5)=str2double(st{6});
SatJ2000(6,6)=str2double(st{7});%% ------------通过循环生成5颗蓝方卫星-----------
h=[500;600;700;800;900];%% 先按照确定高度来确定
TAA=[10;20;30;40;50];
for jj=1:5%% B卫星Sat_Name2=['blue',num2str(jj)];satellite2=root.CurrentScenario.Children.New('eSatellite', Sat_Name2);satellite2.Propagator;%% 500-2000km随机生成轨道高度 随机生成真近地点角sma=6378.137+h(jj);Ecc=0;Inc=20;w=0;RAAN=0;TA2=TAA(jj);satellite2.SetPropagatorType('ePropagatorAstrogator'); satellite2.Propagator;root.ExecuteCommand(['Astrogator */Satellite/',Sat_Name2,' SetValue MainSequence.SegmentList Initial_State Propagate']);%% 初始化卫星参数root.ExecuteCommand(['Astrogator */Satellite/',Sat_Name2,' SetValue MainSequence.SegmentList.Initial_State.CoordinateType Modified Keplerian']);root.ExecuteCommand(['Astrogator */Satellite/',Sat_Name2,' SetValue MainSequence.SegmentList.Initial_State.InitialState.Epoch ',StartTime,' UTCG']);root.ExecuteCommand(['Astrogator */Satellite/',Sat_Name2,' SetValue MainSequence.SegmentList.Initial_State.InitialState.Keplerian.ElementType "Osculating"']);root.ExecuteCommand(['Astrogator */Satellite/',Sat_Name2,' SetValue MainSequence.SegmentList.Initial_State.InitialState.Keplerian.sma ',num2str(sma),' km']);root.ExecuteCommand(['Astrogator */Satellite/',Sat_Name2,' SetValue MainSequence.SegmentList.Initial_State.InitialState.Keplerian.ecc ',num2str(Ecc)]);root.ExecuteCommand(['Astrogator */Satellite/',Sat_Name2,' SetValue MainSequence.SegmentList.Initial_State.InitialState.Keplerian.inc ',num2str(Inc),' deg']);root.ExecuteCommand(['Astrogator */Satellite/',Sat_Name2,' SetValue MainSequence.SegmentList.Initial_State.InitialState.Keplerian.w ',num2str(w),' deg']);root.ExecuteCommand(['Astrogator */Satellite/',Sat_Name2,' SetValue MainSequence.SegmentList.Initial_State.InitialState.Keplerian.TA ',num2str(TA2),' deg']);root.ExecuteCommand(['Astrogator */Satellite/',Sat_Name2,' SetValue MainSequence.SegmentList.Initial_State.InitialState.Keplerian.RAAN ',num2str(RAAN),' deg']);sat=root.CurrentScenario.Children.Item(Sat_Name2);Propagate=sat.Propagator.MainSequence.Item(1);Propagate.StoppingConditions.Item(0).Properties.Trip=300;root.ExecuteCommand(['Astrogator */Satellite/',Sat_Name2,' RunMCS']);data2=root.ExecuteCommand(['Report_RM */Satellite/',Sat_Name2,' Style "J2000 Position Velocity" TimePeriod "',StartTime,'" "',Time{2},'" TimeStep 300']);stt=regexp(data2.Item(2),',','split');SatJ2000(jj,1)=str2double(stt{2});SatJ2000(jj,2)=str2double(stt{3});SatJ2000(jj,3)=str2double(stt{4});SatJ2000(jj,4)=str2double(stt{5});SatJ2000(jj,5)=str2double(stt{6});SatJ2000(jj,6)=str2double(stt{7});
end
运行完后,STK生成了6颗卫星,打开每颗卫星的任务序列
可以看到前5分钟的卫星按照给定的初始轨道条件进行预报,并且这六颗卫星的数据值均记录在SatJ2000这个6*6的数组里,蓝方1星在8点05时的在J2000坐标系下位置速度为第一行对应的数据,蓝方2星为第二行,依此类推,最后一行为红星的位置速度。
第三步,根据人工智能等算法计算6颗卫星这个时刻沿着速度方向施加的脉冲大小,这里由于人工智能算法没有搭建出来,将23次施加脉冲策略提前给出,导入数据DeltaV,其中第一行对应的数据为蓝方1,2,3,4,5星,红星在8点05时刻施加的脉冲大小。
在STK中实现,首先清除掉原来8点-8点05的任务序列,将上一时刻SatJ2000中得到的六颗卫星8点05在J2000坐标系下的坐标作为初始状态,将脉冲加入,然后运行300s。然后记录下8点10分的各个卫星的状态,如此往复,记录下每个脉冲开始施加时的位置和速度。MATLAB编程实现的步骤,首先是将六个卫星的名字放在一个元胞数组里,将Sat作为一个1*24的元胞数组,其中的每个元素即为该时刻六个卫星的位置速度,初始时间为8点05。
SatList = root.ExecuteCommand('ShowNames * Class Satellite').Item(0);
SatName = regexp(SatList,' ','split');%匹配正则表达式
for m=1:6Name=SatName{m+1};index=strfind(Name,'Satellite/');NameSat{m}=Name(index+10:end);
end%% 对卫星进行批量操作
Sat=cell(length(Time)-1,1); %% 元胞数组 记录下每次机动前 六颗卫星在J2000坐标系下的位置坐标
for ss=1:length(Sat)Sat{ss}=zeros(6);
end
Sat{1}=SatJ2000;%第一个数组对应的时间为8:05,第二个数组对应的时间为8:10,第三个数组对应的时间为8:15,以此类推
第四步:创建一个循环,代码如下
%% 可以在这里设一个断点
for ii=1:length(Time)-2SatJ2000_2=Sat{ii+1};deltaV=DeltaV(ii,:);%% 按道理应该是通过神经网络计算 这一步for s=1:length(NameSat)Sat_Name=NameSat{s};Satellite=root.CurrentScenario.Children.Item(Sat_Name);Satellite.Propagator.MainSequence.RemoveAll;%% 清空MCS命令 然后添加一个初始条件 一个脉冲数 一个轨道转移root.ExecuteCommand(['Astrogator */Satellite/',Sat_Name,' SetValue MainSequence.SegmentList Initial_State Maneuver Propagate']);Initial=Satellite.Propagator.MainSequence.Item(0);Initial.CoordSystemName='CentralBody/Earth J2000';Initial.SetElementType('eVAElementTypeCartesian');Initial.OrbitEpoch=Time{ii+1};%% 将上一时刻记录的最后记录的位置,作为这个时刻的初始位置RVx=Sat{ii}(s,:);Initial.Element.X=RVx(1);Initial.Element.Y=RVx(2); Initial.Element.Z=RVx(3);Initial.Element.Vx=RVx(4);Initial.Element.Vy=RVx(5); Initial.Element.Vz=RVx(6);%% 然后将脉冲加入Maneuver=Satellite.Propagator.MainSequence.Item(1);Maneuver.Maneuver.AttitudeControl.DeltaVMagnitude=deltaV(s)/1000; %沿着速度脉冲施加方向Propagate=Satellite.Propagator.MainSequence.Item(2);Propagate.StoppingConditions.Item(0).Properties.Trip=300;root.ExecuteCommand(['Astrogator */Satellite/',Sat_Name,' RunMCS']);data3=root.ExecuteCommand(['Report_RM */Satellite/',Sat_Name,' Style "J2000 Position Velocity" TimePeriod "',Time{ii+1},'" "',Time{ii+2},'" TimeStep 300']);sstt=regexp(data3.Item(2),',','split');SatJ2000_2(s,1)=str2double(sstt{2});SatJ2000_2(s,2)=str2double(sstt{3});SatJ2000_2(s,3)=str2double(sstt{4});SatJ2000_2(s,4)=str2double(sstt{5});SatJ2000_2(s,5)=str2double(sstt{6});SatJ2000_2(s,6)=str2double(sstt{7});endSat{ii+1}=SatJ2000_2;%% 在这里设置断点也能看
end
设置断点观测,当ii=1时,这个时候的Sat第一个元素即为8点05时刻的六颗卫星的位置和速度。这个时候六颗卫星的MCS序列如图所示,以蓝星1为例
记录下该卫星在8点10分的位置速度,写入Sat的第二个元素里面的矩阵