Orekit 学习笔记(一)——Attitude

2,476 阅读4分钟

写在前面

最近接触了卫星通信相关的业务,其中接触到了Java开发的飞行动力学库 Orekit, 虽然利用他的 API 完成了一些业务,但对其原理和其设计并不是特别理解,所以打算根据其教程边学习边记录笔记,第一篇就是从 Attitude 开始。其教程的源码 Orekit-tutorials

Earth Observation

轨道定义

这里我利用真实卫星轨道两行轨道根数定义轨道(TLE),后面到轨道篇之后会专门介绍 TLE 数据,获取 TLE 数据可以从 NORAD 网站下载到。

//定义初始化日期
final AbsoluteDate initDate = new AbsoluteDate(2022, 11, 3, 13, 0, 00.000, TimeScalesFactory.getUTC());
//采用 STARLINK-1016 卫星定义轨道
final String line1 = "1 44722U 19074K   22306.13064920  .00001350  00000+0  10954-3 0  9998";
final String line2 = "2 44722  53.0549 279.3841 0001884  44.5577 315.5564 15.06391807164509";
TLE tle = new TLE(line1, line2);
TLEPropagator tlePropagator = TLEPropagator.selectExtrapolator(tle);
//这里定义开普勒轨道
final Orbit initOrbit = new KeplerianOrbit(tlePropagator.getPVCoordinates(initDate),FramesFactory.getEME2000(), initDate, Constants.EIGEN5C_EARTH_MU);
//太阳坐标及坐标系
final PVCoordinatesProvider sun = CelestialBodyFactory.getSun();
//定义地球,J2000坐标系下
final OneAxisEllipsoid earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,Constants.WGS84_EARTH_FLATTENING, FramesFactory.getITRF(IERSConventions.IERS_2010, true));

卫星姿态定义

卫星姿态的定义实际上就是 Local Frames 定义,对于卫星物体坐标系一般采用 LVLH(Local Vertical, Local Horizontal frame) .

  • Z 轴从卫星指向地心
  • Y 轴垂直轨道平面,指向轨道面外侧
  • X 轴是 Y 轴 Z 轴叉乘,满足右手坐标系

lvlh.gif

// Attitudes sequence definition
// 白天观察地球的姿态,Orekit Local Frame 还可以定义旋转角 Pitch(x),Yaw(y),Roll(z),
final AttitudeProvider dayObservationLaw = new LofOffset(initOrbit.getFrame(), LOFType.VVLH, RotationOrder.XYZ, FastMath.toRadians(20), FastMath.toRadians(40), 0);
// 夜晚休息的姿态
final AttitudeProvider nightRestingLaw = new LofOffset(initOrbit.getFrame(), LOFType.VVLH);

roll_pitch_yaw.png

昼夜变化探测

关于事件定义和事件探测的设计,后续再深入展开,这里就姑且先看一下教程的实现逻辑,检测卫星飞行过程中的昼夜变化。

//Sun's radius=696000000m
//定义白天到夜晚的探测事件
final EventDetector dayNightEvent = new EclipseDetector(sun, 696000000., earth).withHandler(new ContinueOnEvent<EclipseDetector>());
//定义黑夜到白天的探测事件
final EventDetector nightDayEvent = new EclipseDetector(sun, 696000000., earth).withHandler(new ContinueOnEvent<EclipseDetector>());
​
final AttitudesSequence attitudesSequence = new AttitudesSequence();
final AttitudesSequence.SwitchHandler switchHandler =
  (preceding, following, s) -> {
    if (preceding == dayObservationLaw) {
      output.add(s.getDate() + ": switching to night law");
    } else {
      output.add(s.getDate() + ": switching to day law");
    }};
​
//添加昼夜切换的条件
attitudesSequence.addSwitchingCondition(dayObservationLaw, nightRestingLaw, dayNightEvent, false, true, 10.0, AngularDerivativesFilter.USE_R, switchHandler);
attitudesSequence.addSwitchingCondition(nightRestingLaw, dayObservationLaw, nightDayEvent, true, false, 10.0, AngularDerivativesFilter.USE_R, switchHandler);
if (dayNightEvent.g(new SpacecraftState(initOrbit)) >= 0) {
  // initial position is in daytime
  attitudesSequence.resetActiveProvider(dayObservationLaw);
} else {
  // initial position is in nighttime
  attitudesSequence.resetActiveProvider(nightRestingLaw);
}

