GPS从入门到放弃(二十六) — RTKLIB函数解析

为了贴合这个系列的标题“从入门到放弃”,在入门之后现在就要放弃此方向了。虽然感觉遗憾,暂时也没有办法。在此附上此系列最后一篇,希望能给大家一些帮助。

此文中一些函数解析参考了 https://www.cnblogs.com/taqikema/p/8819798.html,在此表示感谢!

文章目录

  • GPS从入门到放弃(二十六) --- RTKLIB函数解析
    • rtksvrthread
    • rtkpos
    • pntpos
    • satposs
    • ephclk
    • eph2clk
    • satpos
    • ephpos
    • eph2pos
    • estpos
    • rescode
    • raim_fde
    • estvel
    • resdop
    • pppos
    • udstate_ppp
    • udbias_ppp
    • res_ppp
    • satantpcv
    • antmodel
    • windupcorr
    • corrmeas
    • ifmeas
    • filter
    • filter_
    • relpos
    • zdres
    • zdres_sat
    • tidedisp
    • geterp
    • udstate
    • udpos
    • udbias
    • ddres

rtksvrthread

void *rtksvrthread(void *arg)
  • 所在文件:rtksvr.c
  • 功能说明:rtk服务线程。
  • 参数说明:无
  • 处理过程:
  1. 检查svr->state,若为0,线程结束。
  2. 从input stream 读取数据。
  3. 写入到 log stream。
  4. 若为精密星历,调用 decodefile 解码;否则调用 decoderaw 解码。
  5. 对每一个观测数据,调用 rtkpos 进行定位计算。
  6. 若定位成功,调整时间,写solution;若没成功,写solution。
  7. 若有需要,发送 nmea request 给 base/nrtk input stream。
  8. 休眠等下一个cycle。

rtkpos

int rtkpos(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav)
  • 所在文件:rtkpos.c
  • 功能说明:根据观测数据和导航信息,计算接收机的位置、速度和钟差。
  • 参数说明:
函数参数,4个:
rtk_t    *rtk      IO  rtk控制结构体
obsd_t   *obs      I   观测数据
int      n         I   观测数据的数量
nav_t    *nav      I   导航数据
返回类型:
int                O   (0:no solution,1:valid solution)
  • 处理过程:
  1. 设置基准站位置,记录观测值数量。
  2. 调用 pntpos 进行接收机单点定位。若为单点定位模式,输出,返回。
  3. 若为 PPP 模式,调用 pppos 进行精密单点定位,输出,返回。
  4. 若无基准站观测数据,输出,返回。
  5. 若为移动基站模式,调用 pntpos 进行基站单点定位,并加以时间同步;否则只计算一下差分时间。
  6. 调用 relpos 进行相对基站的接收机定位,输出,返回。

pntpos

int pntpos (const obsd_t *obs, int n, const nav_t *nav, const prcopt_t *opt,sol_t *sol, double *azel, ssat_t *ssat, char *msg)
  • 所在文件:pntpos.c
  • 功能说明:依靠伪距和多普勒频移测量值来进行单点定位,给出接收机的位置、速度和钟差。
  • 参数说明:
函数参数,8个:
obsd_t   *obs      I   观测数据
int      n         I   观测数据的数量
nav_t    *nav      I   导航数据
prcopt_t *opt      I   处理过程选项
sol_t    *sol      IO  solution
double   *azel     IO  方位角和俯仰角 (rad) (NULL: no output)
ssat_t   *ssat     IO  卫星状态            (NULL: no output)
char     *msg      O   错误消息
返回类型:
int                O   (1:ok,0:error)
  • 处理过程:
  1. 当处理选项 opt 中的模式不是单点模式时,电离层校正采用 broadcast 模型,即Klobuchar模型,对流层校正则采用 Saastamoinen 模型;相反,当其为单点模式时,对输入参数 opt 不做修改。
  2. 调用 satposs 计算卫星们位置、速度、时钟
  3. 调用 estpos 根据伪距估计接收机位置,其中会调用 valsol 进行 χ2\chi^2χ2 检验和 GDOP 检验。
  4. 若3中的检验没通过,调用 raim_fde 进行接收机自主完好性监测,判决定位结果的有效性,并进行错误排除。
  5. 调用 estvel 根据多普勒频移测量值计算接收机的速度。
  6. 赋值给卫星状态结构体ssat。

satposs

void satposs(gtime_t teph, const obsd_t *obs, int n, const nav_t *nav,int ephopt, double *rs, double *dts, double *var, int *svh)
  • 所在文件:ephemeris.c
  • 功能说明:按照所观测到的卫星顺序计算出每颗卫星的位置、速度、{钟差、频漂}
  • 参数说明:
函数参数,9个:
gtime_t  teph      I   time to select ephemeris (gpst)
obsd_t   *obs      I   观测量数据
int      n         I   观测量数据的数量
nav_t    *nav      I   导航数据
int      ephopt    I   星历选项 (EPHOPT_???)
double   *rs       O   卫星位置和速度,长度为6*n,{x,y,z,vx,vy,vz}(ecef)(m,m/s)
double   *dts      O   卫星钟差,长度为2*n, {bias,drift} (s|s/s)
double   *var      O   卫星位置和钟差的协方差 (m^2)
int      *svh      O   卫星健康标志 (-1:correction not available)
返回类型: 无
  • 处理过程:
  1. 大循环针对每一条观测数据,按顺序处理。
  2. 首先初始化,将对当前观测数据的 rs、dts、var和svh数组的元素置 0。
  3. 通过判断某一频率下信号的伪距是否为 0,来得到此时所用的频率个数。注意,频率个数不能大于 NFREQ(默认为 3)。
  4. 用数据接收时刻减去伪距信号传播时间,得到卫星信号的发射时刻。
  5. 调用 ephclk 函数,由广播星历计算出当前观测卫星与 GPS 时间的钟差 dt。注意,此时的钟差是没有考虑相对论效应和 TGD 的。
  6. 用 4 中的信号发射时刻减去 5 中的钟差 dt,得到 GPS 时间下的卫星信号发射时刻。
  7. 调用 satpos 函数,计算信号发射时刻卫星的位置(ecef,m)、速度(ecef,m/s)、钟差((s|s/s))。注意,这里计算出的钟差是考虑了相对论效应的了,只是还没有考虑 TGD。
  8. 如果没有精密星历,则用广播星历的钟差替代。
  • 注意:
  1. 4中的公式原理:由 ρ=c(tu−ts)\rho = c(t_u-t_s)ρ=c(tu​−ts​) 可得 ts=tu−ρ/ct_s=t_u-\rho/cts​=tu​−ρ/c。

ephclk

int ephclk(gtime_t time, gtime_t teph, int sat, const nav_t *nav, double *dts)
  • 所在文件:ephemeris.c
  • 功能说明:通过广播星历来确定卫星钟差
  • 参数说明:
函数参数,5个:
gtime_t  time      I   信号发射时刻
gtime_t  teph      I   用于选择星历的时刻 (gpst)
int      sat       I   卫星号 (1-MAXSAT)
nav_t    *nav      I   导航数据
double   *dts      O   卫星钟差,长度为2*n, {bias,drift} (s|s/s)
返回类型:
int                O     (1:ok,0:error)
  • 处理过程:
  1. 调用 satsys 函数,根据卫星编号确定该卫星所属的导航系统和该卫星在该系统中的 PRN编号。
  2. 对于 GPS导航系统,调用 seleph 函数来选择最接近 teph 的那个星历。
  3. 调用 eph2clk 函数,通过广播星历和信号发射时间计算出卫星钟差。
  • 注意:
  1. 此时计算出的卫星钟差是没有考虑相对论效应和 TGD的。

eph2clk

int eph2clk (gtime_t time, const eph_t *eph)
  • 所在文件:ephemeris.c
  • 功能说明:根据信号发射时间和广播星历,计算卫星钟差
  • 参数说明:
函数参数,2个
gtime_t  time    I   time by satellite clock (gpst)
eph_t    *eph    I   broadcast ephemeris
返回类型:
double    satellite clock bias (s) without relativeity correction
  • 处理过程:

    1. 计算与星历参考时间的偏差 dt = t-toc。
    2. 利用二项式校正计算出卫星钟差,从 dt中减去这部分,然后再进行一次上述操作,得到最终的 dt。(这一部分不知道是为什么?)
    3. 使用二项式校正得到最终的钟差。

