本页目录

二次开发

1. 开发手册

文档摘要:本章节旨在为开发者提供 RIG-Puppy 的底层技术细节,涵盖硬件架构原理、LUWU OS软件框架解析及二次开发指南,帮助您深入理解并扩展机器人的能力。

1.1 系统架构

RIG-Puppy 采用高度集成的单芯片架构,所有感知、控制与 AI 逻辑均由一颗 ESP32-S3 独立完成,无需额外的协处理器。这种设计在保证高性能的同时,极大地降低了硬件成本与开发复杂度。

本项目开源了原理图、3D模型、固件代码及固件,组装教程等,适合用于学习机器人运动控制、大模型、多模态,物联网通信等技术。

1.1.1 硬件抽象层

系统硬件通过标准总线协议与主控通信,实现了模块化解耦:

  • 主控核心:ESP32-S3-WROOM-1-N16R8 (双核 240MHz, 2.4G Wi-Fi + BLE 5.0)

1761199541515-3133feff-08b1-47c3-bc5c-dd5ff96617fd.png

  • 运动总线 (UART):采用 TX/RX 串行总线控制 5 个 EM3 串口舵机,支持 ID 寻址与状态回读,极大简化了布线。

  • 视觉链路 (DVP/SPI):GC0308 摄像头通过 DVP 接口采集图像,1.09 寸 TFT 屏幕通过 SPI 接口实时刷新表情 。

1761199627677-4240928b-d4fe-4e4f-b0cc-386a93a0d926.png1761199609236-47117d25-f55b-4838-99e0-d589c325d800.png

  • 音频系统 (I²S)

    • 输入:INMP441 MEMS 数字麦克风(高灵敏度拾音)。

    • 输出:MAX98357A 功放驱动 8Ω 2W 扬声器 。

  • 1761199572481-b9f00d04-b3ab-4c6b-8b43-d5c3dbc816a6.png1761199572555-d902e69a-add1-4aff-a4dc-2e6850bff3ad.png

  • 姿态感知 (I²C):板载 6 轴 IMU (TDK ICM-42670) 用于实时姿态解算与动态平衡 。

1.1.2 PCB 关键分区

主控板 (Mainboard) 集成了电源管理与信号转接功能,实物图如下:

  • 电源域:集成锂电池充电电路 (Type-C 5V/3A 输入),舵机供电与逻辑供电隔离 。

  • 调试接口:引出 UART0 用于固件烧录与 Log 输出 。

  • 外设拓展:预留 5V/3.3V/GND 接口用于流星灯或其他传感器扩展。

1761199702262-0a93aea9-fadc-478d-86eb-88e38a6a4476.png1761199711180-bfd9fcf4-76b3-40d7-af2f-c1e5a13ceded.png


1.2 软件框架

RIG-Puppy 采用基于ESP32-S3的模块化硬件抽象层,提供标准化的舵机控制接口和外设驱动接口(GC0308摄像头、1.09英寸TFT屏幕、六轴IMU),实现硬件与控制逻辑的深度解耦;创新应用MCP(Model Context Protocol)控制协议,通过结构化指令流和断线重连机制保障硬件控制的实时性与可靠性;五自由度关节设计(增加腰部扭动)配合高精度舵机控制(±1°精度)和协同运动算法,支持点位与轨迹控制;六轴IMU提供精准姿态检测与动态平衡能力,GC0308摄像头实现图像识别与视觉交互,1.09英寸TFT屏幕实时显示状态信息,共同构建流畅自然的机器人动作与稳定可靠的桌面级交互体验。

1.2.1 软件架构图

代码段

graph TD
    User(用户语音/指令) --> LLM(云端大模型)
    LLM -- MCP协议 --> XiaoZhi_Core(小智AI核心)
    XiaoZhi_Core --> Tool_Agent(工具/技能代理)
    
    subgraph "Device Firmware (ESP32-S3)"
        Tool_Agent -->|调用| Motion_Ctrl(运动控制算法)
        Tool_Agent -->|调用| Display_Driver(表情渲染)
        Tool_Agent -->|调用| GPIO_Ctrl(外设控制)
        
        Motion_Ctrl -->|UART| Servos(5路总线舵机)
        Display_Driver -->|SPI| Screen(TFT屏幕)
    end

1.2.2 核心代码解析

1. MCP 动作工具注册

