125 lines
4.6 KiB
Python
125 lines
4.6 KiB
Python
|
|
import struct
|
|||
|
|
|
|||
|
|
def create_tcp_packet(packet_type, content):
|
|||
|
|
"""创建符合VDES TCP协议的报文"""
|
|||
|
|
# 报文帧头 (4字节)
|
|||
|
|
header = b'####'
|
|||
|
|
|
|||
|
|
# 报文类型 (4字节,大端)
|
|||
|
|
type_field = struct.pack('>I', packet_type)
|
|||
|
|
|
|||
|
|
# 报文长度 (4字节,大端,内容长度)
|
|||
|
|
length = len(content)
|
|||
|
|
length_field = struct.pack('>I', length)
|
|||
|
|
|
|||
|
|
# 构建完整报文
|
|||
|
|
packet = header + type_field + length_field + content
|
|||
|
|
return packet
|
|||
|
|
|
|||
|
|
def create_gps_packet():
|
|||
|
|
"""创建GPS解析数据报文(类型7)的内容"""
|
|||
|
|
# 模拟GPS数据 (表11定义)
|
|||
|
|
utc_time = 1680000000 # UTC时间 (8字节)
|
|||
|
|
longitude = 1205000000 # 经度 (4字节,东经120.5度)
|
|||
|
|
latitude = 305000000 # 纬度 (4字节,北纬30.5度)
|
|||
|
|
altitude = 50 # 海拔高度 (4字节,50米)
|
|||
|
|
used_sats = 10 # 定位使用的卫星数 (2字节)
|
|||
|
|
gps_sats = 8 # GPS卫星数 (2字节)
|
|||
|
|
beidou_sats = 7 # 北斗卫星数 (2字节)
|
|||
|
|
gps_status = 1 # GPS状态 (1字节,单点定位)
|
|||
|
|
position_mode = 3 # 定位模式 (1字节,3D定位)
|
|||
|
|
hdop = 2550 # 水平精度因子 (4字节,25.5米)
|
|||
|
|
speed = 1024 # 运动速度 (4字节,10.24节)
|
|||
|
|
direction = 359 # 运动方向 (4字节,359度)
|
|||
|
|
|
|||
|
|
# 打包为二进制 (大端字节序)
|
|||
|
|
content = struct.pack(
|
|||
|
|
'>QiiiHHHBBIII', # 格式: Q(8),i(4),i(4),i(4),H(2),H(2),H(2),B(1),B(1),I(4),I(4),I(4)
|
|||
|
|
utc_time,
|
|||
|
|
longitude,
|
|||
|
|
latitude,
|
|||
|
|
altitude,
|
|||
|
|
used_sats,
|
|||
|
|
gps_sats,
|
|||
|
|
beidou_sats,
|
|||
|
|
gps_status,
|
|||
|
|
position_mode,
|
|||
|
|
hdop,
|
|||
|
|
speed,
|
|||
|
|
direction
|
|||
|
|
)
|
|||
|
|
return content
|
|||
|
|
|
|||
|
|
|
|||
|
|
def build_demod_message():
|
|||
|
|
"""创建AIS解调数据报文(类型8)的内容"""
|
|||
|
|
# 模拟AIS数据
|
|||
|
|
message_id = 1 # 消息ID (6 bits)
|
|||
|
|
repeat_indicator = 0 # 转发指示符 (2 bits)
|
|||
|
|
user_id = 123456789 # 用户ID/MMSI (30 bits)
|
|||
|
|
nav_status = 8 # 导航状态 (4 bits)
|
|||
|
|
rot = -128 # 旋转速率 (8 bits)
|
|||
|
|
sog = 102 # 地面航速 (10 bits)
|
|||
|
|
pos_acc = 1 # 位置准确度 (1 bit)
|
|||
|
|
longitude = 120500000 # 经度 (28 bits)
|
|||
|
|
latitude = 30500000 # 纬度 (27 bits)
|
|||
|
|
cog = 900 # 地面航线 (12 bits)
|
|||
|
|
true_heading = 90 # 实际航向 (9 bits)
|
|||
|
|
timestamp = 30 # 时戳 (6 bits)
|
|||
|
|
spare = 0 # 备用 (3 bits)
|
|||
|
|
raim = 0 # RAIM标志 (1 bit)
|
|||
|
|
comm_state = 0 # 通信状态 (19 bits)
|
|||
|
|
# 总比特数 168 (上面字段总和)
|
|||
|
|
# 打包为二进制 (大端字节序)
|
|||
|
|
content = struct.pack(
|
|||
|
|
'>Q', # 使用8字节无符号长整型打包所有位字段
|
|||
|
|
(message_id & 0x3F) << 58 |
|
|||
|
|
(repeat_indicator & 0x3) << 56 |
|
|||
|
|
(user_id & 0x3FFFFFFF) << 26 |
|
|||
|
|
(nav_status & 0xF) << 22 |
|
|||
|
|
(rot & 0xFF) << 14 |
|
|||
|
|
(sog & 0x3FF) << 4 |
|
|||
|
|
(pos_acc & 0x1) << 3 |
|
|||
|
|
((longitude >> 4) & 0xFFFFFFF) << 31 |
|
|||
|
|
(latitude & 0x7FFFFFF) << 4 |
|
|||
|
|
(cog & 0xFFF) << 19 |
|
|||
|
|
(true_heading & 0x1FF) << 10 |
|
|||
|
|
(timestamp & 0x3F) << 4 |
|
|||
|
|
(spare & 0x7) << 1 |
|
|||
|
|
(raim & 0x1)
|
|||
|
|
)
|
|||
|
|
return content
|
|||
|
|
|
|||
|
|
|
|||
|
|
ais_c = build_demod_message()
|
|||
|
|
print(len(ais_c)) # 应该输出21
|
|||
|
|
print(ais_c)
|
|||
|
|
|
|||
|
|
# # 生成GPS报文
|
|||
|
|
# gps_content = create_gps_packet()
|
|||
|
|
# gps_packet = create_tcp_packet(7, gps_content)
|
|||
|
|
|
|||
|
|
# # 打印二进制报文
|
|||
|
|
# print("完整报文字节长度:", len(gps_packet))
|
|||
|
|
# print("二进制表示:")
|
|||
|
|
# print(gps_packet)
|
|||
|
|
# print(' '.join(f'{b:02x}' for b in gps_packet))
|
|||
|
|
|
|||
|
|
# # 打印字段解释
|
|||
|
|
# print("\n报文结构解析:")
|
|||
|
|
# print(f"帧头: {gps_packet[:4].decode('ascii')}")
|
|||
|
|
# print(f"报文类型: {struct.unpack('>I', gps_packet[4:8])[0]} (7=GPS解析数据)")
|
|||
|
|
# print(f"内容长度: {struct.unpack('>I', gps_packet[8:12])[0]} 字节")
|
|||
|
|
|
|||
|
|
# # 解析内容部分
|
|||
|
|
# fields = struct.unpack('>QiiiHHHBBIII', gps_packet[12:])
|
|||
|
|
# print("\nGPS内容解析:")
|
|||
|
|
# print(f"UTC时间: {fields[0]} (自1980-01-06的秒数)")
|
|||
|
|
# print(f"经度: {fields[1]/10000000:.5f}° (东经)")
|
|||
|
|
# print(f"纬度: {fields[2]/10000000:.5f}° (北纬)")
|
|||
|
|
# print(f"海拔: {fields[3]} 米")
|
|||
|
|
# print(f"使用卫星: GPS={fields[5]}, 北斗={fields[6]}, 总计={fields[4]}")
|
|||
|
|
# print(f"定位状态: {fields[7]}(单点定位), 模式: {fields[8]}(3D)")
|
|||
|
|
# print(f"水平精度: {fields[9]/10:.1f} 米")
|
|||
|
|
# print(f"速度: {fields[10]/100:.2f} 节")
|
|||
|
|
# print(f"方向: {fields[11]}°")
|