GNSS之Rtklib代码调试(一)、参数设置及文件读入
1.前言
作为一名GNSS专业的准研究生,趁寒假的时间准备自己对自己学过的东西做一下简单的梳理。
但是了解的越多越发现自己在本科学的东西根本就不够用。
所以,希望自己做梳理的同时能够帮助还未入门但准备学习GNSS专业的小白们。
让我们一起努力吧!
本篇文章的主要内容是在下载完Github上的开源代码并搭建好环境之后,如何进行同GUI(图形用户界面)功能一样的数据处理操作。
本篇内容会以定位后处理(即postpos)的静态(static)PPP(精密单点定位)为例进行讲解
目前,只是做一个流程的大致介绍,之后的数据处理过程会结合专业知识进行详细介绍。
如果还没有进行相应软件下载以及还未进行环境配置的可看2中的详细内容。
2.环境准备
(1). Visual Studio 2019
下载网址:https://visualstudio.microsoft.com/zh-hans/vs/
链接:VS2019下载链接.
(注:VS的其他版本如2010,2017或者其他的IDE也可,只要能够编译C就可以,只是VS用习惯了)
(2). Rtklib 2.4.3
下载网址:http://www.rtklib.com/
链接:Rtklib 2.4.3下载链接.
(注:建议大家下载2.4.2p13版本,2020年最新的版本有一些bug,我还没有调试通过,注意下载右侧的,左侧是可运行的二进制文件,即.exe)
(3). 创建解决方案
其他人有写,自己看。
(4). 传入文件配置
各类文件的下载地址可以看这个链接:
网址:http://www.xsensing.cn/article/767472814310555648
链接:文件下载说明.
(注:上面示例中的sp3和clk文件是SHAO的,链接可能比较难找,大家可以直接从武汉大学IGS数据处理中心下载武汉大学的处理结果)
3.1程序函数调用结构
3.2程序函数调用顺序
通过main函数把文件夹目录传入postInit函数,
之后通过调用read_fildir将文件夹中的所有文件名称读入一个字符串数组(就是一个char类型的二维数组),
之后通过substrend函数读取每个文件的后缀来判断文件类型,并读入相应的参数中,
然后通过addchar新建一个输出结果文件的文件名(实质是根据观测值文件名进行修改后缀所得)
4.分段代码
(1).引入头文件
#include <stdio.h>
#include <assert.h>
#include <iostream>
#include <thread>
#include "dirent.h"
#include <string.h>
#include <stdlib.h>
#include "src/rtklib.h"
(2).main函数
书接上回~ 2中的(3)完成之后,需要在解决方案的源文件中添加一份新建项**main.c**
作为程序的入口(main.cpp也可)
using namespace std;
int main(void)
{
/* 文件夹路径输入 */
char filePath1[] = "C:/Users/Desktop/test/";
/* 以“后处理postpos”为例 */
postInit(filePath1);
return 0;
}
(3).postInit函数
/* postInit ---------------------------------------------------------
* 将各类文件导入数据处理程序
* args : char* filepath I 文件夹路径
*
* return : NULL
* notes : NULL
*-------------------------------------------------------------------*/
I表示输入,O表示输出
(注:该函数在使用前应预先定义或声明函数read_filedir、substrend)
extern void postInit(char* filepath)
{
gtime_t ts = { 0 }, te = { 0 };
double ti = 0.0, tu = 0.0;
int i, n = 0, stat;
char* rov, * base, * p, * q, * r;
char file[FILENUM][FILESIZE] = { "" };
char *infile[FILENUM], outfile[FILESIZE];
char proname[FILESIZE];
read_filedir(filepath, file);
// 处理参数
prcopt_t prcopt = {
PMODE_PPP_STATIC,0,2,SYS_ALL, /* mode,soltype,nf,navsys */
15.0 * D2R,{{0,0}}, /* elmin,snrmask */
EPHOPT_PREC,1,1,1, /* sateph,modear,glomodear,bdsmodear */
5,0,10,1, /* maxout,minlock,minfix,armaxiter */
IONOOPT_IFLC,TROPOPT_ESTG,0,2, /* estion,esttrop,dynamics,tidecorr */
1,0,0,0,0, /* niter,codesmooth,intpref,sbascorr,sbassatsel */
0,0, /* rovpos,refpos */
{100.0,100.0}, /* eratio[] */
{100.0,0.003,0.003,0.0,1.0}, /* err[] */
{30.0,0.03,0.3}, /* std[] */
{1E-4,1E-3,1E-4,1E-1,1E-2,0.0}, /* prn[] */
5E-12, /* sclkstab */
{3.0,0.9999,0.25,0.1,0.05}, /* thresar */
0.0,0.0,0.05, /* elmaskar,almaskhold,thresslip */
30.0,30.0,30.0, /* maxtdif,maxinno,maxgdop */
{0},{0},{0}, /* baseline,ru,rb */
{"*",""}, /* anttype */ //added202012191019withPostpos929
{{0}},{{0}},{0} /* antdel,pcv,exsats */
};
// 输出参数
solopt_t solopt = {
SOLF_XYZ,TIMES_GPST,1,3, /* posf,times,timef,timeu */
1,1,1,0,0,0,0, /* degf,outhead,outopt,outvel,datum,height,geoid */
0,2,0, /* solstatic,sstat,trace */
{0.0,0.0}, /* nmeaintv */
" ","" /* separator/program name */
};
// 文件参数
#pragma region fileOpt
filopt_t filopt = { "" };
for (int i = 0; i < FILENUM; i++)
{
char* substr = substrend(*(file + i), 4);
char* substr2 = substrend(*(file + i), 1);
if (strcmp(substr, ".atx") == 0)
{
sprintf(filopt.satantp, *(file + i)); /* satellite antenna parameters file */
sprintf(filopt.rcvantp, *(file + i)); /* receiver antenna parameters file */
}
if (strcmp(substr, ".snx") == 0)
sprintf(filopt.stapos, *(file + i)); /* station positions file */
if (strcmp(substr, ".BSX") == 0)
sprintf(filopt.dcb, *(file + i)); /* dcb data file */
if (strcmp(substr, ".erp") == 0)
sprintf(filopt.eop, *(file + i)); /* eop data file */
if (strcmp(substr, ".blq") == 0)
sprintf(filopt.blq, *(file + i)); /* ocean tide loading blq file */
if (strcmp(substr2, "o") == 0 || strcmp(substr2, "O") == 0)
{
addchar(*(file + i), outfile, "pos");
strcpy(proname, file[i]);
}
infile[i] = *(file + i);
free(substr);
free(substr2);
n += 1;
}
#pragma endregion
rov = (char*)"";
base = (char*)"";
//trace file output -----------------------------------
if (solopt.trace != 0)
{
#ifndef TRACE
#define TRACE
#endif
}
stat = postpos(ts, te, 0, 0, &prcopt, &solopt, &filopt, infile, n, outfile, rov, base);
printf("%s has done.\n", proname);
}
(4-1).read_filedir函数
/* read_filedir -----------------------------------------------------
* 根据文件夹所在的路径filePath,将文件夹下的所有数据文件名读入到file[][]中
* args : char* filepath I 文件夹路径
* char** result IO 文件夹内文件名集合
* return : NULL
* notes : FILENUM是文件夹内文件的数量,FILESIZE是文件夹内文件名的最大的长度
*-------------------------------------------------------------------*/
#define FILESIZE 100
#define FILENUM 9
static void read_filedir(char* filePath, char file[FILENUM][FILESIZE])
{
int i = 0, j = 0;
int filesize = 0;
DIR* dir = NULL;
struct dirent* entry;
char temp[FILESIZE];
if ((dir = opendir(filePath)) == NULL)
{
printf("opendir failed!");
}
else
{
while (entry = readdir(dir))
{
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
strcpy(temp, filePath);
strcat(temp, entry->d_name);
strcpy(file[i], temp);
i++;
// printf("filename%d = %s\n", i, entry->d_name);
}
}
}
(4-2).substrend函数
/* substrend -----------------------------------------------------
* 读取字符串str的后n位并返回
* args : char* str I 原字符串
* int n I 字符串的后n位
* return : char* substr O 原字符串的后n个字符
* notes :
*-------------------------------------------------------------------*/
static char* substrend(const char* str, int n)
{
int k = 0;
char* substr = (char*)malloc(n + 1);
int length = strlen(str);
if (n >= length)
{
substr = str;
return substr;
}
for (int i = length - n; i < length; i++)
{
substr[k] = str[i];
k++;
}
substr[k] = '\0';
return substr;
}
(4-3).addchar函数
static void addchar(const char* str, char * aim, char* add)
{
int count = strlen(str);
char temp[FILESIZE];
strcpy(temp, str);
*(temp + count - 1) = '\0';
strcat(temp, add);
strcpy(aim, temp);
}
(PS:这个函数写的属实是,哈哈哈哈哈哈哈哈哈)