Skip to content

Chapter 11: Complete Robot Example

11.1 Key Points

  • Integrating all previous peripherals into one project
  • Multi-task architecture on ESP32-S3
  • SBUS remote control and serial debug control
  • Encoder feedback, PID control, ESC output, servo output, and IMU telemetry
  • Safety behavior when failsafe or signal loss occurs

11.2 Course Content

The full example combines the previous chapters into a complete robot application. Instead of testing one peripheral at a time, the firmware runs multiple tasks and coordinates input, control, and output.

11.3 Basic Learning

System Architecture

text
SBUS receiver  ─┐
Serial command ─┼─> command state ─> control task ─> ESC / servo PWM
Encoder feedback ────────────────┘
IMU task ─────────────────────────> telemetry / attitude state

Task Responsibilities

TaskResponsibility
SBUS taskDecode remote-control frames and failsafe state
Control taskRead target command, read encoder speed, run PID, output PWM
IMU taskRead QMI8658 and run AHRS update
Telemetry taskPrint status over USB CDC

Safety Rules

A robot control program should always have safe fallback behavior:

  • If SBUS failsafe is active, set throttle to neutral.
  • If no command is received for a timeout period, stop the motor.
  • If encoder feedback is invalid, limit or disable closed-loop output.
  • Keep servo and ESC outputs within safe pulse limits.

11.4 Program Study

A simplified main initialization flow:

c
void app_main(void)
{
    board_io_init();
    nvs_params_load(&params);
    led_init();
    buzzer_init();
    pwm_init();
    sbus_init();
    encoder_init();
    imu_init();

    xTaskCreatePinnedToCore(sbus_task, "sbus", 4096, NULL, 5, NULL, 0);
    xTaskCreatePinnedToCore(control_task, "ctrl", 4096, NULL, 6, NULL, 1);
    xTaskCreatePinnedToCore(imu_task, "imu", 4096, NULL, 4, NULL, 0);
    xTaskCreatePinnedToCore(telemetry_task, "tele", 4096, NULL, 3, NULL, 0);
}

A simplified control loop:

c
while (1) {
    command_t cmd = command_get_latest();
    float speed = encoder_get_speed_mps();

    if (cmd.failsafe) {
        set_pulse(CH_THROTTLE, 1500);
        set_pulse(CH_STEERING, 1500);
    } else {
        float out = pid_update(&pid, cmd.target_speed, speed, CONTROL_DT);
        uint32_t throttle = clamp_pwm(1500 + (int32_t)out);
        uint32_t steering = clamp_pwm(cmd.steering_us);
        set_pulse(CH_THROTTLE, throttle);
        set_pulse(CH_STEERING, steering);
    }

    vTaskDelay(pdMS_TO_TICKS(10));
}

11.5 Summary

This final chapter integrates LED, buzzer, SBUS, I2C IMU, encoder, NVS, FreeRTOS, PID, AHRS, and PWM output into a complete OSRCORE robot firmware architecture. The project can be used as a base for further robot applications such as autonomous driving, telemetry streaming, and higher-level navigation.

Built for OSRCORE robot development board.