
EDA-SuperBear机器熊
简介
基于ESP32S3打造的小智LLM大模型机器熊,通过LLM完成六舵机控制
简介:基于ESP32S3打造的小智LLM大模型机器熊,通过LLM完成六舵机控制开源协议
:GPL 3.0
描述
本项目使用 ESP32S3R8N16 模组,结合 INMP441 + MAX98357 实现小智AI对话及MCP协议控制机器熊运动。
本项目大部分均为插件,适合新手及教学使用。
固件功能
项目参数
硬件设计
主控选用 ESP32S3系列 模组,集成 WiFi 功能,提供丰富的 GPIO 接口。 板载 USB 转串口芯片,方便程序下载和调试。
本系统使用 INMP441 数字麦克风模块进行音频采集,结构简单,可根据需求替换为更低成本型号。
音频输出部分采用 MAX98357 模块,支持I2S音频输入,驱动扬声器输出。设计简单,性能稳定。
电源供电电路与 EDA-Robot 标准版一致,采用两节串联 18650 电池,串联后满电电压 8.4V, 通过两路 LDO 分别降压至 5V 为舵机供电和 3.3V 为 MCU 供电。
舵机电路与标准版一致,采用 SG90/MG90 舵机,通过 PWM 信号控制角度。 由于舵机内部自带 5V 转 3.3V 驱动电路,PWM 信号可直接由 MCU IO 控制,无需电平转换。
按键电路与下载接口设计简洁,均可直接连接 MCU IO。由于 MCU 资源充足,可轻松扩展更多功能。
软件开发
完整源码请在附件查看
本项目借助以下开源仓库otto板级配置文件源码修改:
依照xiaozhi-esp32主线开源协议,本项目软件源码遵循原作者MIT协议开源
本项目采用 BSP(Board Support Package)板级适配架构,基于 xiaozhi-esp32 框架, 专门为EDA-Super Bear硬件平台定制,实现了AI语音控制的六关节机器熊功能。
- eda_super_bear.cc: 主板支持包,硬件抽象层实现
- eda_super_bear_controller.cc: 机器熊MCP控制器,实现动作队列和工具注册
- eda_super_bear_movements_clean.cc: 步态运动算法实现
- eda_super_bear_movements.h: 步态运动类定义和接口声明
- oscillator.cc / .h: 舵机振荡器实现,提供平滑运动控制
- config.h: 硬件引脚定义和系统参数配置
- config.json: ESP-IDF构建配置,定义目标平台和编译选项
eda_super_bear.cc
硬件抽象层,负责硬件初始化和设备管理,包括音频编解码器、按键控制及机器人控制器。
class EdaRobotMax : public WifiBoard {
private:
Display* display_; // 显示屏实例
Button boot_button_; // Boot按键
Button touch_button_; // 触摸按键
void InitializeButtons(); // 初始化按键
void InitializeEdaSuperBearController(); // 初始化机器人控制器
public:
virtual AudioCodec* GetAudioCodec() override; // 获取音频编解码器
virtual Display* GetDisplay() override; // 获取显示屏
};
eda_super_bear_controller.cc
机器人动作控制模块,实现各种运动模式和动作序列,包括行走、转向、跳跃、摇摆等基本动作和手部动作。
class EdaRobotMaxController {
private:
EdaRobot edarobot_; // 动作执行器
QueueHandle_t action_queue_; // 动作队列
TaskHandle_t action_task_handle_; // 后台任务句柄
bool is_action_in_progress_; // 动作执行状态
bool has_hands_; // 是否有手部舵机
public:
void RegisterMcpTools(); // 注册MCP工具
void QueueAction(int type, int steps, int speed, int dir, int amount);
static void ActionTask(void* arg); // 后台动作执行任务
void LoadTrimsFromNVS(); // 加载舵机微调值
};
eda_super_bear_movements.cc
双足机器人动作库,实现基于振荡器的平滑运动控制,支持行走、跳跃、摇摆、太空步等丰富动作。
class EdaRobot {
private:
Oscillator servo_[6]; // 6个舵机振荡器
int servo_pins_[6]; // 舵机引脚映射
int servo_trim_[6]; // 舵机微调值
bool has_hands_; // 是否有手部舵机
bool is_edarobot_resting_; // 休息状态
public:
void Init(int ll, int rl, int lf, int rf, int lh, int rh);
void Home(bool hands_down); // 复位到初始姿态
void SetTrims(int ll, int rl, int lf, int rf, int lh, int rh);
// 基础移动
void Walk(float steps, int period, int dir, int amount);
void Turn(float steps, int period, int dir, int amount);
void Jump(float steps, int period);
// 特殊动作
void Swing(float steps, int period, int height);
void Moonwalker(float steps, int period, int height, int dir);
void Bend(int steps, int period, int dir);
void ShakeLeg(int steps, int period, int dir);
void UpDown(float steps, int period, int height);
// 手部动作
void HandsUp(int period, int dir);
void HandsDown(int period, int dir);
void HandWave(int period, int dir);
};
oscillator.h
舵机振荡控制器,提供基于正弦波的平滑舵机运动控制,实现各种动作的精确执行。
class Oscillator {
private:
unsigned int amplitude_; // 振幅(度)
int offset_; // 偏移量(度)
unsigned int period_; // 周期(毫秒)
double phase0_; // 初始相位(弧度)
int trim_; // 微调值(校准)
double phase_; // 当前相位
int pos_; // 当前位置
bool stop_; // 停止标志
public:
void SetA(unsigned int amplitude); // 设置振幅
void SetO(int offset); // 设置偏移
void SetPh(double Ph); // 设置相位
void SetT(unsigned int period); // 设置周期
void SetTrim(int trim); // 设置微调
void Refresh(); // 刷新位置
int GetPosition(); // 获取位置
};
config.json
项目构建配置文件,定义目标平台、分区表和编译选项。
{
"target": "esp32s3",
"builds": [{
"name": "eda-super-bear",
"sdkconfig_append": [
"CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v1/16m.csv\""
]
}]
}
实现原理
硬件抽象层架构
基于 xiaozhi-esp32 框架的 BSP 架构,实现硬件抽象层,统一管理音频编解码器、按键控制等外设。
class EdaRobotMax : public WifiBoard {
private:
Display* display_ = nullptr;
Button boot_button_;
Button touch_button_;
void InitializeButtons() {
// Boot按键:切换聊天状态 / 重置WiFi
boot_button_.OnClick([this]() {
auto& app = Application::GetInstance();
if (app.GetDeviceState() == kDeviceStateStarting &&
!WifiStation::GetInstance().IsConnected()) {
ResetWifiConfiguration();
}
app.ToggleChatState();
});
// 触摸按键:按下录音,松开停止
touch_button_.OnPressDown([this]() {
Application::GetInstance().StartListening();
});
touch_button_.OnPressUp([this]() {
Application::GetInstance().StopListening();
});
}
public:
virtual AudioCodec* GetAudioCodec() override {
static NoAudioCodecSimplex audio_codec(
AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE,
AUDIO_I2S_SPK_GPIO_BCLK, AUDIO_I2S_SPK_GPIO_LRCK,
AUDIO_I2S_SPK_GPIO_DOUT, AUDIO_I2S_MIC_GPIO_SCK,
AUDIO_I2S_MIC_GPIO_WS, AUDIO_I2S_MIC_GPIO_DIN);
return &audio_codec;
}
};
舵机振荡控制系统
基于 LEDC PWM 的舵机控制器,通过正弦波振荡实现平滑的舵机运动,支持幅度、偏移、相位和周期控制。
bool Oscillator::NextSample() {
phase_ += inc_; // 相位递增
if (phase_ >= 2 * M_PI) {
phase_ -= 2 * M_PI;
return true; // 完成一个周期
}
// 正弦波位置计算
// position = amplitude * sin(phase + phase0) + offset + trim
int pos = round(amplitude_ * sin(phase_ + phase0_) + offset_ + trim_);
Write(pos); // 写入舵机
return false;
}
void Oscillator::Write(int position) {
// 限制角度范围 -90° 到 +90°
int angle = std::min(std::max(position, -90), 90);
// 转换为LEDC占空比
// 脉宽: 500-2500μs 对应 -90° 到 +90°
uint32_t duty = AngleToCompare(angle);
// 更新PWM输出
ledc_set_duty(ledc_speed_mode_, ledc_channel_, duty);
ledc_update_duty(ledc_speed_mode_, ledc_channel_);
}
步态运动算法
采用振荡器协调控制,通过精确的相位差实现双足机器人的平滑行走运动。
void EdaRobot::Walk(float steps, int period, int dir, int amount) {
// 定义6个舵机的振幅(运动幅度)
int amplitude[6] = {30, 30, 20, 20, amount, amount};
// 定义偏移量(基准位置)
int offset[6] = {0, 0, 4, -4, 0, 0};
// 定义相位差(控制腿部协调运动)
// 左右腿相位差90°实现交替抬腿
// 脚部与腿部同步运动
double phase_diff[6] = {
0, // 左腿
0, // 右腿
DEG2RAD(dir * -90), // 左脚
DEG2RAD(dir * -90), // 右脚
DEG2RAD(dir * -90), // 左手
DEG2RAD(dir * 90) // 右手
};
// 执行振荡运动
Execute(amplitude, offset, period, phase_diff, steps);
}
MCP 协议集成
通过 MCP 协议向 AI 大语言模型暴露机器人控制接口,支持参数验证和回调函数执行。
void EdaRobotMaxController::RegisterMcpTools() {
auto& mcp_server = McpServer::GetInstance();
// 注册行走工具
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](const PropertyList& properties) -> ReturnValue {
int steps = properties["steps"].value();
int speed = properties["speed"].value();
int arm_swing = properties["arm_swing"].value();
int direction = properties["direction"].value();
// 将动作加入队列
QueueAction(ACTION_WALK, steps, speed, direction, arm_swing);
return true;
}
);
// 注册其他工具:jump, swing, turn, moonwalk...
}
FreeRTOS 任务调度
基于 FreeRTOS 队列的异步任务调度,确保动作执行不阻塞 AI 对话和其他系统功能。
static void ActionTask(void* arg) {
EdaRobotMaxController* controller =
static_cast(arg);
EdaRobotActionParams params;
controller->edarobot_.AttachServos(); // 初始化舵机
while (true) {
// 从队列接收动作指令(阻塞等待)
if (xQueueReceive(controller->action_queue_, ¶ms,
pdMS_TO_TICKS(1000)) == pdTRUE) {
controller->is_action_in_progress_ = true;
// 根据动作类型执行相应动作
switch (params.action_type) {
case ACTION_WALK:
controller->edarobot_.Walk(params.steps, params.speed,
params.direction, params.amount);
break;
case ACTION_JUMP:
controller->edarobot_.Jump(params.steps, params.speed);
break;
case ACTION_SWING:
controller->edarobot_.Swing(params.steps, params.speed,
params.amount);
break;
// ... 其他动作
}
// 动作完成后自动复位(除了sit和showcase)
if (params.action_type != ACTION_HOME &&
params.action_type != ACTION_SIT) {
controller->edarobot_.Home(params.action_type < ACTION_HANDS_UP);
}
controller->is_action_in_progress_ = false;
vTaskDelay(pdMS_TO_TICKS(20));
}
}
}
安装结构
项目采用多外壳结构,由底盖,顶壳,头,左手臂,右手臂,腿,左脚,右脚构成。
外壳开源协议说明:本项目外壳由CC-BY及CC-BY-SA协议组成。
- 头部模型由嘉立创模型商城官方的 嘉立创小熊 开源模型修改而来
- 中部凹环用于头部固定
- 底部长柄用于触发PCB上的按键
- 此壳体依照原模型作者的CC-BY协议开源
- 手臂模型由嘉立创模型商城官方的 中国队长-熊 开源模型修改而来
- 手臂内部设计有舵机支架孔位及螺丝孔,便于舵机连接
- 此壳体依照原模型作者的CC-BY协议开源
- 后盖内设计有PCB固定孔,并设计有舵机限位槽
- 背部为18650电池盒开孔,方便电池取出
- 底部设计有舵机线缆开孔及舵机开孔,方便连接腿部
- 前盖设计有喇叭开孔,开关开孔及麦克风开孔
- 背部设计有舵机限位槽,避免舵机移位
- 前盖加高,便于藏线及舵机排针排母链接
- 腿部模型由Otto Robot官方的 Otto Biped 开源模型修改而来
- 腿部内部设计有舵机支架孔位及螺丝孔,便于舵机连接
- 此壳体依照原模型作者的CC-BY-SA协议开源
- 脚部模型由Otto Robot官方的 Otto Biped 开源模型修改而来
- 脚部内部设计有舵机支架孔位及螺丝孔,便于舵机连接
- 此壳体依照原模型作者的CC-BY-SA协议开源
拓展方向
本项目提供了一个基础的 AI 机器人方案,你可以基于此项目进行以下拓展:
- 增加更多机器熊动作和行为模式
- 支持视觉识别,添加摄像头模块
- 集成更多传感器(陀螺仪、加速度计等)
- 添加环境感知和避障功能
- 接入HomeAssistant实现智能家具控制
注意事项
立创商城采购物料清单
| 数量 | 器件 | 商城编号 |
|---|---|---|
| 1 | 100nF | C5632430 |
| 6 | 10uF | C43351 |
| 2 | 按键 | C2686326 |
| 12 | 10kΩ | C410695 |
| 1 | 100kΩ | C176449 |
| 6 | PZ254V-11-03P | C2937625 |
| 2 | AMS1117-5.0 | C33960103 |
| 1 | AMS1117-3.3 | C2977152 |
| 1 | ESP32S3-N16R8 | C2913202 |
| 1 | 10Pin 排针 - 裁切 | C492409 |
| 1 | 13Pin 排母 - 裁切 | C2932676 |
| 2 | 18650电池盒 | C5290175 |
其他平台采购物料清单
| 数量 | 器件 |
|---|---|
| 8 | M2×4 螺丝 |
| 1 | INMP441 模块 |
| 1 | MAX98357 模块 |
| 2 | 18650 电池 |
| 6 | SG90/MG90舵机 |
💡 提示:部分通用元件可选择等效型号,重点关注封装及电气参数一致性。
下表列出了 ESP32S3 固件烧录时的分区布局,地址与文件路径对应关系如下,可直接用于命令行烧录或 Flash 工具导入配置。
| 烧录地址 | 文件路径 | 说明 |
|---|---|---|
| 0x0 | bootloader.bin | Bootloader 启动加载程序 |
| 0x8000 | partition-table.bin | 分区表定义 |
| 0xd000 | ota_data_initial.bin | OTA 初始数据区 |
| 0x20000 | xiaozhi.bin | 主程序固件 |
| 0x800000 | generated_assets.bin | 资源文件(语音模型/AI配置) |
💡 提示:使用 esptool.py 可执行如下命令进行烧录:
esptool.py write_flash 0x0 bootloader/bootloader.bin 0x8000 partition_table/partition-table.bin 0xd000 ota_data_initial.bin 0x20000 xiaozhi.bin 0x800000 generated_assets.bin
设计图
未生成预览图,请在编辑器重新保存一次BOM
暂无BOM
克隆工程知识产权声明&复刻说明
本项目为开源硬件项目,其相关的知识产权归创作者所有。创作者在本平台上传该硬件项目仅供平台用户用于学习交流及研究,不包括任何商业性使用,请勿用于商业售卖或其他盈利性的用途;如您认为本项目涉嫌侵犯了您的相关权益,请点击上方“侵权投诉”按钮,我们将按照嘉立创《侵权投诉与申诉规则》进行处理。
请在进行项目复刻时自行验证电路的可行性,并自行辨别该项目是否对您适用。您对复刻项目的任何后果负责,无论何种情况,本平台将不对您在复刻项目时,遇到的任何因开源项目电路设计问题所导致的直接、间接等损害负责。










