/* average of single position ------------------------------------------------*/ static int avepos(double *ra, int rcv, const obs_t *obs, const nav_t *nav, const prcopt_t *opt) { obsd_t data[MAXOBS]; gtime_t ts={0}; sol_t sol={{0}}; int i,j,n=0,m,iobs; char msg[128]; trace(3,"avepos: rcv=%d obs.n=%d\n",rcv,obs->n); for (i=0;i<3;i++) ra[i]=0.0; for (iobs=0;(m=nextobsf(obs,&iobs,rcv))>0;iobs+=m) { for (i=j=0;i<m&&i<MAXOBS;i++) { data[j]=obs->data[iobs+i]; if ((satsys(data[j].sat,NULL)&opt->navsys)&& opt->exsats[data[j].sat-1]!=1) j++; } if (j<=0||!screent(data[0].time,ts,ts,1.0)) continue; /* only 1 hz */ if (!pntpos(data,j,nav,opt,&sol,NULL,NULL,msg)) continue; for (i=0;i<3;i++) ra[i]+=sol.rr[i]; n++; } if (n<=0) { trace(1,"no average of base station position\n"); return 0; } for (i=0;i<3;i++) ra[i]/=n; return 1; }
/* set approx position -------------------------------------------------------*/ static void setapppos(strfile_t *str, rnxopt_t *opt) { prcopt_t prcopt=prcopt_default; sol_t sol={{0}}; char msg[128]; prcopt.navsys=opt->navsys; /* point positioning with last obs data */ if (!pntpos(str->obs->data,str->obs->n,str->nav,&prcopt,&sol,NULL,NULL, msg)) { trace(2,"point position error (%s)\n",msg); return; } matcpy(opt->apppos,sol.rr,3,1); }
//return: 0 ok, !0 error int rtkpos(rtk_t *rtk,const obsd_t *obs, int n, const nav_t *nav) { gtime_t time; int i,nu,nr; int tmp; // double ep[6]; prcopt_t *opt=&rtk->opt; char *errMsg=rtk->errbuf;//MAKE SURE errMsg length is less than MAX_ERRMSG rtk->errLen = 0; // char **msg=&errMsg; for (i=0; i<n; i++) { if (((obs+i)->rcv) != 1) break; } nu=i;//number of rover observations nr=n-nu; time=rtk->sol.time;//previous epoch /* time2epoch(time,ep); if ((ep[4]>=6.0) && (ep[5]>=19.0)) { errMsg +=sprintf(errMsg,"die"); } */ //rover standard positioning if (pntpos(obs,nu,nav,&rtk->sol,NULL,rtk->ssat,&rtk->opt,&errMsg)) { rtk->sol.stat=SOLQ_NONE; rtk->errLen = errMsg-rtk->errbuf; return -1; } if (time.time !=0)//first solution rtk->tt=timediff(rtk->sol.time,time); if (rtk->opt.mode==PMODE_SINGLE) { rtk->sol.stat=SOLQ_SINGLE; return 0; } if (nr==0) { #ifdef _DEBUG_MSG errMsg+=sprintf(errMsg,"no base obs data\n"); rtk->errLen = errMsg-rtk->errbuf; #endif rtk->sol.stat=SOLQ_SINGLE; // return 0; return -1; } //check age of differential rtk->sol.age=(float)timediff(obs[0].time,obs[nu].time); if ((rtk->sol.age>opt->maxtdiff) || (rtk->sol.age<-opt->maxtdiff)) { #ifdef _DEBUG_MSG errMsg+=sprintf(errMsg,"age of differential error (age=%.1f)\n",rtk->sol.age); rtk->errLen = errMsg-rtk->errbuf; #endif // rtk->sol.stat=SOLQ_SINGLE; return -1; } tmp = relpos(rtk,obs,nu,nr,nav,&errMsg); #ifdef _DEBUG_MSG rtk->errLen = errMsg-(rtk->errbuf); #endif return tmp; }
/* set approx position -------------------------------------------------------*/ static void setapppos(strfile_t *str, rnxopt_t *opt) { prcopt_t prcopt=prcopt_default; sol_t sol={{0}}; char msg[128]; prcopt.navsys=opt->navsys; /* point positioning with last obs data */ #ifdef WAAS_STUDY if (!pntpos(str->obs->data,str->obs->n,str->nav,&prcopt,&sol,NULL,NULL, NULL,msg)) { #else if (!pntpos(str->obs->data,str->obs->n,str->nav,&prcopt,&sol,NULL,NULL, msg)) { #endif trace(2,"point position error (%s)\n",msg); return; } matcpy(opt->apppos,sol.rr,3,1); } /* show status message -------------------------------------------------------*/ static int showstat(int sess, gtime_t ts, gtime_t te, int *n) { const char type[]="ONGHQLSE"; char msg[1024]="",*p=msg,s[64]; int i; if (sess>0) { p+=sprintf(p,"(%d) ",sess); } if (ts.time!=0) { time2str(ts,s,0); p+=sprintf(p,"%s",s); } if (te.time!=0&&timediff(te,ts)>0.9) { time2str(te,s,0); p+=sprintf(p,"-%s",s+5); } p+=sprintf(p,": "); for (i=0;i<NOUTFILE+1;i++) { if (n[i]==0) continue; p+=sprintf(p,"%c=%d%s",type[i],n[i],i<NOUTFILE?" ":""); } return showmsg(msg); } /* rinex converter for single-session ----------------------------------------*/ static int convrnx_s(int sess, int format, rnxopt_t *opt, const char *file, char **ofile) { FILE *ofp[NOUTFILE]={NULL}; strfile_t *str; gtime_t ts={0},te={0},tend={0},time={0}; unsigned char slips[MAXSAT][NFREQ+NEXOBS]={{0}}; int i,j,nf,type,n[NOUTFILE+1]={0},abort=0; char path[1024],*paths[NOUTFILE],s[NOUTFILE][1024]; char *epath[MAXEXFILE]={0},*staid=*opt->staid?opt->staid:"0000"; trace(3,"convrnx_s: sess=%d format=%d file=%s ofile=%s %s %s %s %s %s %s\n", sess,format,file,ofile[0],ofile[1],ofile[2],ofile[3],ofile[4], ofile[5],ofile[6]); /* replace keywords in input file */ if (reppath(file,path,opt->ts,staid,"")<0) { showmsg("no time for input file: %s",file); return 0; } /* expand wild-cards in input file */ for (i=0;i<MAXEXFILE;i++) { if (!(epath[i]=(char *)malloc(1024))) { for (i=0;i<MAXEXFILE;i++) free(epath[i]); return 0; } } nf=expath(path,epath,MAXEXFILE); if (format==STRFMT_RTCM2||format==STRFMT_RTCM3) time=opt->trtcm; if (opt->scanobs) { /* scan observation types */ if (!scan_obstype(format,epath[0],opt,&time)) return 0; } else { /* set observation types by format */ set_obstype(format,opt); } if (!(str=gen_strfile(format,opt->rcvopt,time))) { for (i=0;i<MAXEXFILE;i++) free(epath[i]); return 0; } time=opt->ts.time?opt->ts:(time.time?timeadd(time,TSTARTMARGIN):time); /* replace keywords in output file */ for (i=0;i<NOUTFILE;i++) { paths[i]=s[i]; if (reppath(ofile[i],paths[i],time,staid,"")<0) { showmsg("no time for output path: %s",ofile[i]); for (i=0;i<MAXEXFILE;i++) free(epath[i]); free_strfile(str); return 0; } } /* open output files */ if (!openfile(ofp,paths,path,opt,str->nav)) { for (i=0;i<MAXEXFILE;i++) free(epath[i]); free_strfile(str); return 0; } for (i=0;i<nf&&!abort;i++) { /* open stream file */ if (!open_strfile(str,epath[i])) continue; /* input message */ for (j=0;(type=input_strfile(str))>=-1;j++) { if (j%11==1&&(abort=showstat(sess,te,te,n))) break; /* avioid duplicated if overlapped data */ if (tend.time&&timediff(str->time,tend)<=0.0) continue; /* convert message */ switch (type) { case 1: convobs(ofp,opt,str,n,slips); break; case 2: convnav(ofp,opt,str,n); break; case 3: convsbs(ofp,opt,str,n); break; case 31: convlex(ofp,opt,str,n); break; case -1: n[NOUTFILE]++; break; /* error */ } te=str->time; if (ts.time==0) ts=te; /* set approx position */ if (type==1&&!opt->autopos&&norm(opt->apppos,3)<=0.0) { setapppos(str,opt); } if (opt->te.time&&timediff(te,opt->te)>10.0) break; } /* close stream file */ close_strfile(str); tend=te; /* end time of a file */ } /* set receiver and antenna information to option */ if (format==STRFMT_RTCM2||format==STRFMT_RTCM3) { rtcm2opt(&str->rtcm,opt); } else if (format==STRFMT_RINEX) { rnx2opt(&str->rnx,opt); } /* close output files */ closefile(ofp,opt,str->nav); /* remove empty output files */ for (i=0;i<NOUTFILE;i++) { if (ofp[i]&&n[i]<=0) remove(ofile[i]); } if (ts.time>0) showstat(sess,ts,te,n); for (i=0;i<MAXEXFILE;i++) free(epath[i]); free_strfile(str); if (opt->tstart.time==0) opt->tstart=opt->ts; if (opt->tend .time==0) opt->tend =opt->te; return abort?-1:1; }
// 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(); }