java
复制代码
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.hipparchus.util.FastMath;
import org.orekit.bodies.GeodeticPoint;
import org.orekit.bodies.OneAxisEllipsoid;
import org.orekit.data.DataProvidersManager;
import org.orekit.data.DirectoryCrawler;
import org.orekit.data.DataContext;
import org.orekit.estimation.measurements.AngularRaDec;
import org.orekit.estimation.measurements.GroundStation;
import org.orekit.estimation.measurements.ObservableSatellite;
import org.orekit.frames.Frame;
import org.orekit.frames.FramesFactory;
import org.orekit.frames.Transform;
import org.orekit.frames.TopocentricFrame;
import org.orekit.orbits.CartesianOrbit;
import org.orekit.orbits.KeplerianOrbit;
import org.orekit.orbits.Orbit;
import org.orekit.orbits.OrbitType;
import org.orekit.orbits.PositionAngleType;
import org.orekit.propagation.Propagator;
import org.orekit.propagation.analytical.KeplerianPropagator;
import org.orekit.time.AbsoluteDate;
import org.orekit.time.DateComponents;
import org.orekit.time.TimeScale;
import org.orekit.time.TimeScalesFactory;
import org.orekit.utils.IERSConventions;
import org.orekit.utils.TimeStampedPVCoordinates;
import org.orekit.utils.PVCoordinates;
import org.orekit.utils.Constants;
import java.io.File;
import java.util.List;
import java.util.ArrayList;
public class AngularRaDecTest {
// 静态初始化块,在类加载时初始化Orekit
static {
initOrekit();
}
// 常量定义
private static final double TIME_STEP = 60.0; // 1分钟
private static final double TOLERANCE = 1.0e-3;
private static final double MU = Constants.IERS2010_EARTH_MU;
private static final Frame INERTIAL_FRAME = FramesFactory.getEME2000();
private static final Frame ecefFrame = FramesFactory.getITRF(IERSConventions.IERS_2010, true); //地固系
private static final TimeScale UTC = TimeScalesFactory.getUTC();
// 创建地球参考椭球体(WGS84标准)
private static final OneAxisEllipsoid earth = new OneAxisEllipsoid(
Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
Constants.WGS84_EARTH_FLATTENING,
FramesFactory.getITRF(IERSConventions.IERS_2010, true) // ITRF2000框架
);
/**
* 初始化Orekit环境
*/
private static void initOrekit() {
try {
// 设置Orekit数据路径
String userHome = System.getProperty("user.home");
String orekitDataPath = userHome + File.separator + "orekit-data";
System.out.println("orekit-data:" + orekitDataPath);
File orekitData = new File(orekitDataPath);
if (!orekitData.exists()) {
System.err.println("警告: orekit-data目录不存在");
System.err.println("请从https://gitlab.orekit.org/orekit/orekit-data下载数据");
// 创建目录供用户放置数据
orekitData.mkdirs();
}
// 初始化数据提供者
DataProvidersManager manager = DataContext.getDefault().getDataProvidersManager();
manager.addProvider(new DirectoryCrawler(orekitData));
System.out.println("Orekit初始化完成");
} catch (Exception e) {
System.err.println("Orekit初始化警告: " + e.getMessage());
}
}
public static void main(String[] args) {
System.out.println("\n测试3: 星对星用例1");
AbsoluteDate startDate = new AbsoluteDate(2024, 1, 1, 0, 0, 0.0, UTC);
int stepSizeSeconds = 60;
KeplerianOrbit orbitA = new KeplerianOrbit(6678137, 0, 98, 0, 0, 0,
org.orekit.orbits.PositionAngleType.MEAN, INERTIAL_FRAME, startDate, MU);
KeplerianOrbit orbitB = new KeplerianOrbit(16378137, 0.3,
Math.toRadians(28),
Math.toRadians(20),
Math.toRadians(40),
Math.toRadians(60),
org.orekit.orbits.PositionAngleType.MEAN, INERTIAL_FRAME, startDate, MU);
test(orbitA, orbitB, startDate, stepSizeSeconds);
}
//卫星对卫星
//@para orbitA 观测卫星开普勒根数
//@para orbitB 目标卫星开普勒根数
//@para startDate 起始观测时刻
//@para stepSizeSeconds 单位为秒的步长
public static void test(KeplerianOrbit orbitA, KeplerianOrbit orbitB, AbsoluteDate startDate, int stepSizeSeconds)
{
KeplerianPropagator propagatorA = new KeplerianPropagator(orbitA);
KeplerianPropagator propagatorB = new KeplerianPropagator(orbitB);
List<PVCoordinates> pvListA = new ArrayList<PVCoordinates>(3);
List<PVCoordinates> pvListB = new ArrayList<PVCoordinates>(3);
List<AbsoluteDate> dateList = new ArrayList<AbsoluteDate>(3);
for (int index = 0; index < 3; index++)
{
AbsoluteDate currentDate = startDate.shiftedBy(index * stepSizeSeconds);
PVCoordinates pvA = propagatorA.getPVCoordinates(currentDate, INERTIAL_FRAME);
PVCoordinates pvB = propagatorB.getPVCoordinates(currentDate, INERTIAL_FRAME);
dateList.add(currentDate);
pvListA.add(pvA);
pvListB.add(pvB);
}
// 计算目标相对于移动观测站的赤经赤纬
AngularRaDec azEl1 = calculateAngularRaDec(pvListA.get(0).getPosition(), pvListB.get(0).getPosition(), dateList.get(0));
AngularRaDec azEl2 = calculateAngularRaDec(pvListA.get(1).getPosition(), pvListB.get(1).getPosition(), dateList.get(1));
AngularRaDec azEl3 = calculateAngularRaDec(pvListA.get(2).getPosition(), pvListB.get(2).getPosition(), dateList.get(2));
}
/**
* 计算从观测点A到目标B的视方向赤经赤纬(输入惯性系)
*
* @param ax 观测点A的X坐标 (km)
* @param ay 观测点A的Y坐标 (km)
* @param az 观测点A的Z坐标 (km)
* @param bx 目标点B的X坐标 (km)
* @param by 目标点B的Y坐标 (km)
* @param bz 目标点B的Z坐标 (km)
* @return 包含赤经(度)和赤纬(度)的数组 [RA, Dec]
*/
public static double[] calculateRaDec(Vector3D A, Vector3D B) {
double ax = A.getX();
double ay = A.getY();
double az = A.getZ();
double bx = B.getX();
double by = B.getY();
double bz = B.getZ();
// 计算从A到B的方向向量
double dx = bx - ax;
double dy = by - ay;
double dz = bz - az;
// 计算方向向量的模
double magnitude = Math.sqrt(dx*dx + dy*dy + dz*dz);
// 归一化方向向量
double ux = dx / magnitude;
double uy = dy / magnitude;
double uz = dz / magnitude;
// 计算赤纬 (arcsin(z))
double dec = Math.asin(uz);
// 计算赤经 (arctan2(y, x))
double ra = Math.atan2(uy, ux);
// 将赤经转换到 [0, 2π) 范围
if (ra < 0) {
ra += 2 * Math.PI;
}
return new double[]{ra, dec};
}
private static AngularRaDec calculateAngularRaDec(Vector3D observerPos, Vector3D targetPos, AbsoluteDate date)
{
//从惯性系转大地坐标系经纬高
GeodeticPoint observerLLA = earth.transform(observerPos, INERTIAL_FRAME, date);
// 创建站心坐标系
TopocentricFrame topocentricFrame = new TopocentricFrame(earth, observerLLA, "observerStation");
// 构造地面站对象
GroundStation station = new GroundStation(topocentricFrame);
// 观测角度计算
double[] angular = calculateRaDec(observerPos, targetPos);
// 标准差:假设方位角测量标准差, 单位为弧度
double[] sigma = new double[]{Math.toRadians(0.0), Math.toRadians(0.0)};
// 基础权重:这里可以设置为1,或者根据实际情况计算,例如使用方差的倒数
double[] baseWeight = new double[]{1.0, 1.0};
// 被观测的卫星
ObservableSatellite satellite = new ObservableSatellite(0); // 通常使用索引0
// 创建AngularRaDec对象
AngularRaDec angRaDec = new AngularRaDec(station, INERTIAL_FRAME, date, angular, sigma, baseWeight, satellite);
return angRaDec;
}
}