Skip to content

第 11 章:完整机器人示例

11.1 知识要点

  • 多外设协同初始化的顺序与依赖关系
  • 三任务双核架构的完整实现
  • SBUS 遥控与串口命令的优先级仲裁
  • 串口控制超时安全机制
  • 电池使能 GPIO 的初始化

11.2 课程内容

本章将前 10 章的所有外设整合到一个完整的机器人控制程序中,实现与 OSRCORE 固件相同的三任务架构。系统支持两种控制模式:SBUS 遥控模式(CH7 < 1500)和串口命令模式(CH7 ≥ 1500),遥控模式优先级更高。串口控制设有 500 ms 超时保护,防止通信中断时车辆失控。

11.3 基础学习

三任务架构

Core 1  task_imu     P5  5ms   QMI8658 → Madgwick AHRS → 更新 g_state.quat
Core 1  task_control P4  20ms  编码器 → LPF → PID → ESC/舵机输出
Core 0  task_comm    P3  1ms   SBUS 解码 / USB CDC 命令 / 状态打印

控制模式仲裁

SBUS CH7(index 6)< 1500  → 遥控模式:SBUS CH2 → 速度,CH0 → 转向
SBUS CH7(index 6)≥ 1500  → 串口模式:USB CDC 命令控制
Failsafe 激活              → 强制停止

串口超时安全

串口控制模式下,若 500 ms 内未收到新命令,自动将速度和转向复位到中立位,防止通信中断导致失控。

初始化顺序

1. USB CDC 控制台
2. 电池使能(GPIO16 高电平)
3. NVS Flash 初始化
4. I2C + QMI8658
5. PCNT 编码器
6. LEDC PWM(ESC + 舵机)
7. UART SBUS
8. Madgwick + PID 初始化
9. ESC 解锁(中立位 2 秒)
10. 创建三个任务

11.4 程序学习

全局状态结构体(portMUX 保护):

c
typedef struct {
    float    target_speed;
    uint32_t steering_pulse;
    float    filtered_speed;
    float    quat[4];
    bool     remote_active;
    bool     failsafe;
} app_state_t;

static app_state_t g_state;
static portMUX_TYPE g_mux = portMUX_INITIALIZER_UNLOCKED;

task_comm 中的模式仲裁(核心逻辑):

c
// SBUS 解码后的模式判断
bool remote = (ch[CONTROL_MODE_CH] < 1500);
portENTER_CRITICAL(&g_mux);
g_state.remote_active = remote && !fs;
if (remote && !fs) {
    float vx = ((float)ch[2] - 1024.0f) / 784.0f * 6.0f;
    g_state.target_speed   = vx;
    g_state.steering_pulse = SBUS_TO_US(ch[0]);
}
portEXIT_CRITICAL(&g_mux);

// 串口命令(仅在非遥控模式下生效)
if (!g_state.remote_active) {
    if (sscanf(line, "v %f %f", &v, &s) == 2) {
        g_state.target_speed   = v;
        g_state.steering_pulse = (uint32_t)s;
        last_serial_cmd = esp_timer_get_time();
    }
}

// 串口超时保护(500ms)
if (!g_state.remote_active && last_serial_cmd > 0) {
    if ((esp_timer_get_time() - last_serial_cmd) > 500000) {
        g_state.target_speed   = 0.0f;
        g_state.steering_pulse = 1500;
        last_serial_cmd = 0;
    }
}

app_main 初始化序列:

c
void app_main(void)
{
    // USB CDC
    usb_serial_jtag_driver_install(&usb_cfg);
    esp_vfs_usb_serial_jtag_use_driver();

    // 电池使能
    gpio_set_direction(16, GPIO_MODE_OUTPUT);
    gpio_set_level(16, 1);

    ESP_ERROR_CHECK(nvs_flash_init());

    init_i2c_imu();
    init_encoder();
    init_pwm();
    init_sbus();

    madgwick_init(&g_ahrs, 0.1f);
    pid_init(&g_pid, 447.0f, 4.7f, 47.0f, 1000.0f, 0.05f);

    // ESC 解锁
    set_throttle(1500);
    set_steering(1500);
    vTaskDelay(pdMS_TO_TICKS(2000));

    xTaskCreatePinnedToCore(task_imu,     "imu",     4096, NULL, 5, NULL, 1);
    xTaskCreatePinnedToCore(task_control, "control", 4096, NULL, 4, NULL, 1);
    xTaskCreatePinnedToCore(task_comm,    "comm",    8192, NULL, 3, NULL, 0);
}

11.5 课程总结

本章完成了 OSRCORE 完整机器人控制程序的实现,将 WS2812B、蜂鸣器、ESC、舵机、编码器、IMU、SBUS、NVS 和 FreeRTOS 多任务架构全部整合在一起。三任务双核架构保证了 IMU 采样和 PID 控制的实时性,SBUS/串口双模式控制提供了灵活的操控方式,超时安全机制保障了系统的可靠性。

至此,OSRCORE 开发板教程全部完成。建议按以下路径深入学习:

  • 调整 PID 参数,观察速度响应曲线
  • 在 task_imu 中加入姿态反馈,实现倾斜补偿
  • 扩展 SBUS 通道映射,支持更多遥控功能
  • 使用 ESP-IDF 的 WiFi/BLE 组件,添加无线调试界面

Built for OSRCORE robot development board.