学习rtklib(三)

1.addobsdata函数

在了解这个函数之前,应该先说这个函数中对应的几个结构体。

1.1obsd_t结构体

这个结构体是在rtklib.h中定义的一个用来存储某个历元中的某个卫星的观测值的。定义如下:

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;

之前的博客说过这里面的数组名称代表观测值类型,数组的下标代表载波类型。其中的数组名称如果看过RINEX的格式说明,一眼就能知道代表的意思。

1.2obs_t结构体

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

这个结构体中存储的是所有的观测值数据,n代表实际存储的观测值结构体的个数,nmax代表的是最多存储多少个观测值结构体,如果超过最大个数,需要重新开辟内存空间。在C++中,内存报错是比较讨厌的一类错误。在rtklib中,我们会发现其中的异常捕捉机制运用的非常好,几乎是一步一trace,这也让我学到了需要利用trace语句来处理异常,以便调试代码。

1.3主要函数

static int addobsdata(obs_t *obs, const obsd_t *data)

在了解了上面的结构体之后,就可以知道这个函数就是添加新的观测值,而且还可以很轻松的读懂这个函数的每一条语句。当然,如果只是想要对rtklib有整体的把握,就不用太过于纠结每一个语句了。

2.set_index函数

这个函数是一个比较重要的函数。而且比较容易让人迷惑。顾名思义,这个函数就是为了建立之前我们用到的索引。大家可能忘了,在读取观测值文件的时候,我们用到了索引函数,就是根据观测值文件头中的SYS / # / OBS TYPES这一行的东西。

static void set_index(double ver, int sys, const char *opt, char tobs[MAXOBSTYPE][4], sigind_t *ind)

函数的参数意义如下

ver        //RINEX文件版本号
sys        //卫星所属系统
opt        //选项
tobs       //观测值类型数组
ind        //得到的索引

其中,选项是什么可以先不用知道。观测值类型数组是一个比较容易困惑的地方。之前我们用过这样的一个数组tobs[][MAXOBSTYPE][4],这个是在读取RIENX观测值文件的文件头得到的。里面存储了下面的内容。
观测值类型说明
还是举个例子来说明吧,针对于数组tobs[][MAXOBSTYPE][4]来说,tobs[0]意味着一个指向二位数组的指针,而0代表的是GPS系统,因此tobs[0]代表的是GPS系统的观测值类型。再看tobs[0][0],这个就是指向一个一维数组的指针,代表着GPS系统的第一个观测值类型,也就是说tobs[0][0]="C1C ",注意,一定是一个四位的字符串,因为在RINEX的格式说明中,每一个观测值类型占四位,包括了最后的一个空格。也就是说tobs[0][0]代表着GPS系统中利用L1载波上的C/A码测得的伪距。这下应该理解了吧。哎,因为我当时就迷糊了好一段时间,所以就把这个地方仔细说一下,一是为了防止我以后忘了,二是给大家提个醒。不要嫌弃我啰嗦啊(〃‘▽’〃)

tobs[][MAXOBSTYPE][4]             //以前用的
tobs[MAXOBSTYPE][4]               //本函数中的

对比上面两个可以发现,数组维数少了一维,但是由于函数的参数中已经指明了系统,所以就可以将三维数组退化成为了二维数组了。
参数说明完了,下面看这个函数中用了哪些子函数吧。

2.1obs2code函数

这个函数是位于rtkcnm.c中的一个函数,代码长度不长,但是可能比较难理解。先看主函数中调用obs2code函数的语句吧。

ind->code[i]=obs2code(tobs[i]+1,ind->frq+i);

还是老样子,看传递的参数。tobs[i]+1,这个很考验C语言的指针方面的功底了。由于tobs是一个二维数组,因此tobs[i]+1应该表示的是二维数组中的第i+1个字符串向后舍弃第一位后的子串。说起来很拗口,举个例子就好了。比如对于GPS系统来说,tobs[0]+1就是“C1C "中的"1C "子串。也就是传递了子串和索引中的频率。由于索引中的频率尚未有值,因此可以推断出来,这个函数一定是根据tobs[i]+1来为索引中的频率赋值。
下面来看obs2code的函数体

extern unsigned char obs2code(const char *obs, int *freq)
{
    int i;
    if (freq) *freq=0;
    for (i=1;*obscodes[i];i++) {
        if (strcmp(obscodes[i],obs)) continue;
        if (freq) *freq=obsfreqs[i];
        return (unsigned char)i;
    }
    return CODE_NONE;
}

这个里面的obscodes和obsfreqs都是在rtkcnm.c的文件开头定义的数组。

