编辑 | blame | 历史 | 原始文档

GPS/IMU 数据传输功能实现总结

实现概述

成功实现了从 STM32H7 通过 UART5 向 Python 程序实时发送 GPS/IMU 数据的完整功能,为后续的电脑控制车辆实际行走做好了准备。

主要特性

高频实时传输
- GPS数据: 10Hz (解析成功后立即发送)
- IMU数据: 100Hz (解析成功后立即发送)
- 零额外延迟,最小化控制延迟

可靠的协议设计
- 自定义二进制协议
- CRC16-MODBUS 校验保证数据完整性
- 清晰的帧头/帧尾标识

DMA 高效传输
- UART5 发送和接收均使用 DMA
- 发送队列深度为8,避免丢包
- 波特率: 921600 bps

完整的数据内容
- GPS: 纬度、经度、航向角、东北天速度、高程、UTC时间、定位质量、卫星数
- IMU: 三轴加速度、三轴角速度、温度、UTC时间

文件修改清单

STM32 固件 (C语言)

文件 修改内容 说明
FML/PythonLink.h 新增 定义协议结构体、函数接口
FML/PythonLink.c 新增 实现数据封包、CRC计算、UART发送
FML/GPS.c 修改 在解析函数末尾添加立即发送调用
HAL/Uart.h 修改 添加 UART_ID_PYTHON 枚举
Core/Src/main.c 修改 注册 UART5 为 UART_ID_PYTHON
APL/app.c 修改 初始化和轮询 PythonLink 模块

Python 解析器

文件 说明
python/gps_imu_receiver.py GPS/IMU数据接收解析器,支持CRC校验和数据解包
python/requirements.txt Python依赖 (pyserial, crcmod)
python/README.md 使用说明文档

文档

文件 说明
PROTOCOL.md 详细的协议规范文档
GPS_IMU_IMPLEMENTATION.md 本实现总结文档

实现细节

1. 协议设计

帧格式: AA 55 TYPE LEN(2) DATA CRC16(2) 0D 0A
        ↑帧头  ↑类型 ↑长度  ↑负载 ↑校验   ↑帧尾

数据类型:
- 0x01: GPS数据包 (56字节)
- 0x02: IMU数据包 (32字节)

CRC16: MODBUS标准,校验范围从帧头到数据负载末尾

2. 触发机制

// GPS解析成功后立即发送 (GPS.c)
static HIDO_INT32 GPS_ParseGPRMI(...)
{
    // ... 解析代码 ...
    l_stGPRMI.m_bValid = HIDO_TRUE;
    
    // 立即发送到Python (10Hz)
    PythonLink_SendGPSData(&l_stGPRMI);
    
    return HIDO_OK;
}

// IMU解析成功后立即发送 (GPS.c)
static HIDO_INT32 GPS_ParseGPIMU(...)
{
    // ... 解析代码 ...
    l_stGPIMU.m_bValid = HIDO_TRUE;
    
    // 立即发送到Python (100Hz)
    PythonLink_SendIMUData(&l_stGPIMU);
    
    return HIDO_OK;
}

这种机制确保了**最小延迟**,适合实时控制场景。

3. 数据流

GPS模块 (UART2) ──> GPS_ParseGPRMI() ──> PythonLink_SendGPSData() ──> UART5 TX ──> Python
                        ↓ 10Hz                    ↓ DMA发送              ↓ 921600bps

IMU模块 (UART2) ──> GPS_ParseGPIMU() ──> PythonLink_SendIMUData() ──> UART5 TX ──> Python
                        ↓ 100Hz                   ↓ DMA发送              ↓ 921600bps

4. Python 接收解析

from gps_imu_receiver import GPSIMUReceiver

receiver = GPSIMUReceiver("COM3", 921600)
receiver.connect()

while True:
    gps_data, imu_data = receiver.receive_packet()
    
    if gps_data:
        print(f"GPS: {gps_data.latitude:.8f}°, {gps_data.longitude:.8f}°, ...")
    
    if imu_data:
        print(f"IMU: Accel({imu_data.accel_x:.3f}g, ...), Gyro(...), ...")

