Skip to content

Cust17 智能小车技术文档

1. 项目概述

本项目是基于 ESP32-S3 的麦克纳姆轮智能小车项目。采用 PlatformIO (Arduino 框架) 开发,支持蓝牙手柄控制、MQTT 远程控制、网页遥控和 TTL 串口通信等多种控制方式,具备 PID 闭环速度控制、姿态感知、OTA 固件升级等功能。

项目定位: 四轮全向移动底盘,适用于机器人教育、ROS 底层平台、远程监控等场景。


2. 硬件平台

硬件差异说明: 项目支持 V3 和 V5 两代小车,电机参数不同(见 Head.h)。开发文档中的默认值为 V3 车参数,使用 V5 车需切换注释并测量实际轮距轴距。

组件 说明
主控芯片 ESP32-S3 (ESP32-S3-DevKitC-1)
电机驱动 QGPMaker EmotionPI 驱动板 (MCPWM 控制)
电机 4路直流减速编码器电机 (1:90 减速比 / 1:50 减速比)
编码器 霍尔编码器,48 线/圈 (经倍频后每圈 48×4 = 192 脉冲)
轮系 麦克纳姆轮/普通橡胶轮 (可切换)
IMU MPU6050 六轴陀螺仪+加速度计
磁力计 QMC5883L 三轴电子罗盘
显示 SSD1306 OLED 128×64 (I2C)
LED WS2812B 单灯珠
舵机 4路舵机接口
供电 24V 锂电池 (带分压 ADC 采样)

2.1 引脚定义

编码器引脚(可配置,默认):

通道 A 相 B 相
电机 1 42 41
电机 2 39 40
电机 3 4 18
电机 4 48 38

电机 PWM 引脚:

通道 PWM A PWM B
电机 1 3 10
电机 2 11 12
电机 3 14 13
电机 4 47 21

舵机引脚: 5, 6, 7, 15

其他引脚: - LED: GPIO 46 - 电池 ADC: GPIO 2 - 串口 1: RX=15, TX=16


3. 软件架构

src/
├── main.cpp          # 主程序:初始化和主循环
├── main.h            # 主头文件:声明和全局变量
└── html/             # 网页遥控器前端
    ├── joy.html      # 网页遥控器界面
    ├── main.js       # MQTT 通信和摇杆逻辑
    └── style.css     # 样式表

lib/
├── Head/
│   ├── Head.h        # 硬件参数配置和数据结构
│   └── utils.h       # 工具函数:WiFi、OTA、电池、IMU初始化等
├── Config/
│   ├── ConfigSeting.h  # 配置管理类声明
│   └── ConfigSeting.cpp # NVS 配置读写实现
├── motor/
│   ├── EMotionPI.h   # 电机驱动库 (QGPMaker)
│   └── EMotionPI.cpp # 直流电机、编码器电机、舵机、底盘控制
├── encoder/
│   ├── Encoder.h     # 编码器封装类
│   └── Encoder.cpp   # RPM 计算实现
├── Pid/
│   └── pid.h         # PID 控制器实现 (全头文件)
├── protocal/
│   └── protocol.h    # 串口通信协议 (全头文件)
├── ControlStick/
│   ├── BLEControlStick.h/cpp  # BLE 蓝牙手柄
│   ├── StickCB.h/cpp          # 手柄回调处理
│   ├── BLEControlStick.h/cpp  # BLE 手柄接入
├── MqttServer/
│   ├── MqttServer.h/cpp  # MQTT 远程控制
├── OTA/
│   ├── OTAupdate.h/cpp   # 远程固件升级
├── display/
│   ├── Display.h/cpp     # OLED 显示
├── kinematics/
│   ├── kinematics.h/cpp  # 运动学解算
├── mpu6050/
│   ├── Imu.h/cpp         # MPU6050 封装
│   └── MPU6050_*.h/cpp   # MPU6050 库
└── QMC5883LCompass/
    └── QMC5883LCompass.h/cpp  # 磁力计库

4. 模块详解

4.1 主控流程 (main.cpp)

初始化顺序 (setup):

  1. 串口初始化 (Serial + Serial1)
  2. 从 NVS 读取配置 (编码器引脚、速度参数)
  3. 初始化编码器 (4路)
  4. 初始化 BLE 蓝牙手柄
  5. 初始化 QMC5883L 磁力计 + MPU6050 陀螺仪
  6. 连接 WiFi、初始化 WS2812 LED
  7. 初始化 PID 控制器
  8. 初始化 MQTT 服务
  9. 创建 FreeRTOS 任务 xCore_task (运行在 Core 0)

