예제 #1
0
파일: pntpos.c 프로젝트: PPNav/SMARTNAV-RTK
/* single-point positioning ----------------------------------------------------
* compute receiver position, velocity, clock bias by single-point positioning
* with pseudorange and doppler observables
* args   : obsd_t *obs      I   observation data
*          int    n         I   number of observation data
*          nav_t  *nav      I   navigation data
*          prcopt_t *opt    I   processing options
*          sol_t  *sol      IO  solution
*          double *azel     IO  azimuth/elevation angle (rad) (NULL: no output)
*          ssat_t *ssat     IO  satellite status              (NULL: no output)
*          char   *msg      O   error message for error exit
* return : status(1:ok,0:error)
* notes  : assuming sbas-gps, galileo-gps, qzss-gps, compass-gps time offset and
*          receiver bias are negligible (only involving glonass-gps time offset
*          and receiver bias)
*-----------------------------------------------------------------------------*/
extern int pntpos(const obsd_t *obs, int n, const nav_t *nav,
                  const prcopt_t *opt, sol_t *sol, double *azel, ssat_t *ssat,
                  char *msg)
{
    prcopt_t opt_=*opt;
    double *rs,*dts,*var,*azel_,*resp;
    int i,stat,vsat[MAXOBS]={0},svh[MAXOBS];
    
    sol->stat=SOLQ_NONE;
    
    if (n<=0) {strcpy(msg,"no observation data"); return 0;}
    
    trace(3,"pntpos  : tobs=%s n=%d\n",time_str(obs[0].time,3),n);
    
    sol->time=obs[0].time; msg[0]='\0';
    
    rs=mat(6,n); dts=mat(2,n); var=mat(1,n); azel_=zeros(2,n); resp=mat(1,n);
    
    if (opt_.mode!=PMODE_SINGLE) { /* for precise positioning */
#if 0
        opt_.sateph =EPHOPT_BRDC;
#endif
        opt_.ionoopt=IONOOPT_BRDC;
        opt_.tropopt=TROPOPT_SAAS;
    }
    /* satellite positons, velocities and clocks */
    satposs(sol->time,obs,n,nav,opt_.sateph,rs,dts,var,svh);
    
    /* estimate receiver position with pseudorange */
    stat=estpos(obs,n,rs,dts,var,svh,nav,&opt_,sol,azel_,vsat,resp,msg);
    
    /* raim fde */
    if (!stat&&n>=6&&opt->posopt[4]) {
        stat=raim_fde(obs,n,rs,dts,var,svh,nav,&opt_,sol,azel_,vsat,resp,msg);
    }
    /* estimate receiver velocity with doppler */
    if (stat) estvel(obs,n,rs,dts,nav,&opt_,sol,azel_,vsat);
    
    if (azel) {
        for (i=0;i<n*2;i++) azel[i]=azel_[i];
    }
    if (ssat) {
        for (i=0;i<MAXSAT;i++) {
            ssat[i].vs=0;
            ssat[i].azel[0]=ssat[i].azel[1]=0.0;
            ssat[i].resp[0]=ssat[i].resc[0]=0.0;
            ssat[i].snr[0]=0;
        }
        for (i=0;i<n;i++) {
            ssat[obs[i].sat-1].azel[0]=azel_[  i*2];
            ssat[obs[i].sat-1].azel[1]=azel_[1+i*2];
            ssat[obs[i].sat-1].snr[0]=obs[i].SNR[0];
            if (!vsat[i]) continue;
            ssat[obs[i].sat-1].vs=1;
            ssat[obs[i].sat-1].resp[0]=resp[i];
        }
    }
    free(rs); free(dts); free(var); free(azel_); free(resp);
    return stat;
}
예제 #2
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;
}
예제 #3
0
/* 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);
    }
}
예제 #4
0
파일: pnt.c 프로젝트: alexis93/zhiyu_xihe
//SPP, added by yuan;
extern int pntpos(rtk_t *rtk,obsd_t *obs, int n, nav_t *nav,double *azel,char *msg)
{
    prcopt_t opt_=rtk->opt;
    int i,stat,vsat[MAXOBS]={0},svh[MAXOBS];
	double rs[6 * MAXOBS_]; double dts[2 * MAXOBS_]; double var[1 * MAXOBS_];
	double azel_[2 * MAXOBS_]; double resp[1 * MAXOBS_];
    
    rtk->sol.stat=SOLQ_NONE;
    if (n<=0) { return 0;}
	rtk->sol.time = obs[0].time; msg[0] = '\0';
    opt_.sateph =EPHOPT_BRDC;    //���ù㲥������modified by yuan
    opt_.ionoopt=IONOOPT_BRDC;
    opt_.tropopt=TROPOPT_SAAS;
    /* satellite positons, velocities and clocks */
	satposs(rtk->sol.time, obs, n, nav, opt_.sateph, rs, dts, var, svh);
    
    /* estimate receiver position with pseudorange */
	stat = estpos(obs, n, rs, dts, var, svh, nav, &opt_, &rtk->sol, azel_, vsat, resp, msg, rtk);
    
    if (azel) {
        for (i=0;i<n*2;i++) azel[i]=azel_[i];
    }
    if (rtk->ssat) {
        for (i=0;i<MAXSAT;i++) {
			rtk->ssat[i].vs = 0;
			rtk->ssat[i].azel[0] = rtk->ssat[i].azel[1] = 0.0;
			rtk->ssat[i].resp[0] = rtk->ssat[i].resc[0] = 0.0;
			rtk->ssat[i].snr[0] = 0;
        }
        for (i=0;i<n;i++) {
			rtk->ssat[obs[i].sat - 1].azel[0] = azel_[i * 2];
			rtk->ssat[obs[i].sat - 1].azel[1] = azel_[1 + i * 2];
			rtk->ssat[obs[i].sat - 1].snr[0] = obs[i].SNR[0];
            if (!vsat[i]) continue;
			rtk->ssat[obs[i].sat - 1].vs = 1;
			rtk->ssat[obs[i].sat - 1].resp[0] = resp[i];
        }
    }
    return stat;
}
예제 #5
0
파일: rtkpos.c 프로젝트: ndhuan/GPSRTK
//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;
}
예제 #6
0
/* 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);
}
예제 #7
0
파일: pntpos.c 프로젝트: okopachev/RTKLIB
/* single-point positioning ----------------------------------------------------
* compute receiver position, velocity, clock bias by single-point positioning
* with pseudorange and doppler observables
* args   : obsd_t *obs      I   observation data
*          int    n         I   number of observation data
*          nav_t  *nav      I   navigation data
*          prcopt_t *opt    I   processing options
*          sol_t  *sol      IO  solution
*          double *azel     IO  azimuth/elevation angle (rad) (NULL: no output)
*          ssat_t *ssat     IO  satellite status              (NULL: no output)
*          char   *msg      O   error message for error exit
* return : status(1:ok,0:error)
* notes  : assuming sbas-gps, galileo-gps, qzss-gps, compass-gps time offset and
*          receiver bias are negligible (only involving glonass-gps time offset
*          and receiver bias)
*-----------------------------------------------------------------------------*/
extern int pntpos(const obsd_t *obs, int n, const nav_t *nav,
                  const prcopt_t *opt, sol_t *sol, double *azel, ssat_t *ssat,
                  char *msg)
{
    prcopt_t opt_=*opt;
    double *rs,*dts,*var,*azel_,*resp;
    int i,stat,vsat[MAXOBS]={0},svh[MAXOBS];
    
    double ep[6], ep2[6];

    output = fopen("solution_log.txt", "a");

    fprintf(output, "\nBegin solution in single point positioning mode\n");
    fprintf(output, "  Input observaton data:\n");
    for(i = 0; i < n; i++)
    {
      time2epoch(obs[i].time, ep);
      fprintf(output, "    %i) time: %4.0f/%2.0f/%2.0f %2.0f:%2.0f:%6.4f, sat: %i, code: %i, P1: %f, L1: %f, D1: %f, S1: %f, P2: %f, L2: %f, D2: %f, S2: %f\n", i+1, ep[0], ep[1], ep[2], ep[3], ep[4], ep[5], obs[i].sat, obs[i].code, obs[i].P[0], obs[i].L[0], obs[i].D[0], obs[i].SNR[0], obs[i].P[1], obs[i].L[1], obs[i].D[1], obs[i].SNR[1]);
    }
    fprintf(output, " Input GPS ephemeris:\n");
    for(i = 0; i < nav->n; i++)
    {
      time2epoch(nav->eph[i].toe, ep);
      time2epoch(nav->eph[i].toc, ep2);
      fprintf(output, "    %i) sat: %i, IODE: %i, sva: %i, svh: %i, week: %i, toe: %4.0f/%2.0f/%2.0f %2.0f:%2.0f:%6.4f, toc: %4.0f/%2.0f/%2.0f %2.0f:%2.0f:%6.4f, sqrt(A): %f, E: %f, i0: %f, OMG0: %f, omega: %f, M0: %f, delta_n: %f, OMGdot: %f, Idot: %f, Crc: %f, Crs: %f, Cuc: %f, Cus: %f, Cic: %f, Cis: %f, af0: %f, af1: %f, af2: %f, Tgd: %f\n",
              i + 1, nav->eph[i].sat, nav->eph[i].iode, nav->eph[i].sva, nav->eph[i].svh, nav->eph[i].week,
              ep[0], ep[1], ep[2], ep[3], ep[4], ep[5], ep2[0], ep2[1], ep2[2], ep2[3], ep2[4], ep2[5],
              sqrt(nav->eph[i].A), nav->eph[i].e, nav->eph[i].i0, nav->eph[i].OMG0, nav->eph[i].omg, nav->eph[i].M0,
              nav->eph[i].deln, nav->eph[i].OMGd, nav->eph[i].idot, nav->eph[i].crc, nav->eph[i].crs,
              nav->eph[i].cuc, nav->eph[i].cus, nav->eph[i].cic, nav->eph[i].cis, nav->eph[i].f0,
              nav->eph[i].f0, nav->eph[i].f1, nav->eph[i].f2, nav->eph[i].tgd[0]);
    }
    fprintf(output, "  Input GLONASS ephemeris:\n");
    for(i = 0; i < nav->ng; i++)
    {
      time2epoch(nav->geph[i].toe, ep);
      fprintf(output, "    %i) sat: %i, sva: %i, svh: %i, toe: %4.0f/%2.0f/%2.0f %2.0f:%2.0f:%6.4f, X: %f, Y: %f, Z: %f, VX: %f, VY: %f, VZ: %f, tau_n: %f, gamma_n: %f\n",
              i + 1, nav->geph[i].sat, nav->geph[i].sva, nav->geph[i].svh, ep[0], ep[1], ep[2], ep[3], ep[4], ep[5],
              nav->geph[i].pos[0], nav->geph[i].pos[1], nav->geph[i].pos[2],
              nav->geph[i].vel[0], nav->geph[i].vel[1], nav->geph[i].vel[2], nav->geph[i].taun, nav->geph[i].gamn);
    }

    sol->stat=SOLQ_NONE;
    
    if (n<=0) {strcpy(msg,"no observation data"); return 0;}
    
    trace(3,"pntpos  : tobs=%s n=%d\n",time_str(obs[0].time,3),n);
    
    sol->time=obs[0].time; msg[0]='\0';
    
    rs=mat(6,n); dts=mat(2,n); var=mat(1,n); azel_=zeros(2,n); resp=mat(1,n);
    
    if (opt_.mode!=PMODE_SINGLE) { /* for precise positioning */
#if 0
        opt_.sateph =EPHOPT_BRDC;
#endif
        opt_.ionoopt=IONOOPT_BRDC;
        opt_.tropopt=TROPOPT_SAAS;
    }
    /* satellite positons, velocities and clocks */
    satposs(sol->time,obs,n,nav,opt_.sateph,rs,dts,var,svh);
    
    fprintf(output, "  Satellite positions, velocities and clocks:\n");
    for(i = 0; i < n; i++)
    {
      fprintf(output, "    sat %i: X = %f, Y = %f, Z = %f, VX = %f, VY = %f, VZ = %f, dt = %f, dt_dot = %f\n", obs[i].sat, rs[i*6], rs[i*6 + 1], rs[i*6 + 2], rs[i*6 + 3], rs[i*6 + 4], rs[i*6 + 5], dts[i*2], dts[i*2 + 1]);
    }

    /* estimate receiver position with pseudorange */
    stat=estpos(obs,n,rs,dts,var,svh,nav,&opt_,sol,azel_,vsat,resp,msg);
    
    /* raim fde */
    if (!stat&&n>=6&&opt->posopt[4]) {
        stat=raim_fde(obs,n,rs,dts,var,svh,nav,&opt_,sol,azel_,vsat,resp,msg);
    }
    /* estimate receiver velocity with doppler */
    if (stat) estvel(obs,n,rs,dts,nav,&opt_,sol,azel_,vsat);
    
    if (azel) {
        for (i=0;i<n*2;i++) azel[i]=azel_[i];
    }
    if (ssat) {
        for (i=0;i<MAXSAT;i++) {
            ssat[i].vs=0;
            ssat[i].azel[0]=ssat[i].azel[1]=0.0;
            ssat[i].resp[0]=ssat[i].resc[0]=0.0;
            ssat[i].snr[0]=0;
        }
        for (i=0;i<n;i++) {
            ssat[obs[i].sat-1].azel[0]=azel_[  i*2];
            ssat[obs[i].sat-1].azel[1]=azel_[1+i*2];
            ssat[obs[i].sat-1].snr[0]=obs[i].SNR[0];
            if (!vsat[i]) continue;
            ssat[obs[i].sat-1].vs=1;
            ssat[obs[i].sat-1].resp[0]=resp[i];
        }
    }
    free(rs); free(dts); free(var); free(azel_); free(resp);
    fprintf(output, "End calculations in single point positioning mode\n");
    fclose(output);
    output = fopen("cov_matr_single.txt", "a");
    time2epoch(sol->time, ep);
    fprintf(output, "%4.0f/%2.0f/%2.0f %2.0f:%2.0f:%2.4f coords: %f %f %f %f %f %f velocities: %f %f %f %f %f %f\n", ep[0], ep[1], ep[2], ep[3], ep[4], ep[5], sol->qr[0], sol->qr[3], sol->qr[5], sol->qr[1], sol->qr[4], sol->qr[2], sol->qvr[0], sol->qvr[3], sol->qvr[5], sol->qvr[1], sol->qvr[4], sol->qvr[2]);
    fclose(output);
    return stat;
}