STK与matlab交互 Astrogator模块(13)

一、背景介绍

在本文介绍一个场景,五颗蓝方卫星和一颗红方卫星,在两个小时之内,使用神经网络等人工智能算法,实现一个轨道追踪的问题,其中接口输入是六颗卫星在J2000坐标系下的坐标,接口输出是该六颗卫星沿着自己速度方向施加的脉冲大小。下面开始创建仿真场景。

二、场景搭建

第一步:搭建STK场景,获取施加脉冲机动的时间片段,本文认为该卫星每5分钟进行一次计算,通过预测5分钟后的位置,来计算需要施加的脉冲。所以,根据(12)的方法,可以通过每5分钟更新一次卫星的MCS序列,来实现实时的控制。所以,首先获取时间片段,也就是每次更新的时间节点。代码如下:

Matlab 复制代码
%% 创建六颗卫星,五颗蓝方卫星,一颗红方卫星
clear;clc
uiApplication = actxGetRunningServer('STK12.application');
% Get our IAgStkObjectRoot interface
global root
root = uiApplication.Personality2;
checkempty = root.Children.Count;
if checkempty ~= 0
    root.CurrentScenario.Unload
    root.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-2
    struct=regexp(data.Item(i),',','split');
    Time{i}=struct{1};
end

式子最后获得的Time即为本文中每次更新的时间节点。

第二步:蓝、红方星的轨道高度随机分布在500~2000km的轨道高度,真近地点角随机分布在0~360°。由于人工智能算法还没有搭建起来。目前先固定六颗轨道卫星的轨道六根数。红方星的轨道六根数已经在第一步的代码给出,蓝方星也给出,每一次预报设置的时间为300s

Matlab 复制代码
%% 获取完片段后,将时间设置为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。

Matlab 复制代码
SatList = root.ExecuteCommand('ShowNames * Class Satellite').Item(0);
SatName = regexp(SatList,' ','split');%匹配正则表达式
for m=1:6
    Name=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,以此类推

第四步:创建一个循环,代码如下

Matlab 复制代码
%% 可以在这里设一个断点
for ii=1:length(Time)-2
    SatJ2000_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});

    end
    Sat{ii+1}=SatJ2000_2;%% 在这里设置断点也能看
end

设置断点观测,当ii=1时,这个时候的Sat第一个元素即为8点05时刻的六颗卫星的位置和速度。这个时候六颗卫星的MCS序列如图所示,以蓝星1为例

记录下该卫星在8点10分的位置速度,写入Sat的第二个元素里面的矩阵

相关推荐
_祝你今天愉快2 分钟前
技术成神之路:设计模式(十四)享元模式
java·设计模式
ice___Cpu2 分钟前
Linux 基本使用和 web 程序部署 ( 8000 字 Linux 入门 )
linux·运维·前端
JYbill5 分钟前
nestjs使用ESM模块化
前端
加油吧x青年23 分钟前
Web端开启直播技术方案分享
前端·webrtc·直播
小筱在线40 分钟前
SpringCloud微服务实现服务熔断的实践指南
java·spring cloud·微服务
luoluoal1 小时前
java项目之基于Spring Boot智能无人仓库管理源码(springboot+vue)
java·vue.js·spring boot
ChinaRainbowSea1 小时前
十三,Spring Boot 中注入 Servlet,Filter,Listener
java·spring boot·spring·servlet·web
吕彬-前端1 小时前
使用vite+react+ts+Ant Design开发后台管理项目(二)
前端·react.js·前端框架
小游鱼KF1 小时前
Spring学习前置知识
java·学习·spring
扎克begod1 小时前
JAVA并发编程系列(9)CyclicBarrier循环屏障原理分析
java·开发语言·python