satpos

int satpos(gtime_t time, gtime_t teph, int sat, int ephopt, const nav_t *nav,double *rs, double *dts, double *var, int *svh)
  • 所在文件:ephemeris.c
  • 功能说明:计算信号发射时刻卫星的 P(ecef,m)、V(ecef,m/s)、C((s|s/s))
  • 参数说明:
函数参数,9个:
gtime_t time      I   time (gpst)
gtime_t teph      I   用于选择星历的时刻 (gpst)
int     sat       I   卫星号
nav_t   *nav      I   导航数据
int     ephopt    I   星历选项 (EPHOPT_???)
double  *rs       O   卫星位置和速度,长度为6*n,{x,y,z,vx,vy,vz}(ecef)(m,m/s)
double  *dts      O   卫星钟差,长度为2*n, {bias,drift} (s|s/s)
double  *var      O   卫星位置和钟差的协方差 (m^2)
int     *svh      O   卫星健康标志 (-1:correction not available)
返回类型:
int               O     (1:ok,0:error)
  • 处理过程:
  1. 根据不同的星历选项的值调用不同的处理函数,如果星历选项是 EPHOPT_BRDC,调用 ephpos 函数,根据广播星历计算出算信号发射时刻卫星的 P、V、C。如果星历选项是 EPHOPT_PREC,调用 pephpos 函数,根据精密星历和时钟计算信号发射时刻卫星的 P、V、C。
  • 注意:
  1. 此时计算出的卫星钟差考虑了相对论,还没有考虑 TGD。

ephpos

int ephpos(gtime_t time, gtime_t teph, int sat, const nav_t *nav,int iode, double *rs, double *dts, double *var, int *svh)
  • 所在文件:ephemeris.c
  • 功能说明:根据广播星历计算出算信号发射时刻卫星的 P、V、C
  • 参数说明:
函数参数,9个:
gtime_t  time      I   transmission time by satellite clock
gtime_t  teph      I   time to select ephemeris (gpst)
int      sat       I   卫星号 (1-MAXSAT)
nav_t    *nav      I   导航数据
int      iode      I   星历数据期号
double   *rs       O   卫星位置和速度,长度为6*n,{x,y,z,vx,vy,vz}(ecef)(m,m/s)
double   *dts      O   卫星钟差,长度为2*n, {bias,drift} (s|s/s)
double   *var      O   卫星位置和钟差的协方差 (m^2)
int      *svh      O   卫星健康标志 (-1:correction not available)
返回类型:
int                O    (1:ok,0:error)
  • 处理过程:
  1. 调用 satsys 函数,确定该卫星所属的导航系统。
  2. 调用 seleph 函数来选择广播星历。
  3. 根据选中的广播星历,调用 eph2pos 函数来计算信号发射时刻卫星的 位置、钟差和相应结果的误差。
  4. 在信号发射时刻的基础上给定一个微小的时间间隔,再次计算新时刻的 P、V、C。与3结合,通过扰动法计算出卫星的速度和频漂。
  • 注意:
  1. 这里是使用扰动法计算卫星的速度和频漂,并没有使用那些位置和钟差公式对时间求导的结果。
  2. 由于是调用的 eph2pos 函数,计算得到的钟差考虑了相对论效应,没有考虑 TGD。

eph2pos

void eph2pos(gtime_t time, const eph_t *eph, double *rs, double *dts, double *var)
  • 所在文件:ephemeris.c
  • 功能说明:根据广播星历计算出算信号发射时刻卫星的位置和钟差
  • 参数说明:
函数参数,5个
gtime_t  time      I   transmission time by satellite clock
eph_t    *eph      I   广播星历
double   *rs       O   卫星位置和速度,长度为6*n,{x,y,z,vx,vy,vz}(ecef)(m,m/s)
double   *dts      O   卫星钟差,长度为2*n, {bias,drift} (s|s/s)
double   *var      O   卫星位置和钟差的协方差 (m^2)
返回类型:无
  • 处理过程:
  1. 通过卫星轨道半长轴 A 判断星历是否有效,无效则返回。
  2. 计算规化时间 tk。
  3. 根据不同卫星系统设置相应的地球引力常数 mu 和 地球自转角速度 omge。
  4. 计算平近点角 M。
  5. 用牛顿迭代法来计算偏近点角 E。参考 RTKLIB manual P145 (E.4.19)。
  6. 计算升交点角距 u。
  7. 计算摄动校正后的升交点角距 u、卫星矢径长度 r、轨道倾角 i。
  8. 计算升交点赤经 O。
  9. 计算卫星位置存入 rs 中。
  10. 计算卫星钟差,此处考虑了相对论效应,没有考虑 TGD,也没有计算钟漂。
  11. 用 URA 值来标定误差方差,具体对应关系可在 ICD-GPS-200H 20.3.3.3.1.3 SV Accuracy 中找到。

estpos

int estpos(const obsd_t *obs, int n, const double *rs, const double *dts,const double *vare, const int *svh, const nav_t *nav,const prcopt_t *opt, sol_t *sol, double *azel, int *vsat,double *resp, char *msg)
  • 所在文件:pntpos.c
  • 功能说明:通过伪距实现绝对定位,计算出接收机的位置和钟差,顺带返回实现定位后每颗卫星的{方位角、仰角}、定位时有效性、定位后伪距残差。
  • 参数说明:
函数参数,13个:
obsd_t   *obs      I   观测量数据
int      n         I   观测量数据的数量
double   *rs       I   卫星位置和速度,长度为6*n,{x,y,z,vx,vy,vz}(ecef)(m,m/s)
double   *dts      I   卫星钟差,长度为2*n, {bias,drift} (s|s/s)
double   *vare     I   卫星位置和钟差的协方差 (m^2)
int      *svh      I   卫星健康标志 (-1:correction not available)
nav_t    *nav      I   导航数据
prcopt_t *opt      I   处理过程选项
sol_t    *sol      IO  solution
double   *azel     IO  方位角和俯仰角 (rad)
int      *vsat     IO  卫星在定位时是否有效
double   *resp     IO  定位后伪距残差 (P-(r+c*dtr-c*dts+I+T))
char     *msg      O   错误消息
返回类型:
int                O   1表示成功,0表示出错
  • 处理过程:
  1. 初始化:将 sol->rr 的前 3 项位置信息(ECEF)赋值给 x 数组。
  2. 开始迭代定位计算,首先调用 rescode 函数,计算当前迭代的伪距残差 vvv、几何矩阵 HHH、伪距残差的方差 var、所有观测卫星的方位角和仰角 azel、定位时有效性 vsat、定位后伪距残差 resp、参与定位的卫星个数 ns 和方程个数 nv。
  3. 确定方程组中方程的个数要大于未知数的个数。
  4. 以伪距残差的标准差的倒数作为权重,对 HHH 和 vvv 分别左乘权重对角阵,得到加权之后的 HHH 和 vvv。
  5. 调用 lsq 函数,根据 dx=(HHT)−1Hvdx=(HH^T)^{-1}Hvdx=(HHT)−1Hv 和 Q=(HHT)−1Q=(HH^T)^{-1}Q=(HHT)−1,得到当前 x 的修改量 dx 和定位误差协方差矩阵中的权系数阵 QQQ。
  6. 将 5 中求得的 dx 加入到当前 x 值中,得到更新之后的 x 值。
  7. 如果 5 中求得的修改量 dx 小于截断因子(目前是10−410^{-4}10−4),则将 6 中得到的 x 值作为最终的定位结果,对 sol 的相应参数赋值,之后再调用 valsol 函数确认当前解是否符合要求(伪距残差小于某个 χ2\chi^2χ2值和 GDOP 小于某个门限值,参考 RTKLIB Manual P162, E.6.33, E.6.34)。否则,进行下一次循环。
  8. 如果超过了规定的循环次数,则输出发散信息后,返回 0。
  • 注意:
  1. 关于第 1步,如果是第一次定位,即输入的 sol 为空,则 x 初值为 0;如果之前有过定位,则通过 1 中操作可以将上一历元的定位值作为该历元定位的初始值。
  2. 关于定位方程,RTKLIB中的 HHH 相当于定位方程解算中的 GTG^TGT,即 H=GTH=G^TH=GT。
  3. 关于加权最小二乘,这里的权重值是对角阵,这是建立在假设不同测量值的误差之间是彼此独立的基础上的。大部分资料上这里都是把权重矩阵 W 保留到方程的解的表达式当中,而这里是直接对 H 和 v 分别左乘权重对角阵,得到加权之后的 H 和 v,其表示形式像是没有加权一样。
  4. 解方程时的 dtr 单位是 m,是乘以了光速之后的,解出结果后赋给 sol->dtr 时再除以光速。
  5. sol->time 中存储的是减去接收机钟差后的信号观测时间。

