// read observation data ---------------------------------------------------- void __fastcall TPlot::ReadObs(TStrings *files) { obs_t obs={0}; nav_t nav={0}; sta_t sta={0}; AnsiString s; char file[1024]; int i,nobs; trace(3,"ReadObs\n"); if (files->Count<=0) return; ReadWaitStart(); ShowLegend(NULL); if ((nobs=ReadObsRnx(files,&obs,&nav,&sta))<=0) { ReadWaitEnd(); return; } ClearObs(); Obs=obs; Nav=nav; Sta=sta; SimObs=0; UpdateObs(nobs); UpdateMp(); if (ObsFiles!=files) { ObsFiles->Assign(files); } NavFiles->Clear(); strcpy(file,U2A(files->Strings[0]).c_str()); Caption=s.sprintf("%s%s",file,files->Count>1?"...":""); 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(); }
// read navigation data ----------------------------------------------------- void __fastcall TPlot::ReadNav(TStrings *files) { AnsiString s; gtime_t ts,te; double tint; char navfile[1024],*opt=RnxOpts.c_str(); int i; trace(3,"ReadNav\n"); if (files->Count<=0) return; ReadWaitStart(); ShowLegend(NULL); TimeSpan(&ts,&te,&tint); freenav(&Nav,0xFF); ShowMsg("reading nav data..."); Application->ProcessMessages(); for (i=0;i<files->Count;i++) { strcpy(navfile,U2A(files->Strings[i]).c_str()); readrnxt(navfile,1,ts,te,tint,opt,NULL,&Nav,NULL); } uniqnav(&Nav); if (Nav.n<=0&&Nav.ng<=0&&Nav.ns<=0) { ShowMsg(s.sprintf("no nav message: %s...",files->Strings[0].c_str())); ReadWaitEnd(); return; } if (NavFiles!=files) { NavFiles->Assign(files); } UpdateObs(NObs); UpdateMp(); ReadWaitEnd(); UpdatePlot(); }
// read solutions ----------------------------------------------------------- void __fastcall TPlot::ReadSol(TStrings *files, int sel) { solbuf_t sol={0}; AnsiString s; gtime_t ts,te; double tint; int i,n=0; char *paths[MAXNFILE]={""}; trace(3,"ReadSol: sel=%d\n",sel); if (files->Count<=0) return; ReadWaitStart(); for (i=0;i<files->Count&&n<MAXNFILE;i++) { paths[n++]=files->Strings[i].c_str(); } TimeSpan(&ts,&te,&tint); ShowMsg(s.sprintf("reading %s...",paths[0])); ShowLegend(NULL); if (!readsolt(paths,n,ts,te,tint,0,&sol)) { ShowMsg(s.sprintf("no solution data : %s...",paths[0])); ShowLegend(NULL); ReadWaitEnd(); return; } freesolbuf(SolData+sel); SolData[sel]=sol; if (SolFiles[sel]!=files) { SolFiles[sel]->Assign(files); } Caption=""; ReadSolStat(files,sel); for (i=0;i<2;i++) { if (SolFiles[i]->Count==0) continue; Caption=Caption+SolFiles[i]->Strings[0]+(SolFiles[i]->Count>1?"... ":" "); } BtnSol12->Down=False; if (sel==0) BtnSol1->Down=true; else BtnSol2->Down=true; if (sel==0||SolData[0].n<=0) { time2gpst(SolData[sel].data[0].time,&Week); UpdateOrigin(); } SolIndex[0]=SolIndex[1]=ObsIndex=0; if (PlotType>PLOT_NSAT) { UpdateType(PLOT_TRK); } else { UpdatePlotType(); } FitTime(); if (AutoScale&&PlotType<=PLOT_SOLA) { FitRange(1); } else { SetRange(1,YRange); } UpdateTime(); UpdatePlot(); ReadWaitEnd(); }
// 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(); }
// update Multipath ------------------------------------------------------------ void __fastcall TPlot::UpdateMp(void) { AnsiString s; obsd_t *data; double lam1,lam2,I,C,B; int i,j,k,f1,f2,sat,sys,per,per_=-1,n; trace(3,"UpdateMp\n"); for (i=0;i<NFREQ+NEXOBS;i++) { delete [] Mp[i]; Mp[i]=NULL; } if (Obs.n<=0) return; for (i=0;i<NFREQ+NEXOBS;i++) { Mp[i]=new double[Obs.n]; } ReadWaitStart(); ShowLegend(NULL); for (i=0;i<Obs.n;i++) { data=Obs.data+i; sys=satsys(data->sat,NULL); for (j=0;j<NFREQ+NEXOBS;j++) { Mp[j][i]=0.0; code2obs(data->code[j],&f1); if (sys==SYS_CMP) { if (f1==5) f1=2; /* B2 */ else if (f1==4) f1=3; /* B3 */ } if (sys==SYS_GAL) f2=f1==1?3:1; /* E1/E5a */ else if (sys==SYS_SBS) f2=f1==1?3:1; /* L1/L5 */ else if (sys==SYS_CMP) f2=f1==1?2:1; /* B1/B2 */ else f2=f1==1?2:1; /* L1/L2 */ lam1=satwavelen(data->sat,f1-1,&Nav); lam2=satwavelen(data->sat,f2-1,&Nav); if (lam1==0.0||lam2==0.0) continue; if (data->P[j]!=0.0&&data->L[j]!=0.0&&data->L[f2-1]) { C=SQR(lam1)/(SQR(lam1)-SQR(lam2)); I=lam1*data->L[j]-lam2*data->L[f2-1]; Mp[j][i]=data->P[j]-lam1*data->L[j]+2.0*C*I; } } } for (sat=1;sat<=MAXSAT;sat++) for (i=0;i<NFREQ+NEXOBS;i++) { sys=satsys(sat,NULL); for (j=k=n=0,B=0.0;j<Obs.n;j++) { if (Obs.data[j].sat!=sat) continue; code2obs(Obs.data[j].code[i],&f1); if (sys==SYS_CMP) { if (f1==5) f1=2; /* B2 */ else if (f1==4) f1=3; /* B3 */ } if (sys==SYS_GAL) f2=f1==1?3:1; else if (sys==SYS_CMP) f2=f1==1?2:1; else f2=f1==1?2:1; if ((Obs.data[j].LLI[i]&1)||(Obs.data[j].LLI[f2-1]&1)|| fabs(Mp[i][j]-B)>THRES_SLIP) { for (;k<j;k++) if (Obs.data[k].sat==sat) Mp[i][k]-=B; B=Mp[i][j]; n=1; k=j; } else { if (n==0) k=j; B+=(Mp[i][j]-B)/++n; } } if (n>0) { for (;k<j;k++) if (Obs.data[k].sat==sat) Mp[i][k]-=B; } per=sat*100/MAXSAT; if (per!=per_) { ShowMsg(s.sprintf("updating multipath... (%d%%)",(per_=per))); Application->ProcessMessages(); } } ReadWaitEnd(); }
// 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(); }