/* predict states of ekf -----------------------------------------------------*/ static void ekf_pred(ekf_t *ekf, double *F, double *Q, int ix, int nx) { double *A; int i; A=mat(ekf->nx,nx); /* x(ix)=F*x(ix) */ matmul("NN",nx,1,nx,1.0,F,ekf->x+ix,0.0,A); matcpy(ekf->x+ix,A,nx,1); /* P(ix,:)=F*P(ix,:); P(:,ix)=P(:,ix)*F' */ for (i=0;i<ekf->nx;i++) { matmul("NN",nx,1,nx,1.0,F,ekf->P+ekf->nx*i+ix,0.0,A); matcpy(ekf->P+ekf->nx*i+ix,A,nx,1); } matmul("NT",ekf->nx,nx,nx,1.0,ekf->P+ekf->nx*ix,F,0.0,A); matcpy(ekf->P+ekf->nx*ix,A,ekf->nx,nx); /* P(ix,ix)+=diag(Q) */ for (i=0;i<nx;i++) { ekf->P[(ix+i)*(ekf->nx+1)]+=Q[i]; } free(A); }
//Matrix Inverse cmatrix inv(cmatrix input){ if(input.rows!=input.cols){ fprintf(stderr, "Error in function 'inv': input rows and cols do not match\nPossible reasons:\n'input' was not a square matrix\n"); exit(1); } int i, j, index, zero, indexzero; double complex tempvector[input.rows], multi, detnum=1, detdenom=1; //Copy input so as not to overwrite entries, initialize 'temp' to identity matrix cmatrix output = identity(input.rows); cmatrix temp = matcpy(input); for(index=0, indexzero=0;index<temp.rows;index++){ for(i=index;i<temp.rows;i++)if(temp.entries[i][index]==0){ for(j=i, zero=i;j<temp.rows;j++) if(temp.entries[j][index]!=0) zero=j; for(j=indexzero;j<index;j++) if(temp.entries[j][index]!=0) zero=j; if(i!=zero) detnum*=-1; for(j=0;j<temp.rows;j++) tempvector[j]=temp.entries[i][j]; for(j=0;j<temp.rows;j++) temp.entries[i][j]=temp.entries[zero][j]; for(j=0;j<temp.rows;j++) temp.entries[zero][j]=tempvector[j]; for(j=0;j<temp.rows;j++) tempvector[j]=output.entries[i][j]; for(j=0;j<temp.rows;j++) output.entries[i][j]=output.entries[zero][j]; for(j=0;j<temp.rows;j++) output.entries[zero][j]=tempvector[j]; } if(temp.entries[index][index]!=0) for (indexzero=index+1, i=0; i<temp.rows; i++) if(i!=index && temp.entries[i][index]!=0){ multi=temp.entries[index][index]; detdenom*=temp.entries[i][index]*multi; for (j=0; j<temp.rows; j++){ output.entries[index][j]*=temp.entries[i][index]; temp.entries[index][j]*=temp.entries[i][index]; } for (j=0; j<temp.rows; j++){ output.entries[i][j]*=multi; temp.entries[i][j]*=multi; } for (j=0; j<temp.rows; j++){ output.entries[i][j]-=output.entries[index][j]; temp.entries[i][j]-=temp.entries[index][j]; } } } for(index=0;index<temp.rows;index++) if(temp.entries[index][index]!=0){ for(j=0, multi=temp.entries[index][index];j<temp.rows;j++){ temp.entries[index][j]/=multi; output.entries[index][j]/=multi; } //final division detnum*=multi; } for(i=0;i<temp.rows;i++)for(j=0;j<temp.rows;j++) if(temp.entries[i][j]==0) temp.entries[i][j]=cabs(temp.entries[i][j]); for(i=0;i<temp.rows;i++) if(temp.entries[i][i]==0) detnum=0; return output; }
/* initialize states of ekf --------------------------------------------------*/ static void ekf_init(ekf_t *ekf, const double *xi, double *Pi, int ix, int nx) { int i,j; /* x(ix)=xi */ matcpy(ekf->x+ix,xi,nx,1); /* P(ix,:)=0; P(ix,:)=0; P(ix,ix)=diag(Pi) */ for (i=0;i<nx;i++) for (j=0;j<ekf->nx;j++) { ekf->P[ix+i+ekf->nx*j]=ekf->P[j+ekf->nx*(ix+i)]=j==ix+i?Pi[i]:0.0; } }
/* 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); }
/* matcpy() */ void utest6(void) { double *a=mat(100,200),*b=zeros(100,200),c=0.0; int i,j; for (i=0;i<100;i++) { for (j=0;j<200;j++) { a[i+j*100]=(c+=1.0); } } matcpy(b,a,100,200); for (i=0,c=0.0;i<100;i++) { for (j=0;j<200;j++) { assert(a[i+j*100]==b[i+j*100]); } } free(a); free(b); }
int main ( int argc, char * argv [] ){ matrix_t A=matinit(); matrix_t B=matinit(); matrix_t C=matinit(); loadByName("testfiles/input.mat", "a", &A); loadByName("testfiles/input.mat", "b", &B); printf("Matriz A:\n"); matprint(A); putchar('\n'); printf("Matriz B:\n"); matprint(B); putchar('\n'); C=convolution(A,B); if( C.height==0 ){ return 1; } printf("\nMatriz C:\n"); matprint(C); putchar('\n'); saveByName("testfiles/output.mat", "c", &C); //TEST probar si funciona el copiar: matrix_t D = matinit(); D.height=0; D.width=0; matcpy(&D, &C); printf("\nMatriz D:\n"); matprint(D); matfree(&D); matfree(&C); matfree(&A); matfree(&B); return 0; }
//Determinant double complex det(cmatrix input){ if(input.rows!=input.cols){ fprintf(stderr, "Error in function 'det': input rows and cols do not match\nPossible reasons:\n'input' was not a square matrix\n"); exit(1); } int i, j, index, zero, indexzero; double complex tempvector[input.rows], multi, detnum=1, detdenom=1; //Copy input so as not to overwrite entries cmatrix temp = matcpy(input); for(index=0, indexzero=0;index<temp.rows;index++){ //bring rows with a zero in column 'index' down to the bottom (ignoring rows above 'index' as they have already been used. for(i=index;i<temp.rows;i++)if(temp.entries[i][index]==0){ for(j=i, zero=i;j<temp.rows;j++) if(temp.entries[j][index]!=0) zero=j; for(j=indexzero;j<index;j++) if(temp.entries[j][index]!=0) zero=j; if(i!=zero) detnum*=-1; for(j=0;j<temp.rows;j++) tempvector[j]=temp.entries[i][j]; for(j=0;j<temp.rows;j++) temp.entries[i][j]=temp.entries[zero][j]; for(j=0;j<temp.rows;j++) temp.entries[zero][j]=tempvector[j]; } //if there is a leading 1, then use it to remove all leading 1s below if(temp.entries[index][index]!=0) for (indexzero=index+1, i=0; i<temp.rows; i++) if(i!=index && temp.entries[i][index]!=0){ multi=temp.entries[index][index]; detdenom*=temp.entries[i][index]*multi; for (j=0; j<temp.rows; j++) temp.entries[index][j]*=temp.entries[i][index]; for (j=0; j<temp.rows; j++) temp.entries[i][j]*=multi; for (j=0; j<temp.rows; j++) temp.entries[i][j]-=temp.entries[index][j]; } } //ensure that there are all no for(index=0;index<temp.rows;index++) if(temp.entries[index][index]!=0){ for(j=0, multi=temp.entries[index][index];j<temp.rows;j++) temp.entries[index][j]/=multi; //final division detnum*=multi; } //get rid of -0 for(i=0;i<temp.rows;i++)for(j=0;j<temp.rows;j++) if(temp.entries[i][j]==0) temp.entries[i][j]=cabs(temp.entries[i][j]); //if there is an entry without a leading 1, then the matrix is degenerate an the determinant is 0. for(i=0;i<temp.rows;i++) if(temp.entries[i][i]==0) detnum=0; return detnum/detdenom; }
//0:ok, !0: not ok static int relpos(rtk_t *rtk, const obsd_t *obs, int nu, int nr, const nav_t *nav,char **msg) { prcopt_t *opt=&rtk->opt; gtime_t time=obs[0].time; double *rs,*dts,*var,*y,*e,*azel,*v,*H,*R,*bias,dt; double *xp,*Pp,*xa; int i,n=nu+nr,ns,ny,nv,sat[MAX_SAT],iu[MAX_SAT],ir[MAX_SAT]; int info,vflg[MAX_OBS*2+1],svh[MAX_OBS*2]; int stat=SOLQ_FLOAT; dt=timediff(time,obs[nu].time); rs=mat(6,n); dts=mat(2,n); var=mat(1,n); y=mat(2,n); e=mat(3,n); azel=zeros(2,n); if ((!rs)||(!dts)||(!var)||(!y)||(!e)||(!azel)) { #ifdef _DEBUG_MSG (*msg)+=sprintf(*msg,"relpos mat error 1\n"); #endif free(rs); free(dts); free(var); free(y); free(e); free(azel); return -1; } for (i=0; i<MAX_SAT; i++) { rtk->ssat[i].vsat = rtk->ssat[i].snr=0; } /* satellite positions/clocks*/ satposs(time,obs,n,nav,rs,dts,var,svh,msg); //da tinh trong pntpos rui************************** /* undifferenced residuals for base station */ if (zdres(1,obs+nu,nr,rs+nu*6,dts+nu*2,svh+nu,nav,rtk->rb,opt,1, y+nu*2,e+nu*3,azel+nu*2)) //***************************************** { #ifdef _DEBUG_MSG (*msg)+=sprintf(*msg,"initial base station position error\n"); #endif free(rs); free(dts); free(var); free(y); free(e); free(azel); return -1; }//*********************88 /* select common satellites between rover and base-station */ if ((ns=selsat(obs,azel,nu,nr,opt,sat,iu,ir,msg))<=0) {//check!!!!!!!!!!!!!!!************************************* #ifdef _DEBUG_MSG (*msg)+=sprintf(*msg,"no common satellite\n"); #endif free(rs); free(dts); free(var); free(y); free(e); free(azel); return -1; } // if (ns>7) // ns=7; // (*msg)+=sprintf(*msg,"common satellite:%d\n",ns); /* temporal update of states *///*************************************************************************** udstate(rtk,obs,sat,iu,ir,ns,nav,msg);//********************************************* xp=mat(rtk->nx,1); Pp=zeros(rtk->nx,rtk->nx); xa=mat(rtk->nx,1); matcpy(xp,rtk->x,rtk->nx,1); ny=ns*2+2; v=mat(ny,1); H=zeros(rtk->nx,ny); R=mat(ny,ny); bias=mat(rtk->nx,1); if ((!xp)||(!Pp)||(!xa)||(!v)||(!H)||(!R)||(!bias)) { #ifdef _DEBUG_MSG (*msg)+=sprintf(*msg,"relpos mat error 2\n"); #endif free(rs); free(dts); free(var); free(y); free(e); free(azel); free(xp); free(Pp); free(xa); free(v); free(H); free(R); free(bias); return -1; } //*************************************************8 for (i=0; i<NITER; i++) { /* undifferenced residuals for rover */ if (zdres(0,obs,nu,rs,dts,svh,nav,xp,opt,0,y,e,azel)) { #ifdef _DEBUG_MSG (*msg)+=sprintf(*msg,"rover initial position error\n"); #endif stat=SOLQ_NONE; break; } //************************* /* double-differenced residuals and partial derivatives */ if ((nv=ddres(rtk,nav,dt,xp,Pp,sat,y,e,azel,iu,ir,ns,v,H,R,vflg,msg))<1) { #ifdef _DEBUG_MSG (*msg)+=sprintf(*msg,"no double-differenced residual\n"); #endif stat=SOLQ_NONE; break; } /* kalman filter measurement update */ matcpy(Pp,rtk->P,rtk->nx,rtk->nx); if ((info=filter(xp,Pp,H,v,R,rtk->nx,nv))) { #ifdef _DEBUG_MSG (*msg)+=sprintf(*msg,"filter error (info=%d)\n",info); #endif stat=SOLQ_NONE; break; } } //*************************** if (stat!=SOLQ_NONE&&(!zdres(0,obs,nu,rs,dts,svh,nav,xp,opt,0,y,e,azel))) { /* post-fit residuals for float solution */ nv=ddres(rtk,nav,dt,xp,Pp,sat,y,e,azel,iu,ir,ns,v,NULL,R,vflg,msg); /* validation of float solution */ if (!valpos(rtk,v,R,vflg,nv,4.0,msg)) {//0:ok,!0:not ok /* update state and covariance matrix */ matcpy(rtk->x,xp,rtk->nx,1); matcpy(rtk->P,Pp,rtk->nx,rtk->nx); /* update ambiguity control struct */ rtk->sol.ns=0; for (i=0; i<ns; i++) { if (!rtk->ssat[sat[i]-1].vsat) continue; rtk->ssat[sat[i]-1].lock++; rtk->ssat[sat[i]-1].outc=0; rtk->sol.ns++; /* valid satellite count by L1 */ } /* lack of valid satellites */ if (rtk->sol.ns<4) stat=SOLQ_NONE; } else stat=SOLQ_NONE; } /* resolve integer ambiguity by LAMBDA */ if (stat!=SOLQ_NONE&&(resamb_LAMBDA(rtk,bias,xa,msg)>1)) { if (!zdres(0,obs,nu,rs,dts,svh,nav,xa,opt,0,y,e,azel)) { /* post-fit reisiduals for fixed solution */ nv=ddres(rtk,nav,dt,xa,NULL,sat,y,e,azel,iu,ir,ns,v,NULL,R,vflg,msg); /* validation of fixed solution */ if (!valpos(rtk,v,R,vflg,nv,4.0,msg)) { /* hold integer ambiguity */ if (++rtk->nfix>=rtk->opt.minfix&& rtk->opt.modear==ARMODE_FIXHOLD) { holdamb(rtk,xa,msg); } stat=SOLQ_FIX; } } } /* save solution status */ if (stat==SOLQ_FIX) { for (i=0; i<3; i++) { rtk->sol.rr[i]=rtk->xa[i]; rtk->sol.qr[i]=(float)rtk->Pa[i+i*rtk->na]; } rtk->sol.qr[3]=(float)rtk->Pa[1]; rtk->sol.qr[4]=(float)rtk->Pa[1+2*rtk->na]; rtk->sol.qr[5]=(float)rtk->Pa[2]; } else { 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[1+2*rtk->nx]; rtk->sol.qr[5]=(float)rtk->P[2]; rtk->nfix=0; } for (i=0; i<n; i++) { if (obs[i].L==0.0) continue; rtk->ssat[obs[i].sat-1].pt[obs[i].rcv-1]=obs[i].time; rtk->ssat[obs[i].sat-1].ph[obs[i].rcv-1]=obs[i].L; } for (i=0; i<ns; i++) { /* output snr of rover receiver */ rtk->ssat[sat[i]-1].snr=obs[iu[i]].SNR; } for (i=0; i<MAX_SAT; i++) { if (rtk->ssat[i].fix==2&&stat!=SOLQ_FIX) rtk->ssat[i].fix=1; if (rtk->ssat[i].slip&1) rtk->ssat[i].slipc++; } free(rs); free(dts); free(var); free(y); free(e); free(azel); free(xp); free(Pp); free(xa); free(v); free(H); free(R); free(bias); if (stat!=SOLQ_NONE) rtk->sol.stat=stat; return stat==SOLQ_NONE; }
/* 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); }
/* str2str -------------------------------------------------------------------*/ int main(int argc, char **argv) { static char cmd[MAXRCVCMD]=""; const char ss[]={'E','-','W','C','C'}; strconv_t *conv[MAXSTR]={NULL}; double pos[3],stapos[3]={0},off[3]={0}; char *paths[MAXSTR],s[MAXSTR][MAXSTRPATH]={{0}},*cmdfile=""; char *local="",*proxy="",*msg="1004,1019",*opt="",buff[256],*p; char strmsg[MAXSTRMSG]="",*antinfo="",*rcvinfo=""; char *ant[]={"","",""},*rcv[]={"","",""}; int i,j,n=0,dispint=5000,trlevel=0,opts[]={10000,10000,2000,32768,10,0,30}; int types[MAXSTR]={STR_FILE,STR_FILE},stat[MAXSTR]={0},byte[MAXSTR]={0}; int bps[MAXSTR]={0},fmts[MAXSTR]={0},sta=0; for (i=0;i<MAXSTR;i++) paths[i]=s[i]; for (i=1;i<argc;i++) { if (!strcmp(argv[i],"-in")&&i+1<argc) { if (!decodepath(argv[++i],types,paths[0],fmts)) return -1; } else if (!strcmp(argv[i],"-out")&&i+1<argc&&n<MAXSTR-1) { if (!decodepath(argv[++i],types+n+1,paths[n+1],fmts+n+1)) return -1; n++; } else if (!strcmp(argv[i],"-p")&&i+3<argc) { pos[0]=atof(argv[++i])*D2R; pos[1]=atof(argv[++i])*D2R; pos[2]=atof(argv[++i]); pos2ecef(pos,stapos); } else if (!strcmp(argv[i],"-o")&&i+3<argc) { off[0]=atof(argv[++i]); off[1]=atof(argv[++i]); off[2]=atof(argv[++i]); } else if (!strcmp(argv[i],"-msg")&&i+1<argc) msg=argv[++i]; else if (!strcmp(argv[i],"-opt")&&i+1<argc) opt=argv[++i]; else if (!strcmp(argv[i],"-sta")&&i+1<argc) sta=atoi(argv[++i]); else if (!strcmp(argv[i],"-d" )&&i+1<argc) dispint=atoi(argv[++i]); else if (!strcmp(argv[i],"-s" )&&i+1<argc) opts[0]=atoi(argv[++i]); else if (!strcmp(argv[i],"-r" )&&i+1<argc) opts[1]=atoi(argv[++i]); else if (!strcmp(argv[i],"-n" )&&i+1<argc) opts[5]=atoi(argv[++i]); else if (!strcmp(argv[i],"-f" )&&i+1<argc) opts[6]=atoi(argv[++i]); else if (!strcmp(argv[i],"-c" )&&i+1<argc) cmdfile=argv[++i]; else if (!strcmp(argv[i],"-a" )&&i+1<argc) antinfo=argv[++i]; else if (!strcmp(argv[i],"-i" )&&i+1<argc) rcvinfo=argv[++i]; else if (!strcmp(argv[i],"-l" )&&i+1<argc) local=argv[++i]; else if (!strcmp(argv[i],"-x" )&&i+1<argc) proxy=argv[++i]; else if (!strcmp(argv[i],"-t" )&&i+1<argc) trlevel=atoi(argv[++i]); else if (*argv[i]=='-') printhelp(); } if (n<=0) n=1; /* stdout */ for (i=0;i<n;i++) { if (fmts[i+1]<=0) continue; if (fmts[i+1]!=STRFMT_RTCM3) { fprintf(stderr,"unsupported output format\n"); return -1; } if (fmts[0]<0) { fprintf(stderr,"specify input format\n"); return -1; } if (!(conv[i]=strconvnew(fmts[0],fmts[i+1],msg,sta,sta!=0,opt))) { fprintf(stderr,"stream conversion error\n"); return -1; } strcpy(buff,antinfo); for (p=strtok(buff,","),j=0;p&&j<3;p=strtok(NULL,",")) ant[j++]=p; strcpy(conv[i]->out.sta.antdes,ant[0]); strcpy(conv[i]->out.sta.antsno,ant[1]); conv[i]->out.sta.antsetup=atoi(ant[2]); strcpy(buff,rcvinfo); for (p=strtok(buff,","),j=0;p&&j<3;p=strtok(NULL,",")) rcv[j++]=p; strcpy(conv[i]->out.sta.rectype,rcv[0]); strcpy(conv[i]->out.sta.recver ,rcv[1]); strcpy(conv[i]->out.sta.recsno ,rcv[2]); matcpy(conv[i]->out.sta.pos,pos,3,1); matcpy(conv[i]->out.sta.del,off,3,1); } signal(SIGTERM,sigfunc); signal(SIGINT ,sigfunc); signal(SIGHUP ,SIG_IGN); signal(SIGPIPE,SIG_IGN); strsvrinit(&strsvr,n+1); if (trlevel>0) { traceopen(TRFILE); tracelevel(trlevel); } fprintf(stderr,"stream server start\n"); strsetdir(local); strsetproxy(proxy); if (*cmdfile) readcmd(cmdfile,cmd,0); /* start stream server */ if (!strsvrstart(&strsvr,opts,types,paths,conv,*cmd?cmd:NULL,stapos)) { fprintf(stderr,"stream server start error\n"); return -1; } for (intrflg=0;!intrflg;) { /* get stream server status */ strsvrstat(&strsvr,stat,byte,bps,strmsg); /* show stream server status */ for (i=0,p=buff;i<MAXSTR;i++) p+=sprintf(p,"%c",ss[stat[i]+1]); fprintf(stderr,"%s [%s] %10d B %7d bps %s\n", time_str(utc2gpst(timeget()),0),buff,byte[0],bps[0],strmsg); sleepms(dispint); } if (*cmdfile) readcmd(cmdfile,cmd,1); /* stop stream server */ strsvrstop(&strsvr,*cmd?cmd:NULL); for (i=0;i<n;i++) { strconvfree(conv[i]); } if (trlevel>0) { traceclose(); } fprintf(stderr,"stream server stop\n"); return 0; }
/* 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; }
/* raim fde (failure detection and exclution) -------------------------------*/ static int raim_fde(const obsd_t *obs, int n, const double *rs, const double *dts, const double *vare, const int *svh, const nav_t *nav, const prcopt_t *opt, sol_t *sol, double *azel, int *vsat, double *resp, char *msg) { obsd_t *obs_e; sol_t sol_e={{0}}; char tstr[32],name[16],msg_e[128]; double *rs_e,*dts_e,*vare_e,*azel_e,*resp_e,rms_e,rms=100.0; int i,j,k,nvsat,stat=0,*svh_e,*vsat_e,sat=0; trace(3,"raim_fde: %s n=%2d\n",time_str(obs[0].time,0),n); if (!(obs_e=(obsd_t *)malloc(sizeof(obsd_t)*n))) return 0; rs_e = mat(6,n); dts_e = mat(2,n); vare_e=mat(1,n); azel_e=zeros(2,n); svh_e=imat(1,n); vsat_e=imat(1,n); resp_e=mat(1,n); for (i=0;i<n;i++) { /* satellite exclution */ for (j=k=0;j<n;j++) { if (j==i) continue; obs_e[k]=obs[j]; matcpy(rs_e +6*k,rs +6*j,6,1); matcpy(dts_e+2*k,dts+2*j,2,1); vare_e[k]=vare[j]; svh_e[k++]=svh[j]; } /* estimate receiver position without a satellite */ if (!estpos(obs_e,n-1,rs_e,dts_e,vare_e,svh_e,nav,opt,&sol_e,azel_e, vsat_e,resp_e,msg_e)) { trace(3,"raim_fde: exsat=%2d (%s)\n",obs[i].sat,msg); continue; } for (j=nvsat=0,rms_e=0.0;j<n-1;j++) { if (!vsat_e[j]) continue; rms_e+=SQR(resp_e[j]); nvsat++; } if (nvsat<5) { trace(3,"raim_fde: exsat=%2d lack of satellites nvsat=%2d\n", obs[i].sat,nvsat); continue; } rms_e=sqrt(rms_e/nvsat); trace(3,"raim_fde: exsat=%2d rms=%8.3f\n",obs[i].sat,rms_e); if (rms_e>rms) continue; /* save result */ for (j=k=0;j<n;j++) { if (j==i) continue; matcpy(azel+2*j,azel_e+2*k,2,1); vsat[j]=vsat_e[k]; resp[j]=resp_e[k++]; } stat=1; *sol=sol_e; sat=obs[i].sat; rms=rms_e; vsat[i]=0; strcpy(msg,msg_e); } if (stat) { time2str(obs[0].time,tstr,2); satno2id(sat,name); trace(2,"%s: %s excluded by raim\n",tstr+11,name); } free(obs_e); free(rs_e ); free(dts_e ); free(vare_e); free(azel_e); free(svh_e); free(vsat_e); free(resp_e); return stat; }
/* main ----------------------------------------------------------------------*/ int main(int argc, char **argv) { FILE *fp=stdout; pcvs_t pcvs={0}; nav_t nav={0}; obs_t obs={0}; sta_t sta={{0}}; pcv_t *pcv=NULL; gtime_t ts={0},te={0}; double eps[6]={0},epe[6]={0},rr[3]={0},tint=30.0; char *ifile[32],*ofile="",*afile="",*dfile="",ant[64]=""; int i,j,n=0; for (i=1;i<argc;i++) { if (!strcmp(argv[i],"-ts")&&i+2<argc) { sscanf(argv[++i],"%lf/%lf/%lf",eps,eps+1,eps+2); sscanf(argv[++i],"%lf:%lf:%lf",eps+3,eps+4,eps+5); } else if (!strcmp(argv[i],"-te")&&i+2<argc) { sscanf(argv[++i],"%lf/%lf/%lf",epe,epe+1,epe+2); sscanf(argv[++i],"%lf:%lf:%lf",epe+3,epe+4,epe+5); } else if (!strcmp(argv[i],"-ti")&&i+1<argc) { tint=atof(argv[++i]); } else if (!strcmp(argv[i],"-r")&&i+3<argc) { for (j=0;j<3;j++) rr[j]=atof(argv[++i]); } else if (!strcmp(argv[i],"-o")&&i+1<argc) ofile=argv[++i]; else if (!strcmp(argv[i],"-a")&&i+1<argc) afile=argv[++i]; else if (!strcmp(argv[i],"-d")&&i+1<argc) dfile=argv[++i]; else ifile[n++]=argv[i]; } /* open output file */ if (*ofile&&!(fp=fopen(ofile,"w"))) { fprintf(stderr,"output file open error: %s\n",ofile); return -1; } if (eps[2]>=1.0) ts=epoch2time(eps); if (epe[2]>=1.0) te=epoch2time(epe); /* read rinex obs/nav */ for (i=0;i<n;i++) { fprintf(stderr,"reading: %s\n",ifile[i]); readrnxt(ifile[i],1,ts,te,0.0,"",&obs,&nav,&sta); if (*sta.antdes) strcpy(ant,sta.antdes); if (norm(sta.pos,3)>0.0) matcpy(rr,sta.pos,3,1); } if (!sortobs(&obs)) { fprintf(stderr,"no observation data\n"); return -1; } uniqnav(&nav); /* read antenna file */ if (*afile&&*ant) { if (!readpcv(afile,&pcvs)) { fprintf(stderr,"antenna file open error: %s\n",afile); return -1; } /* search pcv */ if (!(pcv=searchpcv(0,ant,obs.data[0].time,&pcvs))) { fprintf(stderr,"no antenna parmeter: %s\n",ant); } } /* read p1-c1 dcb parameters */ if (*dfile) readdcb(dfile,&nav); /* set p1-p2 dcb parameters */ for (i=0;i<MAXSAT;i++) { for (j=0;j<nav.n;j++) { if (nav.eph[j].sat!=i+1) continue; nav.cbias[i][0]=nav.eph[j].tgd[0]*CLIGHT; break; } } /* estimate ionosphere parameters */ est_iono(&obs,&nav,pcv,rr,tint,fp); fclose(fp); if (*ofile) fprintf(stderr,"output: %s\n",ofile); return 0; }
// 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],name[16]; 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+1]; 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; for (k=0;k<j-i;k++) { azel[k*2]=azel[1+k*2]=0.0; } if (RcvPos==0) { pntpos(Obs.data+i,j-i,&Nav,&opt,&sol,azel,NULL,msg); matcpy(rr,sol.rr,3,1); ecef2pos(rr,pos); } 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); } } // satellite azel by tle data for (k=0;k<j-i;k++) { if (azel[k*2]!=0.0||azel[1+k*2]!=0.0) continue; satno2id(Obs.data[i+k].sat,name); if (!tle_pos(time,name,"","",&TLEData,NULL,rs)) 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 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(); }