简体   繁体   English

如何读取从这个模拟器发送的数据?

[英]How do I read the data sent from this simulator?

I'm required to make a 'height sensing subsystem' to read the data sent from a moonlander by making a UDP protocol.我需要制作一个“高度感应子系统”,通过制作 UDP 协议来读取从月球着陆器发送的数据。 The client is already set up for me, and is a 64bit executable on linux run by using ./simulator.客户端已经为我设置好了,它是一个在 linux 上使用 ./simulator 运行的 64 位可执行文件。 So I need to make the UDP server in linux to connect with the client.所以我需要让linux中的UDP服务器与客户端连接。

The client sends readings from many subsystems in the moonlander, but I only need to read one of them, which is the laser altimeter reading that corresponds to the a type specified by 0xaa01, there are other types such as 0xaa##, and 0xff##, but those correspond to different subsystems of the moonlander I assume.客户端从moonlander的多个子系统发送读数,但我只需要读取其中一个,即激光高度计读数,对应0xaa01指定的a类型,还有0xaa##、0xff#等其他类型#,但这些对应于我假设的月球着陆器的不同子系统。 The data sent from the ./simulator file is sent through the type, which I then need to decode to find if its the laser altimeter, and then I need to decode the values to convert into distance to find when the moonlander has touched down.从 ./simulator 文件发送的数据通过类型发送,然后我需要对其进行解码以查找是否为激光高度计,然后我需要将值解码以转换为距离以查找月球着陆器何时着陆。 I need to read the time first, which has a size of 4 bytes and is an unsigned 32 bit integer, and the laser altimeter reading is 3 unsigned 16-bit integers that correspond to 3 different measurements (as there are 3 different sensors on the altimeter, max height of 1000m, convert by dividing by 65.535 which is UINT16_MAX, and multiplying by 100 to convert to cm).我需要先读取时间,它的大小为 4 个字节,是一个无符号的 32 位整数,激光高度计读数是 3 个无符号的 16 位整数,对应于 3 个不同的测量值(因为有 3 个不同的传感器在高度计,最大高度为 1000m,除以 65.535(即 UINT16_MAX)进行转换,然后乘以 100 转换为 cm)。 I need to then take those readings, convert them into height, and then acknowledge that we've landed once we've hit 40cm away from the ground.然后我需要读取这些读数,将它们转换为高度,然后在距离地面 40 厘米处确认我们已经着陆。

How do I read the data from the ./simulator file?如何从 ./simulator 文件中读取数据? Below is my code in python, and the output in a linux terminal.下面是我在 python 中的代码,以及在 linux 终端中的输出。 I can see that this is in hexadecimal format, but how do I convert this to read into actual numbers?我可以看到这是十六进制格式,但是如何将其转换为实际数字?

import socket

UDP_IP = "127.0.0.1"
UDP_PORT = 12778

sock = socket.socket(socket.AF_INET, # Internet
                      socket.SOCK_DGRAM) # UDP
sock.bind((UDP_IP, UDP_PORT))

while True:
    data, addr = sock.recvfrom(8192) # buffer size is 1024 bytes
    print("received message: %s" % data)


output:

received message: b'\xff\x06\x13\x81(6iF~\xecB<\x951v\xe5\xebr\xd1\xf0r\x91'
received message: b'\xff\x05\x13\x81(6\x06\xef\x06\xfa^\x00\x08O'
received message: b'\xaa\x08\x13\x81(6\xef.\x10@\xba[\x95_-\x0c\xa8\xacD{\xad:\xca\x8c\x14\xc5\xc5\x8c\x84\xdd1Ui\xa5\xf5\xf1\xd4\x98\xc7\xe1\x02R\x11;\xf6\xff{\xd8\x0b\x9b\xae\xe9\x8f\x12)\x08\xe7\xcf|\x13>\xa4\xe4\xe9X\r\xf6\x87.\xfcmc\x06UP#\x89Y\x7f"f=e\x81\x88\xb2&\xcfl\xd7\xbb/ p\x1a\x1f\x1e\xaa\x88\x82\xb1\x82<\xec`\xed\x1c\x86\x1bM)\xef\n\xba|\xa7\xc8\xa6\x86\xa0\\\x13\xab\xda\xeb]\x1435]\x8a\'\x1a\xba'
received message: b'\xff\x01\x13\x81(6Ydo\x03\xadJ\xdc7\xb8\x05\xa0-'
received message: b'\xaa\x10\x13\x81(7d\x805wF\x90\xf2\x9c bq'
received message: b'\xff\x02\x13\x81(6\xa2\xb0\xe5\x94'
received message: b'\xaa\x12\x13\x81(7=\x9f\xea\xe9\xc3\x94\xf0\x82.\x9epWNn\xa0\x8c\xd3\xa2\x99\x08#\xc8\xeb\xb0_#r\x0b\xb8\xdb\xeeZ'
received message: b'\xaa\x01\x13\x81(6\x00\r\x00\x0f\x00\x0e'

All of the output except the last one correspond to different subsystems in the moonlander, so we don't need those.除了最后一个输出之外的所有输出都对应于moonlander中的不同子系统,所以我们不需要这些。 All I need is the last one.我只需要最后一个。 How do I read data?如何读取数据? Some things about the data:关于数据的一些事情:

  1. It is sent through big endian form through: type (2 bytes) --> time (4 bytes) --> payload data (0-4096 bytes)它通过大端形式发送:类型(2字节)->时间(4字节)->有效负载数据(0-4096字节)
  2. Am I reading this correctly?我读对了吗? ''\xaa\x01\x13\x81(6\x00\r\x00\x0f\x00\x0e'', I know that (xaa\x01) are the first 2 bytes that correspond to the type, the next 4 bytes, (x13\x81(6) (not sure why that isnt 4 different data points), and then the other 6 correspond to 3 different 2 16 bit integers which are measurements from the laser altimeter. ''\xaa\x01\x13\x81(6\x00\r\x00\x0f\x00\x0e'',我知道(xaa\x01)是对应类型的前2个字节,后面4个字节, (x13\x81(6) (不知道为什么这不是 4 个不同的数据点),然后其他 6 个对应于 3 个不同的 2 个 16 位整数,它们是激光高度计的测量值。

How do I convert this hexadecimal data format into real information I can then use to detect when the moonlander has indeed landed?如何将这种十六进制数据格式转换为真实信息,然后我可以使用它来检测月球着陆器何时确实着陆?

You'd need a way of determining which message is the one you want to process.您需要一种方法来确定您要处理的消息是哪条消息。 I assumed here that b'\xaa\x01' is the identifier for your message.我在这里假设b'\xaa\x01'是您的消息的标识符。

So if I understand you correctly,所以如果我理解正确的话,

while True:
    ...
    if not data.startswith(b'\xaa\x01'):
        continue
    else:
        num_values = (len(data) - 6) // 2
        values = struct.unpack('>' + 'h' * num_values, data[6:])

Essentially ignore every message that doesn't start with specific bytes in the given order.基本上忽略不以给定顺序的特定字节开头的每条消息。 Then figure number of values you have by looking at the length of the message after type and time (6 bytes).然后通过查看typetime (6 个字节)之后的消息长度来计算您拥有的值的数量。 Use struct to read them.使用 struct 读取它们。

Note: '>' is means Big-Endian and 'h' is signed short (2 bytes integer).注意: '>'表示 Big-Endian, 'h'是有符号短(2 字节整数)。 Refer to struct documentation for more information.有关详细信息,请参阅struct文档。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM