From 3243afeb6e30852504a8857448b7a1c683c94de9 Mon Sep 17 00:00:00 2001 From: Daniel Burr Date: Fri, 18 Feb 2022 16:20:42 +0100 Subject: [PATCH] Wide-lane ambiguity fixing for multi-constellation, L1/L2 or L1/L5. Wide lane support is enabled by setting modear to 'wide-lane' (ARMODE_WL). Wide lane AR fix and hold can be enabled using the wlmodear option. Also includes an example configuration file for using rtkrcv with Swift Navigation's Skylark Cloud Correction Service. --- app/consapp/rtkrcv/conf/rtk_skylark_l1l5.conf | 160 +++++++++++ src/options.c | 5 +- src/rtcm3.c | 4 +- src/rtkcmn.c | 13 +- src/rtklib.h | 4 +- src/rtkpos.c | 251 ++++++++++++++++-- 6 files changed, 412 insertions(+), 25 deletions(-) create mode 100644 app/consapp/rtkrcv/conf/rtk_skylark_l1l5.conf diff --git a/app/consapp/rtkrcv/conf/rtk_skylark_l1l5.conf b/app/consapp/rtkrcv/conf/rtk_skylark_l1l5.conf new file mode 100644 index 000000000..23830252f --- /dev/null +++ b/app/consapp/rtkrcv/conf/rtk_skylark_l1l5.conf @@ -0,0 +1,160 @@ +# rtkrcv options (2022/02/09 22:11:36, v.2.4.3 b34) + +console-passwd =admin +console-timetype =gpst # (0:gpst,1:utc,2:jst,3:tow) +console-soltype =dms # (0:dms,1:deg,2:xyz,3:enu,4:pyl) +console-solflag =1 # (0:off,1:std+2:age/ratio/ns) +inpstr1-type =ntripcli # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripcli,7:ftp,8:http) +inpstr2-type =ntripcli # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripcli,7:ftp,8:http) +inpstr3-type =off # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripcli,7:ftp,8:http) +inpstr1-path =username:password@igs-ip.net:2101/STFU00USA0 +# SWIFT: Skylark host may vary depending on geographic region and frequency range +inpstr2-path =username:password@na2.skylark.swiftnav.com:2101/CRS +inpstr3-path = +inpstr1-format =rtcm3 # (0:rtcm2,1:rtcm3,2:oem4,3:oem3,4:ubx,5:ss2,6:hemis,7:skytraq,8:javad,9:nvs,10:binex,11:rt17) +inpstr2-format =rtcm3 # (0:rtcm2,1:rtcm3,2:oem4,3:oem3,4:ubx,5:ss2,6:hemis,7:skytraq,8:javad,9:nvs,10:binex,11:rt17) +inpstr3-format =rtcm3 # (0:rtcm2,1:rtcm3,2:oem4,3:oem3,4:ubx,5:ss2,6:hemis,7:skytraq,8:javad,9:nvs,10:binex,11:rt17) +inpstr2-nmeareq =single # (0:off,1:latlon,2:single) +inpstr2-nmealat =0 # (deg) +inpstr2-nmealon =0 # (deg) +inpstr2-nmeahgt =0 # (m) +outstr1-type =off # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripsvr,11:ntripc_c) +outstr2-type =off # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripsvr,11:ntripc_c) +outstr1-path = +outstr2-path = +outstr1-format =xyz # (0:llh,1:xyz,2:enu,3:nmea,4:stat) +outstr2-format =llh # (0:llh,1:xyz,2:enu,3:nmea,4:stat) +logstr1-type =off # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripsvr,11:ntripc_c) +logstr2-type =off # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripsvr,11:ntripc_c) +logstr3-type =off # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripsvr,11:ntripc_c) +logstr1-path = +logstr2-path = +logstr3-path = +misc-svrcycle =10 # (ms) +misc-timeout =10000 # (ms) +misc-reconnect =10000 # (ms) +misc-nmeacycle =5000 # (ms) +misc-buffsize =32768 # (bytes) +misc-navmsgsel =all # (0:all,1:rover,2:base,3:corr) +misc-proxyaddr = +misc-fswapmargin =30 # (s) +misc-startcmd = +misc-stopcmd = +file-cmdfile1 = +file-cmdfile2 = +file-cmdfile3 = +pos1-posmode =kinematic # (0:single,1:dgps,2:kinematic,3:static,4:movingbase,5:fixed,6:ppp-kine,7:ppp-static,8:ppp-fixed) +# SWIFT: l1+2 for L1/L2, l1+2+3 for L1/L5 +pos1-frequency =l1+2+3 # (1:l1,2:l1+2,3:l1+2+3,4:l1+2+3+4,5:l1+2+3+4+5) +pos1-soltype =forward # (0:forward,1:backward,2:combined) +pos1-elmask =15 # (deg) +pos1-snrmask_r =off # (0:off,1:on) +pos1-snrmask_b =off # (0:off,1:on) +pos1-snrmask_L1 =0,0,0,0,0,0,0,0,0 +pos1-snrmask_L2 =0,0,0,0,0,0,0,0,0 +pos1-snrmask_L5 =0,0,0,0,0,0,0,0,0 +pos1-dynamics =off # (0:off,1:on) +pos1-tidecorr =off # (0:off,1:on,2:otl) +pos1-ionoopt =brdc # (0:off,1:brdc,2:sbas,3:dual-freq,4:est-stec,5:ionex-tec,6:qzs-brdc) +pos1-tropopt =saas # (0:off,1:saas,2:sbas,3:est-ztd,4:est-ztdgrad) +pos1-sateph =brdc # (0:brdc,1:precise,2:brdc+sbas,3:brdc+ssrapc,4:brdc+ssrcom) +pos1-posopt1 =on # (0:off,1:on) +pos1-posopt2 =on # (0:off,1:on) +pos1-posopt3 =on # (0:off,1:on,2:precise) +pos1-posopt4 =on # (0:off,1:on) +pos1-posopt5 =on # (0:off,1:on) +pos1-posopt6 =off # (0:off,1:on) +pos1-exclsats =C02 # (prn ...) +pos1-navsys =41 # (1:gps+2:sbas+4:glo+8:gal+16:qzs+32:bds+64:navic) +pos2-armode =wide-lane # (0:off,1:continuous,2:instantaneous,3:fix-and-hold,4:WLNL,5:TCAR,6:wide-lane) +# SWIFT: only enable for static positioning mode +pos2-wlarmode =off # (0:off,1:on) +pos2-gloarmode =off # (0:off,1:on) +pos2-bdsarmode =off # (0:off,1:on) +pos2-arthres =3 +pos2-arthres1 =0.9999 +pos2-arthres2 =0.25 +pos2-arthres3 =0.1 +pos2-arthres4 =0.05 +pos2-arlockcnt =30 +pos2-arelmask =0 # (deg) +pos2-arminfix =30 +pos2-armaxiter =1 +pos2-elmaskhold =0 # (deg) +pos2-aroutcnt =30 +pos2-maxage =30 # (s) +pos2-syncsol =off # (0:off,1:on) +pos2-slipthres =0.05 # (m) +pos2-rejionno =30 # (m) +pos2-rejgdop =30 +pos2-niter =1 +pos2-baselen =0 # (m) +pos2-basesig =0 # (m) +out-solformat =xyz # (0:llh,1:xyz,2:enu,3:nmea) +out-outhead =off # (0:off,1:on) +out-outopt =off # (0:off,1:on) +out-outvel =off # (0:off,1:on) +out-timesys =gpst # (0:gpst,1:utc,2:jst) +out-timeform =tow # (0:tow,1:hms) +out-timendec =3 +out-degform =dms # (0:deg,1:dms) +out-fieldsep = +out-outsingle =on # (0:off,1:on) +out-maxsolstd =0 # (m) +out-height =geodetic # (0:ellipsoidal,1:geodetic) +out-geoid =internal # (0:internal,1:egm96,2:egm08_2.5,3:egm08_1,4:gsi2000) +out-solstatic =all # (0:all,1:single) +out-nmeaintv1 =0 # (s) +out-nmeaintv2 =0 # (s) +out-outstat =state # (0:off,1:state,2:residual) +stats-eratio1 =100 +stats-eratio2 =100 +stats-errphase =0.01 # (m) +stats-errphaseel =0.01 # (m) +stats-errphasebl =0 # (m/10km) +stats-errdoppler =1 # (Hz) +stats-stdbias =30 # (m) +stats-stdiono =0.03 # (m) +stats-stdtrop =0.3 # (m) +stats-prnaccelh =10 # (m/s^2) +stats-prnaccelv =10 # (m/s^2) +stats-prnbias =0.0001 # (m) +stats-prniono =0.001 # (m) +stats-prntrop =0.0001 # (m) +stats-prnpos =0 # (m) +stats-clkstab =5e-12 # (s/s) +ant1-postype =llh # (0:llh,1:xyz,2:single,3:posfile,4:rinexhead,5:rtcm,6:raw,7:rinexdynamic) +ant1-pos1 =90 # (deg|m) +ant1-pos2 =0 # (deg|m) +ant1-pos3 =-6335367.6285 # (m|m) +ant1-anttype = +ant1-antdele =0 # (m) +ant1-antdeln =0 # (m) +ant1-antdelu =0 # (m) +ant2-postype =rtcm # (0:llh,1:xyz,2:single,3:posfile,4:rinexhead,5:rtcm,6:raw,7:rinexdynamic) +ant2-pos1 =0 # (deg|m) +ant2-pos2 =0 # (deg|m) +ant2-pos3 =0 # (m|m) +ant2-anttype = +ant2-antdele =0 # (m) +ant2-antdeln =0 # (m) +ant2-antdelu =0 # (m) +ant2-maxaveep =3600 +ant2-initrst =on # (0:off,1:on) +misc-timeinterp =off # (0:off,1:on) +misc-sbasatsel =0 # (0:all) +misc-rnxopt1 = +misc-rnxopt2 = +misc-pppopt = +file-satantfile = +file-rcvantfile = +file-staposfile = +file-geoidfile = +file-ionofile = +file-dcbfile = +file-eopfile = +file-blqfile = +file-tempdir = +file-geexefile = +file-solstatfile = +file-tracefile = diff --git a/src/options.c b/src/options.c index a64b12e31..dac0bf298 100644 --- a/src/options.c +++ b/src/options.c @@ -58,7 +58,7 @@ static char snrmask_[NFREQ][1024]; #define GEOOPT "0:internal,1:egm96,2:egm08_2.5,3:egm08_1,4:gsi2000" #define STAOPT "0:all,1:single" #define STSOPT "0:off,1:state,2:residual" -#define ARMOPT "0:off,1:continuous,2:instantaneous,3:fix-and-hold" +#define ARMOPT "0:off,1:continuous,2:instantaneous,3:fix-and-hold,4:WLNL,5:TCAR,6:wide-lane" #define POSOPT "0:llh,1:xyz,2:single,3:posfile,4:rinexhead,5:rtcm,6:raw" #define TIDEOPT "0:off,1:on,2:otl" #define PHWOPT "0:off,1:on,2:precise" @@ -86,8 +86,9 @@ EXPORT opt_t sysopts[]={ {"pos1-posopt6", 3, (void *)&prcopt_.posopt[5], SWTOPT }, {"pos1-exclsats", 2, (void *)exsats_, "prn ..."}, {"pos1-navsys", 0, (void *)&prcopt_.navsys, NAVOPT }, - + {"pos2-armode", 3, (void *)&prcopt_.modear, ARMOPT }, + {"pos2-wlarmode", 3, (void *)&prcopt_.wlmodear, SWTOPT }, {"pos2-gloarmode", 3, (void *)&prcopt_.glomodear, GAROPT }, {"pos2-bdsarmode", 3, (void *)&prcopt_.bdsmodear, SWTOPT }, {"pos2-arthres", 1, (void *)&prcopt_.thresar[0], "" }, diff --git a/src/rtcm3.c b/src/rtcm3.c index 1aa92989b..252c9b906 100644 --- a/src/rtcm3.c +++ b/src/rtcm3.c @@ -113,7 +113,7 @@ const char *msm_sig_sbs[32]={ const char *msm_sig_cmp[32]={ /* BeiDou: ref [17] table 3.5-108 */ "" ,"2I","2Q","2X","" ,"" ,"" ,"6I","6Q","6X","" ,"" , - "" ,"7I","7Q","7X","" ,"" ,"" ,"" ,"" ,"" ,"" ,"" , + "" ,"7I","7Q","7X","" ,"" ,"" ,"" ,"" ,"5D","5P","5X", "" ,"" ,"" ,"" ,"" ,"" ,"" ,"" }; const char *msm_sig_irn[32]={ @@ -2088,7 +2088,7 @@ static void save_msm_obs(rtcm_t *rtcm, int sys, msm_h_t *h, const double *r, (float)(-(rr[i]+rrf[j])*freq/CLIGHT); } rtcm->obs.data[index].LLI[idx[k]]= - lossoflock(rtcm,sat,idx[k],lock[j])+(half[j]?3:0); + lossoflock(rtcm,sat,idx[k],lock[j])+(half[j]?2:0); rtcm->obs.data[index].SNR [idx[k]]=(uint16_t)(cnr[j]/SNR_UNIT+0.5); rtcm->obs.data[index].code[idx[k]]=code[k]; } diff --git a/src/rtkcmn.c b/src/rtkcmn.c index 9a0acf58c..6c55b76be 100644 --- a/src/rtkcmn.c +++ b/src/rtkcmn.c @@ -204,7 +204,7 @@ const double chisqr[100]={ /* chi-sqr(n) (alpha=0.001) */ const prcopt_t prcopt_default={ /* defaults processing options */ PMODE_SINGLE,0,2,SYS_GPS, /* mode,soltype,nf,navsys */ 15.0*D2R,{{0,0}}, /* elmin,snrmask */ - 0,1,1,1, /* sateph,modear,glomodear,bdsmodear */ + 0,1,0,1,1, /* sateph,modear,wlmodear,glomodear,bdsmodear */ 5,0,10,1, /* maxout,minlock,minfix,armaxiter */ 0,0,0,0, /* estion,esttrop,dynamics,tidecorr */ 1,0,0,0,0, /* niter,codesmooth,intpref,sbascorr,sbassatsel */ @@ -3114,10 +3114,13 @@ extern void traceobs(int level, const obsd_t *obs, int n) for (i=0;i +#include #include "rtklib.h" /* constants/macros ----------------------------------------------------------*/ @@ -1278,7 +1279,7 @@ static int ddidx(rtk_t *rtk, int *ix) /* restore SD (single-differenced) ambiguity ---------------------------------*/ static void restamb(rtk_t *rtk, const double *bias, int nb, double *xa) { - int i,n,m,f,index[MAXSAT],nv=0,nf=NF(&rtk->opt); + int i,n,m,f,index[MAXSAT]={0},index0[MAXSAT]={0},nv=0,nf=NF(&rtk->opt); trace(3,"restamb :\n"); @@ -1291,23 +1292,41 @@ static void restamb(rtk_t *rtk, const double *bias, int nb, double *xa) if (!test_sys(rtk->ssat[i].sys,m)||rtk->ssat[i].fix[f]!=2) { continue; } + if (f==0) { + index0[n]=IB(i+1,0,&rtk->opt); + } index[n++]=IB(i+1,f,&rtk->opt); } if (n<2) continue; - xa[index[0]]=rtk->x[index[0]]; - - for (i=1;iopt.modear==ARMODE_WL) { + for (i=1;i0&&index0[0]!=0&& + index0[i]!=0&& + index[0] !=0&& + index[i] !=0) { + xa[index[i]]=bias[nv++]-(xa[index0[0]]-xa[index0[i]]-xa[index[0]]); + } + } + } + else { + xa[index[0]]=rtk->x[index[0]]; + + for (i=1;inx-rtk->na,nv=0,nf=NF(&rtk->opt); - + int i,n,m,f,info,index[MAXSAT]={0},index0[MAXSAT]={0},nb=rtk->nx-rtk->na; + int nv=0,nf=NF(&rtk->opt); + trace(3,"holdamb :\n"); v=mat(nb,1); H=zeros(nb,rtk->nx); @@ -1319,16 +1338,43 @@ static void holdamb(rtk_t *rtk, const double *xa) rtk->ssat[i].azel[1]opt.elmaskhold) { continue; } + if (f==0) { + index0[n]=IB(i+1,0,&rtk->opt); + } index[n++]=IB(i+1,f,&rtk->opt); rtk->ssat[i].fix[f]=3; /* hold */ } /* constraint to fixed ambiguity */ - for (i=1;ix[index[0]]-rtk->x[index[i]]); - - H[index[0]+nv*rtk->nx]= 1.0; - H[index[i]+nv*rtk->nx]=-1.0; - nv++; + if (rtk->opt.modear==ARMODE_WL) { + for (i=1;i0&&index0[0]!=0&& + index0[i]!=0&& + index[0] !=0&& + index[i] !=0) { + v[nv]=xa[index0[0]]-xa[index0[i]] + -(xa[index[0]]-xa[index[i]]) + -(rtk->x[index0[0]]-rtk->x[index0[i]] + -(rtk->x[index[0]]-rtk->x[index[i]])); + + trace(3,"hold_amb = %lf \n",xa[index0[0]]-xa[index0[i]] + -(xa[index[0]]-xa[index[i]])); + + H[index[0]+nv*rtk->nx]= -1.0; + H[index[i]+nv*rtk->nx]= 1.0; + H[index0[0]+nv*rtk->nx]= 1.0; + H[index0[i]+nv*rtk->nx]=-1.0; + nv++; + } + } + } else { + for (i=1;ix[index[0]]-rtk->x[index[i]]); + + H[index[0]+nv*rtk->nx]= 1.0; + H[index[i]+nv*rtk->nx]=-1.0; + nv++; + } } } if (nv>0) { @@ -1343,6 +1389,174 @@ static void holdamb(rtk_t *rtk, const double *xa) } free(v); free(H); } + +/* single to double-differenced wide-lane transformation matrix (D') ---------*/ +static int dd_wl_mat(rtk_t *rtk, double *D) +{ + int i,j,k,m,f,nb=0,nx=rtk->nx,na=rtk->na,nf=NF(&rtk->opt),nofix; + + trace(3,"dd_wl_mat :\n"); + + for (i=0;issat[i].fix[j]=0; + } + for (i=0;iopt.glomodear==0)||(m==3&&rtk->opt.bdsmodear==0); + if (nofix) { + continue; + } + + k=na; + f=nf==2?1:2; + for (i=k;ix[i]==0.0|| + rtk->x[i+f*MAXSAT]==0.0|| + !test_sys(rtk->ssat[i-k].sys,m)|| + !rtk->ssat[i-k].vsat[0]|| + !rtk->ssat[i-k].half[0]|| + !rtk->ssat[i-k].vsat[f]|| + !rtk->ssat[i-k].half[f]) { + continue; + } + if (rtk->ssat[i-k].lock[0]>0&& + rtk->ssat[i-k].lock[f]>0&& + !(rtk->ssat[i-k].slip[f]&2)&& + !(rtk->ssat[i-k].slip[0]&2)&& + rtk->ssat[i-k].azel[1]>=rtk->opt.elmaskar) { + rtk->ssat[i-k].fix[0]=2; /* fix */ + rtk->ssat[i-k].fix[f]=2; /* fix */ + break; + } + else { + rtk->ssat[i-k].fix[0]=1; + rtk->ssat[i-k].fix[f]=1; + } + } + + for (j=k;jx[j]==0.0|| + rtk->x[j+f*MAXSAT]==0.0|| + !test_sys(rtk->ssat[j-k].sys,m)|| + !rtk->ssat[j-k].vsat[0]|| + !rtk->ssat[j-k].vsat[f]) { + continue; + } + if (rtk->ssat[j-k].lock[0]>0&& + rtk->ssat[j-k].lock[f]>0&& + !(rtk->ssat[j-k].slip[0]&2)&& + !(rtk->ssat[j-k].slip[f]&2)&& + rtk->ssat[j-k].azel[1]>=rtk->opt.elmaskar) { + D[i+(na+nb)*nx]= 1.0; + D[i+f*MAXSAT+(na+nb)*nx]=-1.0; + D[j+(na+nb)*nx]=-1.0; + D[j+f*MAXSAT+(na+nb)*nx]=1.0; + nb++; + rtk->ssat[j-k].fix[f]=2; /* fix */ + rtk->ssat[j-k].fix[0]=2; /* fix */ + } + else { + rtk->ssat[j-k].fix[0]=1; + rtk->ssat[j-k].fix[f]=1; + } + } + } + + trace(4,"Dw=\n"); tracemat(4,D,nx,na+nb,2,0); + return nb; +} + +/* resolve integer ambiguity by LAMBDA ---------------------------------------*/ +static int resamb_WL(rtk_t *rtk, double *bias, double *xa) +{ + prcopt_t *opt=&rtk->opt; + int i,j,ny,nb,info,nx=rtk->nx,na=rtk->na; + double *D,*DP,*y,*Qy,*b,*db,*Qb,*Qab,*QQ,s[2]; + + trace(3,"resamb_WL : nx=%d\n",nx); + + rtk->sol.ratio=0.0; + + if (rtk->opt.modear!=ARMODE_WL||rtk->opt.thresar[0]<1.0||rtk->opt.nf<2) { + return 0; + } + /* single to double-differenced wide-lane transformation matrix (D') */ + D=zeros(nx,nx); + if ((nb=dd_wl_mat(rtk,D))<=0) { + errmsg(rtk,"no valid double, wide-lane difference\n"); + free(D); + return 0; + }; + trace(2,"na = %d, nb = %d\n", na, nb); + ny=na+nb; y=mat(ny,1); Qy=mat(ny,ny); DP=mat(ny,nx); + b=mat(nb,2); db=mat(nb,1); Qb=mat(nb,nb); Qab=mat(na,nb); QQ=mat(na,nb); + + /* transform single to DD wide-lane phase-bias (y=D'*x, Qy=D'*P*D) */ + matmul("TN",ny, 1,nx,1.0,D ,rtk->x,0.0,y ); + matmul("TN",ny,nx,nx,1.0,D ,rtk->P,0.0,DP); + matmul("NN",ny,ny,nx,1.0,DP,D ,0.0,Qy); + + /* phase-bias covariance (Qb) and real-parameters to bias covariance (Qab) */ + for (i=0;ixa); + + /* covariance of fixed solution (Qa=Qa-Qab*Qb^-1*Qab') */ + matmul("NN",na,nb,nb, 1.0,Qab,Qb ,0.0,QQ); + matmul("NT",na,na,nb,-1.0,QQ ,Qab,1.0,rtk->Pa); + + trace(3,"resamb : validation ok (nb=%d ratio=%.2f s=%.2f/%.2f)\n", + nb,s[0]==0.0?0.0:s[1]/s[0],s[0],s[1]); + + /* restore single-differenced ambiguity */ + trace(2,"nb = %d\n",nb); + restamb(rtk,bias,nb,xa); + } + else nb=0; + } + else { /* validation failed */ + errmsg(rtk,"ambiguity validation failed (nb=%d ratio=%.2f s=%.2f/%.2f)\n", + nb,s[1]/s[0],s[0],s[1]); + nb=0; + } + } + else { + errmsg(rtk,"lambda error (info=%d)\n",info); + nb=0; + } + free(D); free(y); free(Qy); free(DP); + free(b); free(db); free(Qb); free(Qab); free(QQ); + + return nb; /* number of ambiguities */ +} /* resolve integer ambiguity by LAMBDA ---------------------------------------*/ static int resamb_LAMBDA(rtk_t *rtk, double *bias, double *xa) { @@ -1567,8 +1781,15 @@ static int relpos(rtk_t *rtk, const obsd_t *obs, int nu, int nr, } else stat=SOLQ_NONE; } + /* resolve integer ambiguity by WL */ + if (stat!=SOLQ_NONE&&rtk->opt.modear==ARMODE_WL) { + if (resamb_WL(rtk,bias,xa)>1) { + if (rtk->opt.wlmodear==1) holdamb(rtk,xa); + stat=SOLQ_FIX; + } + } /* resolve integer ambiguity by LAMBDA */ - if (stat!=SOLQ_NONE&&resamb_LAMBDA(rtk,bias,xa)>1) { + else if (stat!=SOLQ_NONE&&resamb_LAMBDA(rtk,bias,xa)>1) { if (zdres(0,obs,nu,rs,dts,var,svh,nav,xa,opt,0,y,e,azel,freq)) { @@ -1773,7 +1994,7 @@ extern int rtkpos(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav) /* count rover/base station observations */ for (nu=0;nu sol.time; /* previous epoch */ /* rover position by single point positioning */