【Java】读取单颗北斗卫星导航星历文件进行卫星位置计算(RENIX3.04)

该文章是【python】读取卫星星历(RENIX 3.04)进行卫星位置的计算(北斗卫星专题)​​​​​​

一个其他语言实现的一个副本,其中可以计算出北斗GEO卫星的位置,进行检校。

其中文件的读取仍需要进行一定的格式,我是按照一个数据中间使用空格隔开的方法进行的文件读取,所以由于工作量的原因,比较适合单颗卫星的检校工作。

首先,是所需文件的准备工作。

这是准备文件,数据通过空格进行分割。

其次为代码结构。

代码结构为 location类内置函数read()方法和calculation()方法,其中read()方法负责对文件中的数据进行读取,然后存储到相应的成员变量中;calculation()方法是进行对所读取的数据进行计算,输出时,以字符串形式输出,格式如下。

"卫星:" + this.satellite + ",长半径:" + a + ",平均角速度:" + n0
                + ",\n偏近点角:" + Ek + ",真近点角" + vk + ",升交角据:" + uk
                + ",\n改正赤经:" + u + ",改正半径:" + r + ",改正轨道倾角:" + i
                + ",\n卫星在轨道上的位置(" + x + "," + y + "),赤纬:" + lambda
                + ",\n卫星在BDCS坐标系的坐标:(" + x_R + "," + y_R + "," + z_R + ")\n\n";

read()方法:

public void read(){
        ArrayList<String> arr=new ArrayList<String>();
        ArrayList<String> arr1=new ArrayList<String>();
        String str[]=new String[36];
        try{

            Scanner sc=new Scanner(new File(address1));
            while (sc.hasNextLine()) {
                str = sc.nextLine().split(" ");

                for(int i=0;i<str.length;i++){

                    arr.add(str[i]);
                }
            }
        }catch(FileNotFoundException e){
            e.printStackTrace();
        }
        for (int i = 0; i <arr.size(); i++) {
            if (arr.get(i)!=null&&!arr.get(i).equals("")){
                arr1.add(arr.get(i));
            }
        }
        this.satellite=arr1.get(0);
        this.IODE=Double.parseDouble(arr1.get(10));
        //System.out.println("这是IODE:"+this.IODE);
        //Crs
        this.Crs=Double.parseDouble(arr1.get(11));
        //System.out.println("这是Crs:"+this.Crs);
        //角速度改正数
        this.delta_n=Double.parseDouble(arr1.get(12));
        //参考时刻的平近点角
        this.M0=Double.parseDouble(arr1.get(13));
        //Cuc
        this.Cuc=Double.parseDouble(arr1.get(14));
        //偏心率
        this.e=Double.parseDouble(arr1.get(15));
        //Cus
        this.Cus=Double.parseDouble(arr1.get(16));
        //长半轴的开方
        this.sqrt_a=Double.parseDouble(arr1.get(17));
        //toe
        this.toe=Double.parseDouble(arr1.get(18));
        //Cic
        this.Cic=Double.parseDouble(arr1.get(19));
        //参考时刻的升交点赤经
        this.OMG0=Double.parseDouble(arr1.get(20));
        //Cis
        this.Cis=Double.parseDouble(arr1.get(21));
        //参考时刻的轨道倾角
        this.i0=Double.parseDouble(arr1.get(22));
        //Crc
        this.Crc=Double.parseDouble(arr1.get(23));
        //参考时刻的近地点角距
        this.omg=Double.parseDouble(arr1.get(24));
        //升交点赤经变化率
        this.OMG0_DOT=Double.parseDouble(arr1.get(25));
        //轨道倾角变化率
        this.IDOT=Double.parseDouble(arr1.get(26));

        //toc 时钟时间的周内秒
        Integer year=Integer.parseInt(arr1.get(1));
        Integer month=Integer.parseInt(arr1.get(2));
        Integer date=Integer.parseInt(arr1.get(3));
        Integer hour=Integer.parseInt(arr1.get(4));
        Integer minu=Integer.parseInt(arr1.get(5));
        Integer sec=Integer.parseInt(arr1.get(6));
        LocalDateTime time=LocalDateTime.of(year, month, date, hour, minu, sec);
        Date dtTime=Date.from(time.atZone(ZoneId.systemDefault()).toInstant());
        Long timeSec=dtTime.getTime();
        //BDT起始时间 2006年1月1日0时0分0秒 星期日
        LocalDateTime time0=LocalDateTime.of(2006,1,1,0,0,0);
        Date dtTime0=Date.from(time0.atZone(ZoneId.systemDefault()).toInstant());
        Long time0Sec=dtTime0.getTime();
        //求toc 时钟时间
        Long toc=((timeSec-time0Sec)/1000)%(604800);
        System.out.println("toc="+toc);

        //钟差参数 a0,a1,a2
        Double a0=Double.parseDouble(arr1.get(7));
        Double a1=Double.parseDouble(arr1.get(8));
        Double a2=Double.parseDouble(arr1.get(9));
        //设置观测时间为每分钟的第13秒
        Long t0=toc;
        LocalDateTime time_ob=LocalDateTime.of(year, month, date, hour, minu, sec);
        Double dt=a0+a1*(t0-toc)+a2*Math.pow((t0-toc), 2);
        this.t=t0-dt;
        System.out.print("观测时间:"+time_ob+"\n");
        System.out.print(calculateLocation());


    }

