int main(int argc, char **argv) { double lat1, lon1, lat2, lon2, distance; /***************************************************************************** * * * Test computing distances between points on Earth. * * * *****************************************************************************/ fprintf(stdout, "Computing distances between points on Earth\n"); /* SFO (San Francisco) */ lat1 = 37.62; lon1 = 122.38; /* LAX (Los Angeles) */ lat2 = 33.94; lon2 = 118.41; if (geodist(lat1, lon1, lat2, lon2, &distance) != 0) return 1; fprintf(stdout, "SFO: (%+07.2lf,%+07.2lf)\n", lat1, lon1); fprintf(stdout, "LAX: (%+07.2lf,%+07.2lf)\n", lat2, lon2); fprintf(stdout, "distance=%d\n", (int)distance); /* CDG (Paris) */ lat1 = 49.01; lon1 = -2.55; /* PER (Perth) */ lat2 = -31.94; lon2 = -115.97; if (geodist(lat1, lon1, lat2, lon2, &distance) != 0) return 1; fprintf(stdout, "CDG: (%+07.2lf,%+07.2lf)\n", lat1, lon1); fprintf(stdout, "PER: (%+07.2lf,%+07.2lf)\n", lat2, lon2); fprintf(stdout, "distance=%d\n", (int)distance); return 0; }
/* static 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, double *y, double *e, double *azel) Description: zero differenced residual Params: base I 1:base, 0: rover obs I n I number of obs data rs I sat positions/velocities dts I sat clock bias svh I nav I rr I receiver position y O zero diff residuals e O azel O {az/el} Return: 0 ok, !0 error */ static 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) { double r,rr_[3],pos[3]; double zhd, zazel[]= {0.0,90.0*D2R}; //tai sao init zazel = {0,90} int i; for (i=0; i<2*n; i++) y[i]=0.0; if (sos3(rr)<=0.0) return -1;//no receiver pos for (i=0; i<3; i++) rr_[i]=rr[i]; ecef2pos(rr_,pos); for (i=0; i<n; i++) { 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; //satellite clock-bias r -= CLIGHT*dts[i*2]; /* troposphere delay model (hydrostatic) */ zhd=tropmodel(obs[0].time,pos,zazel,0.0);//tai sao chon rel_humi = 0??????????? r+=tropmapf(obs[i].time,pos,azel+i*2,NULL)*zhd; /* undifferenced phase/code residual for satellite */ zdres_sat(base,r,obs+i,nav,azel+i*2,opt,y+i*2); } return 0; }
/* estimate ionosphere -------------------------------------------------------*/ static int est_iono(obs_t *obs, nav_t *nav, const pcv_t *pcv, double *rr, double tint, FILE *fp) { sstat_t sstat[MAXSAT]={{{0}}}; ekf_t *ekf; gtime_t time; double pos[3],rs[MAXOBS*6],dts[MAXOBS*2],var[MAXOBS],e[3],azel[MAXOBS*2]; double *v,*H,*R,phw[MAXSAT]={0}; int i,j,n=0,info,nx=NX,nv=MAXSAT*2,svh[MAXOBS]; ekf=ekf_new(NX); v=mat(nv,1); H=mat(nx,nv); R=mat(nv,nv); /* receiver position */ ecef2pos(rr,pos); out_head(obs->data[0].time,pos,fp); for (i=0;i<obs->n;i+=n) { for (n=1;i+n<obs->n;n++) { if (timediff(obs->data[i+n].time,obs->data[i].time)>1E-3) break; } time=obs->data[i].time; /* satellite positions and clocks */ satposs(time,obs->data+i,n,nav,EPHOPT_BRDC,rs,dts,var,svh); /* satellite azimuth/elevation angle */ for (j=0;j<n;j++) { if (geodist(rs+j*6,rr,e)>0.0) satazel(pos,e,azel+j*2); else azel[j*2]=azel[1+j*2]=0.0; } /* time update of parameters */ ud_state(obs->data+i,n,nav,pos,azel,ekf,sstat); /* ionosphere residuals */ if ((nv=res_iono(obs->data+i,n,nav,rs,rr,pos,azel,pcv,ekf,phw,v,H,R))<=0) { continue; } /* filter */ if ((info=filter(ekf->x,ekf->P,H,v,R,ekf->nx,nv))) { fprintf(stderr,"filter error: info=%d\n",info); break; } /* output ionopshere parameters */ if (tint<=0.0||fmod(time2gpst(time,NULL)+0.005,tint)<0.01) { out_iono(obs->data[i].time,ekf,sstat,fp); } } ekf_free(ekf); free(v); free(H); free(R); return 1; }
/* satellite azimuth/elevation angle -----------------------------------------*/ static void sat_azel(const obsd_t *obs, int n, const nav_t *nav, const double *pos, double *azel) { double rs[MAXOBS*6],dts[MAXOBS*2],var[MAXOBS],r,e[3]; int svh[MAXOBS]; /* satellite positions and clocks */ satposs(obs[0].time,obs,n,nav,EPHOPT_BRDC,rs,dts,var,svh); for (i=0;i<n;i++) { if (geodist(rs+i*6,rr,e))>0.0) satazel(pos,e,azel+i*2); } }
/* pseudorange residuals -----------------------------------------------------*/ static 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, prcopt_t *opt, double *v, double *H, double *var, double *azel, int *vsat, double *resp, int *ns, rtk_t *rtk) { double r,dion,dtrp,vmeas,vion,vtrp,rr[3],pos[3],dtr,e[3],P; int i, j, nv = 0, sys, mask[4] = { 0 }; double azl = 0; for (i=0;i<3;i++) rr[i]=x[i]; dtr=x[3]; ecef2pos(rr,pos); for (i=*ns=0;i<n&&i<MAXOBS;i++) { vsat[i]=0; azel[i*2]=azel[1+i*2]=resp[i]=0.0; if (obs[i].sat>32){ //added by yuan; continue; } //���������ز�����α��Ͳ�����������ǵķ���; if ((fabs(obs[i].L[0]) < 0.0001) || (fabs(obs[i].P[0]) < 0.0001)){ continue; } if (!(sys=satsys(obs[i].sat,NULL))) continue; /* reject duplicated observation data */ if (i<n-1&&i<MAXOBS-1&&obs[i].sat==obs[i+1].sat) { i++; continue; } /* geometric distance/azimuth/elevation angle */ if ((r=geodist(rs+i*6,rr,e))<=0.0|| satazel(pos,e,azel+i*2)<opt->elmin) continue; azl = satazel(pos, e, azel + i * 2); /* psudorange with code bias correction */ if ((P=prange(obs+i,nav,azel+i*2,iter,opt,&vmeas))==0.0) continue; /* excluded satellite? */ if (satexclude(obs[i].sat,svh[i],opt)) continue; /* ionospheric corrections */ if (!ionocorr(obs[i].time,nav,obs[i].sat,pos,azel+i*2, iter>0?opt->ionoopt:IONOOPT_BRDC,&dion,&vion)) continue; /* tropospheric corrections */ if (!tropcorr(obs[i].time,nav,pos,azel+i*2, iter>0?opt->tropopt:TROPOPT_SAAS,&dtrp,&vtrp)) { continue; } /* pseudorange residual */ v[nv]=P-(r+dtr-CLIGHT*dts[i*2]+dion+dtrp); /* design matrix */ for (j=0;j<NX;j++) H[j+nv*NX]=j<3?-e[j]:(j==3?1.0:0.0); /* time system and receiver bias offset correction */ if (sys==SYS_GLO) {v[nv]-=x[4]; H[4+nv*NX]=1.0; mask[1]=1;} else if (sys==SYS_GAL) {v[nv]-=x[5]; H[5+nv*NX]=1.0; mask[2]=1;} else if (sys==SYS_CMP) {v[nv]-=x[6]; H[6+nv*NX]=1.0; mask[3]=1;} else mask[0]=1; vsat[i]=1; resp[i]=v[nv]; (*ns)++; rtk->sat_[nv] = obs[i].sat; //added by yuan; /* error variance */ if ((rtk->counter > 5) && (obs[i].mark_ < 4)){ var[nv++] = varerr(opt, azel[1 + i * 2], sys) + (4 - obs[i].mark_)*2 + vare[i] + vmeas + vion + vtrp; //varm:α���ز�����;vare:������������;vart:����������; //var[nv - 1] = var[nv - 1] * (4-obs[i].mark_); //�������ʧ���������������Ŵ�; } else{ var[nv++] = varerr(opt, azel[1 + i * 2], sys) + vare[i] + vmeas + vion + vtrp; //varm:α���ز�����;vare:������������;vart:����������; } } /* constraint to avoid rank-deficient */ for (i=0;i<4;i++) { if (mask[i]) continue; v[nv]=0.0; for (j=0;j<NX;j++) H[j+nv*NX]=j==i+3?1.0:0.0; var[nv++]=0.01; } return nv; }
/* phase and code residuals --------------------------------------------------*/ static 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) { prcopt_t *opt=&rtk->opt; double r,rr[3],disp[3],pos[3],e[3],meas[2],dtdx[3],dantr[NFREQ]={0}; double dants[NFREQ]={0},var[MAXOBS*2],dtrp=0.0,vart=0.0,varm[2]={0}; int i,j,k,sat,sys,nv=0,nx=rtk->nx,brk,tideopt; trace(3,"res_ppp : n=%d nx=%d\n",n,nx); for (i=0;i<MAXSAT;i++) rtk->ssat[i].vsat[0]=0; for (i=0;i<3;i++) rr[i]=x[i]; /* earth tides correction */ if (opt->tidecorr) { tideopt=opt->tidecorr==1?1:7; /* 1:solid, 2:solid+otl+pole */ tidedisp(gpst2utc(obs[0].time),rr,tideopt,&nav->erp,opt->odisp[0], disp); for (i=0;i<3;i++) rr[i]+=disp[i]; } ecef2pos(rr,pos); for (i=0;i<n&&i<MAXOBS;i++) { sat=obs[i].sat; if (!(sys=satsys(sat,NULL))||!rtk->ssat[sat-1].vs) continue; /* geometric distance/azimuth/elevation angle */ if ((r=geodist(rs+i*6,rr,e))<=0.0|| satazel(pos,e,azel+i*2)<opt->elmin) continue; /* excluded satellite? */ if (satexclude(obs[i].sat,svh[i],opt)) continue; /* tropospheric delay correction */ if (opt->tropopt==TROPOPT_SAAS) { dtrp=tropmodel(obs[i].time,pos,azel+i*2,REL_HUMI); vart=SQR(ERR_SAAS); } else if (opt->tropopt==TROPOPT_SBAS) { dtrp=sbstropcorr(obs[i].time,pos,azel+i*2,&vart); } else if (opt->tropopt==TROPOPT_EST||opt->tropopt==TROPOPT_ESTG) { dtrp=prectrop(obs[i].time,pos,azel+i*2,opt,x+IT(opt),dtdx,&vart); } else if (opt->tropopt==TROPOPT_COR||opt->tropopt==TROPOPT_CORG) { dtrp=prectrop(obs[i].time,pos,azel+i*2,opt,x,dtdx,&vart); } /* satellite antenna model */ if (opt->posopt[0]) { satantpcv(rs+i*6,rr,nav->pcvs+sat-1,dants); } /* receiver antenna model */ antmodel(opt->pcvr,opt->antdel[0],azel+i*2,opt->posopt[1],dantr); /* phase windup correction */ if (opt->posopt[2]) { windupcorr(rtk->sol.time,rs+i*6,rr,&rtk->ssat[sat-1].phw); } /* ionosphere and antenna phase corrected measurements */ if (!corrmeas(obs+i,nav,pos,azel+i*2,&rtk->opt,dantr,dants, rtk->ssat[sat-1].phw,meas,varm,&brk)) { continue; } /* satellite clock and tropospheric delay */ r+=-CLIGHT*dts[i*2]+dtrp; trace(5,"sat=%2d azel=%6.1f %5.1f dtrp=%.3f dantr=%6.3f %6.3f dants=%6.3f %6.3f phw=%6.3f\n", sat,azel[i*2]*R2D,azel[1+i*2]*R2D,dtrp,dantr[0],dantr[1],dants[0], dants[1],rtk->ssat[sat-1].phw); for (j=0;j<2;j++) { /* for phase and code */ if (meas[j]==0.0) continue; for (k=0;k<nx;k++) H[k+nx*nv]=0.0; v[nv]=meas[j]-r; for (k=0;k<3;k++) H[k+nx*nv]=-e[k]; if (sys!=SYS_GLO) { v[nv]-=x[IC(0,opt)]; H[IC(0,opt)+nx*nv]=1.0; } else { v[nv]-=x[IC(1,opt)]; H[IC(1,opt)+nx*nv]=1.0; } if (opt->tropopt>=TROPOPT_EST) { for (k=0;k<(opt->tropopt>=TROPOPT_ESTG?3:1);k++) { H[IT(opt)+k+nx*nv]=dtdx[k]; } } if (j==0) { v[nv]-=x[IB(obs[i].sat,opt)]; H[IB(obs[i].sat,opt)+nx*nv]=1.0; } var[nv]=varerr(obs[i].sat,sys,azel[1+i*2],j,opt)+varm[j]+vare[i]+vart; if (j==0) rtk->ssat[sat-1].resc[0]=v[nv]; else rtk->ssat[sat-1].resp[0]=v[nv]; /* test innovation */ #if 0 if (opt->maxinno>0.0&&fabs(v[nv])>opt->maxinno) { #else if (opt->maxinno>0.0&&fabs(v[nv])>opt->maxinno&&sys!=SYS_GLO) { #endif trace(2,"ppp outlier rejected %s sat=%2d type=%d v=%.3f\n", time_str(obs[i].time,0),sat,j,v[nv]); rtk->ssat[sat-1].rejc[0]++; continue; } if (j==0) rtk->ssat[sat-1].vsat[0]=1; nv++; } } for (i=0;i<nv;i++) for (j=0;j<nv;j++) { R[i+j*nv]=i==j?var[i]:0.0; } trace(5,"x=\n"); tracemat(5,x, 1,nx,8,3); trace(5,"v=\n"); tracemat(5,v, 1,nv,8,3); trace(5,"H=\n"); tracemat(5,H,nx,nv,8,3); trace(5,"R=\n"); tracemat(5,R,nv,nv,8,5); return nv; } /* number of estimated states ------------------------------------------------*/ extern int pppnx(const prcopt_t *opt) { return NX(opt); } /* precise point positioning -------------------------------------------------*/ extern void pppos(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav) { const prcopt_t *opt=&rtk->opt; double *rs,*dts,*var,*v,*H,*R,*azel,*xp,*Pp; int i,nv,info,svh[MAXOBS],stat=SOLQ_SINGLE; trace(3,"pppos : nx=%d n=%d\n",rtk->nx,n); rs=mat(6,n); dts=mat(2,n); var=mat(1,n); azel=zeros(2,n); for (i=0;i<MAXSAT;i++) rtk->ssat[i].fix[0]=0; /* temporal update of states */ udstate_ppp(rtk,obs,n,nav); trace(4,"x(0)="); tracemat(4,rtk->x,1,NR(opt),13,4); /* satellite positions and clocks */ satposs(obs[0].time,obs,n,nav,rtk->opt.sateph,rs,dts,var,svh); /* exclude measurements of eclipsing satellite */ if (rtk->opt.posopt[3]) { testeclipse(obs,n,nav,rs); } xp=mat(rtk->nx,1); Pp=zeros(rtk->nx,rtk->nx); matcpy(xp,rtk->x,rtk->nx,1); nv=n*rtk->opt.nf*2; v=mat(nv,1); H=mat(rtk->nx,nv); R=mat(nv,nv); for (i=0;i<rtk->opt.niter;i++) { /* phase and code residuals */ if ((nv=res_ppp(i,obs,n,rs,dts,var,svh,nav,xp,rtk,v,H,R,azel))<=0) break; /* measurement update */ matcpy(Pp,rtk->P,rtk->nx,rtk->nx); if ((info=filter(xp,Pp,H,v,R,rtk->nx,nv))) { trace(2,"ppp filter error %s info=%d\n",time_str(rtk->sol.time,0), info); break; } trace(4,"x(%d)=",i+1); tracemat(4,xp,1,NR(opt),13,4); stat=SOLQ_PPP; } if (stat==SOLQ_PPP) { /* postfit residuals */ res_ppp(1,obs,n,rs,dts,var,svh,nav,xp,rtk,v,H,R,azel); /* update state and covariance matrix */ matcpy(rtk->x,xp,rtk->nx,1); matcpy(rtk->P,Pp,rtk->nx,rtk->nx); /* ambiguity resolution in ppp */ if (opt->modear==ARMODE_PPPAR||opt->modear==ARMODE_PPPAR_ILS) { if (pppamb(rtk,obs,n,nav,azel)) stat=SOLQ_FIX; } /* update solution status */ rtk->sol.ns=0; for (i=0;i<n&&i<MAXOBS;i++) { if (!rtk->ssat[obs[i].sat-1].vsat[0]) continue; rtk->ssat[obs[i].sat-1].lock[0]++; rtk->ssat[obs[i].sat-1].outc[0]=0; rtk->ssat[obs[i].sat-1].fix [0]=4; rtk->sol.ns++; } rtk->sol.stat=stat; for (i=0;i<3;i++) { rtk->sol.rr[i]=rtk->x[i]; rtk->sol.qr[i]=(float)rtk->P[i+i*rtk->nx]; } rtk->sol.qr[3]=(float)rtk->P[1]; rtk->sol.qr[4]=(float)rtk->P[2+rtk->nx]; rtk->sol.qr[5]=(float)rtk->P[2]; rtk->sol.dtr[0]=rtk->x[IC(0,opt)]; rtk->sol.dtr[1]=rtk->x[IC(1,opt)]-rtk->x[IC(0,opt)]; for (i=0;i<n&&i<MAXOBS;i++) { rtk->ssat[obs[i].sat-1].snr[0]=MIN(obs[i].SNR[0],obs[i].SNR[1]); } for (i=0;i<MAXSAT;i++) { if (rtk->ssat[i].slip[0]&3) rtk->ssat[i].slipc[0]++; } } free(rs); free(dts); free(var); free(azel); free(xp); free(Pp); free(v); free(H); free(R); }
/* pseudorange residuals -----------------------------------------------------*/ static 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) { double r,dion,dtrp,vmeas,vion,vtrp,rr[3],pos[3],dtr,e[3],P,lam_L1; int i,j,nv=0,sys,mask[4]={0}; trace(3,"resprng : n=%d\n",n); for (i=0;i<3;i++) rr[i]=x[i]; dtr=x[3]; ecef2pos(rr,pos); for (i=*ns=0;i<n&&i<MAXOBS;i++) { vsat[i]=0; azel[i*2]=azel[1+i*2]=resp[i]=0.0; if (!(sys=satsys(obs[i].sat,NULL))) continue; /* reject duplicated observation data */ if (i<n-1&&i<MAXOBS-1&&obs[i].sat==obs[i+1].sat) { trace(2,"duplicated observation data %s sat=%2d\n", time_str(obs[i].time,3),obs[i].sat); i++; continue; } /* geometric distance/azimuth/elevation angle */ if ((r=geodist(rs+i*6,rr,e))<=0.0|| satazel(pos,e,azel+i*2)<opt->elmin) continue; /* psudorange with code bias correction */ if ((P=prange(obs+i,nav,azel+i*2,iter,opt,&vmeas))==0.0) continue; /* excluded satellite? */ if (satexclude(obs[i].sat,svh[i],opt)) continue; /* ionospheric corrections */ if (!ionocorr(obs[i].time,nav,obs[i].sat,pos,azel+i*2, iter>0?opt->ionoopt:IONOOPT_BRDC,&dion,&vion)) continue; /* GPS-L1 -> L1/B1 */ if ((lam_L1=nav->lam[obs[i].sat-1][0])>0.0) { dion*=SQR(lam_L1/lam_carr[0]); } /* tropospheric corrections */ if (!tropcorr(obs[i].time,nav,pos,azel+i*2, iter>0?opt->tropopt:TROPOPT_SAAS,&dtrp,&vtrp)) { continue; } /* pseudorange residual */ v[nv]=P-(r+dtr-CLIGHT*dts[i*2]+dion+dtrp); /* design matrix */ for (j=0;j<NX;j++) H[j+nv*NX]=j<3?-e[j]:(j==3?1.0:0.0); /* time system and receiver bias offset correction */ if (sys==SYS_GLO) {v[nv]-=x[4]; H[4+nv*NX]=1.0; mask[1]=1;} else if (sys==SYS_GAL) {v[nv]-=x[5]; H[5+nv*NX]=1.0; mask[2]=1;} else if (sys==SYS_CMP) {v[nv]-=x[6]; H[6+nv*NX]=1.0; mask[3]=1;} else mask[0]=1; vsat[i]=1; resp[i]=v[nv]; (*ns)++; /* error variance */ var[nv++]=varerr(opt,azel[1+i*2],sys)+vare[i]+vmeas+vion+vtrp; trace(4,"sat=%2d azel=%5.1f %4.1f res=%7.3f sig=%5.3f\n",obs[i].sat, azel[i*2]*R2D,azel[1+i*2]*R2D,resp[i],sqrt(var[nv-1])); } /* constraint to avoid rank-deficient */ for (i=0;i<4;i++) { if (mask[i]) continue; v[nv]=0.0; for (j=0;j<NX;j++) H[j+nv*NX]=j==i+3?1.0:0.0; var[nv++]=0.01; } return nv; }
// update observation data index, azimuth/elevation, satellite list --------- void __fastcall TPlot::UpdateObs(int nobs) { AnsiString s; prcopt_t opt=prcopt_default; gtime_t time; sol_t sol={0}; double pos[3],rr[3],e[3],azel[MAXOBS*2]={0},rs[6],dts[2],var; int i,j,k,svh,per,per_=-1; char msg[128]; trace(3,"UpdateObs\n"); delete [] IndexObs; IndexObs=NULL; delete [] Az; Az=NULL; delete [] El; El=NULL; NObs=0; if (nobs<=0) return; IndexObs=new int[nobs]; Az=new double[Obs.n]; El=new double[Obs.n]; opt.err[0]=900.0; ReadWaitStart(); ShowLegend(NULL); for (i=0;i<Obs.n;i=j) { time=Obs.data[i].time; for (j=i;j<Obs.n;j++) { if (timediff(Obs.data[j].time,time)>TTOL) break; } IndexObs[NObs++]=i; if (Nav.n<=0&&Nav.ng<=0&&Nav.ns<=0) { for (k=0;k<j-i;k++) Az[i+k]=El[i+k]=0.0; continue; } if (RcvPos==0) { pntpos(Obs.data+i,j-i,&Nav,&opt,&sol,azel,NULL,msg); } else { if (RcvPos==1) { // lat/lon/height for (k=0;k<3;k++) pos[k]=OOPos[k]; pos2ecef(pos,rr); } else { // rinex header position for (k=0;k<3;k++) rr[k]=Sta.pos[k]; ecef2pos(rr,pos); } for (k=0;k<j-i;k++) { azel[k*2]=azel[1+k*2]=0.0; if (!satpos(time,time,Obs.data[i+k].sat,EPHOPT_BRDC,&Nav,rs,dts, &var,&svh)) continue; if (geodist(rs,rr,e)>0.0) satazel(pos,e,azel+k*2); } } for (k=0;k<j-i;k++) { Az[i+k]=azel[ k*2]; El[i+k]=azel[1+k*2]; if (Az[i+k]<0.0) Az[i+k]+=2.0*PI; } per=(i+1)*100/Obs.n; if (per!=per_) { ShowMsg(s.sprintf("updating azimuth/elevation... (%d%%)",(per_=per))); Application->ProcessMessages(); } } IndexObs[NObs]=Obs.n; UpdateSatList(); ReadWaitEnd(); }
/* generate simulated observation data ---------------------------------------*/ static int simobs(gtime_t ts, gtime_t te, double tint, const double *rr, nav_t *nav, obs_t *obs, int opt) { gtime_t time; obsd_t data[MAXSAT]={{{0}}}; double pos[3],rs[3*MAXSAT],dts[MAXSAT],r,e[3],azel[2]; double ecp[MAXSAT][NFREQ]={{0}},epr[MAXSAT][NFREQ]={{0}}; double snr[MAXSAT][NFREQ]={{0}},ers[MAXSAT][3]={{0}}; double iono,trop,fact,cp,pr,dtr=0.0,rref[3],bl; int i,j,k,n,ns,amb[MAXSAT][NFREQ]={{0}},sys,prn; char s[64]; double pref[]={36.106114294,140.087190410,70.3010}; /* ref station */ trace(3,"simobs:nnav=%d ngnav=%d\n",nav->n,nav->ng); for (i=0;i<2;i++) pref[i]*=D2R; pos2ecef(pref,rref); for (i=0;i<3;i++) rref[i]-=rr[i]; bl=norm(rref,3)/1E4; /* baseline (10km) */ srand(0); /* ephemeris error */ for (i=0;i<MAXSAT;i++) { data[i].sat=i+1; data[i].P[0]=2E7; for (j=0;j<3;j++) ers[i][j]=randn(0.0,erreph); } srand(tickget()); ecef2pos(rr,pos); n=(int)(timediff(te,ts)/tint+1.0); for (i=0;i<n;i++) { time=timeadd(ts,tint*i); time2str(time,s,0); for (j=0;j<MAXSAT;j++) data[j].time=time; for (j=0;j<3;j++) { /* iteration for pseudorange */ satpos(time,data,MAXSAT,nav,rs,dts); for (k=0;k<MAXSAT;k++) { if ((r=geodist(rs+k*3,rr,e))<=0.0) continue; data[k].P[0]=r+CLIGHT*(dtr-dts[k]); } } satpos(time,data,MAXSAT,nav,rs,dts); for (j=ns=0;j<MAXSAT;j++) { /* add ephemeris error */ for (k=0;k<3;k++) rs[k+j*3]+=ers[j][k]; if ((r=geodist(rs+j*3,rr,e))<=0.0) continue; satazel(pos,e,azel); if (azel[1]<minel*D2R) continue; iono=ionmodel(time,nav->ion,pos,azel); trop=tropmodel(pos,azel,0.3); /* add ionospheric error */ iono+=errion*bl*ionmapf(pos,azel); snrmodel(azel,snr[j]); errmodel(azel,snr[j],ecp[j],epr[j]); sys=satsys(data[j].sat,&prn); for (k=0;k<NFREQ;k++) { data[j].L[k]=data[j].P[k]=0.0; data[j].SNR[k]=0; data[j].LLI[k]=0; if (sys==SYS_GPS) { if (k>=3) continue; /* no L5a/L5b in gps */ if (k>=2&&!gpsblock[prn-1]) continue; /* no L5 in block II */ } else if (sys==SYS_GLO) { if (k>=3) continue; } else if (sys==SYS_GAL) { if (k==1) continue; /* no L2 in galileo */ } else continue; /* generate observation data */ fact=lam[k]*lam[k]/lam[0]/lam[0]; cp=r+CLIGHT*(dtr-dts[j])-fact*iono+trop+ecp[j][k]; pr=r+CLIGHT*(dtr-dts[j])+fact*iono+trop+epr[j][k]; if (amb[j][k]==0) amb[j][k]=(int)(-cp/lam[k]); data[j].L[k]=cp/lam[k]+amb[j][k]; data[j].P[k]=pr; data[j].SNR[k]=(unsigned char)snr[j][k]; data[j].LLI[k]=data[j].SNR[k]<slipthres?1:0; } if (obs->nmax<=obs->n) { if (obs->nmax==0) obs->nmax=65532; else obs->nmax+=65532; if (!(obs->data=(obsd_t *)realloc(obs->data,sizeof(obsd_t)*obs->nmax))) { fprintf(stderr,"malloc error\n"); return 0; } } obs->data[obs->n++]=data[j]; ns++; } fprintf(stderr,"time=%s nsat=%2d\r",s,ns); } fprintf(stderr,"\n"); return 1; }
// generate visibility data ---------------------------------------------------- void __fastcall TPlot::GenVisData(void) { gtime_t time,ts,te; obsd_t data={{0}}; sta_t sta={0}; double tint,r,pos[3],rr[3],rs[6],e[3],azel[2]; int i,j,nobs=0; char name[16]; trace(3,"GenVisData\n"); ClearObs(); SimObs=1; ts=TimeStart; te=TimeEnd; tint=TimeInt; matcpy(pos,OOPos,3,1); pos2ecef(pos,rr); ReadWaitStart(); ShowLegend(NULL); ShowMsg("generating satellite visibility..."); Application->ProcessMessages(); for (time=ts;timediff(time,te)<=0.0;time=timeadd(time,tint)) { for (i=0;i<MAXSAT;i++) { satno2id(i+1,name); if (!tle_pos(time,name,"","",&TLEData,NULL,rs)) continue; if ((r=geodist(rs,rr,e))<=0.0) continue; if (satazel(pos,e,azel)<=0.0) continue; if (Obs.n>=Obs.nmax) { Obs.nmax=Obs.nmax<=0?4096:Obs.nmax*2; Obs.data=(obsd_t *)realloc(Obs.data,sizeof(obsd_t)*Obs.nmax); if (!Obs.data) { Obs.n=Obs.nmax=0; break; } } data.time=time; data.sat=i+1; for (j=0;j<NFREQ;j++) { data.P[j]=data.L[j]=0.0; data.code[j]=CODE_NONE; } data.code[0]=CODE_L1C; Obs.data[Obs.n++]=data; } if (++nobs>=MAX_SIMOBS) break; } if (Obs.n<=0) { ReadWaitEnd(); ShowMsg("no satellite visibility"); return; } UpdateObs(nobs); Caption="Satellite Visibility (Predicted)"; BtnSol1->Down=true; time2gpst(Obs.data[0].time,&Week); SolIndex[0]=SolIndex[1]=ObsIndex=0; if (PlotType<PLOT_OBS||PLOT_DOP<PlotType) { UpdateType(PLOT_OBS); } else { UpdatePlotType(); } FitTime(); ReadWaitEnd(); UpdateObsType(); UpdateTime(); UpdatePlot(); }