使用方法

STM32 端

  1. 确认 UART5 硬件连接正确
  2. 编译并烧录固件到 STM32H7
  3. 上电后 PythonLink 模块自动初始化
  4. GPS/IMU 解析成功后自动发送数据

Python 端

  1. 安装依赖:
    bash cd python pip install -r requirements.txt

  2. 配置串口 (编辑 gps_imu_receiver.py):
    python PORT = "COM3" # Windows # PORT = "/dev/ttyUSB0" # Linux

  3. 运行接收程序:
    bash python gps_imu_receiver.py

测试验证

预期行为

  1. GPS数据: 每秒接收约10个GPS数据包
  2. IMU数据: 每秒接收约100个IMU数据包
  3. CRC校验: 接收端CRC校验应全部通过 (error_count = 0)
  4. 数据完整性:
  • GPS: 纬度/经度在合理范围内
  • IMU: 静止时加速度Z轴约为-1g (重力加速度)
  • 温度在正常范围内 (20-40℃)

调试方法

STM32端:
c // 在 app_task 中添加调试输出 PythonLink_PrintDebugInfo(); // 打印发送统计

Python端:
python receiver.print_stats() # 打印接收统计

串口监控:
使用串口助手查看原始数据,确认帧格式正确。

性能指标

指标 数值
GPS更新率 10 Hz
IMU更新率 100 Hz
串口波特率 921600 bps
GPS数据包大小 65字节 (含协议开销)
IMU数据包大小 41字节 (含协议开销)
理论带宽占用 ~5 KB/s (远低于115 KB/s理论值)
端到端延迟 < 1ms (解析成功到DMA发送)

扩展性

协议预留了扩展能力:

1. 添加新数据类型

// 在 PythonLink.h 中定义新类型
#define PYTHONLINK_TYPE_SBUS    0x03

// 实现发送函数
HIDO_INT32 PythonLink_SendSBUSData(const ST_SBUSData *_pstSBUS)
{
    // 类似 SendGPSData 的实现
}

2. 双向通信

Python 可发送控制命令到 STM32:

# Python端
def send_control_command(steering, throttle):
    packet = struct.pack('<HH', steering, throttle)
    self.serial.write(packet)
// STM32端
// 在 PythonLink_Poll() 中接收并解析命令
void PythonLink_Poll(void)
{
    // 检查接收缓冲区
    // 解析控制命令
    // 调用 SBUS_Control_PWM() 或其他控制函数
}

注意事项

  1. 字节对齐: 使用 __attribute__((packed)) 确保结构体无填充
  2. 字节序: 所有数据使用小端序 (Little Endian)
  3. 线程安全: 当前实现假设单线程访问,多线程环境需添加互斥锁
  4. 错误处理: Python端应正确处理CRC失败、超时等异常
  5. 波特率限制: 921600 bps 足够当前数据量,若增加数据类型可能需提升

后续优化建议

短期优化

  • [ ] 添加数据包序号,检测丢包
  • [ ] 实现 Python -> STM32 的控制命令发送
  • [ ] 添加时间戳同步机制
  • [ ] 优化 Python 端性能 (使用 asyncio)

中期优化

  • [ ] 支持数据压缩 (可选)
  • [ ] 添加数据加密 (可选)
  • [ ] 实现数据录制和回放功能
  • [ ] 集成到 ROS2 (通过 ROS2 bridge)

长期优化

  • [ ] 迁移到更高速接口 (USB, Ethernet)
  • [ ] 实现多客户端支持
  • [ ] 添加远程固件升级功能

总结

本次实现完成了以下目标:

✅ 设计并实现了高效的 GPS/IMU 数据传输协议
✅ 在 GPS/IMU 解析成功后立即触发数据发送,保证实时性
✅ 使用 UART5 + DMA 方式,确保高效可靠传输
✅ 提供完整的 Python 解析器和使用文档
✅ 为后续电脑控制车辆行走奠定基础

所有代码已经集成到仓库中,可以直接编译使用。