RTKLIB观测数据读取修改
作者:互联网
最近在用RTKLIB处理较长时间的观测数据时,会出现内存不足的问题,这是因为在一开始读取星历和观测文件时,将所有的观测数据都存储到了结构体obss中,在后续定位解算的时候再逐历元处理。感觉这种设计不太合理,星历需要预先读取,但是观测文件应该逐历元读取与处理,否则没法处理较长时间的数据。因此,在原程序的基础上进行了相应修改,区分单点定位和相对定位两种模式。
1 源程序分析
首先观察源代码中观测数据的存储和提取位置。
源代码中观测数据在函数readrnxfp()->readrnxh()读取观测文件头,readrnxobs()->readrnxobsb中读取单历元观测数据存储到obsd_t类型的结构体data中,再通过addobsdata()添加到大的全局结构体obss中。
定位解算时通过procpos()->inputobs()函数逐历元读取观测数据,存储到obsd_t类型结构体obs中,再输入进rtkpos()进行解算。
这样看来,中间的存储过程其实并不必要,可以在procpos()函数中直接读取观测值输入给rtkpos(),修改方案如下:
2 修改方案
(1)在读取观测文件的函数readrnxfp()中进行相应修改,不读取观测数据,直接返回
(2)在procpos()中补充添加输入参数及变量
输入参数中增加用户输入的观测文件名:
//infile: 用户输入的观测文件名
//fp: 输出文件指针
static void procpos(char** infile, FILE *fp, const prcopt_t *popt, const solopt_t *sopt,
int mode)
添加变量并初始化内存:
//补充添加的变量
FILE* fp_u = NULL;
FILE* fp_b = NULL;
double ver=0;
char type = ' ';
int sys, tsys = TSYS_GPS, flag = 0;
char tobs[NUMSYS][MAXOBSTYPE][4] = { {""} };
obsd_t *data_u; //存储移动站单历元观测数据
obsd_t *data_b; //存储基准站单历元观测数据
int rcv = 1;//移动站:1;基准站:2
const char* opt = popt->rnxopt[rcv <= 1 ? 0 : 1];
uint8_t slips[MAXSAT][NFREQ + NEXOBS] = { {0} };
uint8_t slips_u[MAXSAT][NFREQ + NEXOBS] = { {0} };
uint8_t slips_b[MAXSAT][NFREQ + NEXOBS] = { {0} };
//初始化内存
if (!(data_u = (obsd_t*)malloc(sizeof(obsd_t) * MAXOBS))) return;
if (!(data_b = (obsd_t*)malloc(sizeof(obsd_t) * MAXOBS))) return;
(3)在procpos()中读取观测文件头
int index_u = 2, index_b = 3; //移动站和基准站在输入文件中的索引序号
//打开移动站观测文件
if (strlen(infile[index_u]) != 0) {
if (!(fp_u = fopen(infile[index_u], "r"))) {
printf("%s", "Error : 移动站观测文件读取失败\n");
trace(2, "rinex file open error: rover obs");
return;
};
//读取观测文件头
if (!readrnxh(fp_u, &ver, &type, &sys, &tsys, tobs, &navs, stas)) return;
}
//打开基准站观测文件
if (strlen(infile[index_b])!=0) {
if (!(fp_b = fopen(infile[index_b], "r"))) {
printf("%s", "Error : 基准站观测文件读取失败\n");
trace(2, "rinex file open error: base obs");
return;
};
//读取观测文件头
if (!readrnxh(fp_b, &ver, &type, &sys, &tsys, tobs, &navs, stas)) return;
}
(4)procpos()中循环读取观测数据
对于单点定位模式,直接读取移动站观测数据即可:
/*SPP和PPP定位只读取移动站观测数据--------------------------------------------*/
if (popt->mode < 1 || popt->mode>5) {
//读观测文件数据
nu = readrnxobsb(fp_u, opt, ver, &tsys, tobs, &flag, data_u, stas);
for (i = 0; i < nu; i++) {
/* UTC -> GPST */
if (tsys == TSYS_UTC) data_u[i].time = utc2gpst(data_u[i].time);
/* save cycle slip */
saveslips(slips, data_u + i);
}
for (i = 0; i < nu; i++) {
/* restore cycle slip */
restslips(slips, data_u + i);
data_u[i].rcv = (uint8_t)rcv;
/* save obs data */
obs[i] = data_u[i];
//if ((stat = addobsdata(obs, data_r + i)) < 0) break;
}
nobs = nu;
if (nu == -1) {
break; //观测文件读取结束
}
}
对于相对定位模式,需要将移动站和基准站的时间进行同步:
/*相对定位模式读移动站和基准站同步的观测数据---------------------------------*/
else if (popt->mode >= 1 && popt->mode <= 5) {
//读观测文件数据
nu = readrnxobsb(fp_u, opt, ver, &tsys, tobs, &flag, data_u, stas);
nb = readrnxobsb(fp_b, opt, ver, &tsys, tobs, &flag, data_b, stas);
//时间同步
double dt = timediff(data_u[1].time, data_b[1].time); //t1-t2
while (fabs(dt) > 1e-2) {
if (dt < 0) {
nu = readrnxobsb(fp_u, opt, ver, &tsys, tobs, &flag, data_u, stas); //移动站时间落后
}
else
{
nb = readrnxobsb(fp_b, opt, ver, &tsys, tobs, &flag, data_b, stas); //基准站时间落后
}
//如果文件读取结束仍未同步,则输出错误信息
if (nu==-1 || nb==-1) {
//if (feof(fp_u) || feof(fp_b)) {
printf("%s", "Error : 观测文件未同步\n");
return;
}
}
}
标签:fp,文件,读取,RTKLIB,观测,data,nu 来源: https://blog.csdn.net/papunzal/article/details/123177594