Files
VDES_Backend/报文模拟解析/报文模拟.py
2026-07-13 15:37:05 +08:00

125 lines
4.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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]}°")