您的位置:首页 > 大数据 > 人工智能

AIS数据分析详解

2010-08-10 14:01 441 查看
想必大家在刚接触AIS时,对AIS数据的解码感到困惑,其是采用6位ASCII压缩码传输的,所以对AIS数据的正确解析,就是完成任务的关键所在。通过最近的一个项目,了解了AIS数据的解码分析过程,现将其流程和相关代码列出,此参表可以参见快乐鹦鹉的AIS解码算法一文http://blog.csdn.net/happyparrot/archive/2007/04/26/1585185.aspx

view plaincopy to clipboardprint?

Public Function fun_Decode(ByVal AISData As String) As String

On Error GoTo DoError

Dim strAisData As String ' 待解码的数据缓冲区

Dim i As Long

Dim strAisBin As String ' 存AIS数据转成二进制的

Dim strTemp As String

Dim strAisDec As String ' 存AIS数据转成十进制的

For i = 1 To Len(AISData)

strTemp = Mid(AISData, i, 1) ' 取ASCII

strAisDec = fun_Hex2Dec(AsciiToHex(strTemp)) ' AIS数据转成十进制的

If CInt(strAisDec) < 48 Or CInt(strAisDec) > 119 Or (CInt(strAisDec) > 87 And CInt(strAisDec) < 96) Then

Exit Function

Else

strAisDec = CStr(CInt(strAisDec) + 40)

If CInt(strAisDec) > 128 Then

strAisDec = CStr(CInt(strAisDec) + 32)

Else

strAisDec = CStr(CInt(strAisDec) + 40)

End If

strAisBin = fun_Hex2Bin(DecToHex(strAisDec)) ' AIS数据转成二进制的

'strAisBin = CDec(strAisDec)

fun_Decode = fun_Decode & (Right("000000" & strAisBin, 6)) ' 取AIS数据低六位

End If

Next i

Debug.Print fun_Decode

Debug.Print Len(fun_Decode)

Debug.Print BinToDec(strAisBin)

Exit Function

' --------------- 错误处理 部分, 注意: 前面正常代码必须有 结束语句 --------------------

DoError:

Call sub_DoErrors("Cls_AISDecode fun_Decode", Err.Description)

End Function

Public Function fun_Decode(ByVal AISData As String) As String

On Error GoTo DoError

Dim strAisData As String ' 待解码的数据缓冲区

Dim i As Long

Dim strAisBin As String ' 存AIS数据转成二进制的

Dim strTemp As String

Dim strAisDec As String ' 存AIS数据转成十进制的

For i = 1 To Len(AISData)

strTemp = Mid(AISData, i, 1) ' 取ASCII

strAisDec = fun_Hex2Dec(AsciiToHex(strTemp)) ' AIS数据转成十进制的

If CInt(strAisDec) < 48 Or CInt(strAisDec) > 119 Or (CInt(strAisDec) > 87 And CInt(strAisDec) < 96) Then

Exit Function

Else

strAisDec = CStr(CInt(strAisDec) + 40)

If CInt(strAisDec) > 128 Then

strAisDec = CStr(CInt(strAisDec) + 32)

Else

strAisDec = CStr(CInt(strAisDec) + 40)

End If

strAisBin = fun_Hex2Bin(DecToHex(strAisDec)) ' AIS数据转成二进制的

'strAisBin = CDec(strAisDec)

fun_Decode = fun_Decode & (Right("000000" & strAisBin, 6)) ' 取AIS数据低六位

End If

Next i

Debug.Print fun_Decode

Debug.Print Len(fun_Decode)

Debug.Print BinToDec(strAisBin)

Exit Function

' --------------- 错误处理 部分, 注意: 前面正常代码必须有 结束语句 --------------------

DoError:

Call sub_DoErrors("Cls_AISDecode fun_Decode", Err.Description)

End Function

结合自己在AIS项目中的理解,提出几点需要注意的方面:

1. AIS的数据校验采用的是异或校验,校验的数据时!和*之间的数据,比如原始数据位:!ABVDM,1,1,,B,169G?I0P007k`vT;BwhP7gv4@d0e,0*0A

则校验的数据应该是:ABVDM,1,1,,B,169G?I0P007k`vT;BwhP7gv4@d0e,0。下面列出异或算法的代码:

view plaincopy to clipboardprint?

Public Function ChkSumXOR(ByVal strMYGPS As String) As String

On Error GoTo DoError

Dim i As Integer ' 临时循环变量

Dim tmp As Variant ' 临时变量 保存每次读取的 字符内容

Dim Length As Integer ' 保存 需要计算校验码字符串的长度

Dim Result As Integer ' 保存 异或校验 计算的结果

strMYGPS = Trim(strMYGPS) ' 冗余设计, 前后不能有 空格 字符

Length = Len(strMYGPS) ' 计算 刷新字符串后的字符串长度

Result = 0

For i = 1 To Length

tmp = Mid(strMYGPS, i, 1)

tmp = Asc(tmp)

Result = Result Xor tmp

Next

ChkSumXOR = Hex(Result / 256) & Hex(Result Mod 256) ' Hex(Result) 为了使用者的方便 提供 2 位数字

ChkSumXOR = Mid(ChkSumXOR, 2, 2) '上述计算时 可能得到 3 位数据 显示后两位 (最高位此时为 0)

