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 stateTask Responsibilities
| Task | Responsibility |
|---|---|
| SBUS task | Decode remote-control frames and failsafe state |
| Control task | Read target command, read encoder speed, run PID, output PWM |
| IMU task | Read QMI8658 and run AHRS update |
| Telemetry task | Print 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(¶ms);
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.