5

我曾经使用 theis 包 (Python) https://github.com/schwehr/noaadata/tree/master/ais解码 AIS 消息, 直到我开始获取新格式的消息。您可能知道,AIS 消息主要有两种类型。一部分(一条消息)或两部分(多条消息)。消息#5 总是分为两部分。例子:

!AIVDM,2,1,1,A,55?MbV02;H;s<HtKR20EHE:address@hidden@Dn2222222216L961O5Gf0NSQEp6ClRp8,0*1C
!AIVDM,2,2,1,A,88888888880,2*25

我曾经使用以下代码对此进行解码:

   nmeamsg = fields.split(',')
   if nmeamsg[0] != '!AIVDM': 
    return
   total = eval(nmeamsg[1])
   part = eval(nmeamsg[2])
   aismsg = nmeamsg[5]
   nmeastring = string.join(nmeamsg[0:-1],',')


   bv = binary.ais6tobitvec(aismsg)
   msgnum = int(bv[0:6])

--

elif (total>1):
     # Multi Slot Messages: 5,6,8,12,14,17,19,20?,21,24,26
     global multimsg
     if total==2:
       if msgnum==5:
         if nmeastring.count('!AIVDM')==2 and len(nmeamsg)==13: # make sure there are two parts concatenated together
           aismsg = nmeamsg[5]+nmeamsg[11]
           bv = binary.ais6tobitvec(aismsg)    

           msg5 = ais_msg_5.decode(bv)
           print "message5 :",msg5
           return msg5

现在我得到了一种新的消息格式:

!SAVDM,2,1,7,A,55@0hd01sq`pQ3W?O81L5@E:1=0U8U@000000016000006H0004m8523k@Dp,0*2A,1410825672
!SAVDM,2,2,7,A,4hC`2U@C`40,2*76,1410825672,1410825673

笔记。最后一个索引处的数字是纪元格式的时间

我试图调整我的代码来解码这种新格式。我成功地用一个部分解码消息。我的问题是多消息类型。

   nmeamsg = fields.split(',')
   if nmeamsg[0] != '!AIVDM' and nmeamsg[0] != '!SAVDM': 
    return
   total = eval(nmeamsg[1])
   part = eval(nmeamsg[2])
   aismsg = nmeamsg[5]
   nmeastring = string.join(nmeamsg[0:-1],',')
   dbtimestring = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(float(nmeamsg[7])))

   bv = binary.ais6tobitvec(aismsg)
   msgnum = int(bv[0:6])

解码器不能将两条线合二为一。所以解码失败,因为 message#5 应该包含两个字符串而不是一个。我得到的错误在这些行中:

if nmeastring.count('!SAVDM')==2 and len(nmeamsg)==13: 
aismsg = nmeamsg[5]+nmeamsg[11]

wherelen(nmeamsg)总是 8(第二行)并且nmeastring.count('!SAVDM')总是 1

我希望我清楚地解释了这一点,以便有人可以让我知道我在这里缺少什么。

更新

好吧,我想我找到了原因。我将消息从文件逐行传递到脚本:

for line in file:
    i=i+1

    try:
        doais(line)

其中 message#5 应该作为两行传递。关于如何实现这一点的任何想法?

更新

我通过稍微修改代码来做到这一点:

for line in file:
    i=i+1

try:
        nmeamsg = line.split(',')
        aismsg = nmeamsg[5]
        bv = binary.ais6tobitvec(aismsg)
        msgnum = int(bv[0:6])
        print msgnum
        if nmeamsg[0] != '!AIVDM' and nmeamsg[0] != '!SAVDM': 
         print "wrong format"
        total = eval(nmeamsg[1])
        if total == 1:
         dbtimestring = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(float(nmeamsg[8])))
         doais(line,msgnum,dbtimestring,aismsg)
        if total == 2: #Multi-line messages
         lines= line+file.next()
         nmeamsg = lines.split(',')
         dbtimestring = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(float(nmeamsg[15])))
         aismsg = nmeamsg[5]+nmeamsg[12]
         doais(lines,msgnum,dbtimestring,aismsg)
4

2 回答 2

3

请注意,noaadata 是我的旧研究代码。libais 是我的生产库,用于 NOAA 的 ERMA 和 WhaleAlert。

我通常将解码过程分为两遍。首先加入多行消息。我将此称为规范化(ais_normalize.py)。您在此步骤中有几个问题。首先,两个组成行在第二个字符串的右侧具有不同的时间戳。根据 USCG 旧的元数据标准,最后一个很重要。所以我的代码会假设这两行是不相关的。其次,您没有必填的车站 ID 字段。

您在 SAVDM 中从哪里获得 SA?什么设备(NMEA 词汇中的“说话者”)正在接收这些消息?

于 2014-12-20T18:38:50.253 回答
0

如果您使用 Ruby,我可以推荐我编写的NMEA 和 AIS 解码器 ruby​​ gem可在 github 上找到。它基于由 Kurt 的一位同事维护的 catb.org 上的非官方 AIS 规范。

It handles combining of multipart messages, reads from streams, and supports a large of NMEA and AIS messages. Decoding the 50 binary subtypes of AIS messages 6 and 8 is presently in development.

To handle the nonstandard lines you posted:

!SAVDM,2,1,7,A,55@0hd01sq`pQ3W?O81L5@E:1=0U8U@000000016000006H0004m8523k@Dp,0*2A,1410825672
!SAVDM,2,2,7,A,4hC`2U@C`40,2*76,1410825672,1410825673

It would be necessary to add a new parse rule that accepts fields after the checksum, but aside from that it should go smoothly. In other words, you'd copy the parser line here:

    | BANG DATA CSUM  { result = NMEAPlus::AISMessageFactory.create(val[0], val[1], val[2]) }

and have something like

    | BANG DATA CSUM COMMA DATA { result = NMEAPlus::AISMessageFactory.create(val[0], val[1], val[2], val[4]) }

What do you do with those extra timestamp(s)? It almost looks like they've been appended by whatever software is doing the logging, rather than being part of the actual message.

于 2015-12-02T17:26:22.747 回答