If Len(ChkSumXOR) = 1 Then ' 保证

ChkSumXOR = "0" & ChkSumXOR

End If

Exit Function

' --------------- 错误处理 部分, 注意: 前面正常代码必须有 结束语句 --------------------

DoError:

Call sub_DoErrors("mod_Public ChkSumXOR", Err.Description)

End Funct

Public Function ChkSumXOR(ByVal strMYGPS As String) As String

On Error GoTo DoError

Dim i As Integer ' 临时循环变量

Dim tmp As Variant ' 临时变量 保存每次读取的 字符内容

Dim Length As Integer ' 保存 需要计算校验码字符串的长度

Dim Result As Integer ' 保存 异或校验 计算的结果

strMYGPS = Trim(strMYGPS) ' 冗余设计, 前后不能有 空格 字符

Length = Len(strMYGPS) ' 计算 刷新字符串后的字符串长度

Result = 0

For i = 1 To Length

tmp = Mid(strMYGPS, i, 1)

tmp = Asc(tmp)

Result = Result Xor tmp

Next

ChkSumXOR = Hex(Result / 256) & Hex(Result Mod 256) ' Hex(Result) 为了使用者的方便 提供 2 位数字

ChkSumXOR = Mid(ChkSumXOR, 2, 2) '上述计算时 可能得到 3 位数据 显示后两位 (最高位此时为 0)

If Len(ChkSumXOR) = 1 Then ' 保证

ChkSumXOR = "0" & ChkSumXOR

End If

Exit Function

' --------------- 错误处理 部分, 注意: 前面正常代码必须有 结束语句 --------------------

DoError:

Call sub_DoErrors("mod_Public ChkSumXOR", Err.Description)

End Funct

2、关于AIS数据各个数据段的具体含义

!aaccc,x,y,z,u,c-c,v*hh <CR><LF>

aaccc为标识符,指明本条句子封装的背景信息;

x为传输该条消息所需的表达句数目(至多为9条);

y为本条句子在序列中的牌号;

z为同一序列的统一标识(0-9的循环);

u表示接收该条消息时对应的频道(A/B);

c-c为封装信息,需要映射6位ASCII码;

v表 示填充的字符,因为封装的字符需要是6的整数倍,若不满足,则需要填充0-5个字符;

hh表示的是检验和字段。

这里需要说明的是:关于填充字符,已经填充在封装信息,时期成为6的整数倍,在数据解码过程中无需在额外填充。

3、关于数据解析过程中,有些数据需要使用ASCII码,比如说船舶类型,这就涉及到将解码的二进制进行编码的问题,下面将实现程序列出:

+ expand sourceview plaincopy to clipboardprint?

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150

Public Function fun_Code(ByVal AISData As String) As String

On Error GoTo DoError

Dim strAisData As String ' 待解码的数据缓冲区

Dim i As Long

Dim strAisBin As String ' 存AIS数据 二进制

Dim strASCII As String

Dim strAisDec As String ' 存AIS数据转成十进制的

strAisData = AISData

For i = 1 To Len(strAisData) Step 6

strAisDec = BinToDec(Mid(strAisData, i, 6))

If CInt(strAisDec) >= 32 Then ' 在32以后 都是在六位的压缩码前加"00"

strAisBin = "00" & Mid(strAisData, i, 6)

ElseIf CInt(strAisDec) >= 0 And CInt(strAisDec) < 32 Then ' 0~31 都是在六位的压缩码前加"01"

strAisBin = "01" & Mid(strAisData, i, 6)

End If

strASCII = strASCII & Chr(CLng(BinToDec(strAisBin)))

Next i

fun_Code = strASCII

Exit Function

' --------------- 错误处理 部分, 注意: 前面正常代码必须有 结束语句 --------------------

DoError:

Call sub_DoErrors("Cls_AISDecode fun_Code", Err.Description)

End Function

Public Function fun_Code(ByVal AISData As String) As String

On Error GoTo DoError

Dim strAisData As String ' 待解码的数据缓冲区

Dim i As Long

Dim strAisBin As String ' 存AIS数据 二进制

Dim strASCII As String

Dim strAisDec As String ' 存AIS数据转成十进制的

strAisData = AISData

For i = 1 To Len(strAisData) Step 6

strAisDec = BinToDec(Mid(strAisData, i, 6))

If CInt(strAisDec) >= 32 Then ' 在32以后 都是在六位的压缩码前加"00"

strAisBin = "00" & Mid(strAisData, i, 6)

ElseIf CInt(strAisDec) >= 0 And CInt(strAisDec) < 32 Then ' 0~31 都是在六位的压缩码前加"01"

strAisBin = "01" & Mid(strAisData, i, 6)

End If

strASCII = strASCII & Chr(CLng(BinToDec(strAisBin)))

Next i

fun_Code = strASCII

Exit Function

' --------------- 错误处理 部分, 注意: 前面正常代码必须有 结束语句 --------------------

DoError:

Call sub_DoErrors("Cls_AISDecode fun_Code", Err.Description)

End Function

此算法对应的参表请查看 GB-T20068-2006船载自动识别系统(AIS)技术要求

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lenyusun/archive/2010/03/19/5395978.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: