n文件提供的轨道参数:
PS:需要对文件内容格式做一定修改:D改成E/e,各个数据间以空格隔开
计算步骤参考武汉大学出版的《GPS测量原理及应用》(第四版)的4.3部分。
使用Java编写代码计算GPS在地固坐标系中的坐标:
原文链接:根据北斗广播星历计算卫星位置的小程序 Java版本 RINEX VERSION3.04_我们与食堂的距离的博客-CSDN博客
根据个人实际情况对代码做了修改。 calculateLocation()方法:用来计算卫星位置
//轨道长半径
double a=Math.pow(sqrt_a, 2);
//WGS-84坐标系中的地球引力常数
double constGM=3.986005e+14;
//卫星运行的平均角速度
double n0=Math.sqrt(constGM/Math.pow(a, 3));
//delta_n为卫星电文给出的摄动改正数
double n=n0+delta_n;
//tk为相对于参考时刻toe的归化时间
double tk=t-toe;
if(tk>302400){
tk=tk-604800;
}else if(tk<-302400){
tk=tk+604800;
}
//观测时刻卫星平近点角Mk
//M0是卫星电文给出的参考时刻toe的平近点角
double Mk=M0+n*(tk);
if (Mk < 0){
Mk += 2*Math.PI;
}
if (Mk > 2*Math.PI){
Mk -= 2*Math.PI;
}
//利用迭代法计算偏近点角Ek
double E0=Mk;
double Ek=Mk+e*Math.sin(E0);
while(Math.abs(Ek-E0)>10e-12) {
E0=Ek;
Ek=Mk+e*Math.sin(E0);
}
//真近点角vk
double cosNu_k = (Math.cos(Ek) - e) / (1 - e*Math.cos(Ek));
double sinNu_k = (Math.sqrt(1-e*e)*Math.sin(Ek)) / (1 - e*Math.cos(Ek));
double vk;
if (cosNu_k == 0){
if (sinNu_k > 0){
vk = Math.PI/2;
}
else{
vk=Math.PI/2;
}
}
else{
vk = Math.atan(sinNu_k/cosNu_k);
}
if (cosNu_k < 0){
if (sinNu_k >= 0){
vk += Math.PI;
}
else{
vk -= Math.PI;
}
}
//升交距角fk,omg为卫星电文给出的近地点角距
double fk=vk+omg;
//计算摄动改正项
//delta_uk为升交距角u的摄动量
double delta_uk=Cuc*Math.cos(2*fk)+Cus*Math.sin(2*fk);
//delta_rk为卫星矢径r的摄动量
double delta_rk=Crc*Math.cos(2*fk)+Crs*Math.sin(2*fk);
//delta_ik为轨道倾角i的摄动量
double delta_ik=Cic*Math.cos(2*fk)+Cis*Math.sin(2*fk);
//计算经过摄动改正的升交距角uk,卫星矢径rk和轨道倾角ik
double uk=fk+delta_uk;
double rk = a * (1 - e * Math.cos(Ek))+delta_rk;
double ik=i0+delta_ik+I*tk;
//计算卫星在轨道平面坐标系(X轴指向升交点)的坐标
double x=rk*Math.cos(uk);
double y=rk*Math.sin(uk);
//地球自转角速度
double omge=7.2921151467e-05;
//lambda为升交点经度
double lambda=OMG0+(OMG0_DOT-omge)*tk-omge*toe;
//卫星在地心地固坐标系中的直角坐标
double x_E=(x*Math.cos(lambda)-y*Math.cos(ik)*Math.sin(lambda))/1000;
double y_E=(x*Math.sin(lambda)+y*Math.cos(ik)*Math.cos(lambda))/1000;
double z_E=(y*Math.sin(ik))/1000;
return "卫星:"+satellite+",长半径:"+a+",平均角速度:"+n0
+",\n偏近点角:"+Ek+",真近点角:"+vk+",升交角距:"+fk
+",\n改正升交距角:"+uk+",改正矢径:"+rk+",改正轨道倾角:"+ik
+",\n卫星在轨道平面直角坐标系的坐标:("+x+","+y+"),升交点经度:"+lambda
+",\n卫星在地心地固坐标系中的位置:("+x_E+","+y_E+","+z_E+")\n\n";
}
在main()方法中编写读取文件内容,对文件中数据进行处理:
public static void main(String[] args) {
//读取文件
File file=new File("D:\\GNSS\\homework.txt");
try {
//读取字符流
BufferedReader br = new BufferedReader(new FileReader(file));
String line=null;
StringBuffer navMsg=new StringBuffer();
while((line=br.readLine())!=null) {
//System.out.println(line);
navMsg.append(line+"\n");
}
//类型转换 StringBuffer->String
String navStr=navMsg.toString();
br.close();
//处理格式问题
//将字符串通过空格拆分为单个字符数组
String[] arrayChar=navStr.split(" ");
StringBuffer sb_output=new StringBuffer();
ArrayList<String> al=new ArrayList<String>();
for(String element:arrayChar) {
al.add(element);
//System.out.print(element+",");
}
//System.out.println(arrayChar[0]);
//卫星号
String satellite=arrayChar[0];
//Crs
double Crs = Double.parseDouble(arrayChar[11]);
//角速度改正数
double delta_n=Double.parseDouble(arrayChar[12]);
//参考时刻的平近点角
double M0=Double.parseDouble(arrayChar[13]);
//Cuc
double Cuc=Double.parseDouble(arrayChar[14]);
//偏心率
double e=Double.parseDouble(arrayChar[15]);
//Cus
double Cus=Double.parseDouble(arrayChar[16]);
//长半轴的开方
double sqrt_a=Double.parseDouble(arrayChar[17]);
//toe
double toe=Double.parseDouble(arrayChar[18]);
//观测时刻
double t=Double.parseDouble(arrayChar[18]);
//Cic
double Cic=Double.parseDouble(arrayChar[19]);
//参考时刻的升交点赤经
double OMG0=Double.parseDouble(arrayChar[20]);
//Cis
double Cis=Double.parseDouble(arrayChar[21]);
//参考时刻的轨道倾角
double i0=Double.parseDouble(arrayChar[22]);
//Crc
double Crc=Double.parseDouble(arrayChar[23]);
//参考时刻的近地点角距
double omg=Double.parseDouble(arrayChar[24]);
//升交点赤经变化率
double OMG0_DOT=Double.parseDouble(arrayChar[25]);
//轨道倾角变化率I
double I = Double.parseDouble(arrayChar[26]);
System.out.print(calculateLocation(satellite,sqrt_a,delta_n,t,toe,M0,e,omg,Cuc,Cus,Crc,Crs,Cic,Cis,i0,OMG0,OMG0_DOT,I));
sb_output.append(calculateLocation(satellite,sqrt_a,delta_n,t,toe,M0,e,omg,Cuc,Cus,Crc,Crs,Cic,Cis,i0,OMG0,OMG0_DOT,I));
String outputStr=sb_output.toString();
//向文件中写入计算结果
File outFile=new File("D:\\GNSS\\position1.txt");
FileWriter write= new FileWriter(outFile,true);
BufferedWriter rt=new BufferedWriter(write);
rt.write(outputStr);
rt.flush();
write.close();
rt.close();
} catch (Exception e) {
e.printStackTrace();
}
}
PS:关于归化时间的计算:直接将观测时刻 t 和参考时刻 toe 设置相等,让归化时间 tk 为0
运行结果:
卫星:8,长半径:2.6559583055585682E7,平均角速度:1.4586027904433575E-4,
偏近点角:4.063443127407144,真近点角:-2.2275177585569397,升交角距:0.44221424540006016,
改正升交距角:0.442216645938399,改正矢径:2.6716897503814127E7,改正轨道倾角:0.9740108899816725,
卫星在轨道平面直角坐标系的坐标:(2.414687314275234E7,1.1433334144383926E7),升交点经度:-34.768456592379,
卫星在地心地固坐标系中的位置:(-24956.983621633484,-1227.1703999123695,9457.041479680973)
与精密星历进行比较:
PG08 -24956.985176 -1227.169887 9457.040848