
小智 ESP32 接入 EDA-Super-Bear 机器熊从分区表配置到 MCP 动作控制全解析【免费下载链接】xiaozhi-esp32An MCP-based chatbot | 一个基于MCP的聊天机器人项目地址: https://gitcode.com/GitHub_Trending/xia/xiaozhi-esp32EDA-Super-Bear机器熊是立创 EDA 课程项目中的双足舵机机器人在本仓库中它作为一块独立的 ESP32-S3 开发板被完整接入 xiaozhi-esp32 语音助手固件通过 MCPModel Context Protocol工具集实现语音指令 → 机器人动作的闭环。本文以该板卡的 README 文档 为骨架结合仓库内的 config.h、eda_super_bear.cc、eda_super_bear_controller.cc 与 eda_super_bear_movements.cc 等源码完整讲解该板卡的硬件引脚、编译分区配置、MCP 工具注册机制与底层步态运动学原理读完即可独立完成烧录与二次开发。一、板卡概览一台能听懂人话的双足机器熊EDA-Super-Bear 是立创 EDA 课程项目Smart Internet 系列的机器熊结构上属于经典的 Otto 类双足机器人两条腿各由大腿leg与脚掌foot两个舵机驱动可选配左右手舵机。在本仓库中它被封装为一块标准的 xiaozhi-esp32 开发板目标芯片为ESP32-S3由 config.json 声明{ manufacturer: lceda-course-examples, type: eda-super-bear, target: esp32s3, builds: [ { name: eda-super-bear, sdkconfig_append: [ CONFIG_PARTITION_TABLE_CUSTOM_FILENAME\partitions/v1/16m.csv\ ] } ] }其板级接入入口在 eda_super_bear.ccEdaSuperBear类继承自WifiBoard通过DECLARE_BOARD(EdaSuperBear)注册到固件框架。它的角色定位很特别无物理显示屏InitializeDisplay()中直接使用NoDisplay开机日志会打印使用NoDisplay (无物理显示屏)语音不经过本机扬声器音频编解码使用NoAudioCodecSimplex麦克风采集的音频照常上传云端但音频输出走云端 TTS 后由用户侧设备播放动作全部交给 MCP 工具构造函数末尾调用InitializeEdaSuperBearController()注册一套完整的self.edarobot.*MCP 工具大模型根据对话语义直接调用这些工具驱动舵机。从源码结构看该板卡的交互界面不是屏幕而是身体语言——机器人通过行走、转身、跳跃、挥手等动作对用户做出反馈。二、硬件引脚配置详解板卡的硬件映射全部集中在 config.h包括 6 路舵机、I2S 音频与按键#define RIGHT_LEG_PIN GPIO_NUM_11 #define RIGHT_FOOT_PIN GPIO_NUM_14 #define LEFT_LEG_PIN GPIO_NUM_13 #define LEFT_FOOT_PIN GPIO_NUM_12 #define LEFT_HAND_PIN GPIO_NUM_21 #define RIGHT_HAND_PIN GPIO_NUM_10 #define AUDIO_INPUT_SAMPLE_RATE 16000 #define AUDIO_OUTPUT_SAMPLE_RATE 24000 #define AUDIO_I2S_METHOD_SIMPLEX #define AUDIO_I2S_MIC_GPIO_WS GPIO_NUM_40 #define AUDIO_I2S_MIC_GPIO_SCK GPIO_NUM_39 #define AUDIO_I2S_MIC_GPIO_DIN GPIO_NUM_41 #define AUDIO_I2S_SPK_GPIO_DOUT GPIO_NUM_47 #define AUDIO_I2S_SPK_GPIO_BCLK GPIO_NUM_48 #define AUDIO_I2S_SPK_GPIO_LRCK GPIO_NUM_45 #define TOUCH_BUTTON_GPIO GPIO_NUM_14 #define BOOT_BUTTON_GPIO GPIO_NUM_38 #define EDA_SUPER_BEAR_VERSION 1.0.0要点说明类别引脚用途舵机GPIO 13 / 11左 / 右大腿leg舵机GPIO 12 / 14左 / 右脚掌foot舵机GPIO 21 / 10左 / 右手hand可选音频输入GPIO 39 / 40 / 41I2S 麦克风 SCK / WS / DIN16 kHz 采样音频输出GPIO 48 / 45 / 47I2S 扬声器 BCLK / LRCK / DOUT24 kHz 采样按键GPIO 38BOOT 键用于配网与对话开关在 eda_super_bear.cc 中BOOT 按键被复用为交互入口设备处于kDeviceStateStarting状态时单击进入 Wi-Fi 配网模式否则单击切换对话状态app.ToggleChatState()。手部舵机是可选项——eda_super_bear_movements.h 中Init()的left_hand/right_hand参数默认值为-1控制器会根据LEFT_HAND_PIN ! -1 RIGHT_HAND_PIN ! -1判断是否启用全部手部动作因此无手版机器熊也能正常编译运行。三、编译配置按模组 Flash 容量选择分区表这是原 README 的核心实操内容Flash 大小需按 ESP32-S3 模组实际容量调整分区表。README 给出的示例是模组 Flash 为 8MB 时在 ESP-IDF 的 menuconfig 中进行如下配置Partition Table --- Partition Table (Custom partition table CSV) --- (partitions/v2/8m.csv) Custom partition CSV file即把分区表指定为仓库根目录下的 partitions/v2/8m.csv。该文件的内容如下# ESP-IDF Partition Table # Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, 0x9000, 0x4000, otadata, data, ota, 0xd000, 0x2000, phy_init, data, phy, 0xf000, 0x1000, ota_0, app, ota_0, 0x20000, 0x2f0000, ota_1, app, ota_1, , 0x2f0000, assets, data, spiffs, 0x600000, 2M它采用双 OTA 分区ota_0/ota_1各约 3MB并预留 2MB 的assetsSPIFFS 分区存放语音提示等资源。这里需要留意两处细节默认值与 README 示例的差异仓库的 config.json 在sdkconfig_append中默认写入的是partitions/v1/16m.csv面向 16MB 模组。因此如果手头模组 Flash 不足 16MB例如 8MB 的常见 ESP32-S3 模组就必须按 README 的指引通过 menuconfig 手工切换分区表否则固件烧录或 OTA 会出现空间不足问题。分区表可选范围仓库在 partitions/v2 目录下提供4m.csv、8m.csv、16m.csv、32m.csv以及 ESP32-C3 专用的16m_c3.csv在 v1 目录下还保留了4m.csv、8m.csv、16m.csv、32m.csv及带自定义唤醒词/回声消除16m_custom_wakeword.csv、16m_echoear.csv的变体可按模组实际 Flash 容量与功能需求选择。编译时main/CMakeLists.txt 中通过CONFIG_BOARD_TYPE_EDA_SUPER_BEAR将BOARD_DIR指向lceda-course-examples/eda-super-bear固件构建系统据此自动纳入该板卡的源码与配置。四、MCP 工具集大模型如何指挥机器熊EDA-Super-Bear 接入的核心亮点是MCP 工具注册机制。控制器 eda_super_bear_controller.cc 在构造时调用RegisterMcpTools()通过McpServer::GetInstance().AddTool(...)向 MCP Server 注册 17 个动作枚举与 10 余个工具云端大模型LLM在对话中按需调用这些工具实现说一句话机器人动一下。4.1 动作分类与 MCP 工具清单动作在内部以枚举ActionType编号1~17控制器通过 FreeRTOS 队列容量 10 条串行投递执行避免多个动作互相抢占舵机枚举编号MCP 工具关键参数默认值/范围说明ACTION_WALK1self.edarobot.walk_forwardsteps3(1-100), speed1000(500-1500), arm_swing50(0-170), direction1(-1后退/1前进)前进/后退行走ACTION_TURN2self.edarobot.turn_leftsteps3, speed1000, arm_swing50, direction1(1左转/-1右转)原地转身ACTION_JUMP3self.edarobot.jumpsteps1(1-100), speed1000跳跃ACTION_SWING4self.edarobot.swingsteps3, speed1000, amount30(0-170)左右摇摆ACTION_MOONWALK5self.edarobot.moonwalksteps3, speed1000, direction1, amount25太空步ACTION_BEND6self.edarobot.bendsteps1, speed1000, direction1左右侧弯ACTION_SHAKE_LEG7self.edarobot.shake_legsteps1, speed1000, direction1(1左腿/-1右腿)摇腿ACTION_UPDOWN8self.edarobot.updownsteps3, speed1000, amount20上下起伏ACTION_TIPTOE_SWING9无独立工具由控制器内部可达steps, speed, amount踮脚摇摆ACTION_JITTER10无独立工具steps, speed, amount抖动ACTION_ASCENDING_TURN11无独立工具steps, speed, amount上升转身ACTION_CRUSAITO12无独立工具steps, speed, amount, direction太空步行走混合ACTION_FLAPPING13无独立工具steps, speed, amount, direction扑翼动作ACTION_HANDS_UP14self.edarobot.hands_upspeed1000, direction1(1左手/-1右手/0双手)举手ACTION_HANDS_DOWN15self.edarobot.hands_downspeed1000, direction1放手ACTION_HAND_WAVE16self.edarobot.hand_wavespeed1000, direction1挥手ACTION_HOME17复位stop 工具内部调用direction1回到站立姿态注部分动作枚举如 TiptoeSwing、Jitter、AscendingTurn、Crusaito、Flapping已具备底层运动函数但当前仅注册了面向对话的常用工具子集开发者可在RegisterMcpTools()中按同样模式补充暴露。手部动作14~16仅在has_hands_为真时注册无手版调用会被QueueAction()拦截并打印尝试执行手部动作但机器人没有配置手部舵机。速度参数的语义需要特别注意数值越小动作越快500 最快、1500 最慢因为它直接对应EdaRobot运动函数中的period周期单位毫秒。4.2 工具参数描述如何喂给大模型AddTool的参数描述是 MCP 与 LLM 交互的关键。以 walk_forward 为例工具描述字符串完整给出了每个参数的语义与范围mcp_server.AddTool(self.edarobot.walk_forward, 行走。steps: 行走步数(1-100); speed: 行走速度(500-1500数值越小越快); direction: 行走方向(-1后退, 1前进); arm_swing: 手臂摆动幅度(0-170度), PropertyList({Property(steps, kPropertyTypeInteger, 3, 1, 100), Property(speed, kPropertyTypeInteger, 1000, 500, 1500), Property(arm_swing, kPropertyTypeInteger, 50, 0, 170), Property(direction, kPropertyTypeInteger, 1, -1, 1)}), this - ReturnValue { ... });Property的五个参数依次为名称、类型kPropertyTypeInteger/kPropertyTypeString、默认值、最小值、最大值。这样大模型既能看到自然语言说明又能拿到结构化的数值约束从而生成合法调用。4.3 状态查询与电池工具除运动工具外控制器还注册了 4 个系统级工具self.edarobot.stop立即停止——删除动作任务、清空队列并回到站立姿态self.edarobot.set_trim校准单个舵机见下文第五节self.edarobot.get_trims查询全部舵机微调值self.edarobot.get_status返回moving或idleself.battery.get_level通过Board::GetInstance().GetBatteryLevel()返回{level:xx,charging:true/false}。动作执行的底层是ActionTask任务栈 3KB、优先级configMAX_PRIORITIES - 1循环从队列取参数先AttachServos()挂载舵机按switch(action_type)分派到EdaRobot的运动函数除ACTION_HOME外每个动作结束后自动调用Home()复位保证机器人始终回到稳定站姿。五、运动学底层Oscillator 正弦振荡器与步态合成机器熊的舞步并非逐帧硬编码而是建立在正弦振荡器模型之上这一思路源自 Otto 系列机器人oscillator.h 标注了 Obijuan 2011 的原始实现与 txp666 的 ESP32 移植。5.1 振荡器模型每个舵机由一个Oscillator实例驱动其输出角度由四个参数决定Aamplitude振幅单位度Ooffset偏移单位度Tperiod周期单位毫秒Phphase0初始相位单位弧度DEG2RAD宏转换。EdaRobot::OscillateServos()将每个舵机的 A/O/T/Ph 设置好后在period * cycle时间内每 5ms 调用一次servo_[i].Refresh()刷新所有舵机角度。Execute()则按steps拆分为整数个完整周期加一个尾周期执行。舵机角度输出还经过两个保护机制见 oscillator.hPWM 脉宽限制在 500~2500 微秒对应 -90°~90°以及默认 240°/秒 的角速度限制器SERVO_LIMIT_DEFAULT防止舵机瞬间大幅跳变损坏齿轮。5.2 步态即相位差组合以最常用的Walk为例eda_super_bear_movements.cc腿部四个舵机的振荡参数为int A[SERVO_COUNT] {30, 30, 30, 30, 0, 0}; // 大腿、脚掌振幅 30° int O[SERVO_COUNT] {0, 0, 5, -5, ...}; // 脚掌轻微偏置模拟踮脚 double phase_diff[SERVO_COUNT] {0, 0, DEG2RAD(dir * -90), DEG2RAD(dir * -90), 0, 0};行走的关键在于大腿与脚掌相位差 90°——dir1时脚掌相位为 -90°dir-1时变为 90°从而决定前进还是后退。转向Turn则把一侧大腿振幅置 0、另一侧置 30°利用左右步幅差走出弧线。手部摆动arm_swing 0且装有手部舵机时也遵循真实步态的相位关系行走时左手与右腿同相、右手与左腿同相交叉摆臂转向时左手与左腿同相、右手与右腿同相增强转向效果。类似地Moonwalker太空步利用两脚 60° 相位差形成蠕虫式行波Jitter让双腿 180° 反相抖动AscendingTurn叠加腿脚同幅反相实现边升边转——每个动作本质上都是(振幅, 偏移, 周期, 相位差)四元组的组合理解这一点后开发者可以轻松在EdaRobot中组合出新动作。六、舵机姿态校准set_trim 与 NVS 持久化机器熊使用廉价舵机装配误差会导致站姿歪斜因此控制器提供了基于 MCP 的在线校准能力。校准值存储在 NVS 命名空间edarobot_trims中通过项目封装的 Settings 读写LoadTrimsFromNVS()在启动时加载并调用edarobot_.SetTrims(...)生效。校准流程全部通过语音对话完成让大模型调用self.edarobot.get_trims查看当前微调值返回 JSON如{left_leg:0,...,right_hand:0}调用self.edarobot.set_trim指定servo_typeleft_leg/right_leg/left_foot/right_foot/left_hand/right_hand和trim_value-50~50 度工具内部更新对应微调值、写入 NVS 永久保存并以一次跳跃ACTION_JUMP作为动作反馈同时返回类似舵机 left_leg 微调设置为 5 度已永久保存的文本供大模型向用户播报。实现细节上SetTrims只对手部舵机存在时has_hands_应用手部微调若对无手版调用left_hand/right_hand校准会返回错误机器人没有配置手部舵机。舵机 0°~180° 的脉宽映射、微调叠加都在 oscillator.cc 的AngleToCompare与SetTrim中完成。七、总结EDA-Super-Bear 板卡展示了 xiaozhi-esp32 框架的万能外设扩展思路一个没有屏幕、甚至不需要本机发声的双足机器人通过继承WifiBoard 注册 MCP 工具即可无缝接入语音对话链路让大模型直接操控硬件。三个层面的知识可以沉淀复用接入层面仿照 eda_super_bear.cc 继承WifiBoard并DECLARE_BOARD在 main/CMakeLists.txt 增加CONFIG_BOARD_TYPE_*分支编译层面务必按模组 Flash 容量在 menuconfig 中切换分区表默认 16MB8MB 模组用 partitions/v2/8m.csv控制层面复用RegisterMcpTools()的AddTool模式为任意外设注册工具底层动作复用EdaRobotOscillator的正弦步态引擎配合set_trim在线校准即可快速完成整机联调。【免费下载链接】xiaozhi-esp32An MCP-based chatbot | 一个基于MCP的聊天机器人项目地址: https://gitcode.com/GitHub_Trending/xia/xiaozhi-esp32创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考