RTKLIB模糊度固定模式介绍以及部分模糊度固定技术(附源码,基于RTKLIB)

模糊度固定简述

伪距从名称上来看,其实是一个距离,虽然该“距离”含有误差以及随机噪声较大;但接收机在第一次跟踪载波时,只能明确知道其初始相位,在信号传播过程中的周期数是没有办法明确知道的,而这个周期数就是我们要确定的模糊度。

虽然伪距精度相对较低,但多历元滤波甚至卫星数足够情况下的单历元解,也可以达到模糊度固定的门槛。 经站星双差的模糊度,可以消除绝大部分误差,比如站间单差可消除绝大部分的大气误差以及卫星轨道、钟误差;星间单差可以消除硬件通道时延相关的误差。双差后的模糊度已经恢复其整数特性,使用lambda搜索并通过ratio检验的话,回代即可计算得到模糊度固定解,达到厘米定位精度。

但是考虑到参考卫星的变换,我们在估计参数时并不是直接估计双差模糊度。如rtklib中的设计那样,状态量中估计的是站间单差模糊度,在进行模糊度固定时再进行星间单差。

rtklib中的模糊度固定模式以及实现

rtklib中共有三种模糊度固定模式:

continuous

个人称之为 滤波模式

这是经典的模式,基本上提到的kalman滤波的论文,都是此模式。即相邻历元的无周跳模糊度给与一个极小的过程噪声。 但如果你用该模式跑自己采的动态数据,会发现固定率不太稳定,有时可能比较高,但大部分情况可能固定率相对较低。比如下图中,使用某同学采集的操场数据,不存在遮挡,开启所有系统并只使用第一个频点参与定位,固定率仅有1.3%,固定率低到不可思议。即使增加第二、三频点,固定率依然不乐观。 为什么该模式这么差,可能原因是rtklib数据预处理不够完善,浮点解精度很差。

instantaneous

单历元模式

该模式中相邻历元模糊度没有相关性,如果定位模式未选择PVA模式的话,相邻历元的所有状态量均不存在相关性,即每个历元做一个最小二乘,然后直接就去尝试固定模糊度。 单历元模式的优势,就是本历元结果仅与当前历元有关,不需要考虑周跳处理问题,不需要考虑滤波发散问题。当然,仅与当前历元有关,这也是它的劣势,未充分利用历元间的相关性。 与上一小节完全一致的配置,只是将模糊度固定模式进行更改,模糊度固定率惊人的达到了94%。

fix and hold

hold模式

该模式是在滤波模式的基础上,如果模糊度固定正确,即会将固定的模糊度约束浮点滤波器。当然,如果模糊度错误固定,会导致浮点解出现较大偏差,导致较长时间的无法固定。

部分模糊度固定技术

部分模糊度固定,其实与上一小节提到的固定模式没有关系,任何一个模式都可以使用部分模糊度固定。 如果熟悉rtklib,就知道其模糊度固定时,直接将模糊度全集进行搜索,如果无法通过ratio检验则判定固定失败,结束固定流程,然后输出模糊度浮点解。

当然,我们可以在配置文件中通过设置参与固定的卫星的高度角,来筛选参与固定的卫星,但一个历元依然只会尝试一次固定,部分模糊度固定技术就是在一个历元中进行多次模糊度固定的尝试,通过优选模糊度子集来进一步提升模糊度固定成功率。

流程如下:

如果我们认为卫星高度角越高的卫星,其模糊度的精度以及被固定成功的概率更高,那么在选择固定的模糊度子集时,就可以将卫星高度角较高的卫星最后删除,优先删除高度角较低的卫星。 原理很简单,基于rtklib实现需要熟悉其固定的流程,尤其是站间单差模糊度转站星双差模糊度的实现流程,在此不在展开。

代码实现

首先在ssat_t结构体中,针对单个卫星每个频率增加以下标识,用来进行模糊度子集选取。

uint8_t amb_flag[NFREQ]; /* ambiguity fix flag (0/1:no need to fix,2:try to fix,3: fix ref sat 4: fix) */
double amb_weight[NFREQ]; /* ambiguity weight for partial ambiguity resolution  */

同时,使用卫星的高度角进行填充,同时考虑到大部分消费级模组第一频点观测值都相对比较充足,所以我们提升了第一频点的权重,优先删除其他频点的模糊度信息。