通过 MCP 协议,将机器人的物理动作注册为 LLM 可调用的“工具”。当用户说出自然语言指令(如“打个招呼”)时,大模型会自动匹配并调用对应的函数 ID 。

// 注册 "打招呼" 动作工具
mcp_server.AddTool("self.dog.Wave", "执行打招呼动作", PropertyList(std::vector<Property>{}),
    [this](const PropertyList& properties) -> ReturnValue {
        Action_ID = Wave_ID; // 设置动作状态机ID
        return true;
    });

// 注册 "撒娇" 动作工具
mcp_server.AddTool("self.dog.Naughty", "执行撒娇动作", PropertyList(std::vector<Property>{}),
    [this](const PropertyList& properties) -> ReturnValue {
        Action_ID = Naughty_ID;
        return true;
    });

2. EM3串口舵机控制

void xgo_control() { 
    if(init_flag == 0){
        return;
    }
    static uint32_t counter = 0;
    static uint32_t counter2 = 0;
    static uint8_t read_id = 1;
    counter++; 
    counter2++;
    move();

    for(int i=0;i<5;i++){
        if(motor[i].Load){    
            SetMotorPos(i+1, 0x35, motor[i].DesPos, motor_speed);            
        }
        vTaskDelay(pdMS_TO_TICKS(1));
    }

    if(counter2%10 == 0){
        detect_triple_click();
    }

    if(counter%10 == 0){
        ReadMotorState(read_id);
        counter = 0;
        read_id++;
        if(read_id > 6){
            read_id = 1;
        }
    }
}

3. 机器狗运动控制

void move(){
    float ratio = 0.0;
    float step = 0.0;
    static float pace_t = 0.0;
    int x_index = 0;
    int yaw_index = 2;
    if(pace_t > 2.0*PI){
        pace_t = 0.0;
    }
    pace_t += 0.2;
    step = sqrt(vx*vx+vyaw*vyaw);
            
    if(vx>0){
        x_index = 0;
    }else{
        x_index = 1;
    }

    if(vyaw>0){
        yaw_index = 3;
    }else{
        yaw_index = 2;
    }
    if(Action_ID==0){
        if(abs(vx)>15 || abs(vyaw)>15){
            ratio = abs(vx)/(abs(vx) + abs(vyaw));
            motor[0].DesPos = motor[0].ZeroPos - 700 + (short)(step*cos(pace_t + ratio*l_p[x_index][0] + (1-ratio)*l_p[yaw_index][0])); 
            motor[1].DesPos = motor[1].ZeroPos + 700 + (short)(step*cos(pace_t + ratio*l_p[x_index][1] + (1-ratio)*l_p[yaw_index][1])); 
            motor[2].DesPos = motor[2].ZeroPos - 700 - (short)(step*cos(pace_t + ratio*l_p[x_index][2] + (1-ratio)*l_p[yaw_index][2]));
            motor[3].DesPos = motor[3].ZeroPos + 700 - (short)(step*cos(pace_t + ratio*l_p[x_index][3] + (1-ratio)*l_p[yaw_index][3]));
            motor[4].DesPos = motor[4].ZeroPos + (short)(step*1.5*cos(pace_t + ratio*l_p[x_index][4] + (1-ratio)*l_p[yaw_index][4]));
        }else{
            motor[0].DesPos = motor[0].ZeroPos - 600; 
            motor[1].DesPos = motor[1].ZeroPos + 600; 
            motor[2].DesPos = motor[2].ZeroPos - 600;
            motor[3].DesPos = motor[3].ZeroPos + 600;
            motor[4].DesPos = motor[4].ZeroPos;
        }
    }else{
        xgo_action();
    }    
} 

1.3 资源下载与开发环境

1.3.1 开源仓库

  1. 工具链:推荐使用 ESP-IDF v5.x 或更高版本 。

  2. 编译器:Xtensa-ESP32-S3-ELF。

  3. 调试工具:推荐使用 USB-TTL 串口工具连接主板 UART0 查看 Log。


现在就开始打造属于你的 AI 机器狗吧!
只需一台3D打印机,就能拥有一个会听、会动、有“灵魂”的伙伴。

技术支持:如有深度开发需求,欢迎加入官方开发者微信群

1767280434454-34af4c62-194c-45ad-b07b-2e2645935c6b.jpeg