rescode

int rescode(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, const prcopt_t *opt,double *v, double *H, double *var, double *azel, int *vsat,double *resp, int *ns)
  • 所在文件:pntpos.c
  • 功能说明:计算当前迭代的伪距残差 v、几何矩阵 H、伪距残差的方差 var、所有观测卫星的方位角和仰角 azel、定位时有效性 vsat、定位后伪距残差 resp、参与定位的卫星个数 ns 和方程个数 nv。
  • 参数说明:
函数参数,17个
int      iter      I   迭代次数
obsd_t   *obs      I   观测量数据
int      n         I   观测量数据的数量
double   *rs       I   卫星位置和速度,长度为6*n,{x,y,z,vx,vy,vz}(ecef)(m,m/s)
double   *dts      I   卫星钟差,长度为2*n, {bias,drift} (s|s/s)
double   *vare     I   卫星位置和钟差的协方差 (m^2)
int      *svh      I   卫星健康标志 (-1:correction not available)
nav_t    *nav      I   导航数据
double   *x        I   本次迭代开始之前的定位值
prcopt_t *opt      I   处理过程选项
double   *v        O   定位方程的右端部分,伪距残差
double   *H        O   定位方程中的几何矩阵
double   *var      O   参与定位的伪距残差的方差
double   *azel     O   对于当前定位值,所有观测卫星的 {方位角、高度角} (2*n)
int      *vsat     O   所有观测卫星在当前定位时是否有效 (1*n)
double   *resp     O   所有观测卫星的伪距残差,(P-(r+c*dtr-c*dts+I+T)) (1*n)
int      *ns       O   参与定位的卫星的个数
返回类型:
int                O   定位方程组的方程个数
  • 处理过程:
  1. 将之前得到的定位解信息赋值给 rr 和 dtr 数组,以进行关于当前解的伪距残差的相关计算。
  2. 调用 ecef2pos 函数,将上一步中得到的位置信息由 ECEF 转化为大地坐标系。
  3. 将 vsat、azel 和 resp 数组置 0,因为在前后两次定位结果中,每颗卫星的上述信息都会发生变化。
  4. 调用 satsys 函数,验证卫星编号是否合理及其所属的导航系统。
  5. 检测当前观测卫星是否和下一个相邻数据重复;重复则不处理这一条,去处理下一条。
  6. 调用 geodist 函数,计算卫星和当前接收机位置之间的几何距离 rrr 和接收机到卫星方向的观测矢量。然后检验几何距离是否 >0。此函数中会进行地球自转影响的校正(Sagnac效应)。
  7. 调用 satazel 函数,计算在接收机位置处的站心坐标系中卫星的方位角和仰角;若仰角低于截断值,不处理此数据。
  8. 调用 prange 函数,得到经过DCB校正后的伪距值 ρ\rhoρ。
  9. 可以在处理选项中事先指定定位时排除哪些导航系统或卫星,这是通过调用 satexclude 函数完成的。
  10. 调用 ionocorr 函数,计算电离层延时 III (m)。所得的电离层延时是建立在 L1 信号上的,当使用其它频率信号时,依据所用信号频组中第一个频率的波长与 L1 波长的关系,对上一步得到的电离层延时进行修正。
  11. 调用 tropcorr 函数,计算对流层延时 TTT (m)。
  12. 由 ρ−(r+dtr−c⋅dts+I+T)\rho-(r+dt_r-c·dt_s+I+T)ρ−(r+dtr​−c⋅dts​+I+T),计算出此时的伪距残差。
  13. 组装几何矩阵 HHH,前 3 行为 6 中计算得到的视线单位向量的反向,第 4 行为 1,其它行为 0。
  14. 处理不同系统(GPS、GLO、GAL、CMP)之间的时间偏差,修改矩阵 HHH。
  15. 将参与定位的卫星的定位有效性标志设为 1,给当前卫星的伪距残差赋值,参与定位的卫星个数 ns 加 1。
  16. 调用 varerr 函数,计算此时的导航系统误差,然后累加计算用户测距误差(URE)。
  17. 为了防止不满秩的情况,把矩阵 HHH 补满秩了。
  • 注意:
  1. 输入参数x的size为7*1,前3个是本次迭代开始之前的定位值,第4个是钟差,后三个分别是gps系统与glonass、galileo、北斗系统的钟差。但是从代码看,后三个没有用上。
  2. 返回值 v和 resp的主要区别在于长度不一致, v是需要参与定位方程组的解算的,维度为 nv*1;而 resp仅表示所有观测卫星的伪距残余,维度为 n*1,对于没有参与定位的卫星,该值为 0。

raim_fde

int raim_fde(const obsd_t *obs, int n, const double *rs,const double *dts, const double *vare, const int *svh,const nav_t *nav, const prcopt_t *opt, sol_t *sol,double *azel, int *vsat, double *resp, char *msg)
  • 所在文件:pntpos.c
  • 功能说明:使用伪距残差判决法对计算得到的定位结果进行接收机自主正直性检测(RAIM),每次舍弃一颗卫星测量值,用剩余的值组成一组进行定位运算,选择定位后伪距残差最小的一组作为最终结果。这样如果只有一个异常观测值的话,这个错误可以被排除掉;有两个或以上错误则排除不了。注意这里只会在对定位结果有贡献的卫星数据进行检测。
  • 参数说明:
函数参数,13个:
obsd_t   *obs      I   观测数据
int      n         I   观测数据的数量
double   *rs       I   卫星位置和速度,长度为6*n,{x,y,z,vx,vy,vz}(ecef)(m,m/s)
double   *dts      I   卫星钟差,长度为2*n, {bias,drift} (s|s/s)
double   *vare     I   卫星位置和钟差的协方差 (m^2)
int      *svh      I   卫星健康标志 (-1:correction not available)
nav_t    *nav      I   导航数据
prcopt_t *opt      I   处理过程选项
sol_t    *sol      IO  solution
double   *azel     IO  方位角和俯仰角 (rad)
int      *vsat     IO  卫星在定位时是否有效
double   *resp     IO  定位后伪距残差 (P-(r+c*dtr-c*dts+I+T))
char     *msg      O   错误消息
返回类型:
int                O   (1:ok,0:error)
  • 处理过程:
  1. 大循环是每次舍弃第 i 颗卫星。
  2. 舍弃第 i 颗卫星后,将剩下卫星的数据复制到一起,调用 estpos 函数计算使用剩下卫星进行定位的定位值。
  3. 累加使用当前卫星实现定位后的伪距残差平方和与可用卫星数目,如果 nvsat<5,则说明当前卫星数目过少,无法进行 RAIM_FDE 操作。
  4. 计算伪距残差平方和的标准差,如果小于 rms,则说明当前定位结果更合理,将 stat 置为 1,重新更新 sol、azel、vsat(当前被舍弃的卫星,此值置为0)、resp等值,并将当前的 rms_e更新到 rms 中。
  5. 继续弃用下一颗卫星,重复 2-4 操作。总而言之,将同样是弃用一颗卫星条件下,伪距残差标准平均值最小的组合所得的结果作为最终的结果输出。
  6. 如果 stat不为 0,则说明在弃用卫星的前提下有更好的解出现,输出信息,指出弃用了哪颗卫星。
  • 注意:
  1. 源码中有很多关于 i、j、k的循环。其中,i表示最外面的大循环,每次将将第 i颗卫星舍弃不用,这是通过 if (j==i) continue实现的;j表示剩余使用的卫星的循环,每次进行相应数据的赋值;k表示参与定位的卫星的循环,与 j一起使用。

estvel

void estvel(const obsd_t *obs, int n, const double *rs, const double *dts,const nav_t *nav, const prcopt_t *opt, sol_t *sol,const double *azel, const int *vsat)
  • 所在文件:pntpos.c
  • 功能说明:依靠多普勒频移测量值计算接收机的速度,用牛顿迭代法。
  • 参数说明:
