/* correlator ------------------------------------------------------------------ * multiply sampling data and carrier (I/Q), multiply code (E/P/L), and integrate * args : char *data I sampling data vector (n x 1 or 2n x 1) * int dtype I sampling data type (1:real,2:complex) * double ti I sampling interval (s) * int n I number of samples * double freq I carrier frequency (Hz) * double phi0 I carrier initial phase (rad) * double crate I code chip rate (chip/s) * double coff I code chip offset (chip) * int s I correlator points (sample) * short *I,*Q O correlation power I,Q * I={I_P,I_E1,I_L1,I_E2,I_L2,...,I_Em,I_Lm} * Q={Q_P,Q_E1,Q_L1,Q_E2,Q_L2,...,Q_Em,Q_Lm} * return : none * notes : see above for data *-----------------------------------------------------------------------------*/ extern void correlator(const char *data, int dtype, double ti, int n, double freq, double phi0, double crate, double coff, int* s, int ns, double *II, double *QQ, double *remc, double *remp, short* codein, int coden) { short *dataI=NULL,*dataQ=NULL,*code_e=NULL,*code; int i; int smax=s[ns-1]; /* 8 is treatment of remainder in SSE2 */ if (!(dataI=(short *)sdrmalloc(sizeof(short)*(n+64)))|| !(dataQ=(short *)sdrmalloc(sizeof(short)*(n+64)))|| !(code_e=(short *)sdrmalloc(sizeof(short)*(n+2*smax)))) { SDRPRINTF("error: correlator memory allocation\n"); return; } code=code_e+smax; /* mix local carrier */ *remp=mixcarr(data,dtype,ti,n,freq,phi0,dataI,dataQ); /* resampling code */ *remc=rescode(codein,coden,coff,smax,ti*crate,n,code_e); /* multiply code and integrate */ dot_23(dataI,dataQ,code,code-s[0],code+s[0],n,II,QQ); for (i=1;i<ns;i++) { dot_22(dataI,dataQ,code-s[i],code+s[i],n,II+1+i*2,QQ+1+i*2); } for (i=0;i<1+2*ns;i++) { II[i]*=CSCALE; QQ[i]*=CSCALE; } sdrfree(dataI); sdrfree(dataQ); sdrfree(code_e); dataI=dataQ=code_e=NULL; }
/* estimate receiver position ------------------------------------------------*/ static int estpos(const obsd_t *obs, int n, const double *rs, const double *dts, const double *vare, const int *svh, const nav_t *nav, prcopt_t *opt, sol_t *sol, double *azel, int *vsat, double *resp, char *msg, rtk_t *rtk) { double x[NX]={0},dx[NX],Q[NX*NX],sig; int i,j,k,info,stat,nv,ns; double rms = 0; //added by yuan; double RMS = 0; int nv_ = 0; double temp = 0; int kk = 0; double v[(MAXOBS_+4)*1];double H[(MAXOBS_+4)*135];double var[MAXOBS_+4*1]; for (i=0;i<3;i++) x[i]=sol->rr[i]; for (i = 0; i < MAXITR; i++) { /* pseudorange residuals */ nv=rescode(i,obs,n,rs,dts,vare,svh,nav,x,opt,v,H,var,azel,vsat,resp, &ns,rtk); if (nv<4) { //sprintf(msg,"lack of valid sats ns=%d",nv); break; } //added by yuan, ̽��ϴ�ֲ���н�ȷ�������������; if ( (rtk->counter>=1) && (i>=1) ){ for (j = 0; j < nv;j++){ if (fabs(v[j]) != 0.0){ rms += v[j]; nv_++; } } rms = rms / nv_; for (j = 0; j < nv_; j++){ RMS += (v[j] - rms)*(v[j] - rms); } RMS = sqrt(RMS/nv_); //�в�ľ�����; if (RMS>2.5){ temp = fabs(v[0] - rms); for (j = 1; j < nv_;j++){ if (temp <= fabs(v[j] - rms)){ temp = fabs(v[j] - rms); kk = j; } else{ continue; } } opt->exsats[rtk->sat_[kk] - 1] = 1; } rms = 0; RMS = 0; nv_ = 0; temp = 0; kk = 0; //nv = nv - 1; //����һ������; } if (nv < NX) { //sprintf(msg, "lack of valid sats ns=%d", nv); break; } /* weight by variance */ for (j = 0; j < nv; j++) { sig = sqrt(var[j]); v[j] /= sig; for (k = 0; k < NX; k++) H[k + j*NX] /= sig; } /* least square estimation */ if ((info=lsq(H,v,NX,nv,dx,Q))) { //sprintf(msg,"lsq error info=%d",info); break; } for (j=0;j<NX;j++) x[j]+=dx[j]; if (norm(dx,NX)<1E-4) { sol->type=0; sol->time=timeadd(obs[0].time,-x[3]/CLIGHT); sol->dtr[0]=x[3]/CLIGHT; /* receiver clock bias (s) */ sol->dtr[1]=x[4]/CLIGHT; /* glo-gps time offset (s) */ sol->dtr[2]=x[5]/CLIGHT; /* gal-gps time offset (s) */ sol->dtr[3]=x[6]/CLIGHT; /* bds-gps time offset (s) */ for (j=0;j<6;j++) sol->rr[j]=j<3?x[j]:0.0; for (j=0;j<3;j++) sol->qr[j]=(float)Q[j+j*NX]; sol->qr[3]=(float)Q[1]; /* cov xy */ sol->qr[4]=(float)Q[2+NX]; /* cov yz */ sol->qr[5]=(float)Q[2]; /* cov zx */ sol->ns=(unsigned char)ns; sol->age=sol->ratio=0.0; /* validate solution */ if ((stat = valsol(azel, vsat, n, opt, v, nv, NX, msg))) { sol->stat = opt->sateph == EPHOPT_SBAS ? SOLQ_SBAS : SOLQ_SINGLE; } return stat; } } return 0; }
void *lexthread(void * arg) #endif { sdrch_t *sdr=(sdrch_t*)arg; int cnt=0,lexch=0,state,i,nerr,errloc[LENLEXRS],time=0,dt,mid; uint64_t buffloc; double dfreq,cn0; char *data; uint8_t corri,sendbuf[LENLEXRCV],rsmsg[LENLEXRS]; uint8_t lexpre[LENLEXPRE]={0x1A,0xCF,0xFC,0x1D}; /* preamble */ sdrlex_t sdrlex={{0}}; sdrout_t out={0}; unsigned long tick=0; FILE *fplexlog=NULL,*fplexbin=NULL; short *rcode; cpx_t *xcode; if (sdrini.log) { fplexlog=fopen("LEXLOG.csv","w"); fplexbin=fopen("LEXBIN.bin","wb"); fprintf(fplexlog,"Tow,CN0,Time(ms),Error\n"); } /* start tcp server (lex) */ if (sdrini.lex) { out.soc_lex.port=sdrini.lexport; tcpsvrstart(&out.soc_lex); } data=(char*)sdrmalloc(sizeof(char)*sdr->nsamp*sdr->dtype); /* lex channel is last */ lexch=sdrini.nch; /* FFT code generation */ if (!(rcode=(short *)sdrmalloc(sizeof(short)*sdr->nsamp)) || !(xcode=cpxmalloc(sdr->nsamp))) { SDRPRINTF("error: initsdrch memory alocation\n"); return THRETVAL; } rescode(sdr->code,sdr->clen,0,0,sdr->ci,sdr->nsamp,rcode); /* resampled code */ cpxcpx(rcode,NULL,1.0,sdr->nsamp,xcode); /* FFT code */ cpxfft(NULL,xcode,sdr->nsamp); sdrfree(rcode); sleepms(3000*sdrini.nch); SDRPRINTF("**** LEX sdr thread start! ****\n"); do { /* wait event */ mlock(hlexmtx); waitevent(hlexeve,hlexmtx); unmlock(hlexmtx); /* assist from L1CA */ buffloc=sdrch[lexch].trk.codei[1]+sdrch[lexch].currnsamp+DSAMPLEX; dfreq=-sdrch[lexch].trk.D[1]*(FREQ6/FREQ1); /* get current data */ rcvgetbuff(&sdrini,buffloc,sdr->nsamp,sdr->ftype,sdr->dtype,data); tick=tickgetus(); /* LEX correlation */ corri=lexcorr_fft(sdr,data,sdr->dtype,sdr->ti,sdr->nsamp,dfreq,sdr->crate, sdr->nsamp,xcode,&cn0); dt=tickgetus()-tick; time+=dt; if (dt>4000) SDRPRINTF("error: dt=%.1fms(must be < 4ms)\n",(double)dt/1000); /* check computation time */ if (cnt%250==0) { //SDRPRINTF("time=%.2fms doppler=%.1f\n",(double)time/250000,dfreq); time=0; } shiftdata(&sdrlex.msg[0],&sdrlex.msg[1],1,LENLEXMSG-1); /* shift to left */ sdrlex.msg[LENLEXMSG-1]=corri; /* add last */ /* preamble search */ state=0; for (i=0;i<LENLEXPRE;i++) state+=abs(sdrlex.msg[i]-lexpre[i]); if (state==0) { /* reed solomon */ memset(rsmsg,0,LENLEXRS); memcpy(&rsmsg[9],&sdrlex.msg[LENLEXPRE],LENLEXRS-9); /* RS decode */ nerr=decode_rs_ccsds(rsmsg,errloc,0,0); if (nerr!=0) SDRPRINTF("RS correct %d symbols!\n",nerr); if (sdrini.log) { fprintf(fplexlog,"%f,%f,%d,%d\n", sdrch[lexch].trk.tow[0],cn0,time,nerr); fwrite(sdrlex.msg,1,LENLEXMSG,fplexbin); } if (nerr<0) { cnt++; continue; } /* <0 means failed to RS decode */ /* correct lex message */ memcpy(&sdrlex.msg[LENLEXPRE],&rsmsg[9],LENLEXRSK-9); mid=getbitu(sdrlex.msg,5*8,8); SDRPRINTF("LEX Message Type ID=%d\n",mid); /* generate send buffer */ sendbuf[0]=0xAA; /* sync code1 (see rcvlex.c) */ sendbuf[1]=0x55; /* sync code2 (see rcvlex.c) */ /* set tow (LEX message does not contain tow information...) */ setbitu(sendbuf,2*8,4*8,ROUND(sdrch[lexch].trk.tow[0]*1000)); /* set week ()*/ setbitu(sendbuf,6*8,2*8,sdrch[lexch].nav.sdreph.eph.week); memcpy(&sendbuf[8],sdrlex.msg,LENLEXMSG-LENLEXRSP); /* LEX message */ /* send LEX message */ if (sdrini.lex&&out.soc_lex.flag) send(out.soc_lex.c_soc,(char*)sendbuf,LENLEXRCV,0); } cnt++; } while (!sdrstat.stopflag); if (sdrini.log) { fclose(fplexlog); fclose(fplexbin); } if (out.soc_lex.flag) tcpsvrclose(&out.soc_lex); cpxfree(xcode); return THRETVAL; }
/* estimate receiver position ------------------------------------------------*/ static int estpos(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) { double x[NX]={0},dx[NX],Q[NX*NX],*v,*H,*var,sig; int i,j,k,info,stat,nv,ns; trace(3,"estpos : n=%d\n",n); v=mat(n+4,1); H=mat(NX,n+4); var=mat(n+4,1); for (i=0;i<3;i++) x[i]=sol->rr[i]; for (i=0;i<MAXITR;i++) { /* pseudorange residuals */ nv=rescode(i,obs,n,rs,dts,vare,svh,nav,x,opt,v,H,var,azel,vsat,resp, &ns); if (nv<NX) { sprintf(msg,"lack of valid sats ns=%d",nv); break; } /* weight by variance */ for (j=0;j<nv;j++) { sig=sqrt(var[j]); v[j]/=sig; for (k=0;k<NX;k++) H[k+j*NX]/=sig; } /* least square estimation */ if ((info=lsq(H,v,NX,nv,dx,Q))) { sprintf(msg,"lsq error info=%d",info); break; } for (j=0;j<NX;j++) x[j]+=dx[j]; if (norm(dx,NX)<1E-4) { sol->type=0; sol->time=timeadd(obs[0].time,-x[3]/CLIGHT); sol->dtr[0]=x[3]/CLIGHT; /* receiver clock bias (s) */ sol->dtr[1]=x[4]/CLIGHT; /* glo-gps time offset (s) */ sol->dtr[2]=x[5]/CLIGHT; /* gal-gps time offset (s) */ sol->dtr[3]=x[6]/CLIGHT; /* bds-gps time offset (s) */ for (j=0;j<6;j++) sol->rr[j]=j<3?x[j]:0.0; for (j=0;j<3;j++) sol->qr[j]=(float)Q[j+j*NX]; sol->qr[3]=(float)Q[1]; /* cov xy */ sol->qr[4]=(float)Q[2+NX]; /* cov yz */ sol->qr[5]=(float)Q[2]; /* cov zx */ sol->ns=(unsigned char)ns; sol->age=sol->ratio=0.0; /* validate solution */ if ((stat=valsol(azel,vsat,n,opt,v,nv,NX,msg))) { sol->stat=opt->sateph==EPHOPT_SBAS?SOLQ_SBAS:SOLQ_SINGLE; } free(v); free(H); free(var); return stat; } } if (i>=MAXITR) sprintf(msg,"iteration divergent i=%d",i); free(v); free(H); free(var); return 0; }
/* initialize sdr channel struct ----------------------------------------------- * set value to sdr channel struct * args : int chno I channel number (1,2,...) * int sys I system type (SYS_***) * int prn I PRN number * int ctype I code type (CTYPE_***) * int dtype I data type (DTYPEI or DTYPEIQ) * int ftype I front end type (FTYPE1 or FTYPE2) * double f_cf I center (carrier) frequency (Hz) * double f_sf I sampling frequency (Hz) * double f_if I intermidiate frequency (Hz) * sdrch_t *sdr I/0 sdr channel struct * return : int 0:okay -1:error *-----------------------------------------------------------------------------*/ extern int initsdrch(int chno, int sys, int prn, int ctype, int dtype, int ftype, double f_cf, double f_sf, double f_if, sdrch_t *sdr) { int i; short *rcode; sdr->no=chno; sdr->sys=sys; sdr->prn=prn; sdr->sat=satno(sys,prn); sdr->ctype=ctype; sdr->dtype=dtype; sdr->ftype=ftype; sdr->f_sf=f_sf; sdr->f_if=f_if; sdr->ti=1/f_sf; /* code generation */ if (!(sdr->code=gencode(prn,ctype,&sdr->clen,&sdr->crate))) { SDRPRINTF("error: gencode\n"); return -1; } sdr->ci=sdr->ti*sdr->crate; sdr->ctime=sdr->clen/sdr->crate; sdr->nsamp=(int)(f_sf*sdr->ctime); sdr->nsampchip=(int)(sdr->nsamp/sdr->clen); satno2id(sdr->sat,sdr->satstr); /* set carrier frequency */ if (ctype==CTYPE_G1) { sprintf(sdr->satstr,"R%d",prn); /* frequency number instead of PRN */ sdr->f_cf=FREQ1_GLO+DFRQ1_GLO*prn; /* FDMA */ sdr->foffset=DFRQ1_GLO*prn; /* FDMA */ } else if (sdrini.fend==FEND_FRTLSDR) { sdr->foffset=f_cf*sdrini.rtlsdrppmerr*1e-6; } else { sdr->f_cf=f_cf; /* carrier frequency */ sdr->foffset=0.0; /* frequency offset */ } /* for BeiDou B1I */ if (ctype==CTYPE_B1I) sdr->nsampchip*=2; /* for BOC code */ /* acqisition struct */ initacqstruct(sys,ctype,prn,&sdr->acq); sdr->acq.nfft=2*sdr->nsamp;//calcfftnum(2*sdr->nsamp,0); /* memory allocation */ if (!(sdr->acq.freq=(double*)malloc(sizeof(double)*sdr->acq.nfreq))) { SDRPRINTF("error: initsdrch memory alocation\n"); return -1; } /* doppler search frequency */ for (i=0;i<sdr->acq.nfreq;i++) sdr->acq.freq[i]=sdr->f_if+((i-(sdr->acq.nfreq-1)/2)*sdr->acq.step) +sdr->foffset; /* tracking struct */ if (inittrkstruct(sdr->sat,ctype,sdr->ctime,&sdr->trk)<0) return -1; /* navigation struct */ if (initnavstruct(sys,ctype,prn,&sdr->nav)<0) { return -1; } /* memory allocation */ if (!(rcode=(short *)sdrmalloc(sizeof(short)*sdr->acq.nfft)) || !(sdr->xcode=cpxmalloc(sdr->acq.nfft))) { SDRPRINTF("error: initsdrch memory alocation\n"); return -1; } /* other code generation */ for (i=0;i<sdr->acq.nfft;i++) rcode[i]=0; /* zero padding */ rescode(sdr->code,sdr->clen,0,0,sdr->ci,sdr->nsamp,rcode); /* resampling */ cpxcpx(rcode,NULL,1.0,sdr->acq.nfft,sdr->xcode); /* FFT for acquisition */ cpxfft(NULL,sdr->xcode,sdr->acq.nfft); sdrfree(rcode); return 0; }
/* estimate receiver position ------------------------------------------------*/ static int estpos(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) { double x[NX]={0},dx[NX],Q[NX*NX],*v,*H,*var,sig; int i,j,k,info,stat,nv,ns; trace(3,"estpos : n=%d\n",n); v=mat(n+4,1); H=mat(NX,n+4); var=mat(n+4,1); for (i=0;i<3;i++) x[i]=sol->rr[i]; fprintf(output, " Begin coordinates calculation in single point positioning mode\n"); fprintf(output, " Current coordinates: X = %f, Y = %f, Z = %f\n", x[0], x[1], x[2]); for (i=0;i<MAXITR;i++) { fprintf(output, " Begin iteration %i:\n", i); /* pseudorange residuals */ nv=rescode(i,obs,n,rs,dts,vare,svh,nav,x,opt,v,H,var,azel,vsat,resp, &ns); if (nv<NX) { sprintf(msg,"lack of valid sats ns=%d",nv); break; } /* weight by variance */ for (j=0;j<nv;j++) { sig=sqrt(var[j]); v[j]/=sig; for (k=0;k<NX;k++) H[k+j*NX]/=sig; } fprintf(output, " Begin least-square estimation:\n"); fprintf(output, " "); for(j = 0; j < NX; j++) fprintf(output, " X[%i] = %f,", j, dx[j]); fprintf(output, "\n"); fprintf(output, " "); for(j = 0; j < nv; j++) fprintf(output, " v[%i] = %f,", j, v[j]); fprintf(output, "\n"); for(j = 0; j < nv; j++) { fprintf(output, " "); for(k = 0; k < NX; k++) fprintf(output, " H[%i][%i] = %f,", j, k, H[k + j * NX]); fprintf(output, "\n"); } /* least square estimation */ if ((info=lsq(H,v,NX,nv,dx,Q))) { sprintf(msg,"lsq error info=%d",info); break; } fprintf(output, " End least-square estimation\n"); fprintf(output, " Results of least square estimation: dx1 = %f, dx2 = %f, dx3 = %f, dx4 = %f, dx5 = %f, dx6 = %f, dx7 = %f\n", dx[0], dx[1], dx[2], dx[3], dx[4], dx[5], dx[6]); for (j=0;j<NX;j++) x[j]+=dx[j]; fprintf(output, " New state of vector X: X[0] = %f, X[1] = %f, X[2] = %f, X[3] = %f, X[4] = %f, X[5] = %f, X[6] = %f\n", x[0], x[1], x[2], x[3], x[4], x[5], x[6]); fprintf(output, " norm(dx) = %f\n", norm(dx, NX)); if (norm(dx,NX)<1E-4) { sol->type=0; sol->time=timeadd(obs[0].time,-x[3]/CLIGHT); sol->dtr[0]=x[3]/CLIGHT; /* receiver clock bias (s) */ sol->dtr[1]=x[4]/CLIGHT; /* glo-gps time offset (s) */ sol->dtr[2]=x[5]/CLIGHT; /* gal-gps time offset (s) */ sol->dtr[3]=x[6]/CLIGHT; /* bds-gps time offset (s) */ for (j=0;j<6;j++) sol->rr[j]=j<3?x[j]:0.0; for (j=0;j<3;j++) sol->qr[j]=(float)Q[j+j*NX]; sol->qr[3]=(float)Q[1]; /* cov xy */ sol->qr[4]=(float)Q[2+NX]; /* cov yz */ sol->qr[5]=(float)Q[2]; /* cov zx */ sol->ns=(unsigned char)ns; sol->age=sol->ratio=0.0; /* validate solution */ if ((stat=valsol(azel,vsat,n,opt,v,nv,NX,msg))) { sol->stat=opt->sateph==EPHOPT_SBAS?SOLQ_SBAS:SOLQ_SINGLE; } free(v); free(H); free(var); fprintf(output, " End of coordinates calculation\n"); return stat; } } if (i>=MAXITR) sprintf(msg,"iteration divergent i=%d",i); free(v); free(H); free(var); return 0; }