当前位置: 首页 > web >正文

[学习]RTKLib详解:ppp.c与ppp_ar.c

文章目录

  • RTKLib详解:ppp.c与ppp_ar.c
  • Part A: ppp.c
    • 一、整体作用与工作流程
    • 二、核心函数说明
      • 1. `pppos`
      • 2. `res_ppp`
      • 3. `tide_solid`
      • 4. `prectrop`
      • 5. `corrmeas`
      • 6. `udbias_ppp`
    • 三、数学原理补充
    • 四、代码特点
  • Part B: ppp_ar.c
    • 一、整体作用与工作流程分析
    • 二、函数功能与参数说明
      • 1. `lam_LC(i, j, k)`
      • 2. `L_LC(i, j, k, L)`
      • 3. `P_LC(i, j, k, P)`
      • 4. `var_LC(i, j, k, sig)`
      • 5. `conffunc(N, B, sig)`
      • 6. `average_LC(rtk, obs, n, nav, azel)`
      • 7. `fix_amb_WL(rtk, nav, sat1, sat2, NW)`
      • 8. `fix_amb_ROUND(rtk, sat1, sat2, NW, n)`
      • 9. `fix_amb_ILS(rtk, sat1, sat2, NW, n)`
      • 10. `pppamb(rtk, obs, n, nav, azel)`
    • 三、数学推导补充
      • 1.宽巷与窄巷组合
      • 2.整数最小二乘(ILS)

RTKLib详解:ppp.c与ppp_ar.c

本文是 RTKLlib详解 系列文章的一篇,目前该系列文章还在持续总结写作中,以发表的如下,有兴趣的可以翻阅。

[学习] RTKlib详解:功能、工具与源码结构解析
[学习]RTKLib详解:pntpos.c与postpos.c
[学习]RTKLib详解:rtkcmn.c与rtkpos.c
[学习]RTKLib详解:ppp.c与ppp_ar.c


Part A: ppp.c


一、整体作用与工作流程

该代码实现了GNSS精密单点定位(PPP)算法,基于非差相位和伪距观测值进行卡尔曼滤波状态估计,该代码完整实现了PPP算法的所有核心环节,通过模块化设计将各个误差源独立处理,便于维护和扩展。主要流程包括:

  1. 状态时间更新:通过udstate_ppp更新接收机位置、钟差、对流层参数和相位偏差
  2. 观测方程构建:res_ppp计算理论距离与观测值的残差
  3. 卡尔曼滤波更新:通过filter函数进行状态估计更新
  4. 模糊度固定:pppamb尝试进行整周模糊度固定

具体的函数调用关系如下:

pppos
udstate_ppp
res_ppp
filter
pppamb
udpos_ppp
udclk_ppp
udtrop_ppp
udbias_ppp
corrmeas
satposs
testeclipse
ifmeas
corr_ion
initx
detslp_ll
detslp_gf
initx
initx
initx
prectrop
satantpcv
antmodel
windupcorr
tidedisp
tide_solid
tide_oload
tide_pole

二、核心函数说明

1. pppos

void pppos(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav)
  • 功能:PPP主处理函数
  • 输入
    • rtk: RTK控制结构体
    • obs: 观测值数组
    • n: 观测值数量
    • nav: 导航数据
  • 处理流程
    1. 初始化状态向量
    2. 计算卫星位置和钟差
    3. 排除日食卫星观测值
    4. 多次迭代执行残差计算和滤波更新
    5. 更新解算状态和协方差矩阵

2. res_ppp

int res_ppp(int iter, const obsd_t *obs, int n, const double *rs, const double *dts, const double *vare, const int *svh,const nav_t *nav, const double *x, rtk_t *rtk, double *v, double *H, double *R, double *azel)
  • 功能:计算观测残差和设计矩阵
  • 数学原理
    • 几何距离计算: r = ( x i s − x ) 2 + ( y i s − y ) 2 + ( z i s − z ) 2 r = \sqrt{(x^s_i - x)^2 + (y^s_i - y)^2 + (z^s_i - z)^2} r=(xisx)2+(yisy)2+(zisz)2
    • 相位观测方程: ϕ = λ N + r + c ( d t r − d t s ) + T + I + ϵ \phi = \lambda N + r + c(dt^r - dt^s) + T + I + \epsilon ϕ=λN+r+c(dtrdts)+T+I+ϵ
  • 输出
    • v: 残差向量
    • H: 设计矩阵
    • R: 观测噪声协方差

3. tide_solid

