/*------------------------------------------------------------------------------ * rtcm2.c : rtcm ver.2 message functions * * Copyright (C) 2009-2014 by T.TAKASU, All rights reserved. * * references : * see rtcm.c * * version : $Revision:$ $Date:$ * history : 2011/11/28 1.0 separated from rtcm.c * 2014/10/21 1.1 fix problem on week rollover in rtcm 2 type 14 *-----------------------------------------------------------------------------*/ #include "rtklib.h" /* adjust hourly rollover of rtcm 2 time -------------------------------------*/ static void adjhour(rtcm_t *rtcm, double zcnt) { double tow,hour,sec; int week; /* if no time, get cpu time */ if (rtcm->time.time==0) rtcm->time=utc2gpst(timeget()); tow=time2gpst(rtcm->time,&week); hour=floor(tow/3600.0); sec=tow-hour*3600.0; if (zcntsec+1800.0) zcnt-=3600.0; rtcm->time=gpst2time(week,hour*3600+zcnt); } /* get observation data index ------------------------------------------------*/ static int obsindex(obs_t *obs, gtime_t time, int sat) { int i,j; for (i=0;in;i++) { if (obs->data[i].sat==sat) return i; /* field already exists */ } if (i>=MAXOBS) return -1; /* overflow */ /* add new field */ obs->data[i].time=time; obs->data[i].sat=sat; for (j=0;jdata[i].L[j]=obs->data[i].P[j]=0.0; obs->data[i].D[j]=0.0; obs->data[i].SNR[j]=obs->data[i].LLI[j]=obs->data[i].code[j]=0; } obs->n++; return i; } /* decode type 1/9: differential gps correction/partial correction set -------*/ static int decode_type1(rtcm_t *rtcm) { int i=48,fact,udre,prn,sat,iod; double prc,rrc; trace(4,"decode_type1: len=%d\n",rtcm->len); while (i+40<=rtcm->len*8) { fact=getbitu(rtcm->buff,i, 1); i+= 1; udre=getbitu(rtcm->buff,i, 2); i+= 2; prn =getbitu(rtcm->buff,i, 5); i+= 5; prc =getbits(rtcm->buff,i,16); i+=16; rrc =getbits(rtcm->buff,i, 8); i+= 8; iod =getbits(rtcm->buff,i, 8); i+= 8; if (prn==0) prn=32; if (prc==0x80000000||rrc==0xFFFF8000) { trace(2,"rtcm2 1 prc/rrc indicates satellite problem: prn=%d\n",prn); continue; } if (rtcm->dgps) { sat=satno(SYS_GPS,prn); rtcm->dgps[sat-1].t0=rtcm->time; rtcm->dgps[sat-1].prc=prc*(fact?0.32:0.02); rtcm->dgps[sat-1].rrc=rrc*(fact?0.032:0.002); rtcm->dgps[sat-1].iod=iod; rtcm->dgps[sat-1].udre=udre; } } return 7; } /* decode type 3: reference station parameter --------------------------------*/ static int decode_type3(rtcm_t *rtcm) { int i=48; trace(4,"decode_type3: len=%d\n",rtcm->len); if (i+96<=rtcm->len*8) { rtcm->sta.pos[0]=getbits(rtcm->buff,i,32)*0.01; i+=32; rtcm->sta.pos[1]=getbits(rtcm->buff,i,32)*0.01; i+=32; rtcm->sta.pos[2]=getbits(rtcm->buff,i,32)*0.01; } else { trace(2,"rtcm2 3 length error: len=%d\n",rtcm->len); return -1; } return 5; } /* decode type 14: gps time of week ------------------------------------------*/ static int decode_type14(rtcm_t *rtcm) { double zcnt; int i=48,week,hour,leaps; trace(4,"decode_type14: len=%d\n",rtcm->len); zcnt=getbitu(rtcm->buff,24,13); if (i+24<=rtcm->len*8) { week =getbitu(rtcm->buff,i,10); i+=10; hour =getbitu(rtcm->buff,i, 8); i+= 8; leaps=getbitu(rtcm->buff,i, 6); } else { trace(2,"rtcm2 14 length error: len=%d\n",rtcm->len); return -1; } week=adjgpsweek(week); rtcm->time=gpst2time(week,hour*3600.0+zcnt*0.6); rtcm->nav.utc_gps[4]=leaps; return 6; } /* decode type 16: gps special message ---------------------------------------*/ static int decode_type16(rtcm_t *rtcm) { int i=48,n=0; trace(4,"decode_type16: len=%d\n",rtcm->len); while (i+8<=rtcm->len*8&&n<90) { rtcm->msg[n++]=getbitu(rtcm->buff,i,8); i+=8; } rtcm->msg[n]='\0'; trace(3,"rtcm2 16 message: %s\n",rtcm->msg); return 9; } /* decode type 17: gps ephemerides -------------------------------------------*/ static int decode_type17(rtcm_t *rtcm) { eph_t eph={0}; double toc,sqrtA; int i=48,week,prn,sat; trace(4,"decode_type17: len=%d\n",rtcm->len); if (i+480<=rtcm->len*8) { week =getbitu(rtcm->buff,i,10); i+=10; eph.idot =getbits(rtcm->buff,i,14)*P2_43*SC2RAD; i+=14; eph.iode =getbitu(rtcm->buff,i, 8); i+= 8; toc =getbitu(rtcm->buff,i,16)*16.0; i+=16; eph.f1 =getbits(rtcm->buff,i,16)*P2_43; i+=16; eph.f2 =getbits(rtcm->buff,i, 8)*P2_55; i+= 8; eph.crs =getbits(rtcm->buff,i,16)*P2_5; i+=16; eph.deln =getbits(rtcm->buff,i,16)*P2_43*SC2RAD; i+=16; eph.cuc =getbits(rtcm->buff,i,16)*P2_29; i+=16; eph.e =getbitu(rtcm->buff,i,32)*P2_33; i+=32; eph.cus =getbits(rtcm->buff,i,16); i+=16; sqrtA =getbitu(rtcm->buff,i,32)*P2_19; i+=32; eph.toes =getbitu(rtcm->buff,i,16); i+=16; eph.OMG0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; eph.cic =getbits(rtcm->buff,i,16)*P2_29; i+=16; eph.i0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; eph.cis =getbits(rtcm->buff,i,16)*P2_29; i+=16; eph.omg =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; eph.crc =getbits(rtcm->buff,i,16)*P2_5; i+=16; eph.OMGd =getbits(rtcm->buff,i,24)*P2_43*SC2RAD; i+=24; eph.M0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; eph.iodc =getbitu(rtcm->buff,i,10); i+=10; eph.f0 =getbits(rtcm->buff,i,22)*P2_31; i+=22; prn =getbitu(rtcm->buff,i, 5); i+= 5+3; eph.tgd[0]=getbits(rtcm->buff,i, 8)*P2_31; i+= 8; eph.code =getbitu(rtcm->buff,i, 2); i+= 2; eph.sva =getbitu(rtcm->buff,i, 4); i+= 4; eph.svh =getbitu(rtcm->buff,i, 6); i+= 6; eph.flag =getbitu(rtcm->buff,i, 1); } else { trace(2,"rtcm2 17 length error: len=%d\n",rtcm->len); return -1; } if (prn==0) prn=32; sat=satno(SYS_GPS,prn); eph.sat=sat; eph.week=adjgpsweek(week); eph.toe=gpst2time(eph.week,eph.toes); eph.toc=gpst2time(eph.week,toc); eph.ttr=rtcm->time; eph.A=sqrtA*sqrtA; rtcm->nav.eph[sat-1]=eph; rtcm->ephset=0; rtcm->ephsat=sat; return 2; } /* decode type 18: rtk uncorrected carrier-phase -----------------------------*/ static int decode_type18(rtcm_t *rtcm) { gtime_t time; double usec,cp,tt; int i=48,index,freq,sync=1,code,sys,prn,sat,loss; trace(4,"decode_type18: len=%d\n",rtcm->len); if (i+24<=rtcm->len*8) { freq=getbitu(rtcm->buff,i, 2); i+= 2+2; usec=getbitu(rtcm->buff,i,20); i+=20; } else { trace(2,"rtcm2 18 length error: len=%d\n",rtcm->len); return -1; } if (freq&0x1) { trace(2,"rtcm2 18 not supported frequency: freq=%d\n",freq); return -1; } freq>>=1; while (i+48<=rtcm->len*8&&rtcm->obs.nbuff,i, 1); i+= 1; code=getbitu(rtcm->buff,i, 1); i+= 1; sys =getbitu(rtcm->buff,i, 1); i+= 1; prn =getbitu(rtcm->buff,i, 5); i+= 5+3; loss=getbitu(rtcm->buff,i, 5); i+= 5; cp =getbits(rtcm->buff,i,32); i+=32; if (prn==0) prn=32; if (!(sat=satno(sys?SYS_GLO:SYS_GPS,prn))) { trace(2,"rtcm2 18 satellite number error: sys=%d prn=%d\n",sys,prn); continue; } time=timeadd(rtcm->time,usec*1E-6); if (sys) time=utc2gpst(time); /* convert glonass time to gpst */ tt=timediff(rtcm->obs.data[0].time,time); if (rtcm->obsflag||fabs(tt)>1E-9) { rtcm->obs.n=rtcm->obsflag=0; } if ((index=obsindex(&rtcm->obs,time,sat))>=0) { rtcm->obs.data[index].L[freq]=-cp/256.0; rtcm->obs.data[index].LLI[freq]=rtcm->loss[sat-1][freq]!=loss; rtcm->obs.data[index].code[freq]= !freq?(code?CODE_L1P:CODE_L1C):(code?CODE_L2P:CODE_L2C); rtcm->loss[sat-1][freq]=loss; } } rtcm->obsflag=!sync; return sync?0:1; } /* decode type 19: rtk uncorrected pseudorange -------------------------------*/ static int decode_type19(rtcm_t *rtcm) { gtime_t time; double usec,pr,tt; int i=48,index,freq,sync=1,code,sys,prn,sat; trace(4,"decode_type19: len=%d\n",rtcm->len); if (i+24<=rtcm->len*8) { freq=getbitu(rtcm->buff,i, 2); i+= 2+2; usec=getbitu(rtcm->buff,i,20); i+=20; } else { trace(2,"rtcm2 19 length error: len=%d\n",rtcm->len); return -1; } if (freq&0x1) { trace(2,"rtcm2 19 not supported frequency: freq=%d\n",freq); return -1; } freq>>=1; while (i+48<=rtcm->len*8&&rtcm->obs.nbuff,i, 1); i+= 1; code=getbitu(rtcm->buff,i, 1); i+= 1; sys =getbitu(rtcm->buff,i, 1); i+= 1; prn =getbitu(rtcm->buff,i, 5); i+= 5+8; pr =getbitu(rtcm->buff,i,32); i+=32; if (prn==0) prn=32; if (!(sat=satno(sys?SYS_GLO:SYS_GPS,prn))) { trace(2,"rtcm2 19 satellite number error: sys=%d prn=%d\n",sys,prn); continue; } time=timeadd(rtcm->time,usec*1E-6); if (sys) time=utc2gpst(time); /* convert glonass time to gpst */ tt=timediff(rtcm->obs.data[0].time,time); if (rtcm->obsflag||fabs(tt)>1E-9) { rtcm->obs.n=rtcm->obsflag=0; } if ((index=obsindex(&rtcm->obs,time,sat))>=0) { rtcm->obs.data[index].P[freq]=pr*0.02; rtcm->obs.data[index].code[freq]= !freq?(code?CODE_L1P:CODE_L1C):(code?CODE_L2P:CODE_L2C); } } rtcm->obsflag=!sync; return sync?0:1; } /* decode type 22: extended reference station parameter ----------------------*/ static int decode_type22(rtcm_t *rtcm) { double del[2][3]={{0}},hgt=0.0; int i=48,j,noh; trace(4,"decode_type22: len=%d\n",rtcm->len); if (i+24<=rtcm->len*8) { del[0][0]=getbits(rtcm->buff,i,8)/25600.0; i+=8; del[0][1]=getbits(rtcm->buff,i,8)/25600.0; i+=8; del[0][2]=getbits(rtcm->buff,i,8)/25600.0; i+=8; } else { trace(2,"rtcm2 22 length error: len=%d\n",rtcm->len); return -1; } if (i+24<=rtcm->len*8) { i+=5; noh=getbits(rtcm->buff,i,1); i+=1; hgt=noh?0.0:getbitu(rtcm->buff,i,18)/25600.0; i+=18; } if (i+24<=rtcm->len*8) { del[1][0]=getbits(rtcm->buff,i,8)/1600.0; i+=8; del[1][1]=getbits(rtcm->buff,i,8)/1600.0; i+=8; del[1][2]=getbits(rtcm->buff,i,8)/1600.0; } rtcm->sta.deltype=1; /* xyz */ for (j=0;j<3;j++) rtcm->sta.del[j]=del[0][j]; rtcm->sta.hgt=hgt; return 5; } /* decode type 23: antenna type definition record ----------------------------*/ static int decode_type23(rtcm_t *rtcm) { return 0; } /* decode type 24: antenna reference point (arp) -----------------------------*/ static int decode_type24(rtcm_t *rtcm) { return 0; } /* decode type 31: differential glonass correction ---------------------------*/ static int decode_type31(rtcm_t *rtcm) { return 0; } /* decode type 32: differential glonass reference station parameters ---------*/ static int decode_type32(rtcm_t *rtcm) { return 0; } /* decode type 34: glonass partial differential correction set ---------------*/ static int decode_type34(rtcm_t *rtcm) { return 0; } /* decode type 36: glonass special message -----------------------------------*/ static int decode_type36(rtcm_t *rtcm) { return 0; } /* decode type 37: gnss system time offset -----------------------------------*/ static int decode_type37(rtcm_t *rtcm) { return 0; } /* decode type 59: proprietary message ---------------------------------------*/ static int decode_type59(rtcm_t *rtcm) { return 0; } /* decode rtcm ver.2 message -------------------------------------------------*/ extern int decode_rtcm2(rtcm_t *rtcm) { double zcnt; int staid,seqno,stah,ret=0,type=getbitu(rtcm->buff,8,6); trace(3,"decode_rtcm2: type=%2d len=%3d\n",type,rtcm->len); if ((zcnt=getbitu(rtcm->buff,24,13)*0.6)>=3600.0) { trace(2,"rtcm2 modified z-count error: zcnt=%.1f\n",zcnt); return -1; } adjhour(rtcm,zcnt); staid=getbitu(rtcm->buff,14,10); seqno=getbitu(rtcm->buff,37, 3); stah =getbitu(rtcm->buff,45, 3); if (seqno-rtcm->seqno!=1&&seqno-rtcm->seqno!=-7) { trace(2,"rtcm2 message outage: seqno=%d->%d\n",rtcm->seqno,seqno); } rtcm->seqno=seqno; rtcm->stah =stah; if (rtcm->outtype) { sprintf(rtcm->msgtype,"RTCM %2d (%4d) zcnt=%7.1f staid=%3d seqno=%d", type,rtcm->len,zcnt,staid,seqno); } if (type==3||type==22||type==23||type==24) { if (rtcm->staid!=0&&staid!=rtcm->staid) { trace(2,"rtcm2 station id changed: %d->%d\n",rtcm->staid,staid); } rtcm->staid=staid; } if (rtcm->staid!=0&&staid!=rtcm->staid) { trace(2,"rtcm2 station id invalid: %d %d\n",staid,rtcm->staid); return -1; } switch (type) { case 1: ret=decode_type1 (rtcm); break; case 3: ret=decode_type3 (rtcm); break; case 9: ret=decode_type1 (rtcm); break; case 14: ret=decode_type14(rtcm); break; case 16: ret=decode_type16(rtcm); break; case 17: ret=decode_type17(rtcm); break; case 18: ret=decode_type18(rtcm); break; case 19: ret=decode_type19(rtcm); break; case 22: ret=decode_type22(rtcm); break; case 23: ret=decode_type23(rtcm); break; /* not supported */ case 24: ret=decode_type24(rtcm); break; /* not supported */ case 31: ret=decode_type31(rtcm); break; /* not supported */ case 32: ret=decode_type32(rtcm); break; /* not supported */ case 34: ret=decode_type34(rtcm); break; /* not supported */ case 36: ret=decode_type36(rtcm); break; /* not supported */ case 37: ret=decode_type37(rtcm); break; /* not supported */ case 59: ret=decode_type59(rtcm); break; /* not supported */ } if (ret>=0) { if (1<=type&&type<=99) rtcm->nmsg2[type]++; else rtcm->nmsg2[0]++; } return ret; }