函数参数,9个:
obsd_t   *obs      I   观测数据
int      n         I   观测数据的数量
double   *rs       I   卫星位置和速度,长度为6*n,{x,y,z,vx,vy,vz}(ecef)(m,m/s)
double   *dts      I   卫星钟差,长度为2*n, {bias,drift} (s|s/s)
nav_t    *nav      I   导航数据
prcopt_t *opt      I   处理过程选项
sol_t    *sol      IO  solution
double   *azel     IO  方位角和俯仰角 (rad)
int      *vsat     IO  卫星在定位时是否有效
返回类型:
int                O     (1:ok,0:error)
  • 处理过程:
  1. 在最大迭代次数限制内,调用 resdop,计算定速方程组左边的几何矩阵和右端的速度残余,返回定速时所使用的卫星数目。
  2. 调用最小二乘法 lsq 函数,解出{速度、频漂}的步长 dx,累加到 x 中。
  3. 检查当前计算出的步长的绝对值是否小于 1E-6。是,则说明当前解已经很接近真实值了,将接收机三个方向上的速度存入到 sol->rr 中;否,则进行下一次循环。
  • 注意:
  1. 最终向 sol_t 类型存储定速解时,并没有存储所计算出的接收器时钟频漂。
  2. 这里不像定位时,初始值可能为上一历元的位置(从 sol 中读取初始值),这里定速的初始值直接给定为 0.

resdop

int resdop(const obsd_t *obs, int n, const double *rs, const double *dts,const nav_t *nav, const double *rr, const double *x,const double *azel, const int *vsat, double *v, double *H)
  • 所在文件:pntpos.c
  • 功能说明:计算定速方程组左边的几何矩阵和右端的速度残余,返回定速时所使用的卫星数目
  • 参数说明:
函数参数,11个:
obsd_t   *obs      I   观测数据
int      n         I   观测数据的数量
double   *rs       I   卫星位置和速度,长度为6*n,{x,y,z,vx,vy,vz}(ecef)(m,m/s)
double   *dts      I   卫星钟差,长度为2*n, {bias,drift} (s|s/s)
nav_t    *nav      I   导航数据
double   *rr       I   接收机位置和速度,长度为6,{x,y,z,vx,vy,vz}(ecef)(m,m/s)
double   *x        I   本次迭代开始之前的定速值,长度为4,{vx,vy,vz,drift}
double   *azel     IO  方位角和俯仰角 (rad)
int      *vsat     I   卫星在定速时是否有效
double   *v        O   定速方程的右端部分,速度残差
double   *H        O   定速方程中的几何矩阵
返回类型:
int                O   定速时所使用的卫星数目
  • 处理过程:
  1. 调用 ecef2pos 函数,将接收机位置由 ECEF 转换为大地坐标系。
  2. 调用 xyz2enu 函数,计算此时的坐标转换矩阵。
  3. 去除在定速时不可用的卫星。
  4. 计算当前接收机位置下 ENU中的视向量,然后转换得到 ECEF 中视向量的值。
  5. 计算 ECEF 中卫星相对于接收机的速度。
  6. 计算考虑了地球自转的用户和卫星之间的几何距离变化率,校正公式见 RTKLIB manual P159 (F.6.29),此公式可由 P140 (E.3.8b) 对时间求导得到。
  7. 根据公式计算出定速方程组右端项的多普勒残差,构建左端项的几何矩阵,最后再将观测方程数增 1.
  • 注意:
  1. 这里与定位不同,构建几何矩阵时,就只有 4个未知数,而定位时是有 NX个。
  2. 多普勒定速方程中几何矩阵 G 与定位方程中的一样。
  3. 第7步中计算多普勒残差 b 与很多资料不同,因为 estvel 中用的是牛顿迭代法,其最小二乘法并不是直接求解x,而是求解dx,再加到x上。下面式子可以参考,其中 xr、yrx_r、y_rxr​、yr​ 分别为接收机位置的x,y分量,xs、ysx_s、y_sxs​、ys​ 分别为卫星s位置的x,y分量,rsr_srs​ 为接收机到卫星s的距离。注意在计算 G 的时候忽略了地球自转校正项。
    x=[v,c⋅δt˙]T=[vx,vy,vz,c⋅δt˙]T\boldsymbol{x} = [\boldsymbol{v},\:c\cdot\dot{\delta_t}]^T=[v_x,\:v_y,\:v_z,\:c\cdot\dot{\delta_t}]^Tx=[v,c⋅δt​˙​]T=[vx​,vy​,vz​,c⋅δt​˙​]T

rs=(vs−v)⋅es+ωec(vs,yxr+ysvx−vs,xyr−xsvy)r_{s} = (\boldsymbol{v_s}-\boldsymbol{v})\cdot\boldsymbol{e_s} + \frac{\omega_e}{c}(v_{s,y}x_r+y_sv_x-v_{s,x}y_r-x_sv_y) rs​=(vs​−v)⋅es​+cωe​​(vs,y​xr​+ys​vx​−vs,x​yr​−xs​vy​)

y=−λfd=h(x)=rs+c⋅δt˙−c⋅δ˙t,sy = -\lambda f_d = h(x) = r_{s} + c\cdot\dot{\delta_t} - c\cdot\dot{\delta}_{t,s} y=−λfd​=h(x)=rs​+c⋅δt​˙​−c⋅δ˙t,s​

G=∂h∂x=[−e1,k1−e2,k1−e3,k1−e4,k1]\boldsymbol{G} = \frac{\partial h}{\partial x} = \left[ \begin{array}{cc} -\boldsymbol{e}_{1,k} & 1\\ -\boldsymbol{e}_{2,k} & 1\\ -\boldsymbol{e}_{3,k} & 1\\ -\boldsymbol{e}_{4,k} & 1 \end{array} \right]G=∂x∂h​=⎣⎢⎢⎡​−e1,k​−e2,k​−e3,k​−e4,k​​1111​⎦⎥⎥⎤​

b=y−h(x)=−λfd−(rs+c⋅δt˙−c⋅δ˙t,s)b = y-h(x) = -\lambda f_d - (r_{s} + c\cdot\dot{\delta_t} - c\cdot\dot{\delta}_{t,s}) b=y−h(x)=−λfd​−(rs​+c⋅δt​˙​−c⋅δ˙t,s​)

pppos

void pppos(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav)
  • 所在文件:ppp.c
  • 功能说明:精确点定位
  • 参数说明:
函数参数,4个:
rtk_t    *rtk      IO  rtk控制结构体
obsd_t   *obs      I   观测数据
int      n         I   观测数据的数量
nav_t    *nav      I   导航数据
返回类型: 无
  • 处理过程:
  1. 调用 udstate_ppp 更新状态值 rtk->x 及其误差协方差 rtk->P。
  2. 调用 satposs 计算卫星位置和钟差。
  3. 若有需要排除观测的卫星,调用 testeclipse 进行排除。
  4. 根据设置的滤波迭代次数,循环调用 res_ppp 计算载波相位和伪距残差 v 和观测矩阵 H,以及测量误差的协方差 R,并将残差值存入 rtk->ssat[sat-1].resc 和 rtk->ssat[sat-1].resp 中。然后调用 filter 进行 Kalman 滤波运算。
  5. 4 中循环结束后,再次调用 res_ppp,更新残差值,并将残差值存入 rtk->ssat[sat-1].resc 和 rtk->ssat[sat-1].resp 中。
  6. 对某些周整模糊度计算模式,调用 pppamb 进行周整模糊度解算。
  7. 更新 solution 状态。
  • 注意:
  1. 状态变量包含接收机位置、接收机速度、接收机钟差、[对流层参数]、每颗卫星的载波偏移。(参考 RTKLIB Manual P177 E.8.16)。其中载波偏移包含周整模糊度以及小数部分,可参考 RTKLIB Manual P139 E.3.5。
  2. 过程5中的目的是在过程6中的某些周整模糊度计算中会用上,以及一些输出中可能会用上。

udstate_ppp

void udstate_ppp(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav)
  • 所在文件:ppp.c
  • 功能说明:更新状态值 rtk->x。
  • 参数说明:
函数参数,4个:
rtk_t    *rtk      IO  rtk控制结构体
obsd_t   *obs      I   观测数据
int      n         I   观测数据的数量
nav_t    *nav      I   导航数据
返回类型: 无
  • 处理过程:
  1. 调用 udpos_ppp 根据不同模式初始化状态 rtk->x 中的位置值。
  2. 调用 udclk_ppp 初始化状态 rtk->x 中的钟差值(6个,因有6个系统)。
  3. 对某些对流层模型,初始化状态 rtk->x 中的对流层参数。
  4. 调用 udbias_ppp 更新载波相位偏移状态值以及其误差协方差。
  • 注意:
  1. 状态变量包含接收机位置、接收机速度、接收机钟差、[对流层参数]、每颗卫星的载波偏移。(参考 RTKLIB Manual P177 E.8.16)。其中载波偏移包含周整模糊度以及小数部分,可参考 RTKLIB Manual P139 E.3.5。
  2. 处理过程 1 的 udpos_ppp 中,PPP-static 模式只用 rtk->sol.rr 初始化一次状态 rtk->x,而 PPP-Kinematic 模式每次都会用 rtk->sol.rr 重新初始化 rtk->x。而 rtk->sol.rr 的值来源于单点定位。
  3. 处理过程 1 的 udpos_ppp 中,PPP-Fixed 模式只用于残差分析,不用于定位。

udbias_ppp

void udbias_ppp(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav)
  • 所在文件:ppp.c
  • 功能说明:从观测值 obs 经过计算得到偏移值存入状态 rtk->x 中,若有周跳需要更新状态 rtk->x。更新偏移值的误差协方差到 rtk->P。
  • 参数说明:
函数参数,4个:
rtk_t    *rtk      IO  rtk控制结构体
obsd_t   *obs      I   观测数据
int      n         I   观测数据的数量
nav_t    *nav      I   导航数据
返回类型: 无
  • 处理过程:
  1. 调用 detslp_ll 通过 LLI 检查是否有周跳。
  2. 调用 detslp_gf 通过 geometry-free phase jump 检查是否有周跳。
  3. 若观测中断需要 reset 载波偏移值。
  4. 接收机位置转换到大地坐标系。
  5. 对每一组观测数据,调用 corrmeas 计算观测值 meas,是否有周跳,然后计算出偏移值 bias。
  6. 若载波和伪距跳变太大,为了保持一致性,需要进行校正。
  7. 对每一组观测值更新偏移值的误差协方差到 rtk->P。若有周跳,或者 rtk->x 状态还未初始化,则用偏移值 bias 重置 rtk->x。

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)
  • 所在文件:ppp.c
  • 功能说明:计算载波相位和伪距残差 v 和观测矩阵 H,以及测量误差的协方差 R。并将残差值存入 rtk->ssat[sat-1].resc 和 rtk->ssat[sat-1].resp 中。
  • 参数说明:
函数参数:14个
int     iter    I   迭代次数(该函数中没有用到)
obsd_t  *obs    I   观测数据
int      n      I   观测数据的数量
double  *rs     I   卫星位置和速度,长度为6*n,{x,y,z,vx,vy,vz}(ecef)(m,m/s)
double  *dts    I   卫星钟差,长度为2*n, {bias,drift} (s|s/s)
double  *vare   I   卫星位置和钟差的协方差 (m^2)
int     *svh    I   卫星健康标志 (-1:correction not available)
nav_t   *nav    I   导航数据
double  *x      I   状态变量
rtk_t   *rtk    IO  rtk控制结构体
double  *v      O   实际观测量与预测观测量的残差 (2n个,因每个观测数据有phase和code两个观测值)
double  *H      O   观测矩阵
double  *R      O   测量误差的协方差
double  *azel   O   方位角和俯仰角 (rad)
返回类型:
int             O   残差个数,<=0表示失败
  • 处理过程
  1. 接收机位置传给 rr。
  2. 若需要地球潮校正,调用 tidedisp 对 rr 进行校正。地球潮包含固体潮、极潮和海潮负荷。
  3. rr 转换坐标系到大地坐标系 pos。
  4. 大循环,对每一个观测量
  5. 计算卫星到接收机的几何距离 r,计算仰角,若仰角低于阈值,排除此观测量。
  6. 若设置有卫星需要排除的,排除掉。
  7. 根据对流层模型设置,计算对流层延时校正值 dtrp。
  8. 调用 satantpcv 根据卫星天线模型计算校正值 dants。
  9. 调用 antmodel 根据接收机天线模型计算校正值 dantr。
  10. 调用 windupcorr 计算相位缠绕校正值存入 rtk->ssat[sat-1].phw 中。
  11. 调用 corrmeas 计算经过电离层和天线相位校正后的测量值 meas(包含相位和伪距两个值),把 8~10 步中的计算值都合并到 meas 中了。
  12. 对几何距离 r 进行卫星钟差和对流层校正。
  13. 构造残差 v 和观测矩阵 H。v 由经过电离层和天线相位校正后的测量值 meas 减去经过卫星钟差和对流层校正后的 r,再减去接收机钟差(若 meas 为载波,再减去载波偏移)得到。 H 参考 RTKLIB Manual P177 E.8.21。并将残差值存入 rtk->ssat[sat-1].resc 和 rtk->ssat[sat-1].resp 中。
  14. 重复 5~13 直到大循环结束。
  15. 计算测量误差的协方差 R。
  • 注意:
  1. 状态变量包含接收机位置、接收机速度、接收机钟差、[对流层参数]、载波偏移。(参考 RTKLIB Manual P177 E.8.16)。其中载波偏移包含周整模糊度以及小数部分,可参考 RTKLIB Manual P139 E.3.5。

satantpcv

void satantpcv(const double *rs, const double *rr, const pcv_t *pcv,double *dant)
  • 所在文件:ppp.c
  • 功能说明:根据模型计算卫星天线偏移校正值dant。
  • 参数说明:
函数参数:4个
double   *rs     I   卫星位置和速度,长度为6*n,{x,y,z,vx,vy,vz}(ecef)(m,m/s)
double   *rr     I   接收机位置和速度,长度为6*n,{x,y,z,vx,vy,vz}(ecef)(m,m/s)
pcv_t    *pcv    I   天线相位中心参数结构体
double   *dant   O   卫星天线校正值
返回类型:无
  • 处理过程:
  1. 根据卫星位置和接收机位置计算天底角。
  2. 调用 antmodel_s 计算卫星天线偏移校正值 dant。
  • 注意:
  1. antmodel_s 中的计算只是对 phase center variation 进行了简单的插值,并没有考虑 phase center offset。这里存疑!?
  2. 类似的对接收机天线偏移进行校正计算的 antmodel 函数中则不仅考虑了phase center variation,也同时考虑了phase center offset。

antmodel

void antmodel(const pcv_t *pcv, const double *del, const double *azel,int opt, double *dant)
  • 所在文件:rtkcmn.c
  • 功能说明:根据模型计算接收机天线偏移校正值dant。
  • 参数说明:
函数参数:5个
pcv_t    *pcv    I   天线相位中心参数结构体
double   *del    I   相对天线参考点偏移值
double   *azel   I   方位角和俯仰角
int       opt    I   选项(非0则需要考虑pcv)
double   *dant   O   接收机天线校正值
返回类型:无
  • 处理过程:
  1. 根据方位角和俯仰角计算单位观测矢量。
  2. 对每一个频率,先计算偏移,再根据opt值看是否要加上pcv的影响,最后得出dant。

windupcorr

void windupcorr(gtime_t time, const double *rs, const double *rr,double *phw)
  • 所在文件:rtkcmn.c
  • 功能说明:根据模型计算相位缠绕校正值 phw。
  • 参数说明:
函数参数:4个
gtime_t time     I   time (GPST)
double  *rs      I   卫星位置 (ecef) {x,y,z} (m)
double  *rr      I   接收机位置 (ecef) {x,y,z} (m)
double  *phw     IO  相位缠绕校正值 (cycle)
返回类型:无
  • 处理过程:
  1. 调用 sunmoonpos 获取太阳的位置。
  2. 计算卫星到接收机的单位矢量 ek。
  3. 计算卫星天线坐标系的三个轴的单位矢量 exs, eys, ezs。
  4. 计算站点坐标系的三个轴的单位矢量 exr, eyr。
  5. 计算有效偶极 ds 和 dr。
  6. 计算相位缠绕校正值 phw。
  • 注意:
  1. 使用这个函数时需要传入之前的相位缠绕校正值,因为此函数假设校正值不会跳变超过0.5个载波周期。