static void tide_solid(const double *rsun, const double *rmoon, const double *pos, const double *E, double gmst, int opt, double *dr)
  • 功能:计算固体地球潮汐位移
  • 数学模型
    u = K 2 [ H 2 ( 3 2 cos ⁡ 2 θ − 1 2 ) − 3 L 2 a 2 ] + K 3 [ H 3 ( . . . ) ] u = K_2[H_2(\frac{3}{2}\cos^2\theta - \frac{1}{2}) - 3L_2a^2] + K_3[H_3(...)] u=K2[H2(23cos2θ21)3L2a2]+K3[H3(...)]
    其中 K n = G M r n + 1 R n K_n = \frac{GM}{r^{n+1}}R^n Kn=rn+1GMRn
  • 输入
    • rsun/rmoon: 日月位置向量
    • pos: 测站坐标
    • E: 坐标转换矩阵

4. prectrop

static double prectrop(gtime_t time, const double *pos, const double *azel,const prcopt_t *opt, const double *x, double *dtdx,double *var)
  • 功能:精密对流层延迟模型
  • 数学模型
    T = m h ( θ ) Z H D + m w ( θ ) ( Z W D + G n cot ⁡ θ cos ⁡ α + G e cot ⁡ θ sin ⁡ α ) T = m_h(\theta)ZHD + m_w(\theta)(ZWD + G_n\cot\theta\cos\alpha + G_e\cot\theta\sin\alpha) T=mh(θ)ZHD+mw(θ)(ZWD+Gncotθcosα+Gecotθsinα)
  • 参数
    • m_h/m_w: 干湿映射函数
    • ZHD: 天顶静力学延迟
    • G_n/G_e: 水平梯度参数

5. corrmeas

static int corrmeas(const obsd_t *obs, const nav_t *nav, const double *pos,const double *azel, const prcopt_t *opt,const double *dantr, const double *dants, double phw,double *meas, double *var, int *brk)
  • 功能:电离层和天线校正
  • 处理流程
    1. 无电离层组合计算
    2. 天线相位中心校正
    3. 风化改正
    4. DCB偏差校正

6. udbias_ppp

static void udbias_ppp(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav)
  • 功能:相位偏差状态更新
  • 处理步骤
    1. LLI检测周跳
    2. 几何自由组合检测周跳
    3. 相位偏差初始化
    4. 相位-码一致性校正

三、数学原理补充

卡尔曼滤波更新公式

  1. 预测:

    • 状态转移: x ^ k ∣ k − 1 − = Φ k − 1 x k − 1 \hat{x}^-_{k|k-1} = \Phi_{k-1}x_{k-1} x^kk1=Φk1xk1
    • 协方差预测: P k ∣ k − 1 − = Φ k − 1 P k − 1 Φ k − 1 T + Q k − 1 P^-_{k|k-1} = \Phi_{k-1}P_{k-1}\Phi^T_{k-1} + Q_{k-1} Pkk1=Φk1Pk1Φk1T+Qk1
  2. 更新:

    • 卡尔曼增益: K k = P k ∣ k − 1 − H k T ( H k P k ∣ k − 1 − H k T + R k ) − 1 K_k = P^-_{k|k-1}H^T_k(H_kP^-_{k|k-1}H^T_k + R_k)^{-1} Kk=Pkk1HkT(HkPkk1HkT+Rk)1
    • 状态更新: x ^ k = x ^ k ∣ k − 1 − + K k ( z k − H k x ^ k ∣ k − 1 − ) \hat{x}_k = \hat{x}^-_{k|k-1} + K_k(z_k - H_k\hat{x}^-_{k|k-1}) x^k=x^kk1+Kk(zkHkx^kk1)
    • 协方差更新: P k = ( I − K k H k ) P k ∣ k − 1 − P_k = (I - K_kH_k)P^-_{k|k-1} Pk=(IKkHk)Pkk1

Saastamoinen对流层模型
Z H D = 0.002277 P 1 − 0.00266 cos ⁡ ( 2 ϕ ) − 0.00028 H ZHD = 0.002277 \frac{P}{1 - 0.00266\cos(2\phi) - 0.00028H} ZHD=0.00227710.00266cos(2ϕ)0.00028HP
其中P为地面气压,φ为纬度,H为高程


四、代码特点

  1. 支持多系统(GPS/GLO/GAL/SBS)
  2. 提供多种电离层处理模式(广播星历/STEC/无模型)
  3. 包含完整的误差修正模型(潮汐/对流层/天线偏差)
  4. 实现了PPP-AR模糊度固定功能
  5. 支持动态/静态模式切换

Part B: ppp_ar.c


一、整体作用与工作流程分析

这段代码实现了精密单点定位(PPP)中的整数模糊度解析(AR)功能,主要目标是通过宽巷(Wide-Lane, WL)和窄巷(Narrow-Lane, NL)组合观测值,固定载波相位模糊度以提高定位精度。整体工作流程如下:

  1. LC(线性组合)观测值预处理:计算三频观测值的线性组合(如宽巷、窄巷组合),并进行噪声统计。
  2. 宽巷模糊度固定:通过双频组合的宽巷模糊度解析,利用几何无关模型和置信度验证。
  3. 窄巷模糊度固定:基于宽巷结果,采用四舍五入法(ROUND)或整数最小二乘法(ILS)进一步固定窄巷模糊度。
  4. 状态更新:将固定后的模糊度作为约束条件,更新系统状态和协方差矩阵。

