You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何读取月球着陆器模拟器UDP数据并实现着陆检测?

月球着陆器UDP高度感知子系统实现与数据解析

需求说明

  • 在Linux环境搭建UDP服务器,对接已部署的64位月球着陆器模拟器(通过./simulator启动)
  • 仅处理**类型标识为0xaa01**的激光高度计数据,忽略其他子系统UDP数据包
  • 数据采用大端序传输,格式定义:
    • 前2字节:类型字段(无符号16位)
    • 接下来4字节:无符号32位时间戳
    • 剩余部分:负载数据(激光高度计负载含3个无符号16位测量值)
  • 高度转换规则:高度(cm) = 测量值 / 65.535 * 100,最大高度1000m
  • 着陆判定条件:当高度≤40cm时,判定为着陆状态

原代码问题

现有Python UDP接收代码仅打印原始二进制数据,未对目标数据进行解析,无法提取可用的高度数值。

解析实现代码

使用Python的struct模块完成大端序数据解析,修改后的代码如下:

import socket
import struct

UDP_IP = "127.0.0.1"
UDP_PORT = 12778

# 绑定UDP端口
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP, UDP_PORT))

# 目标类型标识(大端序对应0xaa01)
TARGET_TYPE = 0xaa01

while True:
    data, addr = sock.recvfrom(8192)
    # 至少需要2字节类型字段,否则跳过
    if len(data) < 2:
        continue
    
    # 解析前2字节的类型字段(大端序无符号16位)
    data_type = struct.unpack('!H', data[:2])[0]
    
    # 仅处理目标类型数据
    if data_type != TARGET_TYPE:
        continue
    
    # 解析接下来4字节的时间戳(大端序无符号32位)
    timestamp = struct.unpack('!I', data[2:6])[0]
    
    # 解析负载中的3个无符号16位测量值(大端序)
    # 激光高度计负载固定为6字节(3*2),需确保数据长度足够
    if len(data) < 6 + 6:
        print("激光高度计数据长度不足,跳过")
        continue
    measurements = struct.unpack('!HHH', data[6:6+6])
    
    # 转换为厘米单位并计算平均高度(可根据需求选择单值或平均值)
    heights_cm = [round(m / 65.535 * 100, 2) for m in measurements]
    avg_height_cm = sum(heights_cm) / len(heights_cm)
    
    # 判定着陆状态
    is_landed = avg_height_cm <= 40
    
    # 输出解析结果
    print(f"=== 激光高度计数据 ===")
    print(f"时间戳: {timestamp}")
    print(f"原始测量值: {measurements}")
    print(f"转换后高度(cm): {heights_cm}")
    print(f"平均高度(cm): {round(avg_height_cm, 2)}")
    print(f"着陆状态: {'已着陆' if is_landed else '未着陆'}")
    print("=====================")

代码关键说明

  1. 数据解析核心:使用struct模块的!标识大端序,对应解析格式:
    • !H:大端序无符号16位整数(类型字段)
    • !I:大端序无符号32位整数(时间戳)
    • !HHH:3个大端序无符号16位整数(高度测量值)
  2. 数据筛选:仅处理data_type == 0xaa01的数据包,过滤其他子系统数据
  3. 边界检查:增加数据长度校验,避免因数据包不完整导致解析错误
  4. 高度计算:严格按照给定公式转换,保留两位小数提升可读性
  5. 着陆判定:采用平均高度作为判定依据(可根据需求调整为单值判定)

示例验证

针对你提供的最后一条0xaa01数据:b'\xaa\x01\x13\x81(6\x00\r\x00\x0f\x00\x0e'

  • 类型字段:0xaa01(符合目标类型)
  • 时间戳:struct.unpack('!I', b'\x13\x81(6') → 328966246
  • 原始测量值:0x000d=13、0x000f=15、0x000e=14
  • 转换后高度:
    • 13/65.535*100≈19.84cm
    • 15/65.535*100≈22.89cm
    • 14/65.535*100≈21.36cm
  • 平均高度≈21.36cm ≤40cm → 判定为已着陆

内容的提问来源于stack exchange,提问作者ayoubster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 04:12:10