该包提供了使用不同方法传播轨道状态的工具。
传播是从初始状态预测系统演化的过程。在Orekit中,初始状态由SpacecraftState
表示,它是一个简单的容器,包含所有所需的信息:轨道、质量、运动学、姿态、日期、参考系,还可以保存任意数量的用户自定义附加数据,例如电池状态或操作模式。
传播基于顶层的Propagation
接口(实际上扩展了PVCoordinatesProvider
接口)和多个实现。
根据调用应用程序的需求,传播器可以在初始时间和传播目标时间之间提供中间状态,或者仅提供最终状态。
中间状态:为了获得中间状态,用户需要在运行传播器之前向传播器注册一些实现了OrekitStepHandler
或OrekitFixedStephHandler
接口的自定义对象。当传播器计算航天器状态的演化时,它执行一些内部时间循环,并在每个完成的步骤调用这些步骤处理程序。用户通常在只有一个目标传播时间的情况下使用此模式,该时间表示最终日期的结束。应用程序的核心业务在于步骤处理程序,应用程序本身并不真正处理时间,而是让传播器来处理。
仅最终状态:当用户希望完全控制时间的演化时,使用此方法。应用程序提供目标时间,但没有任何步骤处理程序。传播器没有回调函数要执行,其内部循环对调用应用程序是不可见的。唯一的反馈是传播器在目标时间返回的最终状态。用户通常在循环中使用此模式,每个目标传播时间表示下一个小时间步长。
对于可以注册到传播器的步骤处理程序数量没有限制。每个传播器都包含一个多路复用器,可以接受多个步骤处理程序。步骤处理程序可以是OrekitFixedStepHandler
类型,它将在规则的时间间隔内被调用,并提供一个SpacecraftState
;或者可以是OrekitStepHandler
类型,它将在传播器根据其内部时间循环接受一个步骤时被调用(此时时间步长的持续时间可能会有所变化),并提供一个在整个步骤中有效的OrekitStepInterpolator
,从而提供密集输出。以下类图显示了这个架构。
Orekit在内部使用此机制来提供一些重要的功能,其中包括专门的内部步骤处理程序。例如,下面的类图显示了可以从传播器请求的EphemerisGenerator
是基于一个步骤处理程序的,该步骤处理程序将在传播过程中存储所有中间步骤。当用户需要在初始时间和目标时间之间的任何时间点上以任意顺序访问轨道状态时,可以使用传播器生成星历。一个典型的例子是在找到结果之前,搜索和迭代算法可能在传播范围内前后导航。
注意事项:请注意,此模式不支持修改航天器初始状态的事件。请注意,由于此模式存储了所有中间结果,对于长时间积分范围和高精度/短时间步长,可能会占用大量内存。
星历生成基于一个专门的步骤处理器,如下序列图所示,解释了为了生成星历,用户必须按顺序调用三个方法:
final EphemerisGenerator generator = propagator.getEphemerisGenerator();
propagator.propagate(start, end); // 这里我们忽略返回的最终状态
final BoundedPropagator = generator.getGeneratedEphemeris();
当然,由于可以同时使用多个步骤处理器,因此可以同时生成星历并设置其他执行其他计算的步骤处理器。
下面的序列图展示了处理不同速率的固定步长的多个步骤处理器的用例:一个高速率(即小步长)的处理器将详细信息记录在一个巨大的日志文件中,同时一个低速率(即大步长)的处理器用于在计算时间较长时向用户显示进度。
下一个序列图展示了用户想要在应用程序内部紧密控制时间循环的情况。在这种情况下,步骤处理器复用器被清除,多次调用传播器,并返回所请求目标时间的状态。
通过忽略步骤处理器,仅在指定的时间获取状态来在应用程序级别控制时间循环可能对大多数初次使用Orekit的用户来说更具吸引力和更自然。前一个类图比前一个类图更简单。事实上,时间管理复杂性的负担在用户一侧,而不是在Orekit一侧。因此,这不是推荐的使用传播的方式。
推荐的方式是注册步骤处理器,并将传播器仅调用一次,目标时间为研究的最终时间,让传播器执行时间循环。这非常简单易用,并允许用户摆脱关于同步力模型、文件输出、离散事件的担忧。所有这些部分在不同的用户代码部分中单独处理,Orekit负责所有管理。从用户的角度来看,使用步骤处理器可以使代码更简单易于维护,具有更小的独立部分。另一个重要的点是,让传播器管理时间循环可以选择比用户输出采样更大的积分步长,从而大大提高性能(一些实验显示性能提高了50倍,主要是在需要高速率输出时)。
所有的传播器,包括解析传播器,在传播过程中都支持离散事件处理。通过将事件探测器注册到传播器中,可以激活此功能。每个事件探测器都与一个事件处理器相关联,事件发生时将自动触发该事件处理器。下面的类图显示了用于事件处理的主要接口。
在每个传播步骤中,传播器会检查已注册的事件探测器是否发生了某个事件,如下面的序列图所示。如果发生了事件,则触发相应的操作,该操作可以通知传播器继续传播(可能带有更新后的状态)或停止传播。
使用更改后的状态继续传播的示例是ImpulseManeuver
类。当触发机动时,根据机动所关联的速度增量改变轨道,并根据消耗减少质量。这使得即使在基本传播器(如开普勒或Eckstein-Heschler)中,也可以透明地处理简单的机动。
当希望获得某个特定状态但其真实发生时间事先未知时,停止传播是有用的。一个典型的例子是找到下一个升交点或下一个远地点。在这种情况下,我们可以注册一个NodeDetector
或ApsideDetector
对象,并以未来很远的目标时间启动传播。当事件触发时,它会通知传播器停止,并返回事件发生时的状态。
用户可以定义自己的事件,通常通过扩展AbstractDetector
抽象类来实现。还有一些预定义的事件探测器可供使用,其中包括:
DateDetector
,在预定日期触发,可以在运行时重置以添加新的日期(这对于设置在前一个事件被检测到时开始延迟很有用)ElevationDetector
,在卫星相对于地面点的升起或落下时间触发,考虑大气折射,并且当阈值高度与方位角有关时,可以使用恒定高度或地面遮罩ElevationExtremumDetector
,在卫星相对于地面点的最大(或最小)高度触发AltitudeDetector
,在卫星越过预定高度限制时触发,可用于轻松计算操作预测FieldOfViewDetector
,在某个目标进入或离开卫星传感器视场(任何形状)时触发FootprintOverlapDetector
,在传感器视场(任何形状,甚至分割为非连接部分或包含孔洞)与地理区域重叠时触发,该区域可以是非凸的,分割为不同的子区域,具有孔洞,包含极点GeographicZoneDetector
,在航天器进入或离开区域时触发,该区域可以是非凸的,分割为不同的子区域,具有孔洞,包含极点GroundFieldOfViewDetector
,在航天器进入或离开地面视场时触发,该视场可以是非凸的,分割为不同的子区域,具有孔洞EclipseDetector
,在某个物体进入或离开另一个遮挡物的本影或半影时触发ApsideDetector
,在远地点和近地点触发NodeDetector
,在升交点和降交点触发PositionAngleDetector
,在卫星在轨道上的角度穿过某个值时触发(可以使用真近点角、纬度参数或经度参数以及真偏角、偏心角或平均角)LatitudeCrossingDetector
、LatitudeExtremumDetector
、LongitudeCrossingDetector
、LongitudeExtremumDetector
,在卫星相对于中心体的位置达到某些预定值时触发ExtremumApproachDetector
,在卫星与某个移动物体的距离达到局部最大值或最小值时触发AlignmentDetector
,在卫星和在轨道平面上投影的某个物体具有指定的角度分离时触发(术语AlignmentDetector
显然是一个误称,因为角度分离可能不为零)AngularSeparationDetector
,在卫星与观测者看到的某个信标之间的角度分离低于阈值时触发。信标通常是太阳,观测者通常是地面站AngularSeparationFromSatelliteDetector
,当两个移动物体从航天器上看起来靠近时触发FunctionalDetector
,根据用户提供的函数触发,可以是一个简单的lambda表达式GroundAtNightDetector
,在民用、航海或天文黄昏/黎明时触发(这对于安排地面望远镜的光学测量非常有用)HaloXZPlaneCrossingDetector
,当一个在环轨道上的航天器穿过XZ平面时触发IntersatDirectViewDetector
,当两个航天器直接可见时触发,即当中心天体的边缘加上可自定义的接触高度不会遮挡视线时MagneticFieldDetector
,当穿过南大西洋异常边界时触发ParameterDrivenDateIntervalDetector
,在时间间隔边界处触发,额外的特性是这些边界可以通过参数驱动器进行偏移还提供了一个EventShifter
,用于轻微地移动事件发生的时间。一个典型的用例是在某个物理事件真正发生之前或之后处理操作延迟。
当用户只对成对发生的一类事件感兴趣时,可以使用EventSlopeFilter
。例如,对于高度探测器的升起/设置对中的升起,或者对于日食探测器的进入/退出对中的日食进入。该过滤器不仅仅在检测到事件后忽略它们,而是在定位它们之前对它们进行过滤,从而通过不对最终将被忽略的事件进行精确搜索来节省一些计算时间。
当用户想要根据用户提供的启用谓词函数设置的外部条件来过滤掉一些事件时,可以使用EventEnablingPredicateFilter
。这允许例如在传播过程中动态地打开和关闭某些事件,或者设置一些复杂的逻辑,例如只在高度本身超过某个阈值时触发高度的第一导数(即一个高度最大值)。该过滤器不仅仅在检测到事件后忽略它们,而是在定位它们之前对它们进行过滤,从而通过不对最终将被忽略的事件进行精确搜索来节省一些计算时间。
提供了一个BooleanDetector
,用于使用布尔运算符and
、or
和not
组合多个其他探测器。这允许例如在卫星既可见于地面站又不在日食中时进行检测。
提供了一个NegateDetector
,用于对另一个探测器的切换函数g
的符号进行取反。
可以使用EventsLogger
类自动记录事件的发生。
所有的传播器都可以用于传播用户的附加状态,这些状态是在正常的轨道姿态和质量状态之上的。这些附加状态在整个传播过程中都是可用的,即它们可以在步骤处理器、事件检测器和事件处理器中使用,并且它们也可以在最终传播的状态中使用。有三种主要情况:
AdditionalStateProvider
接口的实现中,并将其注册到传播器中,传播器将在每次构建SpacecraftState
时调用它。AdditionalDerivativesProvider
接口的实现中,并将其注册到基于积分器的传播器中,传播器将对其进行积分并提供积分后的状态。前两种情况对应于传播器管理的附加状态,最后一种情况不被视为被管理的状态。可以使用getManagedAdditionalStates
和isAdditionalStateManaged
来获取传播器管理的状态列表。
下面的类图显示了可用的传播器
KeplerianPropagator
基于仅开普勒运动。它仅依赖于µ。
这个解析模型适用于近圆轨道,且倾角既不是赤道也不是临界。它考虑了J2到J6的势函数球谐系数,并使用平均参数计算新的位置。
需要注意的是,在7.0版本之前,生成的轨道存在较大的不一致性。从Orekit的7.0版本开始,这个问题已经修复,但有一个明显的副作用。问题在于,如果使用Eckstein-Hechler模型产生的圆形参数来构建一个被认为是游离的轨道,那么从这个轨道推导出的速度与位置的演化是不一致的!原因是该模型包括非开普勒效应,但没有包括相应的圆形/笛卡尔转换。因此,所有涉及速度的后续计算都是错误的。这包括偏航补偿和多普勒效应等姿态模式。由于这个效应被认为是严重的,并且准确的速度被认为是重要的,传播器现在生成的是笛卡尔轨道,这些轨道以一种特殊的方式构建,以确保整个传播过程的一致性。一个副作用是,如果用户从这些传播的笛卡尔轨道重新构建圆形参数,圆形参数通常不会与初始轨道匹配(半长轴的差异可能超过120米)。然而,位置将匹配到亚微米级别,并且这个位置将与之前版本生成的位置完全相同(换句话说,模型的内部没有改变,只是输出参数发生了变化)。初始化的正确性已经得到评估,并且是良好的,因为它使得后续轨道保持接近数值参考轨道。
如果用户需要更确定的Eckstein-Hechler传播器的初始化,他们应该考虑使用传播器转换器,使用完整的样本来初始化他们的Eckstein-Hechler传播器,而不仅仅是单个初始轨道。
与Eckstein-Hechler模型相反,Brouwer-Lyddane模型适用于椭圆轨道。换句话说,具有小(或大)离心率或倾角都没有问题。Lyddane通过将平近点角的长周期和短周期变化与平近点角参数的变化相加来解决了这个问题。仍然需要注意的是,离心率低于5e-4时会出现奇点。通过Warren Phipps在1992年的论文中开发的方法避免了临界倾角i = 63.4°的奇点。
Brouwer-Lyddane模型考虑了J2到J5的势函数球谐系数,并使用开普勒元素的平均值和短周期变化来计算位置。然而,对于低地球轨道,由大气阻力引起的摄动加速度的大小可能是显著的。Warren Phipps在1992年的论文中通过使用平均平近点角的时间导数来考虑大气阻力,其中使用了一个通用系数M2。通常,在轨道确定过程中调整M2,并且它代表了所有未建模的沿轨道效应的组合(即不仅仅是大气阻力)。M2的行为接近于TLE的B*参数。
有几个专用模型用于GNSS星座传播。这些模型通常由定期更新的导航消息或星载信号直接提供。支持所有导航星座(GPS、Galileo、GLONASS、Beidou、IRNSS、QZSS和SBAS)。
这个分析模型专门用于两行根数(TLE)传播。
这个模型用于给底层传播器添加一些它没有考虑到的效应。一个典型的例子是给预先计算的星历或参考轨道添加小的保持轨道的机动,而这些机动在计算时没有考虑到。这些附加机动可以同时考虑直接效应(开普勒部分)和由于J2引起的效应,例如当机动改变了太阳同步卫星的倾角或半长轴时,升交点速率会发生变化。
数值传播是Orekit项目中最重要的部分之一。基于Hipparchus普通微分方程积分器,NumericalPropagator
类实现了空间力学和数学解决方案之间的接口。尽管初次使用时可能看起来令人生畏,但实际上非常简单易用。
要积分的数学问题是一个七维时间导数方程系统。状态向量的前六个元素是轨道参数,可以是任何轨道类型(以米和弧度为单位的KeplerianOrbit
、CircularOrbit
、EquinoctialOrbit
或CartesianOrbit
),最后一个元素是质量(以千克为单位)。如果已经添加了AdditionalDerivativesProvider
(例如,内部类实现了AdditionalDerivativesProvider
以计算与传播参数相关的状态转移矩阵和雅可比矩阵),则状态向量中可以有更多的元素。Orekit会自动使用高斯方程计算与所选轨道类型对应的前几个参数的时间导数,并使用质量演化的流速计算质量的时间导数。用户只需要注册模拟所需的各种力模型。库中已经提供了各种力模型,用户还可以轻松地添加专门的力模型以满足特定需求。
Hipparchus提供的(一阶积分器)需要在t0时刻的状态向量、t0时刻的状态向量的一阶导数,然后计算下一个步长的状态向量,并请求下一个一阶导数,以此类推,直到达到所要求的最终日期。这些底层的数值积分器也可以进行配置。自适应步长积分器的典型调整参数包括最小步长、最大步长、初始步长以及绝对误差和/或相对误差阈值。以下代码片段展示了一个典型的低地球轨道传播设置:
// 步长限制
final double minStep = 0.001;
final double maxStep = 1000;
final double initStep = 60;
// 误差控制参数(绝对误差和相对误差)
final double positionError = 10.0;
final double[][] tolerances = NumericalPropagator.tolerances(positionError, orbit, orbit.getType());
// 设置数学积分器
AdaptiveStepsizeIntegrator integrator =
new DormandPrince853Integrator(minStep, maxStep, tolerances[0], tolerances[1]);
integrator.setInitialStepSize(initStep);
// 设置空间动力学传播器
propagator = new NumericalPropagator(integrator);
下面的序列图展示了数值传播期间触发的内部调用。需要注意的重要事项是,力模型与积分过程是解耦的,它们只需要计算加速度。
有时候,简单的运动方程是不够的。在轨迹之外,一些附加参数可能会很有用,比如最优控制中的双参数或雅可比矩阵(也称为状态转移矩阵)。对于计算轨迹相对于初始状态变化或力模型参数变化的敏感性,后一种情况尤其有用。
Orekit使用附加状态来处理这两种情况,可以通过附加导数提供器(对于NumericalPropagator
和DSSTPropagator
)进行积分,也可以通过解析计算(对于解析传播器)。当模型化需要积分导数时,相应的方程和状态不会用于步长控制,因此使用或不使用这些方程不应改变轨迹,并且不需要为它们设置容差。
上面的类图显示了在NumericalPropagator
的情况下如何计算偏导数。可以看到,所有传播器都提供了一种触发偏导数矩阵(状态转移矩阵和相对于参数的雅可比矩阵)计算的方法,用户可以调用一个不透明的MatrixHarvester
接口来从传播的状态中检索这些矩阵。在内部,NumericalPropagator
引用了一个包私有的该接口的实现,并且还使用了其他几个包私有类(StateTransitionMatrixGenerator
和IntegrableJacobianColumnGenerator
)来填充矩阵。这些辅助类实现了AdditionalDerivativesProvider
来模拟矩阵元素的演化,并传播与运动方程对应的主要方程集和与主要方程的雅可比矩阵对应的附加方程集。因此,这个附加方程集与主要方程集紧密相关,特别是依赖于所选的力模型。各种力模型直接将它们的贡献直接添加到主要方程集中,就像简单传播中一样。
半解析传播是解析传播和数值传播之间的中间方式。它保留了解析模型的速度和数值模型的准确性。半解析传播使用Draper半解析卫星理论(DSST)实现。
自版本7.0以来,已经实现并验证了平均元素运动方程模型和短周期项。
自版本10.0以来,半解析传播可用于传播运动方程和附加方程。
上面的类图显示了半解析传播的偏导数方程的设计。可以看出,该过程与数值传播非常相似。
自10.0版本以来,Orekit的所有传播器都有一个常规版本,它基于经典的实数(即双精度数)来传播状态,还有一个更通用的版本,它基于任何实现Hipparchus的CalculusFieldElement
接口的类来传播状态。这些类在支持实数域的所有操作(加法、减法、乘法、除法,以及直接和反三角函数、直接和反双曲函数、对数、幂、根等)方面模拟实数。
CalculusFieldElement
接口的一个非常重要的实现是DerivativeStructure
类,除了计算规范操作的结果(加法、乘法、sin、atanh等),还计算其导数,对任意数量的变量和任意导数阶数。例如,如果用户使用6个规范变量px、py、pz、vx、vy、vz来表示初始状态并执行传播计算。在所有生成的结果(最终位置、最终速度,以及Orekit计算的椭球体相对于椭球体的大地高度等)的情况下,可以检索其相对于6个规范变量的计算阶数的偏导数。因此,例如在步骤处理器中计算大地高度h时,还可以计算∂³h/∂px²∂vz或任何84个分量之一,这些分量在每个值(1个值、6个一阶导数、14个二阶导数、56个三阶导数)的阶数3上计算。DerivativeStructure
类还提供了泰勒展开,可以将结果准确地外推到接近的值。这是泰勒代数的一种实现。它在航天动力学中的两个主要用途是
Orekit的场传播器实现支持所有经典传播器的功能:传播模式、事件(所有事件检测器)、参考系转换、大地点。支持所有传播器和所有姿态模式。
然而,必须意识到计算规模的组合爆炸。对于p个导数参数和o阶数,对于每个值计算的组件数由二项式系数(o+p¦p)给出。例如,6个参数和6阶意味着在常规传播中的每个双精度数都将被924个场传播中的数字替换。这些数字在加法和减法中线性组合在一起,但在乘法和除法中是二次组合的。DerivativeStructure
类经过高度优化,但是高阶和高参数数量仍然具有固有的成本。
然而,一旦传播已经完成,例如在蒙特卡洛应用程序中评估泰勒展开是非常快速的。因此,即使传播最终比常规传播慢100倍,取决于导数的数量,只要我们评估几百个点,回报仍然非常重要。由于蒙特卡洛分析通常使用数千次评估,回报非常有趣。
CalculusFieldElement
接口的另一个重要实现是Tuple
类,它对元组的多个分量执行相同的操作,因此可以在一次运行中进行并行轨道传播。每个航天器对应元组的一个分量。第一个航天器(索引为0的分量)是参考航天器。
然而,有一个问题。在许多轨道传播的地方,有条件语句依赖于当前状态(例如,航天器是否在日食中或仍处于阳光下)。由于只允许做出单一选择,检查的结果基于参考航天器(即元组的第一个分量),并且根据此参考航天器选择条件分支。元组的其他分量所代表的航天器将遵循算法中的相同分支,即使它们可能不处于相同的条件下。这意味着使用Tuple
进行轨道传播仅适用于足够接近的航天器。这非常适合有限差分、编队飞行或共位置,但不适用于星座。