【问题标题】:Interpreting F1 2012 UDP packets in Python在 Python 中解释 F1 2012 UDP 数据包
【发布时间】:2014-08-12 17:38:47
【问题描述】:

我正在开展一个项目,在该项目中,来自 F1 2012 的游戏遥测数据由 Python 解释并发送到 Arduino 以显示为物理仪表板。

F1 2012 通过 UDP 数据包在地址 127.0.0.1、端口 20777 发送数据。

我有一个简单的 python 程序来读取传入的数据包:

import socket

UDP_IP = "127.0.0.1"
UDP_PORT = 20777

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

sock.bind((UDP_IP, UDP_PORT))

while True:
    data, addr = sock.recvfrom(1024)
    print ("Message:" data)

这会输出如下消息:

b'\xce\xb3T@\x00\x00\x00\x001K\xa7E\xa0\xf1\xf0\xbc\xa1\xc6\x13\xc4OY\x0b\xc3\xd5\xbf.D\xca\xe2\xc2;\xb0\x9109\xf0\x19\xbd\xbb\xdd8\xbb:q\x19M\xbf\x81t.933\x19\xbf\x1e,\x19\xbf\xc2\x82\x9d\xbc\x9c\x0fM?\xa2#H\xbc\xd6\x16x\xbe\x92hr\xba:\xa8\x88=X\xd7&?q$\xc7>\x82w#><\xe9\x1d>w\xc9\xb8\xa7Bh\x010\x00\x00\x00\x00kr\xb7\xaf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80?\x00\x00\x80?\x96z\x98\xb9!f\x849\x00\x00\x00\x00\x8d\x8b5C'

我知道这是一个相当长的输出,但它包含关于汽车的 38 个参数,每秒刷新 60 次。这些由从事类似项目的人在this website 中进行了概述。

我在 stackeoverflow 上寻找与我类似的 UDP 输出的类似问题,我被告知必须以合适的格式解压缩数据。

看了this website,好像包里的数据都是C里的float类型所以我修改了我原来的Python代码。

import socket
import struct

UDP_IP = "127.0.0.1"
UDP_PORT = 20777

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

sock.bind((UDP_IP, UDP_PORT))

while True:
    data, addr = sock.recvfrom(1024)
    output = struct.unpack('f', data)
    print ("Message:", output)

Unpack 被赋予格式 'f' 以根据来自此页面的信息分配传入数据的格式:docs.python.org/3.2/library/struct.html#format-characters

这会产生错误:

struct.error: unpack requires a bytes object of length 4

我现在相信我已经走入了死胡同,我不知道该怎么做。

请帮忙。

【问题讨论】:

  • 非原生大小将消除填充,即格式字符串之前的=&lt;&gt;!,例如=f。这是假设您的数据小于 4 个字节。
  • 看起来您正在一次解压缩多个值,这将超过 4 个字节,因此不适合 C 结构。

标签: python sockets python-3.x udp game-engine


【解决方案1】:

正如错误消息所说:struct.error: unpack requires a bytes object of length 4,您需要一次传递 4 个字节。

修改您的代码以每次发送 4 个字节

while True:
    data, addr = sock.recvfrom(1024)
    # data is 1024 length bytearray, break into 4 bytes and get the output
    output = struct.unpack('f', data[0:4]) # 4 bytes at a time
    print ("Message:", output)

【讨论】:

  • 非常感谢,这很好用。您的解决方案能够输出我的第二个链接中列出的第一个参数,即“时间”(即自遥测会话开始以来经过的时间。)现在我知道每个参数是四个字节,我可以调整值以便部分可以为我希望使用的参数解压缩读取的数据。例如,要读取第 34 个参数的当前档位的值,我会使用 data[136:140]。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-31
  • 1970-01-01
  • 2013-09-15
  • 2014-12-13
相关资源
最近更新 更多