当前位置:网站首页>rtklib2.4.3 b34 单点定位的一个bug

rtklib2.4.3 b34 单点定位的一个bug

2022-06-23 03:53:00 奔跑的橘子

单点定位部分的一个问题

这是一个本次更新引入的新问题,以前是没有的,如下图:

  • 如果没有对代码重新编译则不会遇到本文将要提到的问题,因为release版本的程序是不会有问题的
  • 如果对代码进行debug,那么也不会遇到这个问题
  • 如果尝试直接运行debug版本的程序,那么大概率会出现此问题
    在这里插入图片描述

老生常谈的root cause

这个issue是由局部变量没有初始化引起的,因此想要fix这个issue也很简单,只要将这四个变量dion,dtrp,vmeas,vion,vtrp初始化即可。从算法角度讲,这四个变量只有在第一次迭代的时候不会初始化,所以我们将其初始化为0.

static int rescode(int iter, const obsd_t *obs, int n, const double *rs,
...
{
    
    gtime_t time;
    double r,freq,dion,dtrp,vmeas,vion,vtrp,rr[3],pos[3],dtr,e[3],P;
   ...   
        if (iter>0) {
    
            // 这里计算电离层 对流程延迟及方差
        } 
        /* pseudorange residual */
        v[nv]=P-(r+dtr-CLIGHT*dts[i*2]+dion+dtrp); // this is line 306
   ...
}

从代码角度讲,这段代码有两个地方对我们普通开发者来说不太好(代码是大神写的嘛,大神可以随便写)。这两个地方都很老生常谈,只要有一个地方注意了,就不会产生这个issue.

  • 局部变量没有初始化,何止局部变量,一切变量都是要初始化的,这真的是一个非常好的习惯
  • if 没有else。可能在以下两种情况下else没有任何意义。
    if(true),ture也可能是表达式等等,无论何种考虑出现了这种情况,反正他出现了
    else中不需要做任何事情。
    以上两种情况,写不写else对程序执行来说没有任何区别。但是对避错和阅读代码来说区别很大。因为只要写了else就证明了代码的作者考虑了else这个情况,这是一种刻意行为。所以此时的else建议写成如下形式,
if(...) {
    
//...
} else {
    
    NULL; // REMINDER!:do nothing on purpose
}

亦或是如下形式也是可以接受的,

if(...) {
    
//...
} else {
    } // REMINDER!:do nothing on purpose

为何如此修改

那么作者为何做了如下修改呢?道理很简单,我们看一下代码,这个if里做了以下四件事,而这些都是与接收机位置有关的量。虽然这个位置不需要很准,概略坐标就够了。但是我们知道在pvt解算时,初始位置是不知道的,这里计算这些量没有任何意义,且计算的结果是错的,起了副作用,还不如不算。这个改动不仅节省了CPU,个人猜测还会提高迭代效率。

  • 仰角mask
  • SNR mask
  • 电离层延迟计算
  • 对流层延迟计算
if (iter>0) {
    
    /* test elevation mask */
            if (satazel(pos,e,azel+i*2)<opt->elmin) continue;
            
            /* test SNR mask */
            if (!snrmask(obs+i,azel+i*2,opt)) continue;
            
            /* ionospheric correction */
            if (!ionocorr(time,nav,sat,pos,azel+i*2,opt->ionoopt,&dion,&vion)) {
    
                continue;
            }
            if ((freq=sat2freq(sat,obs[i].code[0],nav))==0.0) continue;
            dion*=SQR(FREQ1/freq);
            vion*=SQR(FREQ1/freq);
            
            /* tropospheric correction */
            if (!tropcorr(time,nav,pos,azel+i*2,opt->tropopt,&dtrp,&vtrp)) {
    
                continue;
            }
        } 

于是改动

于是,fix的方法也就水到渠成了,大概下边这样改,

    dion = 0; dtrp = 0; vion = 0; vtrp = 0;
    
    for (i=*ns=0;i<n&&i<MAXOBS;i++) {
    

或者如此,

if (iter>0) {
    
            // 这里计算电离层 对流程延迟及方差
} else {
    
    dion = 0; dtrp = 0; vion = 0; vtrp = 0;
}
原网站

版权声明
本文为[奔跑的橘子]所创,转载请带上原文链接,感谢
https://xiaoqiang666.blog.csdn.net/article/details/115533384