corrmeas

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)
  • 所在文件:ppp.c
  • 功能说明:计算经过电离层、DCB、卫星天线、接收机天线、相位缠绕校正后的测量值 meas(包含相位和伪距两个值)。
  • 参数说明:
函数参数:11个
obsd_t   *obs    I   观测数据
nav_t    *nav    I   导航数据
double   *pos    I   接收机位置 (lat,lon,h)(rad,m)
double   *azel   I   方位角和俯仰角 (rad)
prcopt_t *opt    I   处理过程选项
double   *dantr  I   接收机天线校正值
double   *dants  I   卫星天线校正值
double   phw     I   相位缠绕校正值
double   *meas   O   校正后的测量值
double   *var    O   校正后的测量值的误差协方差
int      *brk    O   用与判断是否有周跳
返回类型:
int              O   (>0:ok,0:sth wrong)
  • 处理过程:
  1. 若电离层校正模式为 iono-free LC,调用 ifmeas 计算 meas 值,然后返回。否则进行下面的步骤。
  2. 调用 testsnr 看观测值的信噪比是否过低,过低则忽略此观测值。
  3. 进行 DCB 校正。
  4. 调用 corr_ion 计算 slant ionospheric delay 值 ion。
  5. 合并各种校正值得到 meas 值。

ifmeas

int ifmeas(const obsd_t *obs, const nav_t *nav, const double *azel,const prcopt_t *opt, const double *dantr, const double *dants,double phw, double *meas, double *var)
  • 所在文件:ppp.c
  • 功能说明:计算经过电离层、DCB、卫星天线、接收机天线、相位缠绕校正后的测量值 meas(包含相位和伪距两个值)。电离层延时计算需要双频点数据。
  • 参数说明:
函数参数:9个
obsd_t   *obs    I   观测数据
nav_t    *nav    I   导航数据
double   *azel   I   方位角和俯仰角 (rad)
prcopt_t *opt    I   处理过程选项
double   *dantr  I   接收机天线校正值
double   *dants  I   卫星天线校正值
double   phw     I   相位缠绕校正值
double   *meas   O   校正后的测量值
double   *var    O   校正后的测量值的误差协方差
返回类型:
int              O   (>0:ok,0:sth wrong)
  • 处理过程:
  1. 选择所用频段,没有足够可用的频段则返回。
  2. 调用 testsnr 看观测值的信噪比是否过低,过低则返回。
  3. 按公式计算 γ,c1,c2\gamma, c_1, c_2γ,c1​,c2​, 获取L1, L2, P1, P2, P1_C1, P1_P2的值。
  4. 按公式计算电离层校正和相位缠绕校正后的载波测量值。
  5. 按公式计算电离层校正和DCB校正后的伪距测量值。
  6. 若有SBAS,加上SBAS钟差校正到伪距测量值。
  7. 若有GLONASS,加上GPS和GLONASS的硬件偏差校正到伪距测量值。
  8. 加上卫星天线、接收机天线校正值到载波测量值和伪距测量值。

filter

int filter(double *x, double *P, const double *H, const double *v,const double *R, int n, int m)
  • 所在文件:rtkcmn.c
  • 功能说明:kalman滤波运算
  • 参数说明:
函数参数,7个:
double   *x        IO 状态变量 (n x 1)
double   *P        IO 状态变量的误差协方差阵 (n x n)
double   *H        I  观测矩阵的转置 (n x m)
double   *v        I  实际观测量与预测观测量的残差 (measurement - model) (m x 1)
double   *R        I  测量误差的协方差 (m x m)
int      n         I  状态变量个数
int      m         I  观测值个数
返回类型:
int                O (0:ok,<0:error)
  • 处理过程:
  1. 选择需要更新的状态 x 和对应的 P、H 到 x_、p_、H_ 中。
  2. 调用 filter_ 进行kalman滤波更新。
  3. 将更新值存到 x、P中。
  • 注意:
  1. 若状态 x[i]==0.0, 则不会更新 x[i] 和 P[i+i*n]

filter_

int filter_(const double *x, const double *P, const double *H,const double *v, const double *R, int n, int m,double *xp, double *Pp)
  • 所在文件:rtkcmn.c
  • 功能说明:kalman滤波运算,K=PH(HTPH+R)−1,xp=x+Kv,Pp=(I−KHT)PK=PH(H^TPH+R)^{-1}, xp=x+Kv, Pp=(I-KH^T)PK=PH(HTPH+R)−1,xp=x+Kv,Pp=(I−KHT)P
  • 参数说明:
函数参数,9个:
double   *x        I  状态变量 (n x 1)
double   *P        I  状态变量的误差协方差阵 (n x n)
double   *H        I  观测矩阵的转置 (n x m)
double   *v        I  实际观测量与预测观测量的残差 (measurement - model) (m x 1)
double   *R        I  测量误差的协方差 (m x m)
int      n         I  状态变量个数
int      m         I  观测值个数
double   *xp       O  更新后的状态变量 (n x 1)
double   *Pp       O  更新后的状态变量的误差协方差阵 (n x n)
返回类型:
int                O (0:ok,<0:error)
  • 处理过程:
  1. 调用矩阵运算函数按照公式进行矩阵运算
  • 注意:
  1. 矩阵是按列优先的顺序存的 (fortran convention)

relpos

int relpos(rtk_t *rtk, const obsd_t *obs, int nu, int nr, const nav_t *nav)
  • 所在文件:rtkpos.c
  • 功能说明:相对定位
  • 参数说明:
函数参数,5个:
rtk_t    *rtk      IO  rtk控制结构体
obsd_t   *obs      I   观测数据
int      nu        I   接收机观测数据的数量
int      nr        I   基站观测数据的数量
nav_t    *nav      I   导航数据
返回类型:
int                O   (1:ok,0:error)
  • 处理过程:
  1. 一系列值、状态、中间变量的初始化。
  2. 调用 satposs 计算卫星们的位置、速度和钟差。
  3. 调用 zdres 计算基站的没有差分的相位/码残差,若出错则返回0。
  4. 若为后处理,需要插值的,调用 intpres 进行插值。
  5. 调用 selsat 选择接收机与基站共同观测的卫星,返回共同观测的卫星个数,输出卫星号列表sat、在接收机观测值中的index值列表 iu 和在基站观测值中的index值列表 ir。
  6. 调用 udstate 更新状态值 rtk->x 及其误差协方差 rtk->P。
  7. 按迭代次数循环第8~10步。
  8. 调用 zdres 计算接收机的没有差分的相位/码残差。
  9. 调用 ddres 计算双差相位/码残差。
  10. 调用 filter 进行 Kalman 滤波运算。
  11. 再次调用 zdres 和 ddres 计算双差相位/码残差,调用 valpos 进行验证,若通过则更新 rtk->x 以及 rtk->P,并更新模糊度控制结构体。
  12. 根据选项模式调用不同的 resamb_* 函数解析周整模糊度。
  13. 保存solution状态。

zdres

int zdres(int base, const obsd_t *obs, int n, const double *rs,const double *dts, const int *svh, const nav_t *nav,const double *rr, const prcopt_t *opt, int index, double *y,double *e, double *azel)
  • 所在文件:rtkpos.c
  • 功能说明:计算接收机或基站的没有差分的相位/码残差(Zero-Difference Residuals)
  • 参数说明:
函数参数,13个:
int      base      I   0表示接收机,1表示基站
obsd_t   *obs      I   观测数据
int      n         I   观测数据的数量
double   *rs       I   卫星位置和速度,长度为6*n,{x,y,z,vx,vy,vz}(ecef)(m,m/s)
double   *dts      I   卫星钟差,长度为2*n, {bias,drift} (s|s/s)
int      *svh      I   卫星健康标志 (-1:correction not available)
nav_t    *nav      I   导航数据
double   *rr       I   接收机/基站的位置和速度,长度为6*n,{x,y,z,vx,vy,vz}(ecef)(m,m/s)
prcopt_t *opt      I   处理过程选项
int      index     I   0表示接收机,1表示基站,与参数 base 重复了
double   *y        O   相位/码残差
double   *e        O   观测矢量 (ecef)
double   *azel     O   方位角和俯仰角 (rad)
返回类型:
int                O   (1:ok,0:error)
  • 处理过程:
  1. 若没有接收机位置,返回0。
  2. 接收机位置传给 rr_。
  3. 若需要地球潮校正,调用 tidedisp 对 rr_ 进行校正。地球潮包含固体潮、极潮和海潮负荷。
  4. rr_ 转换坐标系到大地坐标系 pos。
  5. 大循环,对每一个观测量
  6. 调用 geodist 计算卫星到接收机的几何距离 r,调用 satazel 计算仰角,若仰角低于阈值,排除此观测量。
  7. 若设置有卫星需要排除的,排除掉。
  8. 根据卫星钟差校正 r。
  9. 根据对流层模型设置,调用 tropmodel 和 tropmapf 计算对流层延时校正值并校正 r。
  10. 根据接收机天线模型调用 antmodel 计算校正值 dant(对每一个频率都有一个值)。
  11. 调用 zdres_sat 计算没有差分的相位/码残差 y。
  12. 重复6~11直到大循环结束。

