/* psendorange with code bias correction -------------------------------------*/ static double prange(const obsd_t *obs, const nav_t *nav, const double *azel, int iter, const prcopt_t *opt, double *var) { const double *lam=nav->lam[obs->sat-1]; double PC,P1,P2,P1_P2,P1_C1,P2_C2,gamma; int i=0,j=1,sys; *var=0.0; if (!(sys=satsys(obs->sat,NULL))) return 0.0; /* L1-L2 for GPS/GLO/QZS, L1-L5 for GAL/SBS */ if (NFREQ>=3&&(sys&(SYS_GAL|SYS_SBS))) j=2; if (NFREQ<2||lam[i]==0.0||lam[j]==0.0) return 0.0; /* test snr mask */ if (iter>0) { if (testsnr(0,i,azel[1],obs->SNR[i]*0.25,&opt->snrmask)) { trace(4,"snr mask: %s sat=%2d el=%.1f snr=%.1f\n", time_str(obs->time,0),obs->sat,azel[1]*R2D,obs->SNR[i]*0.25); return 0.0; } if (opt->ionoopt==IONOOPT_IFLC) { if (testsnr(0,j,azel[1],obs->SNR[j]*0.25,&opt->snrmask)) return 0.0; } } gamma=SQR(lam[j])/SQR(lam[i]); /* f1^2/f2^2 */ P1=obs->P[i]; P2=obs->P[j]; P1_P2=nav->cbias[obs->sat-1][0]; P1_C1=nav->cbias[obs->sat-1][1]; P2_C2=nav->cbias[obs->sat-1][2]; /* if no P1-P2 DCB, use TGD instead */ if (P1_P2==0.0&&(sys&(SYS_GPS|SYS_GAL|SYS_QZS))) { P1_P2=(1.0-gamma)*gettgd(obs->sat,nav); } if (opt->ionoopt==IONOOPT_IFLC) { /* dual-frequency */ if (P1==0.0||P2==0.0) return 0.0; if (obs->code[i]==CODE_L1C) P1+=P1_C1; /* C1->P1 */ if (obs->code[j]==CODE_L2C) P2+=P2_C2; /* C2->P2 */ /* iono-free combination */ PC=(gamma*P1-P2)/(gamma-1.0); } else { /* single-frequency */ if (P1==0.0) return 0.0; if (obs->code[i]==CODE_L1C) P1+=P1_C1; /* C1->P1 */ PC=P1-P1_P2/(1.0-gamma); } if (opt->sateph==EPHOPT_SBAS) PC-=P1_C1; /* sbas clock based C1 */ *var=SQR(ERR_CBIAS); return PC; }
/* dual-frequency iono-free measurements -------------------------------------*/ static 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) { const double *lam=nav->lam[obs->sat-1]; double c1,c2,L1,L2,P1,P2,P1_C1,P2_C2,gamma; int i=0,j=1,k; trace(4,"ifmeas :\n"); /* L1-L2 for GPS/GLO/QZS, L1-L5 for GAL/SBS */ if (NFREQ>=3&&(satsys(obs->sat,NULL)&(SYS_GAL|SYS_SBS))) j=2; if (NFREQ<2||lam[i]==0.0||lam[j]==0.0) return 0; /* test snr mask */ if (testsnr(0,i,azel[1],obs->SNR[i]*0.25,&opt->snrmask)|| testsnr(0,j,azel[1],obs->SNR[j]*0.25,&opt->snrmask)) { return 0; } gamma=SQR(lam[j])/SQR(lam[i]); /* f1^2/f2^2 */ c1=gamma/(gamma-1.0); /* f1^2/(f1^2-f2^2) */ c2=-1.0 /(gamma-1.0); /* -f2^2/(f1^2-f2^2) */ L1=obs->L[i]*lam[i]; /* cycle -> m */ L2=obs->L[j]*lam[j]; P1=obs->P[i]; P2=obs->P[j]; P1_C1=nav->cbias[obs->sat-1][1]; P2_C2=nav->cbias[obs->sat-1][2]; if (opt->sateph==EPHOPT_LEX) { P1_C1=nav->lexeph[obs->sat-1].isc[0]*CLIGHT; /* ISC_L1C/A */ } if (L1==0.0||L2==0.0||P1==0.0||P2==0.0) return 0; /* iono-free phase with windup correction */ meas[0]=c1*L1+c2*L2-(c1*lam[i]+c2*lam[j])*phw; /* iono-free code with dcb correction */ if (obs->code[i]==CODE_L1C) P1+=P1_C1; /* C1->P1 */ if (obs->code[j]==CODE_L2C) P2+=P2_C2; /* C2->P2 */ meas[1]=c1*P1+c2*P2; var[1]=SQR(ERR_CBIAS); if (opt->sateph==EPHOPT_SBAS) meas[1]-=P1_C1; /* sbas clock based C1 */ /* gps-glonass h/w bias correction for code */ if (opt->exterr.ena[3]&&satsys(obs->sat,NULL)==SYS_GLO) { meas[1]+=c1*opt->exterr.gpsglob[0]+c2*opt->exterr.gpsglob[1]; } /* antenna phase center variation correction */ for (k=0;k<2;k++) { if (dants) meas[k]-=c1*dants[i]+c2*dants[j]; if (dantr) meas[k]-=c1*dantr[i]+c2*dantr[j]; } return 1; }
/* ionosphere and antenna corrected measurements -----------------------------*/ 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) { const double *lam=nav->lam[obs->sat-1]; double ion=0.0,L1,P1,PC,P1_P2,P1_C1,vari,gamma; int i; trace(4,"corrmeas:\n"); meas[0]=meas[1]=var[0]=var[1]=0.0; /* iono-free LC */ if (opt->ionoopt==IONOOPT_IFLC) { return ifmeas(obs,nav,azel,opt,dantr,dants,phw,meas,var); } if (lam[0]==0.0||obs->L[0]==0.0||obs->P[0]==0.0) return 0; if (testsnr(0,0,azel[1],obs->SNR[0]*0.25,&opt->snrmask)) return 0; L1=obs->L[0]*lam[0]; P1=obs->P[0]; /* dcb correction */ gamma=SQR(lam[1]/lam[0]); /* f1^2/f2^2 */ P1_P2=nav->cbias[obs->sat-1][0]; P1_C1=nav->cbias[obs->sat-1][1]; if (P1_P2==0.0&&(satsys(obs->sat,NULL)&(SYS_GPS|SYS_GAL|SYS_QZS))) { P1_P2=(1.0-gamma)*gettgd(obs->sat,nav); } if (obs->code[0]==CODE_L1C) P1+=P1_C1; /* C1->P1 */ PC=P1-P1_P2/(1.0-gamma); /* P1->PC */ /* slant ionospheric delay L1 (m) */ if (!corr_ion(obs->time,nav,obs->sat,pos,azel,opt->ionoopt,&ion,&vari,brk)) { trace(2,"iono correction error: time=%s sat=%2d ionoopt=%d\n", time_str(obs->time,2),obs->sat,opt->ionoopt); return 0; } /* ionosphere and windup corrected phase and code */ meas[0]=L1+ion-lam[0]*phw; meas[1]=PC-ion; var[0]+=vari; var[1]+=vari+SQR(ERR_CBIAS); /* antenna phase center variation correction */ for (i=0;i<2;i++) { if (dants) meas[i]-=dants[0]; if (dantr) meas[i]-=dantr[0]; } return 1; }
static void zdres_sat(int base, double r, const obsd_t *obs, const nav_t *nav, const double *azel, const prcopt_t *opt, double *y) { /* residuals = observable - pseudorange */ if (testsnr(base,azel[1],obs->SNR*0.25,&opt->snrmask)) { return; } if (obs->L!=0.0) y[0]=obs->L*CLIGHT/FREQ1-r; if (obs->P!=0.0) y[1]=obs->P-r; }