这是一个利用广播星历计算GPS卫星位置的小程序,里面包含了结构数据读取的方法。
点击brdc0180.12n.z下载,下载后是一个压缩包,解压后找到brdc0180.12n,可以用记事本打开,样子如下: brdc.PNG brdc2.png 去掉头文件,为了后面的计算方便,把后面数据的D都改为E,后缀我也改成了txt,则变成下面的样子: brdc改后.PNG 经修改后的最终数据想下载的可以访问: 修改数据.PNG
数一下,每一个分区共38个数据 导航n文件结构说明.PNG
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define pi 3.1415926535897
#define gm 3.986005e14
//直接查看数据知道有407个38,这样做只是想少读取一次数据
#define block_count 407
#define we 7.2921151467e-5
double NaturalizedTime(int,int,int,int,int,int);
//此结构包含38个数据
struct data
{
int prn;
int yer;
int month;
int day;
int hour;
int minute;
double sec;
double a0;
double a1;
double a2;
double iode;
double crs;
double var_n;
double m0;
double cuc;
double e;
double cus;
double sqrt_a;
double t0e;
double cic;
double oumiga_0;
double cis;
double i0;
double crc;
double w;
double oumiga;
double idot;
double codes;
double gps_week;
double data_flag;
double sv_accuracy;
double sv_health;
double tgd;
double iodc_issue_of_data;
double transmission_time;
double spare0;
double spare1;
double spare2;
}dt;
int main()
{
void calculate(int,int,int,int,int);
int prn_num;
int differ_time;
int t_temp;
int near_i;
int c_i;
int d_h,d_m,d_s;
FILE *fp;
printf("please input the number of satellite(such as:3)\n");
printf("Or input 0 to quit:");
while(scanf("%d",&prn_num)==1&&prn_num!=0)
{
printf("please input the desired time.List by\n");
printf("hour minute second(such as 15 6 9):");
scanf("%d%d%d",&d_h,&d_m,&d_s);
t_temp=7200;
fp=fopen("E:\\GPSdata\\brdc0180.txt","r");
if(fp==NULL)
{
printf("Can not open the file.\n");
exit(1);
}
//读取数据
for(c_i=1;c_i<=block_count;c_i++)
{
fscanf(fp,"%d%d%d%d%d%d%lf%lf%lf%lf",&dt.prn,&dt.yer,&dt.month,&dt.day,
&dt.hour,&dt.minute,&dt.sec,&dt.a0,&dt.a1,&dt.a2);
fscanf(fp,"%lf%lf%lf%lf%lf%lf%lf%lf",&dt.iode,&dt.crs,&dt.var_n,&dt.m0,
&dt.cuc,&dt.e,&dt.cus,&dt.sqrt_a);
fscanf(fp,"%lf%lf%lf%lf%lf%lf%lf%lf",&dt.t0e,&dt.cic,&dt.oumiga_0,
&dt.cis,&dt.i0,&dt.crc,&dt.w,&dt.oumiga);
fscanf(fp,"%lf%lf%lf%lf%lf%lf%lf%lf",&dt.idot,&dt.codes,&dt.gps_week,
&dt.data_flag,&dt.sv_accuracy,&dt.sv_health,&dt.tgd,&dt.iodc_issue_of_data);
fscanf(fp,"%lf%lf%lf%lf",&dt.transmission_time,&dt.spare0,&dt.spare1,&dt.spare2);
//find the equal number of the PRN and compare the time
if(dt.prn==prn_num)
{
differ_time=abs((dt.hour*3600+dt.minute*60+dt.sec)-(d_h*3600+d_m*60+d_s));
if(differ_time<=t_temp)
{
t_temp=differ_time;
near_i=c_i; /*mark the id */
}
}
}
calculate(near_i,prn_num,d_h,d_m,d_s);
//读取完后关闭文件
fclose(fp);
printf("All right.\n");
putchar('\n');
printf("please input the number of satellite(such as:3)\n");
printf("Or input 0 to quit:");
}
return 0;
}
void calculate(int k,int prn,int hh,int mm,int ss)
{
double avg_n;
double ms;
double es;
double temp;
double fs;
double u0;
double correct_u;
double correct_r;
double correct_i;
double u,r,i;
double longitude;
double X,Y,Z;
double x,y;
double ut;
double tk;
int tk_INT;
double t;
FILE *fp;
int gg;
if((fp=fopen("E:\\GPSdata\\brdc0180.txt","r+"))==NULL)
{
printf("Can not open the file.\n");
exit(1);
}
for(gg=1;gg<=k;gg++)
{
fscanf(fp,"%d%d%d%d%d%d%lf%lf%lf%lf",&dt.prn,&dt.yer,&dt.month,&dt.day,
&dt.hour,&dt.minute,&dt.sec,&dt.a0,&dt.a1,&dt.a2);
fscanf(fp,"%lf%lf%lf%lf%lf%lf%lf%lf",&dt.iode,&dt.crs,&dt.var_n,&dt.m0,
&dt.cuc,&dt.e,&dt.cus,&dt.sqrt_a);
fscanf(fp,"%lf%lf%lf%lf%lf%lf%lf%lf",&dt.t0e,&dt.cic,&dt.oumiga_0,
&dt.cis,&dt.i0,&dt.crc,&dt.w,&dt.oumiga);
fscanf(fp,"%lf%lf%lf%lf%lf%lf%lf%lf",&dt.idot,&dt.codes,&dt.gps_week,
&dt.data_flag,&dt.sv_accuracy,&dt.sv_health,&dt.tgd,&dt.iodc_issue_of_data);
fscanf(fp,"%lf%lf%lf%lf",&dt.transmission_time,&dt.spare0,&dt.spare1,&dt.spare2);
}
avg_n=pow(gm,0.5)/pow(dt.sqrt_a,3)+dt.var_n;
tk=NaturalizedTime(dt.yer,dt.month,dt.day,hh,mm,ss); //此时的tk为double类型,存在精度丢失
tk_INT=(int)(tk+0.5); //将double转成int,防止精度丢失
ms=dt.m0+avg_n*(tk_INT);
es=ms;
temp=0;
//Iteration
do
{
temp=es;
es=ms+dt.e*sin(es);
}while(fabs(es-temp)>1e-12);
fs=atan2(pow((1-dt.e*dt.e),0.5)*sin(es),(cos(es)-dt.e));
u0=dt.w+fs;
correct_u=dt.cuc*cos(2*u0)+dt.cus*sin(2*u0);
correct_r=dt.crc*cos(2*u0)+dt.crs*sin(2*u0);
correct_i=dt.cic*cos(2*u0)+dt.cis*sin(2*u0);
u=u0+correct_u;
r=dt.sqrt_a*dt.sqrt_a*(1-dt.e*cos(es))+correct_r;
i=correct_i+dt.i0+dt.idot*(tk_INT);
longitude=dt.oumiga_0+(dt.oumiga-we)*(tk_INT)-we*dt.t0e;
x=r*cos(u);
y=r*sin(u);
X=x*cos(longitude)-y*cos(i)*sin(longitude);
Y=x*sin(longitude)+y*cos(i)*cos(longitude);
Z=y*sin(i);
printf("The satellite PRN%d's position(x,y,z) is:\n",prn);
printf("(%16.8lf,%16.8lf,%16.8lf)\n",X,Y,Z);
fclose(fp);
}
//将民用时间(年 月 日 时 分 秒)转化为GPS时间(GPS秒)
double NaturalizedTime(int y,int m,int d,int h,int minute,int s)
{
double ut;
double jd;
double gpsw;
double t;
double temp_t;
ut=(double)h+(double)minute/60+(double)s/3600;
if(y>=80)
{
if(y==80&&m==1&&d<6)
{
y=y+2000;
}
y=y+1900;
}
else
{
y=y+2000;
}
if(m<=2)
{
y=y-1;
m=m+12;
}
jd=(int)(365.25*y)+(int)(30.6001*(m+1))+d+ut/24+1720981.5;
gpsw=(int)((jd-2444244.5)/7);
t=(jd-2444244.5-7*gpsw)*24*3600;
temp_t=t-dt.t0e;
while(temp_t>302400||temp_t<-302400)
{
if(temp_t>302400)
temp_t=temp_t-604800;
else
temp_t=temp_t+604800;
}
return temp_t;
}
网友评论