RTKLIB单点定位处理流程之一(postpos/后处理)

本文深入解析RTKLIB库中GPS单点定位流程,涵盖数据读取、参数设置、定位计算与结果输出等核心步骤。通过详细解读源码,揭示了从观测数据到定位结果的全过程。
该文章已生成可运行项目,

版本:

#define VER_RTKLIB  "2.4.3"      /* library version */

#define PATCH_LEVEL "b29"      /* patch level */

处理参数设置:主要是三个结构体:

prcopt_t opt = prcopt_default;  //processing options

solopt_t sopt = solopt_default; //solution options

filopt_t fopt = { 0 }; //file options

#include "rtklib.h"
int main() {
	char* infile[] = { {"移动站观测数据"},
			    {"移动站星历文件"} };
	char* ofile = { "输出结果文件/myposbyVS.pos" };
	gtime_t ts = { 0 }, te = { 0 };
	double st[] = { 2019,12,5,0,0,0 }; //开始处理时间
	double ed[] = { 2019,12,5,1,0,0 }; //结束处理时间
	ts = epoch2time(st);
	te = epoch2time(ed);
	double ti = 0.0;      //  processing interval(s) (0:all) 时间间隔
	double tu = 0.0;    //   processing unit time(s) (0:all)
	prcopt_t opt = prcopt_default;  //processing options
	solopt_t sopt = solopt_default; //solution options
	filopt_t fopt = { 0 }; //file options
	int n = 2;  //number of input files
        //GPS单点定位参数设置
	opt.navsys = SYS_GPS;
	opt.mode = PMODE_SINGLE; // PMODE_SINGLE; // PMODE_MOVEB; // ; PMODE_FIXED           
	opt.nf = 1;             /* number of frequencies (1:L1,2:L1+L2,3:L1+L2+L5) */
	opt.elmin = 10 * D2R;
	opt.ionoopt = IONOOPT_BRDC;       /* ionosphere option (IONOOPT_???) */
	opt.tropopt = TROPOPT_SAAS;       /* troposphere option (TROPOPT_???) */
	opt.dynamics = 0;       /* dynamics model (0:none,1:velociy,2:accel) */
	opt.tidecorr = 0;       /* earth tide correction (0:off,1:solid,2:solid+otl+pole) */
	opt.niter = 1;          /* number of filter iteration */
	opt.codesmooth = 0;     /* code smoothing window size (0:none) */
	opt.rovpos = 0;         /* rover position for fixed mode */
	opt.refpos = 0;         /* base position for relative mode */
						/* (0:pos in prcopt,  1:average of single pos, */
						/*  2:read from file, 3:rinex header, 4:rtcm pos) */
	//opt.eratio[] = {100.0,100.0}; /* code/phase error ratio */
	//opt.err[] = { 100.0,0.003,0.003,0.0,1.0 }; /* err[] */
	/* measurement error factor */
	/* [0]:reserved */
	/* [1-3]:error factor a/b/c of phase (m) */
	/* [4]:doppler frequency (hz) */
	//opt.std[] = { 30.0,0.03,0.3 };            /* std[] */
	/* initial-state std [0]bias,[1]iono [2]trop */
	//opt.prn[] = { 1E-4,1E-3,1E-4,1E-1,1E-2 ,0.0 };
	/* process-noise std [0]bias,[1]iono [2]trop [3]acch [4]accv [5] pos */

//求解选项定义
	sopt.posf = SOLF_LLH; // SOLF_XYZ; //  SOLF_ENU;
	sopt.times = TIMES_GPST; /* time system: gps time */
	sopt.timef = 1; /* time format (0:sssss.s,1:yyyy/mm/dd hh:mm:ss.s) */
	sopt.timeu = 3; /* time digits under decimal point */
	sopt.degf = 0; /* latitude/longitude format (0:ddd.ddd,1:ddd mm ss) */
	sopt.outhead = 1;        /* output header (0:no,1:yes) */
	sopt.outopt = 1;         /* output processing options (0:no,1:yes) */
	sopt.outvel = 1;         /* output velocity options (0:no,1:yes) */
	sopt.datum = 0;          /* datum (0:WGS84,1:Tokyo) */
	sopt.height = 0;         /* height (0:ellipsoidal,1:geodetic) */
	sopt.geoid = 0;          /* geoid model (0:EGM96,1:JGD2000) */
	sopt.solstatic = 0;      /* solution of static mode (0:all,1:single) */
	sopt.sstat = 1;          /* solution statistics level (0:off,1:states,2:residuals) */
	sopt.trace = 3;          /* debug trace level (0:off,1-5:debug) */
	//sopt.nmeaintv[] = { 0.0,0.0 }; /* nmea output interval (s) (<0:no,0:all) */
					/* nmeaintv[0]:gprmc,gpgga,nmeaintv[1]:gpgsv */
	//sopt.sep[] = " ";       /* field separator */
	//sopt.prog[] = "";      /* program name */
	//sopt.maxsolstd = 0;   /* max std-dev for solution output (m) (0:all) */

//文件设置选项 /* file options type */
	// #define MAXSTRPATH  1024        /* max length of stream path */
	//fopt.satantp[MAXSTRPATH] = { 0 }; /* satellite antenna parameters file */
	//fopt.rcvantp[MAXSTRPATH] = { 0 }; /* receiver antenna parameters file */
	//fopt.stapos[MAXSTRPATH] = { 0 }; /* station positions file */
	//fopt.geoid[MAXSTRPATH] = { 0 }; /* external geoid data file */
	//fopt.iono[MAXSTRPATH] = { 0 }; /* ionosphere data file */
	//fopt.dcb[MAXSTRPATH] = { 0 }; /* dcb data file */
	//fopt.eop[MAXSTRPATH] = { 0 }; /* eop data file */
	//fopt.blq[MAXSTRPATH] = { 0 }; /* ocean tide loading blq file */
	//fopt.tempdir[MAXSTRPATH] = { 0 }; /* ftp/http temporaly directory */
	//fopt.geexe[MAXSTRPATH] = { 0 }; /* google earth exec file */
	//fopt.solstat[MAXSTRPATH] = { 0 }; /* solution statistics file */
	//fopt.trace[MAXSTRPATH] = { 0 }; /* debug trace file */


	postpos(ts,te,ti,tu,&opt,&sopt,&fopt,infile,n,ofile,"","");
	printf("*********postpos over*********\n");
	getchar();
	return 0;
}

