按自定义结构(struct)读取数据

这是一个利用广播星历计算GPS卫星位置的小程序,里面包含了结构数据读取的方法。
在读取数据前,先初步了解数据的含义。原数据下载,选择brdc0180.12n.Z下载,可以用记事本打开,样子如下:

按自定义结构(struct)读取数据_第1张图片
brdc2.png
去掉头文件,为了后面的计算方便,把后面数据的D都改为E(这里修改为E是为了能让程序正确地读取数据),后缀我也改成了txt,则变成下面的样子:
按自定义结构(struct)读取数据_第2张图片
brdc改后.PNG
为了方便大家,我将数据修改了上传到网盘,下载 修改后的数据。数一下,每一个分区共38个数据
按自定义结构(struct)读取数据_第3张图片
块数据结构.PNG

下面是利用广播星历数据计算GPS卫星位置的完整代码,对于按结构读取数据的代码已通过注释标明。

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

你可能感兴趣的:(按自定义结构(struct)读取数据)