轨道传播模型(Oribit propagation models)

轨道传播模型有 Keplerian model (effect of central force),Secular J2 model (secular effects due to J2),Eckstein-Hechler model,Lyddane model,对于这几种轨道传播模型以及什么是轨道传播模型,后续介绍 Propagation 专题中会介绍。

轨道传播模型主要用来进行卫星在轨道内进行事件探测。

// Propagator : consider the analytical Eckstein-Hechler model
final Propagator propagator = new EcksteinHechlerPropagator(initOrbit, attitudesSequence,
                                                            Constants.EIGEN5C_EARTH_EQUATORIAL_RADIUS,
                                                            Constants.EIGEN5C_EARTH_MU,
                                                            Constants.EIGEN5C_EARTH_C20,
                                                            Constants.EIGEN5C_EARTH_C30, 
                                                            Constants.EIGEN5C_EARTH_C40,
                                                            Constants.EIGEN5C_EARTH_C50,
                                                            Constants.EIGEN5C_EARTH_C60);
// Register the switching events to the propagator
attitudesSequence.registerSwitchEvents(propagator);
propagator.getMultiplexer().add(180.0, currentState -> {
                final DecimalFormatSymbols angleDegree = new DecimalFormatSymbols(Locale.US);
                angleDegree.setDecimalSeparator('\u00b0');
                final DecimalFormat ad = new DecimalFormat(" 00.000;-00.000", angleDegree);
                // the Earth position in spacecraft frame should be along spacecraft Z axis
                // during nigthtime and away from it during daytime due to roll and pitch offsets
                final Vector3D earthDir = currentState.toTransform().transformPosition(Vector3D.ZERO);
                final double pointingOffset = Vector3D.angle(earthDir, Vector3D.PLUS_K);
​
                // the g function is the eclipse indicator, it is an angle between Sun and Earth limb,
                // positive when Sun is outside of Earth limb, negative when Sun is hidden by Earth limb
                final double eclipseAngle = dayNightEvent.g(currentState);
​
                output.add(currentState.getDate() +
                        " " + ad.format(FastMath.toDegrees(eclipseAngle)) +
                        " " + ad.format(FastMath.toDegrees(pointingOffset)));
});
​
final AbsoluteDate targetDate = new AbsoluteDate(2022, 11, 3, 15, 0, 00.000, TimeScalesFactory.getUTC());
final SpacecraftState finalState = propagator.propagate(targetDate);
​

结果验证

查看北京时间11月3号21点-23点的昼夜过境事件

// we print the lines according to lexicographic order, which is chronological order here
// to make sure out of orders calls between step handler and event handlers don't mess things up
for (final String line : output) {
    System.out.println(line);
}
System.out.println("Propagation ended at " + finalState.getDate());

结果发现在北京时间 21:25:33 卫星可观测地球的白天、22:27:33卫星观测地球的黑夜

2022-11-03T13:25:33.36915618048181Z: switching to day law
2022-11-03T14:27:33.2701364307041Z: switching to night law

我们利用依据 TLE 绘制该时刻的星下轨迹点,计算出卫星在上述两个时间的星下点:

  • 2022-11-03T13:25:34,卫星的位置为(lng:-142.5413,lat:-11.5357)
  • 2022-11-03T14:27:34,卫星的位置为(lng:68.8998,lat:47.9302)

通过 Earth View (fourmilab.ch) 进行卫星位置昼夜观察。

2022-11-03T13:25:34 如图所示卫星所在位置可以看到白天即将到来,卫星可以调整为工作拍摄姿态

image-20221109220007884.png

2022-11-03T14:27:34 如图所示卫星位置可以看到夜晚降临,卫星可以收起拍摄姿态进入休息姿态

image.png