本页目录

09-Developer-Guide

Developer Guide

This guide is for developers who want to read RIG-Omni source code, add actions, tune balance, port hardware, or extend interaction tools for RIG-Hover.

Architecture #

RIG-Hover adopts a highly integrated single-chip architecture. All sensing, control, and AI logic run on a single ESP32-S3 — no external co-processor is needed. This approach delivers high performance while reducing component count and simplifying development.

The project provides open-source resources including schematics, 3D models, firmware code and component lists, plus an assembly tutorial. It is well suited for learning motion control, large-language-model integration, multi-modal systems, and IoT communication.

Hardware Abstraction Layer

  • MCU: ESP32-S3-WROOM-1-N16R8 (Dual-core 240 MHz, 2.4G Wi-Fi + BLE 5.0, 16 MB Flash, 8 MB PSRAM)
  • Motion bus (UART): TX/RX serial bus driving 1 head servo (XGO serial protocol) and 2 serial FOC wheel motors, with ID-based addressing and status feedback, enabling differential drive and self-balancing.
  • Vision link (DVP/SPI): GC9A01 240×240 round LCD refreshes expressions over SPI; GC0308 camera captures images via DVP interface.
  • Audio system (I²S): INMP441 MEMS digital microphone for audio input; MAX98357A amplifier drives an 8 Ω 2 W speaker.
  • Attitude sensing (I²C): On-board 6-axis IMU (QMI8658C) for real-time attitude estimation and self-balancing control.

Main controller

ESP32-S3 main controller schematic

Vision link — camera & display

GC0308 camera DVP schematic

GC9A01 round LCD SPI schematic

Audio system — microphone & amplifier

INMP441 MEMS microphone I2S schematic

MAX98357A amplifier schematic

Board Startup

HoverBoardis registered with:

DECLARE_BOARD(HoverBoard);

The constructor performs the main hardware setup:

InitializeSpi()

InitializeLcdDisplay()

InitializeButtons()

InitializeTools()

InitializeCamera()

InitializeUart()

InitializeController()

InitializeBootButton()

imu_init()

create xgo_control task

create xgo_rx task

create imu_read_once task

Core Tasks

Task

Main function

Role

xgo_task

xgo_control()

Updates robot state, computes LQR balance, sends servo and wheel torque commands

xgo_rx_task

xgo_rx()

Parses UART feedback from wheel motors and head servo

imu_task

imu_read_once()

Updates roll, pitch, yaw, and angular velocity

Important Variables

Variable

Meaning

vx

Target forward velocity

vyaw

Target yaw velocity, retained for command compatibility

target_head_pos

Target head servo angle

q_head

Current head angle feedback

wheel1_vel, wheel2_vel

Left/right wheel velocity feedback

wheel1_x, wheel2_x

Left/right accumulated wheel position

wheel_x

Body position estimate

wheek_vx

Average wheel velocity; historical spelling is retained

pitch, roll, yaw

IMU attitude variables

dq

Pitch angular velocity feedback

stable_pos

Balance target position

stable_yaw

Balance target heading

imu_zero

Balance zero-angle offset

robot_state

0 disables torque, 1 enables balance control

lqr_k[4]

LQR feedback gains

Motion Control

The active balance path is LQR-style full-state feedback:

pitch_ref = imu_zero * cosf(q_head * PI / 180.0f);

lqr_x  = wheel_x - stable_pos;

lqr_vx = wheek_vx - vx;

lqr_q  = pitch - pitch_ref;

lqr_dq = dq;



temp_u = -(lqr_k[0] * lqr_x

        + lqr_k[1] * lqr_vx

        + lqr_k[2] * lqr_q

        + lqr_k[3] * lqr_dq);

Yaw is added as differential torque:

yaw_u = k_yaw * (yaw - q_head - stable_yaw);

tor1 = -temp_u + yaw_u;

tor2 =  temp_u + yaw_u;

If robot_state == 0, the wheel torque output must be zero.

MCP Tools

Tool

Parameter

Behavior

self.robot.head_angle

angle: -45..45

Sets target_head_pos

self.robot.move

distance: -20..20

Adds to stable_pos

self.robot.rotate

angle: -180..180

Adds to stable_yaw

Development rules:

  • MCP callbacks should only update target variables.
  • Do not block for long periods inside callbacks.
  • Let the real-time control loop execute the movement.
  • Keep initial ranges conservative.

Web Debug Server

When Wi-Fi is connected, open:

http://<RIG-Hover-IP>/

Interfaces:

GET /api/data

GET /api/set?i=<index>&v=<value>

Use this server only on a trusted LAN. Do not expose it to the public internet.

Extension Patterns

Add a New Action

Prefer a target-based tool:

mcp_server.AddTool("self.robot.set_motion_target",

    "Set RIG-Hover motion target",

    PropertyList({

        Property("distance", kPropertyTypeInteger, -20, 20),

        Property("yaw", kPropertyTypeInteger, -90, 90),

    }),

    [this](const PropertyList& properties) -> ReturnValue {

        stable_pos += properties["distance"].value<int>();

        stable_yaw += properties["yaw"].value<int>();

        return true;

    });

Add a Debug Variable

Modify hover_debug_server.cc:

  • VAR_LABELS
  • set_handler()switch statement
  • /api/datafields if readback is needed

Change Hardware Pins

Modify board_config.h, then verify:

  • UART TX/RX matches motor bus wiring.
  • IMU I2C pins match PCB routing.
  • Camera SCCB/I2C does not conflict with IMU.
  • Touch GPIO is not reused by another peripheral.

Development Safety

  • Keep fall detection enabled.
  • Keep torque cutoff enabled.
  • Never write wheel torque directly from voice or network callbacks.
  • Do not allocate memory or perform network operations inside xgo_control().
  • Avoid high-frequency logging in real-time control paths.
  • Test every hardware change in suspended, hand-held, and free-standing stages.