zdres_sat

void zdres_sat(int base, double r, const obsd_t *obs, const nav_t *nav,const double *azel, const double *dant,const prcopt_t *opt, double *y)
  • 所在文件:rtkpos.c
  • 功能说明:计算接收机或基站对某一颗卫星的没有差分的相位/码残差(Zero-Difference Residuals)。y = 观测值 - r - dant。
  • 参数说明:
函数参数,13个:
int      base      I   0表示接收机,1表示基站
double   r         I   经过钟差和对流层校正后的几何距离。
obsd_t   *obs      I   观测数据
nav_t    *nav      I   导航数据
double   *azel     I   方位角和俯仰角 (rad)
double   *dant     I   接收机天线校正值
prcopt_t *opt      I   处理过程选项
double   *y        O   相位/码残差
返回类型: 无
  • 处理过程:
  1. 按电离层校正模式是否为 IONOOPT_IFLC 分两种情况。
  2. 若是:检测信噪比,计算天线校正值 dant_if,然后计算残差。
  3. 若否:检测信噪比,然后计算残差。

tidedisp

void tidedisp(gtime_t tutc, const double *rr, int opt, const erp_t *erp,const double *odisp, double *dr)
  • 所在文件:ppp.c
  • 功能说明:计算因地球潮汐而引起的站点位移校正值 dr。
  • 参数说明:
函数参数,6个:
gtime_t  tutc     I   time in utc
double  *rr       I   站点位置 (ecef) (m)
int      opt      I   选项(指定包含哪些潮的影响)1: solid earth tide2: ocean tide loading4: pole tide8: elimate permanent deformation
double  *erp      I   地球自转参数
double  *odisp    I   海潮负荷参数odisp[0+i*6]: consituent i amplitude radial(m)odisp[1+i*6]: consituent i amplitude west  (m)odisp[2+i*6]: consituent i amplitude south (m)odisp[3+i*6]: consituent i phase radial  (deg)odisp[4+i*6]: consituent i phase west    (deg)odisp[5+i*6]: consituent i phase south   (deg)(i=0:M2,1:S2,2:N2,3:K2,4:K1,5:O1,6:P1,7:Q1,8:Mf,9:Mm,10:Ssa)
double  *dr       O   因地球潮汐而引起的站点位移校正值 (ecef) (m)
返回类型: 无
  • 处理过程:
  1. 若有erp,调用 geterp 获取erp参数。
  2. 若有选项,调用 tide_solid 计算固体潮。
  3. 若有选项,调用 tide_oload 计算海潮负荷。
  4. 若有选项,调用 tide_pole 计算极潮。

geterp

int geterp(const erp_t *erp, gtime_t time, double *erpv)
  • 所在文件:rtkcmn.c
  • 功能说明:获取ERP参数值。
  • 参数说明:
函数参数,3个:
erp_t  *erp        I   earth rotation parameters
gtime_t time       I   time (gpst)
double *erpv       O   erp values {xp,yp,ut1_utc,lod} (rad,rad,s,s/d)
返回类型:
int                O   (1:ok,0:error)
  • 处理过程:
  1. 计算当前时间与ERP参数中时间的插值。
  2. 若当前时间早于ERP参数中最早的时间,采用最早的时间来计算。
  3. 若当前时间晚于ERP参数中最晚的时间,采用最晚的时间来计算。
  4. 若当前时间在ERP参数中最早与最晚的时间之间,则先找到最接近的两个时间,然后用插值。

udstate

void udstate(rtk_t *rtk, const obsd_t *obs, const int *sat,const int *iu, const int *ir, int ns, const nav_t *nav)
  • 所在文件:rtkpos.c
  • 功能说明:更新状态值 rtk->x 及其误差协方差 rtk->P。
  • 参数说明:
函数参数,7个:
rtk_t    *rtk      IO  rtk控制结构体
obsd_t   *obs      I   观测数据
int      sat       I   接收机和基站共同观测的卫星号列表
int      *iu       I   接收机和基站共同观测的卫星在接收机观测值中的index值列表
int      *ir       I   接收机和基站共同观测的卫星在基站观测值中的index值列表
int      ns        I   接收机和基站共同观测的卫星个数
nav_t    *nav      I   导航数据
返回类型: 无
  • 处理过程:
  1. 调用 udpos 根据不同模式更新rtk中的位置、速度、加速度值和协方差。
  2. 若 电离层模式>=IONOOPT_EST,调用 udion 更新状态 rtk->x 中的电离层参数(MAXSAT个)及其协方差。
  3. 若 对流层模式>=TROPOPT_EST,调用 udtrop 更新状态 rtk->x 中的对流层参数(2或6个)及其协方差。TROPOPT_EST初始化状态 rtk->x 中的对流层参数。
  4. 若为 GLONASS AR模式,调用 udrcvbias 更新接收机硬件偏移。
  5. 若 模式>PMODE_DGPS,调用 udbias 更新载波相位偏移状态值以及其误差协方差。
  • 注意:
  1. 状态变量包含接收机位置、速度、加速度值、[每颗卫星的电离层参数]、[对流层参数]、[接收机硬件偏移]、每颗卫星的载波偏移。其中载波偏移包含周整模糊度以及小数部分,可参考 RTKLIB Manual P139 E.3.5。
  2. 过程2、3中更新状态x,只根据需要作初始化,给初值;更新时只更新协方差。

udpos

void udpos(rtk_t *rtk, double tt)
  • 所在文件:rtkpos.c
  • 功能说明:更新rtk中的位置、速度、加速度值和协方差。
  • 参数说明:
函数参数,2个:
rtk_t    *rtk      IO  rtk控制结构体
double   tt        I   本次更新与上次更新的时间差
返回类型: 无
  • 处理过程:
  1. 若为 PMODE_FIXED 模式,直接从选项中取得位置值给rtk->x,然后返回。
  2. 若为第一个历元,用rtk->sol中的位置值初始化rtk->x。若为dynamics模式(即需要估计速度和加速度),一并初始化。
  3. 若为 PMODE_STATIC 模式,返回。
  4. 若非dynamics模式,用rtk->sol中的位置值初始化rtk->x,然后返回。
  5. 检查位置协方差,若大于阈值VAR_POS则用rtk->sol中的位置值重置rtk->x
  6. 根据Kalman滤波的预测方程 x=Fx 和 P=FP*F+Q 更新(参考RTKLIB Manual P161 E.7.4, E.7.5)。其中更新Q时需要坐标转换。

udbias

void udbias(rtk_t *rtk, double tt, const obsd_t *obs, const int *sat,const int *iu, const int *ir, int ns, const nav_t *nav)
  • 所在文件:rtkpos.c
  • 功能说明:更新载波相位偏移状态值到 rtk->x 以及更新其误差协方差到 rtk->P。
  • 参数说明:
函数参数,8个:
rtk_t    *rtk      IO  rtk控制结构体
double   tt        I   本次更新与上次更新的时间差
obsd_t   *obs      I   观测数据
int      sat       I   接收机和基站共同观测的卫星号列表
int      *iu       I   接收机和基站共同观测的卫星在接收机观测值中的index值列表
int      *ir       I   接收机和基站共同观测的卫星在基站观测值中的index值列表
int      ns        I   接收机和基站共同观测的卫星个数
nav_t    *nav      I   导航数据
返回类型: 无
  • 处理过程:
  1. 对每一颗卫星,循环2~4步。
  2. 调用 detslp_ll 通过 LLI 检查接收机和基站观测数据是否有周跳。
  3. 调用 detslp_gf_L1L2 和 detslp_gf_L1L5 通过 geometry-free phase jump 检查是否有周跳。
  4. 调用 detslp_dop 通过多普勒和相位差检查接收机和基站观测数据是否有周跳。
  5. 对每一个频率,循环6~10步。
  6. 若为instantaneous AR 模式或者超出 obs outage counter,重置载波偏移值。
  7. 若检测到周跳,重置载波偏移值。
  8. 用 phase - code 的值 (ϕ−ρλ\phi - \frac{\rho}{\lambda}ϕ−λρ​) 来估计载波偏移值。
  9. 校正载波偏移值以保持载波与伪距的一致性。
  10. 更新载波偏移值及其误差协方差。