函数调用关系:

首先通过函数:postpos(ts,te,ti,tu,&opt,&sopt,&fopt,infile,n,ofile,"","");进入子函数;

  • openses函数:预处理

目的:通过读取filopt_t  fopt中的参数,其中filopt_t结构体定义如下,实现对‘文件的读取’,读取子函数为openses!

typedef struct {        /* file options type */
    char satantp[MAXSTRPATH]; /* satellite antenna parameters file */
    char rcvantp[MAXSTRPATH]; /* receiver antenna parameters file */
    char stapos [MAXSTRPATH]; /* station positions file */
    char geoid  [MAXSTRPATH]; /* external geoid data file */
    char iono   [MAXSTRPATH]; /* ionosphere data file */
    char dcb    [MAXSTRPATH]; /* dcb data file */
    char eop    [MAXSTRPATH]; /* eop data file */
    char blq    [MAXSTRPATH]; /* ocean tide loading blq file */
    char tempdir[MAXSTRPATH]; /* ftp/http temporaly directory */
    char geexe  [MAXSTRPATH]; /* google earth exec file */
    char solstat[MAXSTRPATH]; /* solution statistics file */
    char trace  [MAXSTRPATH]; /* debug trace file */
} filopt_t;
/* open procssing session ----------------------------------------------------*/
static int openses(const prcopt_t *popt, const solopt_t *sopt,
                   const filopt_t *fopt, nav_t *nav, pcvs_t *pcvs, pcvs_t *pcvr)

然后为:判断处理时间是否正确,否则程序终止;

然后为:通过malloc函数为ifile[],动态分配内存,否则程序终止;

然后为:进行文件的读取,对于sp3/SP3、.eph/EPH文件的时间,起使和终止相差1小时;brdc文件的开始和终止时间差2小时。

然后为:路径替换,实现语句:

nf+=reppaths(infile[j],ifile+nf,MAXINFILE-nf,tts,ttte,"","");
子函数内实现语句:
reppath(path,rpath[n],time,rov,base);

经过两次读取循环,已经将观测、导航文件读取到ifie数组中:

将输出结果文件路径保存到ofile数组中:

if (!reppath(outfile,ofile,tts,"","")&&i>0) flag=0;
子函数实现代码:
strcpy(rpath,path);
  • execses_b

在main中,输入文件中:第一个为观测文件,第二个为导航文件;

1、readpreceph

/* 读取文件为:read prec ephemeris, sbas data, lex data, tec grid and open rtcm ----------*/
static void readpreceph(char **infile, int n, const prcopt_t *prcopt,nav_t *nav, sbs_t *sbs, lex_t *lex)

读取文件的函数依次为:

/* read precise ephemeris files */

/* read precise clock files */

/* read satellite fcb files */

/* read solution status files for ppp correction */

 /* read sbas message files */

 /* read lex message files */

 /* allocate sbas ephemeris */

 /* set rtcm file and initialize rtcm struct */