static void fillup_amb_weight_flag(rtk_t *rtk)
{
    int i, j, na = rtk->na;
    for (i = 0; i < MAXSAT; i++)
    {
        /* check the system to fix */
        int sys = satsys(i+1, NULL);
        if (sys == SYS_GLO && rtk->opt.glomodear == 0)
        {
            continue;
        }
        if (sys == SYS_CMP && rtk->opt.bdsmodear == 0)
        {
            continue;
        }
        for (j = 0; j < NFREQ; j++)
        {
            if (rtk->x[na + j * MAXSAT + i] == 0.0 ||
                !rtk->ssat[i].vsat[j] || !rtk->ssat[i].half[j])
            {
                continue;
            }
            if (rtk->ssat[i].lock[j] < 0 || (rtk->ssat[i ].slip[j] & 2) ||
                rtk->ssat[i].azel[1] < rtk->opt.elmaskar)
            {
                continue;
            }
            /* We simply use the elevation as the amb weight, future extend to other feature */
            rtk->ssat[i].amb_weight[j] = rtk->ssat[i].azel[1] * R2D;
            if (j == 0)
            {
                /* give more weight to L1 frequency */
                rtk->ssat[i].amb_weight[j] += 35.0;
            }
            rtk->ssat[i].amb_flag[j] = 2;
        }
    }
}

增加部分模糊度的主逻辑,该逻辑会调用rtklib原始的resamb_LAMBDA函数,代码如下:

/* partial resolve integer ambiguity by LAMBDA ---------------------------------------*/
static int resamb_partial(rtk_t *rtk, double *bias, double *xa) 
{
    int i, j;

    /* reset the ambiguity flag and weight */
    for (i = 0; i < MAXSAT; i++)
    {
        for (j = 0; j < NFREQ; j++)
        {
            rtk->ssat[i].amb_flag[j] = 0;
            rtk->ssat[i].amb_weight[j] = 0.0;
        }
    }
    fillup_amb_weight_flag(rtk);
    
    /* iteration for partial resolution */
    int nb = 0;
    while ((nb = resamb_LAMBDA(rtk, bias, xa)) <= 0)
    {
        /* find the min amb weight and mark */
        double min_weight = 999.9;
        int sat_idx = -1, freq_idx = -1;
        for (i = 0; i < MAXSAT; i++)
        {
            for (j = 0; j < NFREQ; j++)
            {
                if (rtk->ssat[i].amb_flag[j] >= 2)
                {
                    if(rtk->ssat[i].amb_weight[j] < min_weight)
                    {
                        min_weight = rtk->ssat[i].amb_weight[j];
                        sat_idx = i;
                        freq_idx = j;
                    }
                }
            }
        }
        if(sat_idx >=0 && freq_idx >= 0)
        {
            rtk->ssat[sat_idx].amb_flag[freq_idx] = 1;
        }

        /* check if have enough satellites to fix */
        if (sat_num_of_to_fix(rtk) <= 5)
        {
            return 0;
        }
    }
    return nb;
}
当然,将resamb_LAMBDA函数中的ddidx函数进行了更改,更改为:
/* index for SD to DD transformation matrix D 
 * in this function, we use the ssat->amb_flag and ->amb_weight to 
 * select the ref satellite and to select the ambiguity subset to fix
 * */
static int ddidx_with_amb_weight_flag(rtk_t *rtk, int *ix)

具体该函数实现,见源码。

测试结果

使用上一小节 instantaneous模式的配置,开启部分模糊度固定的逻辑,固定率从94%提升到接近99%。

代码

公众号后台回复 git 获取码云地址,clone到本地后请切换到rtk分支查看。

公众号

有时会将代码 或者资源放在个人公众号上,有问题,在公众号后台回复,也回答的比较快一些,欢迎关注 GNSS和自动驾驶

  • 8
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
rtklib是一种用于实现实时精确定位的开源软件。在实时精确定位过程中,固定模糊是一个非常重要的步骤,它帮助减小GPS接收机测量误差,提高定位的准确性。 rtklib中的实时固定模糊算法主要包含以下几个步骤: 1. 模糊初始化:在初始阶段,模糊会被初始化为宽松的值,因为此时还没有足够的数据来计算准确的模糊。 2. 模糊首次固定:当有足够的数据可用时,rtklib会进行模糊的首次固定。这个步骤利用载波相位数据和伪距数据进行计算,通过解算两个接收机之间的距离,来确定模糊的候选值。 3. 模糊跟踪:在固定模糊之后,rtklib会通过持续地跟踪载波相位和伪距数据来确定最准确的模糊值。这个过程包括误差补偿、模糊模糊解算及模糊跟踪。 4. 模糊验证:为了确保固定模糊是有效的,rtklib会进行模糊的验证。通过对比解算得到的载波相位和伪距之间的差异,来判断模糊是否有效。 5. 模糊更新:如果模糊验证通过,rtklib会根据最新的载波相位和伪距数据来更新模糊值。这个过程是不断进行的,以确保模糊能够及时准确地固定。 综上所述,rtklib实时ppp模糊固定算法通过对载波相位和伪距数据进行解算和跟踪,来确定最准确的模糊值,从而提高实时精确定位的准确性。这个算法是实时定位过程中的关键步骤之一,对于定位精的提升起到了重要的作用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值