calculation()方法:

 public String calculateLocation() {
        //长半径
        double a = Math.pow(this.sqrt_a, 2);
        //地球重力常数
        double constGM = 3.986004418e14;
        //平均角速度
        double n0 = Math.sqrt(constGM / Math.pow(a, 3));
        double n = n0 + this.delta_n;
        //平近点角
        Double tk = this.t - this.toe;
        double Mk = this.M0 + n * (this.t - this.toe);
        //偏近点角
        double Ek0 = 0;
        double Ek1 = Mk;
        while (Math.abs(Ek1 - Ek0) > 10e-12) {
            Ek0 = Ek1;
            Ek1 = Mk + this.e * Math.sin(Ek0);
        }
        double Ek = Ek0;
        //真近点角
        double vk = Math.acos((Math.cos(Ek) - this.e) / (1 - this.e * Math.cos(Ek)));
        //升交角距
        double uk = vk + this.omg;
        //扰动改正
        double delta_uk = this.Cuc * Math.cos(2 * uk) + this.Cus * Math.sin(2 * uk);
        double delta_rk = this.Crc * Math.cos(2 * uk) + this.Crs * Math.sin(2 * uk);
        double delta_ik = this.Cic * Math.cos(2 * uk) + this.Cis * Math.sin(2 * uk);
        //赤经 半径 轨道倾角改正
        double u = uk + delta_uk;
        double r = a * (1 - this.e * Math.cos(Ek)) + delta_rk;
        double i = this.i0 + delta_ik+this.IDOT*tk;
        //卫星在轨道上的位置
        double x = r * Math.cos(u);
        double y = r * Math.sin(u);
        //地球自转角速度
        double omge = 7.292115e-5;
        //历元t升交点的赤纬
        double lambda = this.OMG0 + this.OMG0_DOT* tk - omge * this.toe;
        //卫星在地心地固坐标系中的位置
        double x_E=x*Math.cos(lambda)-y*Math.cos(i)*Math.sin(lambda);
        double y_E=x*Math.sin(lambda)+y*Math.cos(i)*Math.cos(lambda);
        double z_E=y*Math.sin(i);
        //卫星在BDCS坐标系的坐标
        double fi=omge*tk;
        double five=180/Math.PI*5;
        double x_R=Math.cos(fi)*x_E+Math.sin(fi)*Math.cos(five)*y_E-Math.sin(fi)*Math.sin(five)*z_E;
        double y_R=-1*Math.sin(fi)*x_E+Math.cos(fi)*Math.cos(five)*y_E-Math.sin(five)*Math.cos(fi)*z_E;
        double z_R=Math.sin(five)*y_E+Math.cos(five)*z_E;
        double distance=Math.pow(x_R,2)+Math.pow(y_R,2)+Math.pow(z_R,2);
        System.out.println("轨道高度为:"+(Math.sqrt(distance)));

        return "卫星:" + this.satellite + ",长半径:" + a + ",平均角速度:" + n0
                + ",\n偏近点角:" + Ek + ",真近点角" + vk + ",升交角据:" + uk
                + ",\n改正赤经:" + u + ",改正半径:" + r + ",改正轨道倾角:" + i
                + ",\n卫星在轨道上的位置(" + x + "," + y + "),赤纬:" + lambda
                + ",\n卫星在BDCS坐标系的坐标:(" + x_R + "," + y_R + "," + z_R + ")\n\n";

    }