以函数:readsp3为例

    /* read precise ephemeris files */
    for (i=0;i<n;i++) {
        if (strstr(infile[i],"%r")||strstr(infile[i],"%b")) continue;
        readsp3(infile[i],nav,0);
    }

第一次循环读入的是观测文件,因此进入函数之后,动态分配内存、释放内存,结束!

第二次循环读入的是导航文件,因此进入函数之后,动态分配内存、释放内存,结束!

在函数readrnxc中:读取钟差文件时,读取导航文件时,将导航文件,文件头的相关参数保存到nav中:

    /* read precise clock files */
    for (i=0;i<n;i++) {
        if (strstr(infile[i],"%r")||strstr(infile[i],"%b")) continue;
        readrnxc(infile[i],nav);
    }

导航文件,文件头为:

nav:

2、execses_r

stat=execses_r(ts,te,ti,popt,sopt,fopt,flag,infile,index,n,outfile,rov);

2.1 execses

stat=execses(ts,te,ti,popt,sopt,fopt,flag,infile,index,n,outfile);

如果main函数中,设置了调试等级:

	sopt.sstat = 1;   /* solution statistics level (0:off,1:states,2:residuals) */
	sopt.trace = 3;   /* debug trace level (0:off,1-5:debug) */

则在此处新建生成的调试数据,保存的路径、文件名

    /* open debug trace */
    if (flag&&sopt->trace>0) {
        if (*outfile) {
            strcpy(tracefile,outfile);
            strcat(tracefile,".trace"); //输出文件名,后加.trace
        }
        else {
            strcpy(tracefile,fopt->trace);
        }
        traceclose(); //关闭记录文件
        traceopen(tracefile); //开始对 trace文件进行写处理
        tracelevel(sopt->trace); //读取调试等级
    }

顺序执行,子函数如下:

1、/* read ionosphere data file */ 读取数据放到如下结构体中:

typedef struct {        /* TEC grid type */
    gtime_t time;       /* epoch time (GPST) */
    int ndata[3];       /* TEC grid data size {nlat,nlon,nhgt} */
    double rb;          /* earth radius (km) */
    double lats[3];     /* latitude start/interval (deg) */
    double lons[3];     /* longitude start/interval (deg) */
    double hgts[3];     /* heights start/interval (km) */
    double *data;       /* TEC grid data (tecu) */
    float *rms;         /* RMS values (tecu) */
} tec_t;

2、/* read erp data */ 读取数据放到如下结构体中:

typedef struct {        /* earth rotation parameter type */
    int n,nmax;         /* number and max number of data */
    erpd_t *data;       /* earth rotation parameter data */
} erp_t;

3、/* read obs and nav data */

其中观测数据结构体的使用:

typedef struct {        /* observation data record */
    gtime_t time;       /* receiver sampling time (GPST) */
    unsigned char sat,rcv; /* satellite/receiver number */
    unsigned char SNR [NFREQ+NEXOBS]; /* signal strength (0.25 dBHz) */
    unsigned char LLI [NFREQ+NEXOBS]; /* loss of lock indicator */
    unsigned char code[NFREQ+NEXOBS]; /* code indicator (CODE_???) */
    double L[NFREQ+NEXOBS]; /* observation data carrier-phase (cycle) */
    double P[NFREQ+NEXOBS]; /* observation data pseudorange (m) */
    float  D[NFREQ+NEXOBS]; /* observation data doppler frequency (Hz) */
} obsd_t;

typedef struct {        /* observation data */
    int n,nmax;         /* number of obervation data/allocated */
    obsd_t *data;       /* observation data records */
} obs_t;

2.1.1 readobsnav

函数: static int readobsnav(gtime_t ts, gtime_t te, double ti, char **infile,const int *index, int n, const prcopt_t *prcopt,obs_t *obs, nav_t *nav, sta_t *sta)

程序中,每次都是将相关的变量置0、指针变量赋值为null

    obs->data=NULL; obs->n =obs->nmax =0;
    nav->eph =NULL; nav->n =nav->nmax =0;
    nav->geph=NULL; nav->ng=nav->ngmax=0;
    nav->seph=NULL; nav->ns=nav->nsmax=0;
    nepoch=0;

2.1.1.1 readrnxt

/* read rinex obs and nav files ------------------------------------------------

extern int readrnxt(const char *file, int rcv, gtime_t ts, gtime_t te,double tint, const char *opt, obs_t *obs, nav_t *nav,sta_t *sta)

2.1.1.1.1 readrnxfile

调用子函数:

      stat=readrnxfile(files[i],ts,te,tint,opt,0,rcv,&type,obs,nav,sta);

      调用子函数:

             if (sta) init_sta(sta);

<
本文章已经生成可运行项目
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值