该文章是【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();
}
}
示例文件所得到的结果如图:
学习不易,转载请与博主联系。