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

文章目录

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

c 复制代码
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

c 复制代码
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=(xis−x)2+(yis−y)2+(zis−z)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(dtr−dts)+T+I+ϵ
  • 输出
    • v: 残差向量
    • H: 设计矩阵
    • R: 观测噪声协方差

3. tide_solid

c 复制代码
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

c 复制代码
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

c 复制代码
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

c 复制代码
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^k∣k−1−=Φk−1xk−1
    • 协方差预测: 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} Pk∣k−1−=Φk−1Pk−1Φk−1T+Qk−1
  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=Pk∣k−1−HkT(HkPk∣k−1−HkT+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^k∣k−1−+Kk(zk−Hkx^k∣k−1−)
    • 协方差更新: P k = ( I − K k H k ) P k ∣ k − 1 − P_k = (I - K_kH_k)P^-_{k|k-1} Pk=(I−KkHk)Pk∣k−1−

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.0022771−0.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 σi−x)−erfc(2 σi+x)],其中 x = ∣ B − N ∣ x = |B-N| x=∣B−N∣。
  • 功能:对LC观测值进行滑动窗口平均。
  • 输入
    • rtk:RTK状态结构体。
    • obs:观测数据数组。
    • azel:卫星方位角仰角数组。
  • 输出 :更新 rtk->ambc 中的LC均值和方差。
  • 功能:固定宽巷模糊度。

  • 输入

    • 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 N∈Znmin∥D−1(Bfloat−N)∥Q2
    使用 LAMBDA 算法降维后进行比值检验(ratio-test)。
  • 主函数:协调整个模糊度解析流程。
  • 流程
    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=f1−f2c≈0.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+f2c≈0.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 N∈Znmin∥N^−N∥Q2

通过 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^−N1∥Q2∥N^−N2∥Q2 是否超过阈值。


研究学习不易,点赞易。

工作生活不易,收藏易,点收藏不迷茫 :)


相关推荐
不太可爱的叶某人5 小时前
【学习笔记】MySQL技术内幕InnoDB存储引擎——第5章 索引与算法
笔记·学习·mysql
岁岁岁平安5 小时前
Redis基础学习(五大值数据类型的常用操作命令)
数据库·redis·学习·redis list·redis hash·redis set·redis string
HMS Core6 小时前
京东携手HarmonyOS SDK首发家电AR高精摆放功能
华为·ar·harmonyos
黑听人7 小时前
【力扣 困难 C】329. 矩阵中的最长递增路径
c语言·leetcode
知识分享小能手7 小时前
Vue3 学习教程,从入门到精通,使用 VSCode 开发 Vue3 的详细指南(3)
前端·javascript·vue.js·学习·前端框架·vue·vue3
pay4fun8 小时前
2048-控制台版本
c++·学习
JeffersonZU9 小时前
Linux/Unix 套接字Socket编程(socket基本概念,流程,流式/数据报socket,Unix domain socket示例)
linux·c语言·tcp/ip·udp·unix·gnu
知识分享小能手9 小时前
Bootstrap 5学习教程,从入门到精通,Bootstrap 5 表单验证语法知识点及案例代码(34)
前端·javascript·学习·typescript·bootstrap·html·css3
小小小新人121239 小时前
C语言 ATM (4)
c语言·开发语言·算法
weixin_4188138710 小时前
Python-可视化学习笔记
笔记·python·学习