static char *obscodes[]={       /* observation code strings */
    
    ""  ,"1C","1P","1W","1Y", "1M","1N","1S","1L","1E", /*  0- 9 */
    "1A","1B","1X","1Z","2C", "2D","2S","2L","2X","2P", /* 10-19 */
    "2W","2Y","2M","2N","5I", "5Q","5X","7I","7Q","7X", /* 20-29 */
    "6A","6B","6C","6X","6Z", "6S","6L","8L","8Q","8X", /* 30-39 */
    "2I","2Q","6I","6Q","3I", "3Q","3X",""              /* 40-49 */
};
static unsigned char obsfreqs[]={ /* 1:L1,2:L2,3:L5,4:L6,5:L7,6:L8,7:L3 */
    
    0, 1, 1, 1, 1,  1, 1, 1, 1, 1, /*  0- 9 */
    1, 1, 1, 1, 2,  2, 2, 2, 2, 2, /* 10-19 */
    2, 2, 2, 2, 3,  3, 3, 5, 5, 5, /* 20-29 */
    4, 4, 4, 4, 4,  4, 4, 6, 6, 6, /* 30-39 */
    2, 2, 4, 4, 3,  3, 3, 0        /* 40-49 */
};

也就是说,obscodes中定义的全部是卫星观测值类型的后两个字母。再看obs2code函数体,可以发现,这个函数的作用就是在所有的观测值类型的后两位字母中找到传入的观测值类型。然后将对应的载波赋值给索引中的频率值,最后返回的是唯一确定的位置。
回到主函数,主函数中虽然有很多语句,但是我认为最终要的就是下面的语句,其它的语句可以暂时先不考虑,以后用到了再回头看。

for (i=n=0;*tobs[i];i++,n++) {
        ind->code[i]=obs2code(tobs[i]+1,ind->frq+i);
        ind->type[i]=(p=strchr(obscodes,tobs[i][0]))?(int)(p-obscodes):0;
        ind->pri[i]=getcodepri(sys,ind->code[i],opt);
        ind->pos[i]=-1;
    }
static const char obscodes[]="CLDS";

我感觉解释完第一句之后,其它的句子就可以类推出来了。

函数总结

上面说了好多,总而言之,这个函数就是建立索引的一个函数,索引就是将o文件头中的观测值类型分割开来,分别存入不同的数组中,这些数组合起来构成了索引。

总结

这一篇就先写这么多吧,才写了两个函数,实在是太多了,我怕我自己忘记的东西实在是太多了,我要抓紧时间写了,不然之后又忘记了,感觉自己活成了一条金鱼,只有几秒的记忆(▼皿▼#)

  • 18
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
RTKLib是一种基于GNSS(全球导航卫星系统)的实时运动定位库。它提供了一系列的工具和算法,用于处理GNSS观测数据,进行精确的实时或者后处理定位。下面是一个关于RTKLib学习笔记的概述: 1. RTKLib简介: - RTKLib是由Tomoji Takasu开发的开源软件库,用于实时运动定位和后处理。 - 它支持多种GNSS系统,包括GPS、GLONASS、Galileo、BeiDou等。 - RTKLib提供了一系列的功能模块,包括数据处理、定位算法和可视化工具等。 2. RTKLib的安装: - RTKLib可以从官方网站(http://www.rtklib.com)下载最新的源代码。 - 根据操作系统选择合适的编译工具(如GCC、MinGW等)进行编译。 - 编译完成后,可以得到可执行文件和相关的库文件。 3. RTKLib的数据处理: - RTKLib支持多种数据格式,包括RINEX、SP3、Nav等。 - 使用RTKConv工具可以将原始观测数据转换为RTKLib可识别的格式。 - 使用RTKPLOT工具可以对观测数据进行可视化分析。 4. RTKLib的定位算法: - RTKLib提供了多种定位算法,包括单点定位、差分定位和RTK(实时动态定位)等。 - 单点定位方法适用于无差分数据,可以得到相对较低的定位精度。 - 差分定位方法通过使用基站观测数据进行差分运算,提高了定位精度。 - RTK定位方法使用基站和移动站的观测数据,实现了高精度的实时定位。 5. RTKLib的应用: - RTKLib广泛应用于航空、测绘、农业、机器人等领域,用于精确的定位和导航。 - 它可以用于无人机、自动驾驶、精准农业等应用场景。 - RTKLib还支持多种操作系统,包括Windows、Linux和Android等。 以上是关于RTKLib学习笔记的基本概述。希望对你的学习有所帮助!如果你有更具体的问题,可以继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值