详细函数调用关系如下所示。

pppamb
average_LC
fix_amb_WL
is_depend
fix_amb_ROUND / fix_amb_ILS
sel_amb
fix_sol
filter

二、函数功能与参数说明

1. lam_LC(i, j, k)

  • 功能:计算线性组合的波长(m)。
  • 输入
    • i, j, k:频率系数(如 1,-1,0 表示 L1-L2 组合)。
  • 输出:波长 λ LC = c i f 1 + j f 2 + k f 5 \lambda_{\text{LC}} = \frac{c}{i f_1 + j f_2 + k f_5} λLC=if1+jf2+kf5c

2. L_LC(i, j, k, L)

  • 功能:计算载波相位线性组合(m)。
  • 输入
    • L[0], L[1], L[2]:L1/L2/L5 载波相位观测值(周)。
  • 输出:组合值 L LC = i f 1 L 1 + j f 2 L 2 + k f 5 L 5 i f 1 + j f 2 + k f 5 L_{\text{LC}} = \frac{i f_1 L_1 + j f_2 L_2 + k f_5 L_5}{i f_1 + j f_2 + k f_5} LLC=if1+jf2+kf5if1L1+jf2L2+kf5L5

3. P_LC(i, j, k, P)

  • 功能:计算伪距线性组合(m)。
  • 输入
    • P[0], P[1], P[2]:L1/L2/L5 伪距观测值(m)。
  • 输出:组合值 P LC = i f 1 P 1 + j f 2 P 2 + k f 5 P 5 i f 1 + j f 2 + k f 5 P_{\text{LC}} = \frac{i f_1 P_1 + j f_2 P_2 + k f_5 P_5}{i f_1 + j f_2 + k f_5} PLC=if1+jf2+kf5if1P1+jf2P2+kf5P5

4. var_LC(i, j, k, sig)

  • 功能:计算线性组合的噪声方差(m²)。
  • 输入
    • sig:原始观测值噪声(m)。
  • 输出:方差 σ LC 2 = i 2 f 1 2 + j 2 f 2 2 + k 2 f 5 2 ( i f 1 + j f 2 + k f 5 ) 2 σ 2 \sigma^2_{\text{LC}} = \frac{i^2 f_1^2 + j^2 f_2^2 + k^2 f_5^2}{(i f_1 + j f_2 + k f_5)^2} \sigma^2 σLC2=(if1+jf2+kf5)2i2f12+j2f22+k2f52σ2

5. conffunc(N, B, sig)

  • 功能:计算模糊度整数假设的置信度。
  • 输入
    • N:候选整数模糊度。
    • B:浮点解模糊度。
    • sig:模糊度标准差。
  • 输出:置信度 P = ∑ i = 1 7 [ erfc ( i − x 2 σ ) − erfc ( i + x 2 σ ) ] P = \sum_{i=1}^7 \left[ \text{erfc}\left(\frac{i-x}{\sqrt{2}\sigma}\right) - \text{erfc}\left(\frac{i+x}{\sqrt{2}\sigma}\right) \right] P=i=17[erfc(2 σix)erfc(2 σi+x)],其中 x = ∣ B − N ∣ x = |B-N| x=BN

6. average_LC(rtk, obs, n, nav, azel)

  • 功能:对LC观测值进行滑动窗口平均。
  • 输入
    • rtk:RTK状态结构体。
    • obs:观测数据数组。
    • azel:卫星方位角仰角数组。
  • 输出:更新 rtk->ambc 中的LC均值和方差。

7. fix_amb_WL(rtk, nav, sat1, sat2, NW)

  • 功能:固定宽巷模糊度。

  • 输入

    • sat1, sat2:卫星编号。
  • 输出

    • NW:固定后的整数宽巷模糊度。
  • 公式
    B W = Δ L C 0 ( 1 ) − Δ L C 0 ( 2 ) λ W L + δ b W L ( 1 ) − δ b W L ( 2 ) (无REV_WL_FCB) B_W = \frac{\Delta LC_0^{(1)} - \Delta LC_0^{(2)}}{\lambda_{WL}} + \delta b_{WL}^{(1)} - \delta b_{WL}^{(2)} \quad \text{(无REV\_WL\_FCB)} BW=λWLΔLC0(1)ΔLC0(2)+δbWL(1)δbWL(2)(REV_WL_FCB)

    其中 δ b W L \delta b_{WL} δbWL 为宽巷小数周偏差(FCB)。

