rtklib source code rtk differential calculation, rtkpos and replos function process combing

rtkpos function sorting

overall process

  1. Calculate the number of observations nu and nr for the mobile station and the base station, respectively
  2. Obtain the approximate position and velocity of the mobile station through the single point positioning function
  3. Determine the positioning mode, and output the calculation results according to different positioning modes. If it is rtk, execute the replos function for differential calculation

Replos function combing

replos overall process

  1. Calculate satellite position, velocity, clock difference, clock drift and other parameters

1. Calculate the position, velocity and other parameters of the satellite through the satposs function

It can be seen at the very beginning of the function that the satellite data calculated here are obtained from the observed satellite ephemeris of all mobile stations and base stations. (n here is n=nu+nr, which has been added when it is defined at the head of the replos function)
insert image description here

for (i=0;i<n&&i<2*MAXOBS;i++) {
    
    

2. Calculate the non-differential residual of base station pseudorange and carrier phase by zdres function

    if (!zdres(1,obs+nu,nr,rs+nu*6,dts+nu*2,svh+nu,nav,rtk->rb,opt,1,
               y+nu*nf*2,e+nu*3,azel+nu*2)) {
    
    
        errmsg(rtk,"initial base station position error\n");
        free(rs); free(dts); free(var); free(y); free(e); free(azel);
        return 0;
    }

The incoming obs is obs+nu instead of obs because obs is composed of the observation values ​​of the mobile station and the base station, and the base station part is behind, so add a nu as an offset, nu: the number of satellites observed by the mobile station nr : The number of satellites observed by the reference station
The input rtk->rb is the location information of the base station, which has been positioned before, or the location of the base station has been given in the configuration

2.1 Initialize the residual array y

for (i=0;i<n*nf*2;i++) y[i]=0.0;  //nf=2,载波数量

2.2 Earth tide correction

   if (opt->tidecorr) {
    
    
        tidedisp(gpst2utc(obs[0].time),rr_,opt->tidecorr,&nav->erp,
                 opt->odisp[base],disp);
        for (i=0;i<3;i++) rr_[i]+=disp[i];
    }

(This correction is not used in the configuration)

2.3 The satellite-to-earth distance correction of the base station receiver (every satellite is corrected)

    //huhaoming:将 ecef 转换为大地坐标 pos是转化后的坐标
    ecef2pos(rr_,pos);
    
    for (i=0;i<n;i++) {
    
    
        /* compute geometric-range and azimuth/elevation angle 计算几何范围和方位角/仰角 */
        if ((r=geodist(rs+i*6,rr_,e+i*3))<=0.0) continue;
        if (satazel(pos,e+i*3,azel+i*2)<opt->elmin) continue;
        
        /* excluded satellite? 剔除卫星*/
        if (satexclude(obs[i].sat,svh[i],opt)) continue;
        
        /* satellite clock-bias 使用钟差补偿到星地几何距离 */
        r+=-CLIGHT*dts[i*2];
        
        /* troposphere delay model (hydrostatic)*/
        zhd=tropmodel(obs[0].time,pos,zazel,0.0);
        r+=tropmapf(obs[i].time,pos,azel+i*2,NULL)*zhd;
        
        /* receiver antenna phase center correction 接收机天线相位中心校正*/
        antmodel(opt->pcvr+index,opt->antdel[index],azel+i*2,opt->posopt[1], dant);
        
        /* undifferenced phase/code residual for satellite */
        zdres_sat(base,r,obs+i,nav,azel+i*2,dant,opt,y+i*nf*2);
    }

2.3.1 Calculate the geometric distance from the receiver to the satellite geodist

 //huhaoming:求接收机到卫星的几何距离,存在变量r中
        if ((r=geodist(rs+i*6,rr_,e+i*3))<=0.0) continue;```

```c
/* geometric distance ----------------------------------------------------------
 * compute geometric distance and receiver-to-satellite unit vector
 * args   : double *rs       I   satellilte position (ecef at transmission) (m)
 *          double *rr       I   receiver position (ecef at reception) (m)
 *          double *e        O   line-of-sight vector (ecef)
 * return : geometric distance (m) (0>:error/no satellite position)
 * notes  : distance includes sagnac effect correction
*-----------------------------------------------------------------------------*/
extern double geodist(const double *rs, const double *rr, double *e)
{
    
    
    double r;
    int i;
    
    if (norm(rs,3)<RE_WGS84) return -1.0;
    for (i=0;i<3;i++) e[i]=rs[i]-rr[i];
    r=norm(e,3);
    for (i=0;i<3;i++) e[i]/=r;

    //huhaoming:OMGE*(rs[0]*rr[1]-rs[1]*rr[0])/CLIGHT:地球自转改正
    return r+OMGE*(rs[0]*rr[1]-rs[1]*rr[0])/CLIGHT;
}
  • rs: satellite position
  • rr: receiver position
  • e: the unit vector from the receiver to the satellite, the direction is from the receiver to the satellite

When calculating, subtract the two three-dimensional vectors, and finally calculate the norm to get the distance between the star and the ground. The
final return value is the distance between the star and the ground after the correction of the earth's rotation.

2.3.2 Calculate the azimuth and elevation satazel ​​of each satellite

//如果大于最小值,则在后面用卫星钟差和对流层延时来修正星地距离
if (satazel(pos,e+i*3,azel+i*2)<opt->elmin) continue;```
/* satellite azimuth/elevation angle -------------------------------------------
* compute satellite azimuth/elevation angle
* args   : double *pos      I   geodetic position {lat,lon,h} (rad,m)
*          double *e        I   receiver-to-satellilte unit vevtor (ecef)
*          double *azel     IO  azimuth/elevation {az,el} (rad) (NULL: no output)
*                               (0.0<=azel[0]<2*pi,-pi/2<=azel[1]<=pi/2)
* return : elevation angle (rad)
*-----------------------------------------------------------------------------*/
extern double satazel(const double *pos, const double *e, double *azel)
{
    
    
    double az=0.0,el=PI/2.0,enu[3];
    
    if (pos[2]>-RE_WGS84) {
    
    
        ecef2enu(pos,e,enu);
        az=dot(enu,enu,2)<1E-12?0.0:atan2(enu[0],enu[1]);
        if (az<0.0) az+=2*PI;
        el=asin(enu[2]);
    }
    if (azel) {
    
    azel[0]=az; azel[1]=el;}
    return el;
}

First determine whether the height of the base station location in the longitude-latitude high coordinate system is greater than -RE_WGS84 (the major radius of the reference ellipsoid), and only if it is satisfied can the azimuth and altitude angles be calculated.
The incoming position information pos is the coordinates in the geodetic coordinate system, and the position coordinates of the base station need to be converted from the longitude and latitude heights to the northeast sky coordinate system.

ecef2enu(pos,e,enu);

Then use the formula in the textbook to calculate in the enu coordinate system

        az=dot(enu,enu,2)<1E-12?0.0:atan2(enu[0],enu[1]);
        if (az<0.0) az+=2*PI;
        el=asin(enu[2]);

2.3.3 Eliminate satellite satexclude

The exclusion of satellites is mainly based on the exsats in the prcopt_t structure to determine whether there is satellite data to be excluded or retained

2.3.4 Using clock error compensation to the geometric distance to the satellite and the earth

r+=-CLIGHT*dts[i*2];

2.3.5 Estimate the tropospheric delay and compensate the distance to the satellite-earth tropmodel, tropmapf

     //huhaoming:用saastamoinen经验模型,通过测站纬度、高程、气温、气压和水汽压等信息计算对流层延迟
        zhd=tropmodel(obs[0].time,pos,zazel,0.0);
        /*huhaoming:计算对流层延迟投影函数(即天顶方向到接收机相对卫星观测方向上的对流层延迟投影系数)
        * 这个函数中有两种投影函数的计算方法,分别是GMF和NMF,对应的两篇参考论文为“Global mapping functions for the atmosphere delay at radio wavelengths”和“Global Mapping Function(GMF): A new empirical mapping function base on numerical weather model data”
        *默认使用的是NMF方法,也可以通过定义IERS_MODEL宏来使用GMF方法。
        *这个函数调用完成后,会将返回的干投影函数和tropmodel中计算得到的天顶方向对流层干延迟相乘,从而得到接收机相对卫星观测方向上的对流层延迟。
        *干投影函数是通过返回值获得的,而湿投影是通过输入/输出参数mapfw获得的。在zdres函数中,本函数输入的mapfw=NULL,即不输出湿投影。
        *湿分量会在之后的ddres(计算双差残差的函数)函数中进行扣除。
        */
        r+=tropmapf(obs[i].time,pos,azel+i*2,NULL)*zhd;
2.3.6 Receiver antenna phase center correction
  antmodel(opt->pcvr+index,opt->antdel[index],azel+i*2,opt->posopt[1], dant);

Generate a set of unit vectors e of the receiver relative to the satellite observation direction, e[0], e[1], e[2] are the components in the east, north, and sky directions respectively; the frequency bands are different, and the phase center of the
antenna The offset (PCO) is different. First calculate the total offset of each frequency band antenna in the east, north, and sky directions, that is, the sum of the phase center offset pcv-off[i][j] and del[j] to calculate the phase center offset in
2 The projection dot(off,e,3) on the observation unit vector e, since e is a unit vector, so the inner product with it is actually the projection in this direction; calculate the antenna phase center variation (PCV):
different The altitude angle and the phase center change differently, so the interpolation calculation is performed on pcv->var[i] according to the altitude angle.
The two parts 3 and 4 are the total antenna offset: dant[i]=-dot(off,e,3)+(opt?interpvar(90.0-azel[1]*R2D,pcv->var[i]) :0.0);

2.4 Calculation of pseudorange and carrier phase residual zdres_sat

zdres_sat(base,r,obs+i,nav,azel+i*2,dant,opt,y+i*nf*2);
/* undifferenced phase/code residual for satellite ---------------------------*/
static 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)
{
    
    
    const double *lam=nav->lam[obs->sat-1];
    double f1,f2,C1,C2,dant_if;
    int i,nf=NF(opt);
    
    if (opt->ionoopt==IONOOPT_IFLC) {
    
     /* iono-free linear combination */
        if (lam[0]==0.0||lam[1]==0.0) return;
        
        if (testsnr(base,0,azel[1],obs->SNR[0]*0.25,&opt->snrmask)||
            testsnr(base,1,azel[1],obs->SNR[1]*0.25,&opt->snrmask)) return;
        
        f1=CLIGHT/lam[0];
        f2=CLIGHT/lam[1];
        C1= SQR(f1)/(SQR(f1)-SQR(f2));
        C2=-SQR(f2)/(SQR(f1)-SQR(f2));
        dant_if=C1*dant[0]+C2*dant[1];
        
        if (obs->L[0]!=0.0&&obs->L[1]!=0.0) {
    
    
            y[0]=C1*obs->L[0]*lam[0]+C2*obs->L[1]*lam[1]-r-dant_if;
        }
        if (obs->P[0]!=0.0&&obs->P[1]!=0.0) {
    
    
            y[1]=C1*obs->P[0]+C2*obs->P[1]-r-dant_if;
        }
    }
    else {
    
    
        for (i=0;i<nf;i++) {
    
    
            if (lam[i]==0.0) continue;
            
            /* check snr mask */
            /*
			函数testsnr()是用来排除接收信号强度小于规定强度的数据,这个规定信号强度(最小信号强度)
			是根据卫星的仰角来得到的(或者说与卫星的仰角有关)。
			*/
            if (testsnr(base,i,azel[1],obs->SNR[i]*0.25,&opt->snrmask)) {
    
    
                continue;
            }
            /* residuals = observable - pseudorange 残差 = 观测值 - 伪距 */
            //huhaoming: 计算每个频段下的载波相位、伪距残差:残差 = 观测量 - 卫地距 - 天线偏移
            //dant:天线相位偏差
            //y[0]到y[nf - 1]保存载波相位残差,y[nf]到y[2nf - 1]保存伪距残差
            if (obs->L[i]!=0.0) y[i   ]=obs->L[i]*lam[i]-r-dant[i];//载波相位
            if (obs->P[i]!=0.0) y[i+nf]=obs->P[i]       -r-dant[i];//伪距
        }
    }
}

Processing process
If the ionospheric free linear combination (IFLC: Ionospheric free linear combination) is selected in the configuration:
a). Call the testsnr function to check whether the carrier-to-noise ratio of the L1 and L2 observations is greater than the minimum requirement of the SNR Mask in the configuration (SNR Mask Please refer to Chapter 3.5 of RTKlib manual for settings);
b). Calculate the ionosphere-free linear combination coefficients C1 and C2, and use these coefficients to calculate the antenna offset of the ionosphere-free combination; c). Calculate the ionosphere-free
linear combination carrier phase and pseudo Range residual: residual = IFLC observations - satellite distance - antenna offset.
If it is not an ionosphere-free combination:
a). Call testsnr to check whether the carrier-to-noise ratio of each frequency band is greater than the SNR Mask requirement in the configuration; b
). Calculate the carrier phase and pseudorange residuals in each frequency band: residual = Observation - satellite distance - antenna offset.

3. Select all public satellite selsat between the rover and the base station

/* select common satellites between rover and reference station 选择流动站和参考站之间的公共卫星 --------------*/
static int selsat(const obsd_t *obs, double *azel, int nu, int nr,
                  const prcopt_t *opt, int *sat, int *iu, int *ir)
{
    
    
    int i,j,k=0;
    
    trace(3,"selsat  : nu=%d nr=%d\n",nu,nr);
    
    for (i=0,j=nu;i<nu&&j<nu+nr;i++,j++) {
    
    
        if      (obs[i].sat<obs[j].sat) j--;
        else if (obs[i].sat>obs[j].sat) i--;
        else if (azel[1+j*2]>=opt->elmin) {
    
     /* elevation at base station */
            sat[k]=obs[i].sat; iu[k]=i; ir[k++]=j;
            trace(3,"(%2d) sat=%3d iu=%2d ir=%2d\n",k-1,obs[i].sat,i,j);
        }
    }
    return k;
}

Search algorithm:
The observation data of the base station and the mobile station are all in obs, and the satellite numbers of obs are sorted, so the size of the asterisks is arranged in order from small to large. If the data satellite number observed by the mobile station is smaller than the satellite number observed by the base station, the observation data of the base station will not change, and the observation data of the mobile station will be searched in turn until it is no longer smaller. At this time, there are two situations, one is equal to, one is equal to The species is greater than.

When it is equal: store the current asterisk in sat[0,1….], store the observation data number i of the mobile station and the
observation data j of the base station corresponding to this satellite into iu[0,1….] ,ir[0,1...].

When greater than: It means that the satellite not observed by the mobile station is the same as the satellite of the current base station.

If the data satellite number observed by the mobile station is greater than the satellite number observed by the base station, the algorithm idea is consistent with the above.

4. Current state update udstate

Major updates:

  1. udpos: state update equation and state covariance equation update in kalman, including receiver position, velocity, and acceleration;
  2. udion : ionospheric state, covariance update;
  3. udtrop : Tropospheric state, covariance update;
  4. udrcvbias: Receiver time update
  5. udbias: Update the single difference ambiguity state and covariance;
    finally store it in the rtk parameter

4.1 Get the time difference between adjacent epochs

double tt=rtk->tt,bl,dr[3];

In the previous time rtk->tt has been calculated rtk->tt=timediff(rtk->sol.time,time); time is the previous epoch time, rtk->sol.time is the current epoch time

4.2 rover position, velocity, acceleration and its variance update udpos

udpos(rtk,tt); : update the position, velocity, acceleration, get rtk->x, which is the float state of the floating point solution

  • If the positioning mode is PMODE_FIXED, then assign the mobile station coordinates rtk->opt.ru[] in the configuration to rtk->x, thereby obtaining the covariance matrix of the state
    insert image description here
  • Initialize the position of the first epoch.
    If it is detected that the position of the state matrix is ​​0, it means that the current epoch is the first epoch. We initialize the position of the state to the approximate position of the mobile station obtained by single-point positioning. The state matrix corresponds to The covariance matrix of is:
    insert image description here
  • If it is a static mode, return directly and end udpos
  • If it is Kinmatic mode (unpowered model) (this analysis belongs to this mode), the current
    state matrix is: the position part of the state is initialized to the approximate mobile station position obtained by single point positioning. Covariance matrix:
    insert image description here

Last updated: July 18, 2022 15:43:15

Guess you like

Origin blog.csdn.net/weixin_44296793/article/details/125845946