ddres

int ddres(rtk_t *rtk, const nav_t *nav, double dt, const double *x,const double *P, const int *sat, double *y, double *e,double *azel, const int *iu, const int *ir, int ns, double *v,double *H, double *R, int *vflg)
  • 所在文件:rtkpos.c
  • 功能说明:计算接收机或基站的双差相位/码残差(Double-Difference Residuals)
  • 参数说明:
函数参数,16个:
rtk_t    *rtk      IO  rtk控制结构体
nav_t    *nav      I   导航数据
double   dt        I   接收机和基站的时间差
double   *x        IO  状态变量
double   *P        IO  状态变量的误差协方差阵
int      sat       I   接收机和基站共同观测的卫星号列表
double   *y        IO  相位/码残差
double   *e        IO  观测矢量 (ecef)
double   *azel     O   方位角和俯仰角 (rad)
int      *iu       I   接收机和基站共同观测的卫星在接收机观测值中的index值列表
int      *ir       I   接收机和基站共同观测的卫星在基站观测值中的index值列表
int      ns        I   接收机和基站共同观测的卫星个数
double   *v        O   实际观测量与预测观测量的残差
double   *H        O   观测矩阵
double   *R        O   测量误差的协方差
int      *vflg     O   数据有效标志
返回类型:
int                O   (>0:ok,0:error)
  • 处理过程:
  1. 一些初始化和坐标转换。
  2. 若 电离层模式>=IONOOPT_EST,调用 ionmapf 计算电离层延迟因子。
  3. 若 对流层模式>=TROPOPT_EST,调用 prectrop 计算对流层延迟因子。
  4. 大循环,对每一个频率,循环5~
  5. 寻找仰角最高的参考卫星。
  6. 小循环,对每一种导航系统,对每一颗卫星,循环7~14步,计算双差。
  7. 用传入的没有差分的相位/码残差y计算双差残差v,并计算对应的H。
  8. 若要估计电离层参数,模式IONOOPT_EST,用电离层延迟因子修正v和H。
  9. 若要估计对流层参数,模式TROPOPT_EST,用对流层延迟因子修正v和H。
  10. 用相位偏移修正v和H。
  11. 若是GLONASS系统观测值,做相关修正。
  12. 根据选项maxinno的值检测是否要排除此观测数据。
  13. 计算单差的测量误差协方差Ri、Rj。
  14. 设置数据有效标志。
  15. 若为移动基站模式PMODE_MOVEB,计算移动基站限制并设置相应的数据有效标志。
  16. 用Ri、Rj计算双差的测量误差协方差R。

GPS从入门到放弃(二十六) --- RTKLIB函数解析相关推荐

  1. GPS从入门到放弃(十二) --- 多普勒定速

    GPS从入门到放弃(十二) - 多普勒定速 多普勒效应 多普勒效应在我们日常生活中有很多,比如当一辆救护车迎面驶来的时候,听到声音比原来高:而车离去的时候声音的音高比原来低. 这个效应是为纪念奥地利物 ...

  2. GPS从入门到放弃(十) --- 定位方程解算和定位精度

    GPS从入门到放弃(十) - 定位方程解算和定位精度 上一篇伪距与载波相位中我们介绍了伪距的计算方法,也得到了包含 (x,y,z,δt)(x,\ y,\ z,\ \delta_t)(x, y, z,  ...

  3. GPS从入门到放弃(十四) --- 电离层延时

    GPS从入门到放弃(十四) - 电离层延时 电离层概念 电离层(Ionosphere)是地球大气的一个电离区域.它是受到太阳高能辐射以及宇宙线的激励而电离的大气高层.50千米以上的整个地球大气层都处于 ...

  4. AutoLisp从入门到放弃(十六)

    判断式.循环操作 一.AutoLisp判断式 1.函数(if) 2.参数 3.返回值 4.代码示例 二.AutoLisp重复函数 1.函数(repeat) 2.参数 3.返回值 4.代码示例 三.Au ...

  5. GPS从入门到放弃(十五)、DCB差分码偏差

    一.概念 DCB(Differential Code Bias 差分码偏差)是全球卫星导航系统(GNSS)中,通过不同信号得到的观测值之间存在的系统性偏差.DCB是由卫星和接收机硬件延迟的影响造成的. ...

  6. GPS从入门到放弃(十) 、定位方程解算和定位精度

    上一篇伪距与载波相位中我们介绍了伪距的计算方法,也得到了包含 四个未知数的GPS定位基本方程: 那么根据这个方程我们怎么来定位呢? 根据我们第一篇GPS基础原理讲过GPS的基本原理,只需已知四颗卫星的 ...

  7. keras从入门到放弃(二十二)一维卷积处理 RNN文本分类

    什么是一维卷积 一维卷积 • 图中的输入的数据维度为8,过滤器的维度为5.与二维卷积类似,卷积后输出的数据维度为8−5+1=48−5+1=4. • 如果过滤器数量仍为1,输入数据的channel数量变 ...

  8. RHEL6入门系列之二十六,利用rpm进行软件包管理

    在上篇博文中介绍的yum是目前在RHEL系统中安装软件的首选方式,传统的rpm则主要是用作查询,如查询系统中是否已经安装了某个软件等.今天我们就一起来了解一下rpm的一些常用用法. 一.rpm软件包 ...

  9. GPS从入门到放弃(十九)、精密星历(sp3格式)

    在目前的GPS系统中,除了卫星播发的广播星历之外,IGS 组织(International GNSS Service)还提供精度更高的卫星星历,我们称之为精密星历. 精密星历可以用于更高精度的定位需求 ...

  10. python pipeline框架_Python爬虫从入门到放弃(十六)之 Scrapy框架中Item Pipeline用法...

    原博文 2017-07-17 16:39 − 当Item 在Spider中被收集之后,就会被传递到Item Pipeline中进行处理 每个item pipeline组件是实现了简单的方法的pytho ...

最新文章

  1. postgis启动_PostgreSQL的安装和启动方法大全
  2. springdatajpa命名规则_Spring Boot 之Spring data JPA简介
  3. linux-02-常用的命令-必须掌握
  4. linux 怎么改授权用户权限,linux – systemd:授予非特权用户权限以更改某个特定服务...
  5. CMU Bomblab 答案
  6. 常用代码大全(新手入门必备)
  7. android刷机方法,安卓手机怎么刷机?安卓手机两种刷机方法介绍
  8. 如何学会学习——读唐老师博文有感
  9. FreeWheel创始人/CTO于晶纯访谈:具备大局观方能洞若观火
  10. CodeForces 643 D.Bearish Fanpages(set+multiset)
  11. uilable 上面加子视图图
  12. 解决 git 将文本文件视为二进制文件 导致无法查看diff
  13. Android源码下载(可编译)
  14. Java POI SXSSFWorkbook 读取模板,输出
  15. 统计学习方法-感知机概括和补充
  16. 3DMAX快速入门 界面介绍【上】
  17. 20176408李俊 手写笔记
  18. SQL语句使用06--------案例02
  19. 改版网页的过程和步骤详情
  20. ROS wiki文件系统导航

热门文章

  1. 图像分割库segmentation_models.pytorch
  2. 基于华为云ECS的目标检测与识别的昇腾AI开发体验【华为云至简致远】
  3. springboot项目多moudle打包到一个jar
  4. 如何使用磁性套索工具进行抠图
  5. Hbase最全面入门指南
  6. 何恺明组新论文:只用ViT做主干也可以做好目标检测
  7. 迅雷极速版服务器未响应,迅雷极速版频繁崩溃,求大神帮忙
  8. 游戏建模入门教程:绝地求生—PUBG的游戏模型制作流程
  9. Error:Initialization error (angular 2 language service). Cannot read property 'CommandTypes' of unde
  10. android 日历 签到,Android MaterialCalendarView 日历使用 每日签到