接下来是完整代码,公式请见链接所指向的文章。


import java.io.File;
import java.io.FileNotFoundException;
import java.util.Date;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
class location {
    String address1;//txt文件位置
    String satellite;//PRN号
    private double IDOT;
    private double sqrt_a;
    private double IODE;
    private double delta_n;
    private double t;
    private double toe;
    private double M0;
    private double e;
    private double omg;
    private double Cuc;
    private double Cus;
    private double Crc;
    private double Crs;
    private double Cic;
    private double Cis;
    private double i0;
    private double OMG0;
    private double OMG0_DOT;

    public String calculateLocation() {
        //长半径
        double a = Math.pow(this.sqrt_a, 2);
        //地球重力常数
        double constGM = 3.986004418e14;
        //平均角速度
        double n0 = Math.sqrt(constGM / Math.pow(a, 3));
        double n = n0 + this.delta_n;
        //平近点角
        Double tk = this.t - this.toe;
        double Mk = this.M0 + n * (this.t - this.toe);
        //偏近点角
        double Ek0 = 0;
        double Ek1 = Mk;
        while (Math.abs(Ek1 - Ek0) > 10e-12) {
            Ek0 = Ek1;
            Ek1 = Mk + this.e * Math.sin(Ek0);
        }
        double Ek = Ek0;
        //真近点角
        double vk = Math.acos((Math.cos(Ek) - this.e) / (1 - this.e * Math.cos(Ek)));
        //升交角距
        double uk = vk + this.omg;
        //扰动改正
        double delta_uk = this.Cuc * Math.cos(2 * uk) + this.Cus * Math.sin(2 * uk);
        double delta_rk = this.Crc * Math.cos(2 * uk) + this.Crs * Math.sin(2 * uk);
        double delta_ik = this.Cic * Math.cos(2 * uk) + this.Cis * Math.sin(2 * uk);
        //赤经 半径 轨道倾角改正
        double u = uk + delta_uk;
        double r = a * (1 - this.e * Math.cos(Ek)) + delta_rk;
        double i = this.i0 + delta_ik+this.IDOT*tk;
        //卫星在轨道上的位置
        double x = r * Math.cos(u);
        double y = r * Math.sin(u);
        //地球自转角速度
        double omge = 7.292115e-5;
        //历元t升交点的赤纬
        double lambda = this.OMG0 + this.OMG0_DOT* tk - omge * this.toe;
        //卫星在地心地固坐标系中的位置
        double x_E=x*Math.cos(lambda)-y*Math.cos(i)*Math.sin(lambda);
        double y_E=x*Math.sin(lambda)+y*Math.cos(i)*Math.cos(lambda);
        double z_E=y*Math.sin(i);
        //卫星在BDCS坐标系的坐标
        double fi=omge*tk;
        double five=180/Math.PI*5;
        double x_R=Math.cos(fi)*x_E+Math.sin(fi)*Math.cos(five)*y_E-Math.sin(fi)*Math.sin(five)*z_E;
        double y_R=-1*Math.sin(fi)*x_E+Math.cos(fi)*Math.cos(five)*y_E-Math.sin(five)*Math.cos(fi)*z_E;
        double z_R=Math.sin(five)*y_E+Math.cos(five)*z_E;
        double distance=Math.pow(x_R,2)+Math.pow(y_R,2)+Math.pow(z_R,2);
        System.out.println("轨道高度为:"+(Math.sqrt(distance)));

        return "卫星:" + this.satellite + ",长半径:" + a + ",平均角速度:" + n0
                + ",\n偏近点角:" + Ek + ",真近点角" + vk + ",升交角据:" + uk
                + ",\n改正赤经:" + u + ",改正半径:" + r + ",改正轨道倾角:" + i
                + ",\n卫星在轨道上的位置(" + x + "," + y + "),赤纬:" + lambda
                + ",\n卫星在BDCS坐标系的坐标:(" + x_R + "," + y_R + "," + z_R + ")\n\n";

    }
    public void read(){
        ArrayList<String> arr=new ArrayList<String>();
        ArrayList<String> arr1=new ArrayList<String>();
        String str[]=new String[36];
        try{

            Scanner sc=new Scanner(new File(address1));
            while (sc.hasNextLine()) {
                str = sc.nextLine().split(" ");

                for(int i=0;i<str.length;i++){

                    arr.add(str[i]);
                }
            }
        }catch(FileNotFoundException e){
            e.printStackTrace();
        }
        for (int i = 0; i <arr.size(); i++) {
            if (arr.get(i)!=null&&!arr.get(i).equals("")){
                arr1.add(arr.get(i));
            }
        }
        this.satellite=arr1.get(0);
        this.IODE=Double.parseDouble(arr1.get(10));
        //System.out.println("这是IODE:"+this.IODE);
        //Crs
        this.Crs=Double.parseDouble(arr1.get(11));
        //System.out.println("这是Crs:"+this.Crs);
        //角速度改正数
        this.delta_n=Double.parseDouble(arr1.get(12));
        //参考时刻的平近点角
        this.M0=Double.parseDouble(arr1.get(13));
        //Cuc
        this.Cuc=Double.parseDouble(arr1.get(14));
        //偏心率
        this.e=Double.parseDouble(arr1.get(15));
        //Cus
        this.Cus=Double.parseDouble(arr1.get(16));
        //长半轴的开方
        this.sqrt_a=Double.parseDouble(arr1.get(17));
        //toe
        this.toe=Double.parseDouble(arr1.get(18));
        //Cic
        this.Cic=Double.parseDouble(arr1.get(19));
        //参考时刻的升交点赤经
        this.OMG0=Double.parseDouble(arr1.get(20));
        //Cis
        this.Cis=Double.parseDouble(arr1.get(21));
        //参考时刻的轨道倾角
        this.i0=Double.parseDouble(arr1.get(22));
        //Crc
        this.Crc=Double.parseDouble(arr1.get(23));
        //参考时刻的近地点角距
        this.omg=Double.parseDouble(arr1.get(24));
        //升交点赤经变化率
        this.OMG0_DOT=Double.parseDouble(arr1.get(25));
        //轨道倾角变化率
        this.IDOT=Double.parseDouble(arr1.get(26));

        //toc 时钟时间的周内秒
        Integer year=Integer.parseInt(arr1.get(1));
        Integer month=Integer.parseInt(arr1.get(2));
        Integer date=Integer.parseInt(arr1.get(3));
        Integer hour=Integer.parseInt(arr1.get(4));
        Integer minu=Integer.parseInt(arr1.get(5));
        Integer sec=Integer.parseInt(arr1.get(6));
        LocalDateTime time=LocalDateTime.of(year, month, date, hour, minu, sec);
        Date dtTime=Date.from(time.atZone(ZoneId.systemDefault()).toInstant());
        Long timeSec=dtTime.getTime();
        //BDT起始时间 2006年1月1日0时0分0秒 星期日
        LocalDateTime time0=LocalDateTime.of(2006,1,1,0,0,0);
        Date dtTime0=Date.from(time0.atZone(ZoneId.systemDefault()).toInstant());
        Long time0Sec=dtTime0.getTime();
        //求toc 时钟时间
        Long toc=((timeSec-time0Sec)/1000)%(604800);
        System.out.println("toc="+toc);

        //钟差参数 a0,a1,a2
        Double a0=Double.parseDouble(arr1.get(7));
        Double a1=Double.parseDouble(arr1.get(8));
        Double a2=Double.parseDouble(arr1.get(9));
        //设置观测时间为每分钟的第13秒
        Long t0=toc;
        LocalDateTime time_ob=LocalDateTime.of(year, month, date, hour, minu, sec);
        Double dt=a0+a1*(t0-toc)+a2*Math.pow((t0-toc), 2);
        this.t=t0-dt;
        System.out.print("观测时间:"+time_ob+"\n");
        System.out.print(calculateLocation());


    }
    public location(String address){
        this.address1=address;
    }

}
public class C01position {
    public static void main(String[] args)throws FileNotFoundException,IOException{
        location l=new location("C:\\Users\\Henry\\Desktop\\C01.txt");
        l.read();
    }
}

 示例文件所得到的结果如图:

 学习不易,转载请与博主联系。

猜你喜欢

转载自blog.csdn.net/m0_49684834/article/details/128118459