8. fix_amb_ROUND(rtk, sat1, sat2, NW, n)

  • 功能:通过四舍五入法固定窄巷模糊度。
  • 输入
    • NW:宽巷模糊度数组。
  • 输出:更新状态向量 rtk->x 和协方差矩阵 rtk->P

9. fix_amb_ILS(rtk, sat1, sat2, NW, n)

  • 功能:通过整数最小二乘(ILS)固定窄巷模糊度。
  • 数学原理
    定义窄巷模糊度 B N L = c 1 λ 1 N 1 + c 2 λ 2 N 2 λ N L B_{NL} = \frac{c_1 \lambda_1 N_1 + c_2 \lambda_2 N_2}{\lambda_{NL}} BNL=λNLc1λ1N1+c2λ2N2,构造变换矩阵 $ D $,求解整数最小二乘问题:
    min ⁡ N ∈ Z n ∥ D − 1 ( B float − N ) ∥ Q 2 \min_{N \in \mathbb{Z}^n} \| D^{-1}(B_{\text{float}} - N) \|_Q^2 NZnminD1(BfloatN)Q2
    使用 LAMBDA 算法降维后进行比值检验(ratio-test)。

10. pppamb(rtk, obs, n, nav, azel)

  • 主函数:协调整个模糊度解析流程。
  • 流程
    1. 计算LC观测值均值。
    2. 枚举卫星对,固定宽巷模糊度。
    3. 根据 modear 选择ROUND或ILS方法固定窄巷模糊度。

三、数学推导补充

1.宽巷与窄巷组合

  • 宽巷组合(如 L1-L2):
    λ W L = c f 1 − f 2 ≈ 0.86 m \lambda_{WL} = \frac{c}{f_1 - f_2} \approx 0.86 \, \text{m} λWL=f1f2c0.86m
  • 窄巷组合(如 L1+L2):
    λ N L = c f 1 + f 2 ≈ 0.11 m \lambda_{NL} = \frac{c}{f_1 + f_2} \approx 0.11 \, \text{m} λNL=f1+f2c0.11m

2.整数最小二乘(ILS)

定义模糊度浮点解 N ^ ∈ R n \hat{N} \in \mathbb{R}^n N^Rn 及其协方差 Q Q Q,优化问题:
min ⁡ N ∈ Z n ∥ N ^ − N ∥ Q 2 \min_{N \in \mathbb{Z}^n} \| \hat{N} - N \|_Q^2 NZnminN^NQ2
通过 Cholesky 分解降维后搜索最近整数解,并验证比值 ∥ N ^ − N 2 ∥ Q 2 ∥ N ^ − N 1 ∥ Q 2 \frac{\|\hat{N}-N_2\|_Q^2}{\|\hat{N}-N_1\|_Q^2} N^N1Q2N^N2Q2 是否超过阈值。


研究学习不易,点赞易。
工作生活不易,收藏易,点收藏不迷茫 :)


http://www.xdnf.cn/news/4425.html

相关文章:

  • 如何保证Kafka生产者的消息顺序性? (单分区内有序,需确保同一Key的消息发送到同一分区)
  • 网站网页经常 400 错误,清缓存后就好了的原因剖析
  • 【JMeter技巧】GET请求如何传递Body参数?版本兼容性详解场景需求
  • 风车 AI 翻译如何免费解决跨境电商图片翻译难题
  • 机器学习——逻辑回归ROC练习
  • Milvus 向量数据库详解与实践指南
  • OSCP - Proving Grounds - Sumo
  • powershell批处理——io校验
  • 力扣刷题Day 37:LRU 缓存(146)
  • 7系列 之 ISERDESE2
  • 准确---Typora配置Gitee图床并实现自动图片上传
  • 【上位机——MFC】序列化机制
  • 使用 pgrep 杀掉所有指定进程
  • 【Linux系列】如何区分 SSD 和机械硬盘
  • idea连接mongodb配置schemas
  • 【基础篇】prometheus热更新解读
  • 基于开源链动2+1模式AI智能名片S2B2C商城小程序的分销价格管控机制研究
  • TCGA数据库临床亚型可用!贝叶斯聚类+特征网络分析,这篇 NC 提供的方法可以快速用起来了!
  • 4G与5G网络频率:技术演进与应用场景解析
  • 认识中间件-以及两个简单的示例
  • WebRTC通信原理与流程
  • 矩阵系统源码搭建 UI 设计开发指南,支持OEM
  • C#对SQLServer增删改查
  • 支持向量机
  • 2025数字中国创新大赛-数字安全赛道数据安全产业积分争夺赛决赛Writeup
  • JumpServer批量添加资产
  • linux环境openssh升级到openssh-10.0p1
  • RabbitMQ如何保证消息不丢失?
  • 【Leetcode 每日一题 - 扩展】3342. 到达最后一个房间的最少时间 II
  • 什么是 token-level 嵌入