5

メッセージの新しい形式を取得し始めるまで、私はAIS メッセージを theis パッケージ (Python) https://github.com/schwehr/noaadata/tree/master/aisでデコードしていました。ご存知かもしれませんが、AIS メッセージには主に 2 つのタイプがあります。1 つの部分 (1 つのメッセージ) または 2 つの部分 (複数のメッセージ)。メッセージ #5 は常に 2 つの部分に分かれています。例:

!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

ノート。最後のインデックスの数字はエポック形式の時間です

この新しい形式をデコードするようにコードを調整しようとしました。1つのパーツでメッセージを解読することに成功。私の問題はマルチメッセージタイプです。

   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])

Decoder は 2 つの行を 1 つにまとめることができません。したがって、メッセージ #5 には 1 つではなく 2 つの文字列が含まれている必要があるため、デコードは失敗します。私が得るエラーはこれらの行にあります:

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

は常にlen(nmeamsg)8 (2 行目) で、nmeastring.count('!SAVDM')常に 1 です。

これを明確に説明して、誰かがここで何が欠けているかを教えてくれることを願っています.

アップデート

さて、私は理由を見つけたと思います。ファイルからスクリプトに 1 行ずつメッセージを渡します。

for line in file:
    i=i+1

    try:
        doais(line)

message#5 は 2 行で渡す必要があります。どうすればそれを達成できるかについてのアイデアはありますか?

アップデート

コードを少し変更してそれを行いました:

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

0

Ruby を使用している場合は、私が書いたNMEA および AIS デコーダーの ruby​​ gemをお勧めします。これは github で入手できます。これは、Kurt の同僚の 1 人が管理している catb.org の非公式 AIS 仕様に基づいています。

マルチパート メッセージの結合を処理し、ストリームから読み取り、大量の NMEA および AIS メッセージをサポートします。AIS メッセージ 6 および 8 の 50 のバイナリ サブタイプのデコードは、現在開発中です。

投稿した非標準の行を処理するには:

!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

チェックサムの後にフィールドを受け入れる新しい解析ルールを追加する必要がありますが、それ以外はスムーズに進むはずです。つまり、ここにパーサー行をコピーします。

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

そして次のようなものがあります

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

これらの余分なタイムスタンプをどうしますか? 実際のメッセージの一部ではなく、ロギングを行っているソフトウェアによって追加されたように見えます。

于 2015-12-02T17:26:22.747 に答える