主循环 (loop):

  • 心跳 20ms:处理 MQTT 消息
  • 停车检测:超过 200ms 无命令自动停车
  • TTL 串口数据收发:解析控制协议

Core 0 任务 (xCore_task):

  • 更新 BLE 手柄状态
  • 编码器引脚自动测试(按住 START 键触发)
  • 姿态数据上报(每 100ms):电压、角度、四轮 RPM → 线速度/角速度 → CRC 打包 → Serial1 发送
  • 电压补偿:低于 24V 标准电压时自动降低最大 RPM

4.2 控制模式

4.2.1 蓝牙手柄控制

通过 BLE 连接标准游戏手柄(服务 UUID: 1812,特征值 UUID: 2A4D)。

手柄按键映射:

按键 功能
左摇杆 前后/横移 (速度按幅度比例)
右摇杆 (左右) 旋转 (麦轮模式) / 舵机 (普通模式)
方向键 ↑↓ 前后
方向键 ←→ 横移 (麦轮) / 旋转 (普通)
L1/R1 降低/提高最大速度上限
L2/R2 降低/提高最低起步速度
SELECT 切换车型:麦轮模式(蓝灯) / 普通模式(红灯)
START 进入编码器自动测试模式
A/B/X/Y 预留功能键
右摇杆 (上下) 舵机角度控制

4.2.2 串口协议控制 (TTL)

通过 Serial1 (波特率 115200) 与上位机通信。协议详见第 5 节。

4.2.3 MQTT 远程控制

通过 MqttServer 模块连接远端 MQTT 服务器(121.40.244.99:1883),订阅 evtopic/wfjy/{clientId} 主题,接收 JSON 格式的控制指令。

4.2.4 网页遥控器

前端项目位于 src/html/,提供: - 双摇杆控制(锁定/自由模式可切换) - 方向键 + A/B/X/Y 按钮 - MQTT 直连通信(WebSocket) - 通讯标识可配置(Cookie 存储)

4.3 运动学

4.3.1 麦克纳姆轮逆解

wheelDelta = z_rpm × (轮距 + 轴距) / 轮周长

轮1 (左前) = x_rpm + y_rpm + wheelDelta
轮2 (右后) = x_rpm - y_rpm - wheelDelta
轮3 (左后) = x_rpm - y_rpm + wheelDelta
轮4 (右前) = x_rpm + y_rpm - wheelDelta

4.3.2 PID 闭环控制

每个电机独立 PID 控制器:

参数
Kp 0.25
Ki 0.02
Kd 0.5
输出范围 -100 ~ 100

特性: - 积分限幅 ±10 - 死区补偿(PWM < deadPwm 时直接设为 deadPwm) - 满负荷检测:连续 10 次输出达 ±100 时自动降低速度因子(每次 -0.1,最低 50%)

4.4 姿态感知

融合算法:互补滤波

fusion = 0.7 × 编码器角速度 + 0.3 × IMU 角速度
  • 编码器角速度:通过四轮差速公式计算
  • IMU 角速度:MPU6050 DMP 输出的角度差/时间 (100ms)
  • 最终输出经低通滤波平滑 (last × 0.3 + current × 0.7)

4.5 编码器测试

按住手柄 START 键进入自动测试模式: 1. 4 个电机同向低速旋转 2. 检测编码器计数值变化方向 3. 若计数为负(接线反),自动交换 A/B 相并保存配置 4. 重启生效

4.6 配置管理 (NVS)

使用 ESP32 NVS (Preferences) 存储:

配置项 说明
model 0=麦轮, 1=普通
max_speed 最大速度百分比 (0-100)
min_speed 最低起步速度百分比 (0-100)
E1_a~E4_b 编码器引脚定义
wifi_ssid/pwd WiFi 凭据
mqtt_cid MQTT 客户端 ID

默认配置存储为 JSON 字符串,键为 wifi_ssid,命名空间 mynamespace


5. 通信协议

注意: 所有多字节字段(数据长度、数据体、CRC)均采用小端序(Little Endian),低字节在前。

5.1 数据包格式

帧头(2B) + 数据长度(2B) + 设备ID(1B) + 命令字(1B) + 数据体(NB) + CRC16(2B)
偏移 大小 说明
0 1 帧头1: 0xAA
1 1 帧头2: 0x55
2 2 数据长度 (设备ID+命令+数据体) 小端
4 1 设备 ID
5 1 命令字
6 N 数据体 (小端)
6+N 2 CRC16 (Modbus) 小端

