文章目录
- RTCM消息的帧结构如下表所示
- 消息体
- Multiple Signal Message (MSM)
- message header
- Satellite Data 与 Signal Data
RTCM为国际海运事业无线电技术委员会,是国际标准组织,当我们打开RTCM的官方文档会看到以下小字,
DEVELOPED BY RTCM SPECIAL COMMITTEE NO. 104
,这个特别委员会(
SC,SPECIAL COMMITTEE) 104 就是差分全球导航卫星系统。
RTCM消息的帧结构如下表所示
- RTCM消息的前导符(Preamble)由8个bit组成
11010011
(0xD3
) - Message Length,这个10bits的消息长度不包括前导符,保留位,消息长度和校验位的6个字节
- CRC位3个字节的校验位,校验算法的输入位从前导符到变长数据体
消息体
上表中的Variable Length Data Message大小为0-1023个字节不等,这取决于具体的消息类型,另外对于同类型的消息,消息体的大小也不一定是相等的。对于1005,1006这样的定长消息,那么消息类型确定了,消息体的大小也就确定了。可是也有消息本身也是变长的,如观测值,这些消息的消息体长度不仅与收星数目有关系,如下表中的1004,(Ns就是number of sat的意思),再如MEM消息,则更加复杂,其大小还与signal有关系。
Multiple Signal Message (MSM)
MSM消息用于传送GNSS观测值,如伪距,载波相位,多普勒频移和信噪比等。这个消息很重要,也属于比较复杂的一个消息。这个消息可以认为对应于Rinex文件里的观测文件。
message header
下边这张表对应于上表中的第一个block,大多数DF(Data Field)是很好理解的,值得一提的是GNSS Satellite Mask和GNSS Signal Mask这两个DF。
- GNSS Satellite Mask,通过decode这个DF我们要得到两个信息。第一,消息中包含几颗卫星的观测值,后边的两个block中要用这个值做内循环,没有这个值是无法进行后边的decode的;第二,消息中包含哪几颗卫星的信息,这个bit位和卫星PRN的关系可以再表3.5-90中得知,另外几个卫星系统是一样的,所以这里就不贴了。
- GNSS Signal Mask这个signal Mask也是很有用的,其对应关系在下边的表里可以查看。
Satellite Data 与 Signal Data
这两部分也是需要结合起来才有意义,只decode前边或者后边是没有意义的。简单来概括就是,RTCM格式的GNSS观测值分为三个resolution的DF,这三层DF要全部加到一起才是最终的观测值。,也就是说最终的伪距和载波相位通过以下公式计算,
伪距=DF397+DF398+DF400
载波相位=DF397+DF398+DF401
这部分通过rtklib也反映的比较清楚,
首先,decode这两个block中的观测值,
/* decode satellite data */
for (j=0;j<h.nsat;j++) { /* range */
rng =getbitu(rtcm->buff,i, 8); i+= 8;
if (rng!=255) r[j]=rng*RANGE_MS;
}
for (j=0;j<h.nsat;j++) {
rng_m=getbitu(rtcm->buff,i,10); i+=10;
if (r[j]!=0.0) r[j]+=rng_m*P2_10*RANGE_MS;
}
/* decode signal data */
for (j=0;j<ncell;j++) { /* pseudorange */
prv=getbits(rtcm->buff,i,15); i+=15;
if (prv!=-16384) pr[j]=prv*P2_24*RANGE_MS;
}
for (j=0;j<ncell;j++) { /* phaserange */
cpv=getbits(rtcm->buff,i,22); i+=22;
if (cpv!=-2097152) cp[j]=cpv*P2_29*RANGE_MS;
}
然后,将其组合得到最终的观测信息
/* pseudorange (m) */
if (r[i]!=0.0&&pr[j]>-1E12) {
rtcm->obs.data[index].P[idx[k]]=r[i]+pr[j];
}
/* carrier-phase (cycle) */
if (r[i]!=0.0&&cp[j]>-1E12) {
rtcm->obs.data[index].L[idx[k]]=(r[i]+cp[j])*freq/CLIGHT;
}