当前位置:网站首页>基于rtklib源码进行片上移植的思路分享

基于rtklib源码进行片上移植的思路分享

2022-07-06 09:18:00 Proletarians

移植步骤分享

在移植代码前,一定要对rtklib中rtk的流程熟稔于心。

  • 1.obs和nav数据输入
  • 2.单点结果
  • 3.基站两端的卫星位置计算
  • 4.base端zdres
  • 5.共视星选取
  • 6.时间更新
  • 7.rover端zdres
  • 8.ddres
  • 9.量测更新

  • 这些步骤在移植过程中,一定要按照顺序来进行,可以减少一些错误的发生.比如上述单点结果,如果是芯片自己的单点结果,在共视星选取的时候,要注意azel数组的填充.

移植前的准备工作

希望大家可以通过我分享的rtk项目移植经验提高大家工作和学习中的开发效率,我想对移植的过程分以下几步进行讲解:

1. 对数据格式的准备

1.1 熟悉三种数据格式,rinex、ubx、rtcm。

  • (1) rinex,这个是我们接触最多的观测值格式,而且说明文档网上也容易下载,可以移步igs网站下载。如果是基于自家公司芯片开发的话,我们在ARM中已经对DSP的数据包进行解析,不仅可以拿到观测值信息,还有一些接收机系统误差相关的信息可以获取,方便我们进行误差建模。
  • (2) ubx,这种格式也可以通过ublox的官网去拿到手册,里边有对ublox的格式介绍。如果你是买的芯片进行开发,那么数据格式为ubx的话,就需要进行观测值的解析了,如果是这样的话,那么解析流程可以参考rtknavi软件输出的rover为com口ubx格式,base为ntrip格式的rtk来进行解析,可以进行源码的流程去代码看看咋走的。
  • (3) rtcm,这种格式的说明文档不好获取,不过rtklib中的源码已经有了rtcm格式的编解码,即使不看格式文档,通过源码也能理解rtcm格式,rtcm格式是base端需要使用的,如果我们使用千寻服务的话,就需要对rtcm格式的解析。

上述三种格式中,ubx和rtcm需要将观测值的格式转成rinex格式,这种做的目的是利用rtklib中的obs_t结构体,减少移植代码的工作量。


1.2 对obs和nav数据进行分析

  • 我们拿到了芯片的观测值,就可以直接使用了吗?显然这样做是不严谨的,我们还需要对芯片观测值进行质量分析,粗差探测、周跳探测、伪距残差、相位残差、o/slip、snr等方面。Nav的分析就比较简单了,直接和igs的广播星历进行比较。
  • 千寻基站数据的话,我们在使用过程中,要对切站的逻辑进行处理,staid会变化,这个属于rtcm协议中基站信息的内容。

1.3 数据输入端的逻辑设计

  • 流动站端: 我们可以将obs和nav拿到,那么我们要先进行简单的判断,obs和nav的个数要大于等于4;
  • 基站端: 如果obs和nav个数满足要求了,那么我们代码中就对基站端(rtcm)的数据进行处理,这时候代码要有解析rtcm的逻辑,此时可以拿到基站观测值的数据。

2. rtk代码移植的注意事项

2.1 数组大小的修改

我们知道GPS的总卫星数32,但是我们不可能一下子看到32颗星,通常接收机通道对多模捕获的时候每个卫星系统的最大通道是固定的,根据这个思路,就方便我们去缩减内存了。比如我们对GPS的通道MAX值设为15,那么相比32少了一半多。
我们开发的时候对每个卫星的最大通道都进行宏定义的话,那么四大系统都开的话,我给出的建议是58为最大值。那么相比较rtklib中的MAXSAT是不是少了很多呢。

2.2 所有设计的动态内存分配都要改成静态,设置固定大小。

2.3 移植过程中,一定要对粗差探测进行处理,否则会影响你的模糊度固定不了,甚至fix解的结果都是错误的。(接收机的数据质量良莠不齐)

2.4 所有涉及到索引的地方都要检查修改.

举两个例子说明

  • 例子1,比较简单
#ifndef MAXOBS
#define MAXOBS 96 /* max number of obs in an epoch */
#endif
obsd_t *obs_ptr = (obsd_t *)malloc(sizeof(obsd_t)*MAXOBS*2); /* for rover and base */

我们假设一下,我只用单GPS来做rtk,obs开这么大的内存多浪费,如果我把GPS的最大通道设置为15,那么基站和流动站的obs最大才15 * 2=30,相比较96 * 2=192.我们可以把基站和流动站的数据定义在rtk结构体中,和sol在同一级,那么每次传值的时候就很好拿了.


  • 例子2,更新状态
    我们归根结底要对x和P进行操作,代码如下
        /* reset phase-bias if instantaneous AR or expire obs outage counter */
        for (i=1;i<=MAXSAT;i++) {
    
            
            reset=++rtk->ssat[i-1].outc[k]>(uint32_t)rtk->opt.maxout;
            
            if (rtk->opt.modear==ARMODE_INST&&rtk->x[IB(i,k,&rtk->opt)]!=0.0) {
    
                initx(rtk,0.0,0.0,IB(i,k,&rtk->opt));
            }
            else if (reset&&rtk->x[IB(i,k,&rtk->opt)]!=0.0) {
    
                initx(rtk,0.0,0.0,IB(i,k,&rtk->opt));
                trace(3,"udbias : obs outage counter overflow (sat=%3d L%d n=%d)\n",
                      i,k+1,rtk->ssat[i-1].outc[k]);
                rtk->ssat[i-1].outc[k]=0;
            }
            if (rtk->opt.modear!=ARMODE_INST&&reset) {
    
                rtk->ssat[i-1].lock[k]=-rtk->opt.minlock;
            }
        }
        
        #define MAXSAT (NSATGPS+NSATGLO+NSATGAL+NSATQZS+NSATCMP+NSATIRN+NSATSBS+NSATLEO)

从上述代码中,我们可以看到,MAXSAT的宏定义,循环的时候次数很多,还是单GPS的例子,我只需要循环15次就ok了,同样的ssat也要修改,状态x参数怎么放置呢?xyz3个状态的位置是固定的,那么索引从3开始的phase bias可以可以只放前一历元共视星的相位偏差,那么前一历元和当前历元索引如何对应上呢,rtk结构体中要设置当前历元共识卫星数组和前一历元共识卫星数组,通过比较拿到索引来进行x的取值,对应的P的取值也是如此.这两处是我们移植是最需要关注的索引.


打印信息一定要全面,多注意写条件的设置使代码健壮,方便分析问题和检索错误.

原网站

版权声明
本文为[Proletarians]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_43074576/article/details/125249437