# 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. 触发机制 ```c // 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 接收解析 ```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. 添加新数据类型 ```c // 在 PythonLink.h 中定义新类型 #define PYTHONLINK_TYPE_SBUS 0x03 // 实现发送函数 HIDO_INT32 PythonLink_SendSBUSData(const ST_SBUSData *_pstSBUS) { // 类似 SendGPSData 的实现 } ``` ### 2. 双向通信 Python 可发送控制命令到 STM32: ```python # Python端 def send_control_command(steering, throttle): packet = struct.pack(' STM32 的控制命令发送 - [ ] 添加时间戳同步机制 - [ ] 优化 Python 端性能 (使用 asyncio) ### 中期优化 - [ ] 支持数据压缩 (可选) - [ ] 添加数据加密 (可选) - [ ] 实现数据录制和回放功能 - [ ] 集成到 ROS2 (通过 ROS2 bridge) ### 长期优化 - [ ] 迁移到更高速接口 (USB, Ethernet) - [ ] 实现多客户端支持 - [ ] 添加远程固件升级功能 ## 总结 本次实现完成了以下目标: ✅ 设计并实现了高效的 GPS/IMU 数据传输协议 ✅ 在 GPS/IMU 解析成功后立即触发数据发送,保证实时性 ✅ 使用 UART5 + DMA 方式,确保高效可靠传输 ✅ 提供完整的 Python 解析器和使用文档 ✅ 为后续电脑控制车辆行走奠定基础 所有代码已经集成到仓库中,可以直接编译使用。