5.2 命令定义

命令 方向 说明
CMD_pwmDrive 0x0A 上位机→小车 PWM 速度控制
CMD_rosDrive 0x0B 上位机→小车 三轴速度控制 (mm/s)
CMD_rotation 0x0C 上位机→小车 旋转控制
CMD_pose 0x30 小车→上位机 姿态数据上报

5.3 控制命令数据体

CMD_pwmDrive (0x0A) - PWM 百分比控制:

偏移 类型 说明
0-1 int16 LE X 轴速度 (-100~100)
2-3 int16 LE Y 轴速度 (-100~100)
4-5 int16 LE Z 轴旋转速度 (-100~100)

内部转换:targetRPM = speed × maxRpm × 0.01

CMD_rosDrive (0x0B) - 物理速度控制:

偏移 类型 说明
0-1 int16 LE X 轴线速度 (mm/s)
2-3 int16 LE Y 轴线速度 (mm/s)
4-5 int16 LE Z 轴角速度 (deg/s)

内部转换:线速度 → RPM,角速度 → 差速 RPM

5.4 姿态上报数据体 (CMD_pose 0x30)

小车每 100ms 自动向串口发送:

偏移 类型 说明
0-1 int16 LE 电池电压 (×0.1V)
2-3 int16 LE Z 轴角度 (0~359°)
4-5 int16 LE X 轴线速度 (mm/s)
6-7 int16 LE Y 轴线速度 (mm/s)
8-9 int16 LE Z 轴角速度 (deg/s, 融合值)

5.5 CRC16 算法 (Modbus)

多项式: 0xA001
初始值: 0xFFFF
计算范围: 帧头 + 长度 + 设备ID + 命令 + 数据体

6. 使用指南

6.1 开发环境搭建

  1. 安装 VS Code + PlatformIO 扩展
  2. 打开 cust17/ 目录
  3. PlatformIO 将自动安装依赖库
  4. 编译上传:PlatformIO: Upload

6.2 项目配置

platformio.ini 关键配置:

[env:esp32dev]
platform = espressif32
board = esp32-s3-devkitc-1
framework = arduino
monitor_speed = 115200

依赖库:

用途
NimBLE-Arduino BLE 蓝牙
ArduinoJson JSON 解析
ESP32Servo 舵机控制
ESP32Encoder 编码器计数
PubSubClient MQTT 客户端
ESPAsyncWebServer-esphome 异步 Web 服务器
FastLED WS2812 LED

6.3 硬件参数校准

Head.h 中的以下参数必须根据实际车体测量调整:

参数 说明 默认值 测量方法
maxRpm 电机理论最大转速 (RPM) 110 (1:90减速) / 120 (1:50减速) 查电机规格书
gear 减速器齿数比 90 / 50 减速器标识
encoderTicksPerRevolution 编码器每圈线数 48 编码器规格书
deadPwm 电机启动最小 PWM 40 / 30 实测:逐渐增大PWM至轮子刚好转动
wheelCircumference 轮子周长 (mm) π × 80 / π × 127 实测:轮子转一圈前进距离
wheelSpacing 轮距 (mm) 220 左右轮中心距
wheelBase 轴距 (mm) 200 前后轮中心距

⚠️ 务必根据实际车体测量上述参数,否则会导致速度控制不准、旋转偏移等问题。

6.4 首次使用

  1. 编译并上传固件至 ESP32-S3
  2. 上电后 OLED 显示"奇果派"启动画面
  3. 蓝牙手柄搜索并连接 (服务名 BLE-ControlStick)
  4. 手柄 SELECT 键切换车型模式
  5. 摇杆控制车辆移动

6.5 速度参数调优

  • 手柄实时调节: L1/R1 调最大速度,L2/R2 调起步速度
  • 代码修改: 硬件物理参数见 Head.h(详见 6.3 节),PID 参数见 pid.h
  • PID 调节: pid.hsetupPID() 函数的 Kp/Ki/Kd

7. 注意事项

  1. 电压补偿: 电池电压低于 24V 时自动降速,每降低 1V 最大转速降低 10%
  2. 过载保护: PID 输出持续满负荷时自动降低速度因子,防止电机过热
  3. 停车安全: 200ms 无控制命令自动停止
  4. 编码器接线: 首次使用建议按住 START 键运行编码器自检
  5. 通信冲突: 蓝牙手柄命令和 TTL 串口命令间隔需大于 500ms

8. 版本历史

版本 日期 说明
1.0 - 初始版本

文档生成日期:2026年6月