Orekit生成AngularRaDec观测数据

1、简要

  • 本文基于Orekit生成初轨确定用的观测数据类对象AngularRaDec,实测表明AngularRaDec并不局限于地面站观测的赤经赤纬数据,对于地面移动站(车、船、飞机等)、天基(卫星)都是支持的。
  • 以下根据一个卫星观测另外一个卫星的场景生成观测数据,适用最简单的二体模型进行预报。

2、示例代码(编译运行通过)

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;
	}
	
}

3、环境配置

XML 复制代码
        <!-- Orekit核心库 -->
        <dependency>
            <groupId>org.orekit</groupId>
            <artifactId>orekit</artifactId>
            <version>12.2</version>
        </dependency>
        <!-- 数学库 -->
        <dependency>
            <groupId>org.hipparchus</groupId>
            <artifactId>hipparchus-core</artifactId>
            <version>4.0</version>
        </dependency>
相关推荐
青云计划8 小时前
知光项目知文发布模块
java·后端·spring·mybatis
赶路人儿8 小时前
Jsoniter(java版本)使用介绍
java·开发语言
探路者继续奋斗9 小时前
IDD意图驱动开发之意图规格说明书
java·规格说明书·开发规范·意图驱动开发·idd
消失的旧时光-194310 小时前
第十九课:为什么要引入消息队列?——异步系统设计思想
java·开发语言
A懿轩A10 小时前
【Java 基础编程】Java 面向对象入门:类与对象、构造器、this 关键字,小白也能写 OOP
java·开发语言
乐观勇敢坚强的老彭10 小时前
c++寒假营day03
java·开发语言·c++
biubiubiu070610 小时前
谷歌浏览器无法访问localhost:8080
java
大黄说说11 小时前
新手选语言不再纠结:Java、Python、Go、JavaScript 四大热门语言全景对比与学习路线建议
java·python·golang
烟沙九洲11 小时前
Java 中的 封装、继承、多态
java
识君啊11 小时前
SpringBoot 事务管理解析 - @Transactional 的正确用法与常见坑
java·数据库·spring boot·后端