文章目录
pppos udstate_ppp udbias_ppp corr_meas ppp_res
欢迎关注个人公众号:导航员学习札记
我所基于的代码版本是RTKlib 2.4.3的一个拓展版本RTKexplore Demo5,这个版本主要针对低成本的GNSS进行了一些改进完善。
pppos
extern void pppos ( rtk_t * rtk, const obsd_t * obs, int n, const nav_t * nav)
所在文件 :ppp.c功能说明 :PPP处理参数说明 :
args: IO rtk_t * rtk rtk solution structure
I const obsd_t * obs 当前历元观测值
I int n 当前移动站观测值数目
I const nav_t * nav 星历
Created with Raphaël 2.3.0
pppos
udstate_ppp
satposs
testeclipse(配置可选)
tidedisp(配置可选)
filter
ppp_res
ppp_ar
update_stat
End
调用udstate_ppp函数进行卡尔曼滤波的一步预测; 调用satposs函数计算卫星位置; 如果在配置中选择排除block IIA卫星,调用testeclipse函数,将这些卫星的位置、速度置0; 如果在配置中选择潮汐修正,调用tidedisp函数进行潮汐修正; 调用ppp_res函数计算预测值与量测值之间的残差; 待用filter函数进行卡尔曼滤波的量测更新; 调用ppp_res函数计算量测更新后的残差; 调用ppp_ar进行整周模糊度结算,并调用ppp_res进行残差计算; 调用update_stat更新输入、输出参数rtk solution的状态
需要注意的是,步骤8中ppp_ar是个空函数,返回值为0,因此实际后面的ppp_res函数也不会被调用。如此来看,实际PPP的解为通过卡尔曼滤波得到的浮点解。 satposs和相对定位中的函数一致,不再进行解析,可参考RTKLIB源码解析——单点定位
udstate_ppp
static void udstate_ppp ( rtk_t * rtk, const obsd_t * obs, int n, const nav_t * nav)
所在文件 :ppp.c功能说明 :进行卡尔曼滤波的一步预测,更新rtk->x状态量值参数说明 :
args: IO rtk_t * rtk rtk solution structure
I const obsd_t * obs 当前历元观测值
I int n 当前移动站观测值数目
I const nav_t * nav 星历
Created with Raphaël 2.3.0
udstate_ppp
udpos_ppp
udclk_ppp
udtrop_ppp(配置可选)
udiono_ppp(配置可选)
udbias_ppp
End
调用udpos_ppp函数位置、速度、加速度状态量 rtk->x以及相应协方差阵 rtk->P的更新; 调用udclk_ppp函数,更新钟差状态量(以gpst为基准); 如果在配置中选择的对流层模型为ZTD estimation或者ZTD+grad estimation,调用udtrop_ppp进行对流层参数状态量的更新; 如果在配置中选择电离层模型为estimation,调用udiono_ppp函数,更新电离层误差参数状态量; 如果选择的频率数>=3,则进行L5 dcb状态量的更新; 调用udbias_ppp函数进行相位bias状态量的更新。
参考RTklib manual 来看,PPP算法中使用的量测量为“无电离层组合的伪距、载波相位”,所以配置中可以将电离层模型选择为“Iono free LC”。通过参考RTKexplorer博客Exploring kinematic single-receiver solutions with RTKLIB and the u-blox F9P. 中的配置,对流层模型应该至少配置为ZTD estimation。我在之后的博客中会测试一下不同的PPP配置对精度有多大的影响。 参考 RTKLIB Manual 可知状态量包括位置、速度、接收机钟差、对流层参数、卫星相位偏差; udpos_ppp、udtrop_ppp、udiono_ppp函数与之前相对定位中udpos、udtrop、udion函数流程基本一致,就不再详细解释,具体可参考RTKlib相对定位源码解析: udstate函数。由于udbias_ppp和相对定位中不同,因此在下文中进行解析。
udbias_ppp
static void udbias_ppp ( rtk_t * rtk, const obsd_t * obs, int n, const nav_t * nav)
所在文件 :ppp.c功能说明 :进行相位偏差状态量和协方差阵的一步预测参数说明 :
args: IO rtk_t * rtk rtk solution structure
I const obsd_t * obs 当前历元观测值
I int n 当前移动站观测值数目
I const nav_t * nav 星历
首先是对所有共视星进行周跳检测:调用了detslp_ll函数,根据LLI来判断基站和移动站周跳;然后调用detslp_gf利用几何无关组合进行周跳检测;最后调用了detslp_gf_mw函数进行周跳检测。对RTKlib的周跳检测函数,我专门写了一篇博客解析RTKlib源码解析:ppp和rtkpost中的周跳检测函数 对所有卫星进行循环,判断是否需要重置单差相位偏移状态量。如果所配置的AR的模式为instantaneous(实际由于当前PPP中使用的是浮点解,通常将PPP的AR配置为OFF),或者卫星载波相位的中断次数大于配置中所设置的最大次数,则将单差相位偏移状态量重置为0; 对每一组观测数据,调用 corr_meas函数对伪距、载波相位进行修正,并计算无电离层组合的伪距、载波相位量测量Pc和Lc; 将每颗卫星的载波相位偏差bias初始化为0,如果电离层模型为电离层无关模型,则直接计算bias[i]=Lc-Pc;否则的话,通过伪距计算电离层延迟ion=(obs[i].P[0]-obs[i].P[l])/(1.0-SQR(lam[l]/lam[0]));由于L1和L2伪距相减后,只剩下L1和L2的电离层误差之差,以及伪距噪声项,因此由此计算出来的电离层误差实际包含了伪距噪声,误差相对较大。利用修正电离层误差后的伪距和载波相位之差计算bias: bias[i]=L[f]-P[f]+2.0ion SQR(lam[f]/lam[0]); 计算每颗卫星的bias与载波相位偏差状态量rtk->x之间的偏差offset之和; 在原有的载波相位偏差状态量上加上offset的平均值,以此来作为载波相位偏差一步预测值:rtk->x[j]+=offset/k; 7.对每颗卫星循环,更新一步预测协方差阵,对有周跳的卫星、或者没有初始化载波相位偏差状态量的卫星,用之前计算的bias值重新初始化载波相位偏差状态量。
corr_meas
static void corr_meas ( const obsd_t * obs, const nav_t * nav, const double * azel,
const prcopt_t * opt, const double * dantr,
const double * dants, double phw, double * L, double * P,
double * Lc, double * Pc)
所在文件 :ppp.c功能说明 :计算经过接收机天线修正、相位缠绕校正、SSR修正或者dcb 修正后的伪距、载波相位量测量,并计算无电离层组合的伪距、载波相位值Lc,Pc参数说明 :
args: I const obsd_t * obs 当前历元观测值
I const nav_t * nav 星历
I const double * azel 方位角和俯仰角 ( rad)
I const prcopt_t * opt 处理选项
I const double * dantr 接收机天线校正值
I const double * dants 卫星天线校正值
I double phw 相位缠绕校正值
O double * L 修正后的载波相位
O double * P 修正后的伪距值
O double * Lc 无电离层组合的载波相位值
O double * Pc 无电离层组合的伪距值
调用 testsnr函数检查观测值的信噪比是否大于mask; 对伪距天线修正、相位缠绕校正,对载波相位进行天线修正; 如果星历类型是broadcast + SSR_APC或者broadcast + SSR_COM,对伪距值进行ssr 修正;如果是其他星历类型,进行 DCB 校正; 计算无电离层组合的伪距、载波相位值Lc,Pc
ppp_res
static int ppp_res ( int post, const obsd_t * obs, int n, const double * rs,
const double * dts, const double * var_rs, const int * svh,
const double * dr, int * exc, const nav_t * nav,
const double * x, rtk_t * rtk, double * v, double * H, double * R,
double * azel)
所在文件 :ppp.c功能说明 :计算载波相位和伪距残差参数说明 :
args: I int post 是否是修正后残差计算标志
I const obsd_t * obs 当前历元观测值
I int n 当前移动站观测值数目
I const double * dts 卫星钟差
I const double * var_rs 星位置和钟差的协方差
I const int * svh 卫星健康标志
I const double * dr 地球潮汐位移
IO int * exc 卫星排除标志
I const nav_t * nav 星历
IO const double * x 状态量
IO rtk_t * rtk rtk solution structure
IO double * v 载波相位和伪距残差
IO double * H 卡尔曼滤波中的观测矩阵
IO double * R 测量误差的协方差矩阵
I const double * azel 方位角和俯仰角 ( rad)
把卫星的有效标志位均置0,rtk->ssat[i].vsat[j]=0; 在一步预测值x[i]基础上加上潮汐修正,作为移动站位置:rr[i]=x[i]+dr[i]; 对每颗星进行循环,根据移动站位置,计算卫星仰角,如果小于设定阈值,排除该卫星,并且检查该卫星系统、单点定位卫星有效标志、是否在设置中排除,重置排除标志:exc[i]=1; 调用model_trop函数计算对流层误差dtrp,调用model_iono函数计算电离层误差dion; 调用satantpcv函数计算卫星天线校正参数dants;调用antmodel函数计算根据接收机天线的相位中心参数计算天线偏移量dantr,该函数在此博客曾进行解析; 调用model_phw函数计算相位缠绕校正值rtk->ssat[sat-1].phw; 调用corr_meas函数对伪距和载波相位进行修正,得到量测量; 计算量测矩阵H和残差v,相位残差存放在 rtk->ssat[sat-1].resc中,伪距残差在rtk->ssat[sat-1].resp中; 综合考虑伪距(载波相位)噪声、对流层噪声、电离层噪声、卫星位置钟差噪声后,作为量测噪声;如果是GLONASS卫星,在伪距量测噪声上,还要加上IFB噪声(频间差噪声); 如果是 pre-fit,即!post的情况,如果某颗残差值大于阈值,将这颗星排除; 如果post为1,某颗残差值大于阈值,将这颗星记录下来;整个循环结束; 如果post为1,找到11步中残差值最大的那颗星,将其排除。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)