Bumi 综合使用文档
一、关于Bumi
(一)部件信息
Bumi 整机具备 21 个自由度。单臂拥有 4 个自由度,包括(左手坐标系):
肩关节pitch肩关节roll上臂关节yaw手肘关节pitch
单腿拥有 6 个自由度,包括:
胯关节pitch髋关节roll大腿关节yaw膝关节pitch踝关节pitch踝关节roll
腰关节拥有 1 个自由度,包括:
腰关节yaw
拥有多个关节电机自由度,使得Bumi机器人能够实现精确的运动控制和姿态控制。
详细信息如下:
| 参数 | Bumi | Bumi-教育版 |
|---|---|---|
| 高宽厚(站立) | 98cm*35cm*20cm | |
| 带电池重量 | 约17kg | |
| 总自由度 | 21 | |
| 单腿自由度 | 6 | |
| 单手臂自由度 | 4 | |
| 腰部自由度 | 1 | |
| 算力模块 | / | NVIDIA Jetson Orin(Nano Super / NX) 【个别型号无算力模块】 |
| 关节通讯方式 | Ethercat & Canfd | |
| 关节最大扭矩 | 70N.m | |
| 小腿&大腿长度 | 约513mm | |
| 手臂臂展 | 约379mm | |
| 供电方式 | 锂电池 | |
| 基础算力 | 6 Tops | 6 + 67 / 117 Tops |
| 相机型号 | DC_V93 | Realsense D435ICB(EDU_Air除外) |
| 感知传感器 | IMU、相机 | |
| 麦克风阵列 | 标配 | |
| 扬声器 | 标配 | |
| 智能电池 | 快拆电池 | |
| 图像传输 | App内有 | 开发中可直接在算力板上访问硬件 |
| 充电器 | 有 | |
| 手机APP | 有 | |
| OTA升级 | 有 | |
| 续航时间 | 2~3H | |
| 二次开发(highcontroller) | 有 | |
| 二次开发(lowcontroller) | / | 有 |
| 部件介绍图 | ![]() | |
(二)外观件尺寸

(三)电气接口
在Bumi背面,提供电气接口如下:

| 序号 | 类型 | 说明 | 数量 |
|---|---|---|---|
| 1 | RJ45 | 交换机 1000 BASE-T | 1 |
| 2 | USB | 运控板/算力板 USB 3.0 | 2 |
| 3 | HDMI | 运控板/算力板 高清显示线 | 1 |
带算力板的Bumi 后背接口为算力板的接口,不带算力板的Bumi,后背接口为运控板的接口
(四)机载计算机
| 类型 | 型号 | 用户 | 密码 | IP | 算力 | 频率 | 内存 |
|---|---|---|---|---|---|---|---|
| 运控板 | 瑞星微 RK3576 | 运控板不对用户开放 | 运控板不对用户开放 | 192.168.55.102 | 6 Tops | 2.4GHz | 8+64GB |
| 二开算力板 | NVIDIA Jetson orin nano super | noetix | bumi | 192.168.55.101 | 67 Tops | 1.7GHz | 8+128GB |
| 二开算力板 | NVIDIA Jetson orin NX | noetix | bumi | 192.168.55.101 | 117 Tops | 2.0GHz | 16+128GB |
运控板(瑞星微 RK3576)不面向用户开放,如果用户私自访问运控板,导致机器人运控程序失控,造成损失与我司无关
(五)相机信息
Bumi-EDU:Realsense D435i
英特尔® 实感™ 深度摄像头 D435i - 产品规格 | 英特尔
Bumi-标准:DC_V93

(六)电池信息
| 参数 | 信息 |
|---|---|
| 品牌 | 深圳格瑞普 |
| 型号 | GRP6752097-13S1P |
| 容量 | 5100mAh |
| 电压 | 48V |
(七)充电器规格参数
| 参数 | 信息 |
|---|---|
| 产品型号 | TA300 Robot |
| 输入 | 100-240V~50/60Hz 4.5A |
| 电池类型 | LiPo/LiFe/LiHV 13S-16S |
| 尺寸 | 1729746mm |
| 产品名称 | Smart charger智能充电器 |
| 输出 | 35-72V ⎓ 7.5A 350W Max |
| 工作模式 | Charge/充电 |
| 重量 | 510g±10g |
二、使用说明
(一)启动设备及注意事项
一、设备取出与放置
- 将 Bumi 从收纳位置取出。
- 将其扶稳,使其坐于地面。
二、电池安装
- 将电池插入 Bumi 后背电池仓。
- 确认电池安装到位(卡扣锁定)。
三、设备开机
- 短按一次电池开关,确认电池指示灯亮起。
- 随后长按电池开关,直至出现流水灯效果。
- 等待机器人完成开机。
四、初始化姿态调整
- 将 Bumi 面朝上平躺于地面,要确地面平坦不打滑,Bumi脚底板无其他异物,且周围无杂物,避免Bumi执行自动起身的时候被周围杂物影响而失败
五、系统初始化说明
- 开机后,Bumi 会自动进入全身使能模式:
- 所有关节将自动运动至零位
- 过程中请勿干预或阻挡关节运动
⚠️ 注意事项
- 开机过程中避免触碰关节,防止夹伤或干扰初始化
- 确保地面平整,避免姿态异常
- 电池未正确安装时禁止开机
(二)Bumi连接方式

连接 Bumi 后,请勿在系统设置中选择‘遗忘设备’,否则会清除蓝牙记录,导致该设备无法再次连接。如误操作,请联系售后。
(三)手机APP连接设备及操作控制
Noetix run App下载:
Android:

iOS:NOETIX Run App - App Store
Noetix run App使用说明: BUMI机器人使用说明
(四)设备关机及电池充电
(五)操作教程视频
1. 安装APP
2. 开机
3. 激活绑定
4. 连接BUMI
- 蓝牙连接
- 蓝牙组网和WIFI连接
连接 Bumi 后,请勿在系统设置中选择‘遗忘设备’,否则会清除蓝牙记录,导致该设备无法再次连接。如误操作,请联系售后。
5. 一键起身
使用Bumi的一键起身功能时 要确地面平坦不打滑,且周围无杂物,避免Bumi执行自动起身的时候被周围杂物影响而失败
6. 移动
7. 基本动作
8. 示教模式
9. 舞蹈模式
10. 图传模式
(无算力板版本Bumi有)
11. 语音交互
12. 一键收纳
在 APP 中执行 一键收纳 前,要确保地面平坦不打滑且周围无杂物。
13. 关机
14. 电池充电
(六)常见问题及设备日常维护
- 设备防水系数不高
请勿在雨雪天气室外或者潮湿的环境中使用
三、Bumi开发指南
SDK介绍
本文档介绍Bumi基于 DDS消息中间件 通信开发,本SDK采用 C/S架构,在隔离机制下,使 Bumi 机器人的 二次开发算力板部署DDS客户端程序 与机器人上作为服务器的 运控板的运控程序 以 500HZ 的频率下发控制命令,并持续获取当前机器人状态。dds采用的是 CYCLONEDDS 0.11.0。
(一)系统架构图

(二)开发接口
DDS C++ Python
(三)获取SDK
https://github.com/Noetix-Robotics/noetix_sdk_bumi
(四)URDF文件
(五)应用开发 Highcontrol
应用开发介绍
Highcontrol 基于原厂运动控制策略进行上层调度开发,在不改变底层控制逻辑的前提下,实现机器人自动化应用的快速构建,并支持与大模型集成,打造定制化智能行为系统。
典型应用包括:
- 结合视觉算法与原厂运控系统,实现自主感知与自主行进
- 结合语音交互模块,实现自然语言控制
- 接入大模型,根据输入动态生成并调用原厂控制动作(具备一定风险,需要严格安全策略)
- 配合外挂感知雷达,实现定位导航巡检系统
简而言之,HighControl 通过对原厂控制能力的高层调度封装,实现对遥控器或 APP 可控行为的自动化与程序化调用,并在此基础上拓展部分自主化与智能化能力。
1. Highcontrol架构图

(1)状态上报机制
当客户端 SDK 与机器人运控程序建立连接后,运控程序会持续向客户端推送机器人实时状态信息,包括:
-
全身电机参数数据(pos 位置、vel 速度、tau 扭矩、kp、kd、temperature 温度、error 错误信息)
-
IMU 状态数据
-
当前工作模式(
workmode,表示当前运行的控制策略) -
澳加狮手柄数据(用于同步人工输入或辅助控制)
-
电池电量及相关系统状态信息
(2)客户端控制指令下发
客户端结合自身应用场景向运控程序发送控制指令,主要包括:
-
(x, y, z) 行进控制数据
仅在特定模式下有效,例如走路模式、握手、打招呼、欢呼、示教模式等。
-
action 指令
与
workmode对应,用于切换或触发机器人当前运行的算法策略。 -
data 附加 DDS 数据
通常在
PLAYTEACH(播放示教模式)下使用,用于指定示教文件索引等附加参数。
(3)运控程序内部处理流程
运控程序接收到客户端指令后:
-
将控制参数传递给内部控制算法
-
算法基于强化学习模型进行策略计算
-
生成电机目标期望值(目标位置、速度或力矩)并发送到电机控制接口
-
将计算结果下发至硬件控制层
(4)硬件执行层
硬件层接收目标控制数据后:
-
执行电机控制指令
-
完成对应的期望动作
在整个流程中,用户仅需下发部分高层控制参数。
具体的运动规划、动态平衡与电机级控制计算均由原厂运控程序中的黑盒算法完成。
因此,在 Highcontrol 模式 下,用户能够调用和自动化的能力范围,原则上不超过 APP 或手柄原本可实现的功能边界,但不开放底层电机级控制权限。
2. Highcontrol运行流程图

(1)初始化阶段(init)
系统启动后完成以下初始化流程:
-
建立客户端与机器人运控程序之间的通信连接
-
注册机器人状态数据接收回调函数
(2)DDS 回调线程持续接收回传状态
运控程序持续向客户端推送机器人状态数据。
回调函数接收到数据后进行封装,并分别存入缓冲区及全局状态变量:
-
motor_state_buffer_:电机状态缓冲区 -
imu_buffer_:IMU 状态缓冲区 -
joy_buffer_:手柄数据缓冲区 -
curmode:当前运控策略模式 -
curbattery:当前电池信息
3. HighController常用接口及参数表
| HighController接口 | ||
|---|---|---|
| 接口名称 | 接口描述 | 返回类型 |
| instance | 获取HighController单例指针 | 对象指针 |
| init | HighController对象初始化 | 无 |
| publish_cmd | 发布DDS控制命令数据 | 无 |
| get_mode | 获取当前机器人策略模式 | int |
| from_dds_get_joydata | 从DDS订阅中获取手柄数据 | 手柄数据结构体 |
| get_imu_data | 从DDS订阅中获取imu数据 | IMU数据结构体 |
| get_joint_state | 从DDS订阅中获取电机数据 | 电机数据结构体数组 |
获取HighController对象单例
| 函数名 | instance |
|---|---|
| 函数原型 | static HighController *Instance() |
| 功能概述 | 获取 HighController单例 |
| 参数 | 无 |
| 返回值 | HighController单例对象指针 |
| 备注 |
C++示例:
HighController *ctrl = HighController::Instance();
Python示例:
ctrl = HighController.instance()
HighController对象初始化
| 函数名 | init |
|---|---|
| 函数原型 | bool init() |
| 功能概述 | HighController对象初始化 |
| 参数 | 无 |
| 返回值 | bool |
| 备注 |
C++示例:
ctrl->init()
Python示例:
ctrl.init()
发布机器人控制指令
| 函数名 | publish_cmd |
|---|---|
| 函数原型 | void publish_cmd(double ver, double hor, ControlCmd action, uint16_t index) |
| 功能概述 | 使用HighController发送dds控制指令 |
| 参数 |
|
| 返回值 | 无 |
| 备注 | 此接口不能连续调用,否则机器人接收指令太快会无法响应,需要在每次指令发送至少添加2ms的延时 |
C++示例:
ctrl->publish_cmd(0, 0, ControlCmd.CHEER, 0);
Python示例:
ctrl.publish_cmd(0, 0, ControlCmd.CHEER, 0)
action参数表示切换机器人到对应模式
| 参数名称 | 定义原型 | 序号 | 示例值 | 说明 |
|---|---|---|---|---|
ControlCmd | | 0 | WALK | 走路模式 |
| 1 | SWING | 出厂预设动作挥手 | ||
| 2 | SHAKE | 出厂预设动作握手 | ||
| 3 | CHEER | 出厂预设动作欢呼 | ||
| 4 | RUN | 预留模式,当前版本不可用 | ||
| 5 | START | 使能/失能 | ||
| 6 | SWITCH | 准备模式 | ||
| 7 | STARTTEACH | 开始示教 | ||
| 8 | SAVETEACH | 保存示教 | ||
| 9 | ENDTEACH | 结束示教(弃用) | ||
| 10 | PLAYTEACH | 播放示教 | ||
| 11 | DANCE | 舞蹈1模式 | ||
| 12 | FALLTOSTAND | 倒地起身 | ||
| 13 | STANDTOFALL | 起身倒地 | ||
| 14 | DANCE1 | 舞蹈2模式 | ||
| 15 | DANCE2 | 舞蹈3模式 | ||
| 16 | TEAR | 预设擦眼泪动作 | ||
| 17 | DEFAULT | 空模式 |
DEFAULT空模式使用目的
整个机器人线程会循环执行process 控制函数是周期循环执行的,如果在其中持续下发
action = ControlCmd::PLAYTEACH; 等示教相关命令的话
机器人会在 示教播放动作未播放完的情况,导致动作被反复打断,表现为机器人“卡住、无反应”。
正确做法
PLAYTEACH 属于 一次性触发指令(事件),应 只发送一次;后续循环发送 DEFAULT(空指令),避免重复触发。
示例代码(修正后)
if (is_first) {
action = ControlCmd::`**`PLAYTEACH`**`; // 只触发一次`
is_first = false;
} else {
action = ControlCmd::DEFAULT;
}
效果
-
收到
PLAYTEACH→ 触发并完整执行示教动作 -
后续
DEFAULT→ 不再打断动作 -
机器人行为正常、可预期
动作类指令要“边沿触发”,不能在控制循环里持续下发。
START 使能/失能
workmode == 30,发送START使机器人进入使能模式
workmode != 30,发送START使机器人立刻进入失能模式
index用于在示教相关模式下指定示教文件索引
ctrl.publish_cmd(0, 0, ControlCmd.STARTTEACH, 0) # 开始示教
sleep(10) # 录制示教动作
ctrl.publish_cmd(0, 0, ControlCmd.SAVETEACH, 1) # 结束并保存示教动作,指定索引为1
sleep(2) # 让运控程序执行完保存流程,防止被下条命令打断
ctrl.publish_cmd(0, 0, ControlCmd.PLAYTEACH, 1) # 播放示教文件1
仅当 action 为以下模式时:
TEAR / PLAYTEACH / WALK / SWING / CHEER / SHAKE / DEFAULT
参数 x 和 yaw 才会生效,用于控制机器人运动;在其他模式下,x 和 yaw 无效。
获取当前机器人策略模式
| 函数名 | get_mode |
|---|---|
| 函数原型 | int get_mode() |
| 功能概述 | 获取DDS机器人当前策略模式 |
| 参数 | 无 |
| 返回值 | int |
| 备注 |
C++示例:
int curmode = ctrl->get_mode();
Python示例:
curmode = ctrl.get_mode()
get_mode 返回数据对应表
| int值 | 说明 |
|---|---|
| 0 | 使能模式 |
| 1 | 准备模式 |
| 2 | 走路模式 |
| 5 | 舞蹈模式 |
| 8 | 出厂预设动作 打招呼 |
| 9 | 出厂预设动作 握手 |
| 10 | 出厂预设动作 欢呼 |
| 11 | 开始示教 |
| 12 | 结束示教 |
| 14 | 保存示教1 |
| 23 | 播放示教 |
| 26 | 保护模式 |
| 27 | 倒地起身 |
| 28 | 起身倒地 |
| 29 | 保存示教2 |
| 30 | 失能模式 |
| 31 | 舞蹈模式1 |
| 32 | 舞蹈模式2 |
| 33 | 擦眼泪动作 |
保存示教
SDK向机器人发送 SAVETEACH 后,机器人会陆续返回 退出示教 保存示教1 保存示教2 三个状态
保护模式
在处于站立控制策略(走路,示教,舞蹈等)下,运控程序会对 IMU 姿态数据进行持续监测。
当检测到姿态偏离站立稳定区间,并超过预设阈值时,系统将立即触发保护机制,强制切换至安全模式。
在保护模式下:
-
全身关节进入失能状态(电机停止主动输出)
-
终止当前运动控制策略
-
阻断进一步动作指令执行
该机制的目的在于:
-
防止机器人在跌倒或失稳过程中持续输出控制力矩
-
避免四肢失控摆动造成二次损伤
-
降低对设备本体及周围环境的潜在损害
该保护逻辑属于底层安全防护机制,具有最高优先级,不受上层控制指令影响。
获取DDS订阅的手柄数据
| 函数名 | from_dds_get_joydata |
|---|---|
| 函数原型 | const joydata from_dds_get_joydata() |
| 功能概述 | 获取DDS手柄输入数据 |
| 参数 | 无 |
| 返回值 | joydata结构体 |
| 备注 |
| 参数名称 | 定义原型 | 示例值 | 说明 |
|---|---|---|---|
| joydata | | axes | 遥控器遥感线性数值 |
| button | 遥控器按键按下映射数值 1 被按下 0 正常 |
| 手柄摇杆映射 | 映射说明 | 范围 |
|---|---|---|
| axes[0] | 右摇杆左右推动值 | [-1, 1] |
| axes[1] | 左摇杆前后推动值 | [-1, 1] |
带算力板的Bumi 后背接口为算力板接口,运控板无法插入手柄接收器,所以DDS获取不到手柄数据,所以手柄数据需要直接算力板上获取,详细请看 算力板直接获取手柄数据
C++示例:
joydata jsdata = ctrl->from_dds_get_joydata();
for (int i = 0; i < 14; i++)
std::cout << jsdata.button[i] << std::endl;
std::cout << jsdata.axes[0] << std::endl;
std::cout << jsdata.axes[1] << std::endl;
Python示例:
jsdata = ctrl.from_dds_get_joydata()
for i in range(14):
print(jsdata.button[i])
print(jsdata.axes[0])
print(jsdata.axes[1])
获取DDS订阅IMU数据
| 函数名 | get_imu_data |
|---|---|
| 函数原型 | const NingImuData get_imu_data() |
| 功能概述 | 获取imu数据 |
| 参数 | 无 |
| 返回值 | NingImuData结构体 |
| 备注 |
| 参数名称 | 定义原型 | 示例值 | 说明 |
|---|---|---|---|
| NingImuData | | ori | 姿态四元数 |
| ori_cov | 姿态协方差 | ||
| angular_vel | 角速度 | ||
| angular_vel_cov | 角速度协方差 | ||
| linear_acc | 线加速度 | ||
| linear_acc_cov | 线加速度协方差 |
C++示例:
NingImuData imu_data = ctrl->get_imu_data();
for (int i = 0; i < 4; i++)
std::cout << imu_data.ori[i] << std::endl;
for (int i = 0; i < 9; i++)
std::cout << imu_data.ori_cov[i] << std::endl;
for (int i = 0; i < 3; i++)
std::cout << imu_data.angular_vel[i] << std::endl;
for (int i = 0; i < 9; i++)
std::cout << imu_data.angular_vel_cov[i] << std::endl;
for (int i = 0; i < 3; i++)
std::cout << imu_data.linear_acc[i] << std::endl;
for (int i = 0; i < 9; i++)
std::cout << imu_data.linear_acc_cov[i] << std::endl;
Python示例:
imu_data = ctrl.get_imu_data()
for i in range(4):
print(imu_data.ori[i])
for i in range(9):
print(imu_data.ori_cov[i])
for i in range(3):
print(imu_data.angular_vel[i])
for i in range(9):
print(imu_data.angular_vel_cov[i])
for i in range(3):
print(imu_data.linear_acc[i])
for i in range(9):
print(imu_data.linear_acc_cov[i])
获取DDS订阅的电机信息数据
| 函数名 | get_joint_state |
|---|---|
| 函数原型 | const std::array<MotorState, 21> get_joint_state() |
| 功能概述 | 获取机器人电机状态数据 |
| 参数 | 无 |
| 返回值 | MotorState结构体数组 |
| 备注 |
| 参数名称 | 定义原型 | 示例值 | 说明 |
|---|---|---|---|
| MotorState | | pos | 电机位置 |
| vel | 电机转速 | ||
| tau | 电机扭矩 | ||
| motor_id | 电机ID | ||
| error | 电机错误码:
| ||
| temperature | 温度 |
C++示例:
std::array<MotorState, 21> joint_state = ctrl->get_joint_state();
for (int i = 0; i < 21; i++) {
std::cout << joint_state[i].pos << std::endl;
std::cout << joint_state[i].vel << std::endl;
std::cout << joint_state[i].tau << std::endl;
std::cout << joint_state[i].motor_id << std::endl;
std::cout << static_cast<int>(joint_state[i].error) << std::endl;
std::cout << joint_state[i].temperature << std::endl;
}
Python示例:
joint_state = ctrl.get_joint_state()
for i in range(21):
print(joint_state[i].pos)
print(joint_state[i].vel)
print(joint_state[i].tau)
print(joint_state[i].motor_id)
print(joint_state[i].error)
print(joint_state[i].temperature)
4. 运控状态切换流程图

注意:使用HighController开发过程中,模式切换请遵循上述流程图以确保合理安全
5. Demo例程介绍
SDK 文件夹中的 example_high.cpp 与 src/test_high.cpp 提供了一个示例 Demo,用于解析澳加狮手柄输入数据,并根据手柄操作生成对应控制指令发送至机器人。
(六)运控开发 LowController
运控开发介绍
LowController 将运控程序中的电机控制接口开放至 SDK,允许用户以 500Hz 的控制频率直接调节底层电机参数。结合强化学习算法部署,可实现对 Bumi 运动能力的深度定制,使其完成多样化的新动作与舞蹈等复杂行为。
注意:仅有EDU版本的Bumi可以开发LowController
1. Bumi训练框架
后续开放
2. LowController架构图

(1)状态数据上报
当客户端 SDK 与机器人运控程序建立连接后,运控程序会持续向客户端推送机器人实时状态信息,包括:
-
全身电机参数数据(pos 位置、vel 速度、tau 扭矩、kp、kd、temperature 温度、error 错误信息)
-
IMU 状态数据
-
澳加狮手柄数据
(2)客户端侧控制计算
客户端结合自身算法(通常为强化学习模型)进行实时策略计算,生成各电机的目标期望值(如目标位置等),并将电机控制指令数组写入缓冲区后下发至运控程序。
(3)运控程序转发机制
运控程序接收到客户端下发的电机指令数组后,不进行高层策略计算,而是直接将控制参数转发至硬件控制层。
(4)硬件执行层
硬件层接收电机目标参数后执行控制指令,驱动电机完成期望动作。
在 LowController 模式下:
-
强化学习模型部署在客户端侧
-
用户可直接参与电机级控制
-
运控程序主要承担通信与安全转发职责
-
控制频率可达
500Hz
该模式具备更高的控制自由度与灵活性,但同时也意味着:
-
对算法稳定性要求更高
-
对实时性与系统安全性的要求更严格
-
若控制策略不稳定,可能直接影响机器人运动安全
3. LowController运行流程图

(1)初始化阶段(init)
系统启动后完成以下初始化步骤:
-
建立客户端与机器人运控程序之间的通信连接
-
注册机器人状态数据接收回调函数
-
创建
send_thread数据发送线程
(2)状态数据回调机制
运控程序持续向客户端推送机器人状态数据。
回调函数接收数据后进行封装,并存入对应缓冲区或全局变量:
-
motor_state_buffer_:电机状态缓冲区 -
imu_buffer_:IMU 状态缓冲区 -
joy_buffer_:手柄数据缓冲区
该阶段仅负责数据接收与缓存,不参与控制策略计算。
(3)send_thread(数据发送线程)
数据发送线程同样以 2ms 周期运行:
-
若
motor_cmd_buffer_不为空 -
读取最新电机控制指令
-
将电机目标数组发送至运控程序
运控程序仅负责数据转发至硬件层,不参与高层控制决策。
(4)架构特征
LowController 模式的核心特征是:
-
客户端直接参与电机级控制
-
强化学习或自定义控制算法运行在客户端
-
运控程序不再负责高层策略计算,仅承担通信与安全转发职责
-
控制频率可达 500Hz
该模式提供更高的控制自由度与算法可塑性,但同时对:
-
实时性
-
算法稳定性
-
线程安全与调度精度
提出更高要求。
4. 关节电机信息
| ID | 名称 | 关节 | 扭矩 | 角度范围 | 弧度范围 | ||
|---|---|---|---|---|---|---|---|
| 0 | arm_l1_joint | 左臂肩关节pitch | 5 N.m | -135 | 135 | -2.36 | 2.36 |
| 1 | arm_l2_joint | 左臂肩关节roll | 5 N.m | -8 | 111 | -0.14 | 1.94 |
| 2 | arm_l3_joint | 左臂关节yaw | 5 N.m | -90 | 90 | -1.57 | 1.57 |
| 3 | arm_l4_joint | 左臂肘关节pitch | 5 N.m | -129 | 0 | -2.26 | 0.00 |
| 4 | leg_l1_joint | 左腿髋关节pitch | 60 N.m | -120 | 120 | -2.09 | 2.09 |
| 5 | leg_l2_joint | 左腿髋关节roll | 60 N.m | -38 | 90 | -0.66 | 1.57 |
| 6 | leg_l3_joint | 左大腿关节yaw | 15 N.m | -145 | 145 | -2.53 | 2.53 |
| 7 | leg_l4_joint | 左腿膝关节pitch | 60 N.m | 0 | 128 | 0.00 | 2.24 |
| 8 | leg_l5_joint | 左腿踝关节pitch | 30 N.m | -55 | 25 | -0.96 | 0.44 |
| 9 | leg_l6_joint | 左腿踝关节roll | 30 N.m | -10 | 10 | -0.17 | 0.17 |
| 10 | arm_r1_joint | 右臂肩关节pitch | 5 N.m | -135 | 135 | -2.36 | 2.36 |
| 11 | arm_r2_joint | 右臂肩关节roll | 5 N.m | -111 | 8 | -1.94 | 0.14 |
| 12 | arm_r3_joint | 右臂关节yaw | 5 N.m | -90 | 90 | -1.57 | 1.57 |
| 13 | arm_r4_joint | 右臂肘关节pitch | 5 N.m | -129 | 0 | -2.26 | 0.00 |
| 14 | leg_r1_joint | 右腿髋关节pitch | 60 N.m | -120 | 120 | -2.09 | 2.09 |
| 15 | leg_r2_joint | 右腿髋关节roll | 60 N.m | -90 | 38 | -1.57 | 0.66 |
| 16 | leg_r3_joint | 右大腿关节yaw | 15 N.m | -145 | 145 | -2.53 | 2.53 |
| 17 | leg_r4_joint | 右腿膝关节pitch | 60 N.m | 0 | 128 | 0.00 | 2.24 |
| 18 | leg_r5_joint | 右腿踝关节pitch | 30 N.m | -55 | 25 | -0.96 | 0.44 |
| 19 | leg_r6_joint | 右腿踝关节roll | 30 N.m | -10 | 10 | -0.17 | 0.17 |
| 20 | waist_1_joint | 腰关节yaw | 27 N.m | -90 | 90 | -1.57 | 1.57 |
MotorCmd.pos 对应 弧度信息
5. 澳加狮手柄数据映射
澳加狮手柄。button[]和按键映射表如下:
| 键位描述 | Button index |
|---|---|
| 右肩键 | 1 |
| 左肩键 | 2 |
| X | 5 |
| Y | 6 |
| B | 7 |
| A | 8 |
| + | 9 |
| - | 10 |
| 无 | 11 |
| 左摇杆按下 | 12 |
| 手柄摇杆映射 | 映射说明 |
|---|---|
| axes[0] | 右摇杆Y方向值 |
| axes[1] | 左摇杆X方向值 |
手柄摇杆数据范围
| 最小值 | 最大值 |
|---|---|
| -1 | 1 |
6. LowController常用接口及使用例程
| LowController接口 | ||
|---|---|---|
| 接口名称 | 接口描述 | 返回类型 |
| instance | 获取LowController单例指针 | 对象指针 |
| init | LowController对象初始化 | 无 |
| set_joint | 将电机控制命令写入缓冲区 | 无 |
| get_mode | 获取当前机器人策略模式 | int |
| from_dds_get_joydata | 从DDS订阅中获取手柄数据 | 手柄数据结构体 |
| get_imu_data | 从DDS订阅中获取imu数据 | IMU数据结构体 |
| get_joint_state | 从DDS订阅中获取电机数据 | 电机数据结构体数组 |
获取LowController对象单例
| 函数名 | instance |
|---|---|
| 函数原型 | static LowController *Instance() |
| 功能概述 | 获取 HighController单例 |
| 参数 | 无 |
| 返回值 | LowController单例对象指针 |
| 备注 |
C++示例:
LowController *ctrl = LowController::Instance();
Python示例:
ctrl = LowController.instance()
LowController对象初始化
| 函数名 | init |
|---|---|
| 函数原型 | bool init() |
| 功能概述 | LowController对象初始化 |
| 参数 | 无 |
| 返回值 | bool |
| 备注 |
C++示例:
ctrl->init()
Python示例:
ctrl.init()
电机控制命令数组存入缓冲区
存入缓冲区后,会由send_thread 线程自动发送
| 函数名 | set_joint |
|---|---|
| 函数原型 | void set_joint(std::array<MotorCmd, 21> motorcmd) |
| 功能概述 | 设置关节数据 |
| 参数 | motorcmd 电机命令结构体 |
| 返回值 | 无 |
| 备注 |
| 参数名称 | 定义原型 | 示例值 | 说明 |
|---|---|---|---|
| MotorCmd | | pos | 电机位置 |
| vel | 电机转速 | ||
| tau | 电机扭矩 | ||
| kp | pid参数 | ||
| kd | pid参数 | ||
| motor_id | 电机ID |
电机控制命令下发请严格参考 关节电机信息 中的指定参数范围
C++示例:
std::array<MotorCmd, 21> motorcmd;
// 省略算法逻辑 ...
ctrl->set_joint(motorcmd);
Python示例:
cmds = [MotorCmd() for _ in range(21)]
# 省略算法逻辑 ...
ctrl.set_joint(cmds)
根据关节电机名称获取对应关节电机ID
| 函数名 | getJointsIndex |
|---|---|
| 函数原型 | int getJointsIndex(std::string jointname) |
| 功能概述 | 根据关节电机名称获取对应关节电机ID |
| 参数 | jointname: 关节电机名称 |
| 返回值 | int:对应关节电机ID |
| 备注 |
C++示例:
int id = ctrl->getJointsIndex("arm_l1_joint");
Python示例:
id = ctrl.getJointsIndex("arm_l1_joint");
| 函数名 | from_dds_get_joydata |
|---|---|
| 函数原型 | const joydata from_dds_get_joydata() |
| 功能概述 | 获取DDS手柄输入数据 |
| 参数 | 无 |
| 返回值 | joydata结构体 |
| 备注 |
| 参数名称 | 定义原型 | 示例值 | 说明 |
|---|---|---|---|
| joydata | | axes | 遥控器遥杆线性数值 |
| button | 遥控器按键按下映射数值 1 被按下 0 正常 |
| 手柄摇杆映射 | 映射说明 | 范围 |
|---|---|---|
| axes[0] | 右摇杆左右推动值 | [-1, 1] |
| axes[1] | 左摇杆前后推动值 | [-1, 1] |
带算力板的Bumi 后背接口为算力板接口,运控板无法插入手柄接收器,所以DDS获取不到手柄数据,所以手柄数据需要直接算力板上获取,详细请算力板直接获取手柄数据
C++示例:
joydata jsdata = ctrl->from_dds_get_joydata();
for (int i = 0; i < 14; i++)
std::cout << jsdata.button[i] << std::endl;
std::cout << jsdata.axes[0] << std::endl;
std::cout << jsdata.axes[1] << std::endl;
Python示例:
jsdata = ctrl.from_dds_get_joydata()
for i in range(14):
print(jsdata.button[i])
print(jsdata.axes[0])
print(jsdata.axes[1])
| 函数名 | get_imu_data |
|---|---|
| 函数原型 | const NingImuData get_imu_data() |
| 功能概述 | 获取imu数据 |
| 参数 | 无 |
| 返回值 | NingImuData结构体 |
| 备注 |
| 参数名称 | 定义原型 | 示例值 | 说明 |
|---|---|---|---|
| NingImuData | | ori | 姿态四元数 |
| ori_cov | 姿态协方差 | ||
| angular_vel | 角速度 | ||
| angular_vel_cov | 角速度协方差 | ||
| linear_acc | 线加速度 | ||
| linear_acc_cov | 线加速度协方差 |
C++示例:
NingImuData imu_data = ctrl->get_imu_data();
for (int i = 0; i < 4; i++)
std::cout << imu_data.ori[i] << std::endl;
for (int i = 0; i < 9; i++)
std::cout << imu_data.ori_cov[i] << std::endl;
for (int i = 0; i < 3; i++)
std::cout << imu_data.angular_vel[i] << std::endl;
for (int i = 0; i < 9; i++)
std::cout << imu_data.angular_vel_cov[i] << std::endl;
for (int i = 0; i < 3; i++)
std::cout << imu_data.linear_acc[i] << std::endl;
for (int i = 0; i < 9; i++)
std::cout << imu_data.linear_acc_cov[i] << std::endl;
Python示例:
imu_data = ctrl.get_imu_data()
for i in range(4):
print(imu_data.ori[i])
for i in range(9):
print(imu_data.ori_cov[i])
for i in range(3):
print(imu_data.angular_vel[i])
for i in range(9):
print(imu_data.angular_vel_cov[i])
for i in range(3):
print(imu_data.linear_acc[i])
for i in range(9):
print(imu_data.linear_acc_cov[i])
| 函数名 | get_joint_state |
|---|---|
| 函数原型 | const std::array<MotorState, 21> get_joint_state() |
| 功能概述 | 获取机器人电机状态数据 |
| 参数 | 无 |
| 返回值 | MotorState结构体数组 |
| 备注 |
| 参数名称 | 定义原型 | 示例值 | 说明 |
|---|---|---|---|
| MotorState | | pos | 电机位置 |
| vel | 电机转速 | ||
| tau | 电机扭矩 | ||
| motor_id | 电机ID | ||
| error | 电机错误码:
| ||
| temperature | 温度 |
C++示例:
std::array<MotorState, 21> joint_state = ctrl->get_joint_state();
for (int i = 0; i < 21; i++) {
std::cout << joint_state[i].pos << std::endl;
std::cout << joint_state[i].vel << std::endl;
std::cout << joint_state[i].tau << std::endl;
std::cout << joint_state[i].motor_id << std::endl;
std::cout << static_cast<int>(joint_state[i].error) << std::endl;
std::cout << joint_state[i].temperature << std::endl;
}
Python示例:
joint_state = ctrl.get_joint_state()
for i in range(21):
print(joint_state[i].pos)
print(joint_state[i].vel)
print(joint_state[i].tau)
print(joint_state[i].motor_id)
print(joint_state[i].error)
print(joint_state[i].temperature)
获取澳加狮手柄数据(带算力板的Bumi 算力板直接获取)
AoLionDriver类
| AoLionDriver类接口 | |
|---|---|
| init | 初始化 |
| getremotedata | 获取手柄数据 |
| 函数名 | init |
|---|---|
| 函数原型 | bool init(std::string port, int baudrate) |
| 功能概述 | 初始化手柄设备端口 |
| 参数 |
|
| 返回值 | true:初始化成功 falese:初始化失败 |
| 备注 |
| 函数名 | getremotedata |
|---|---|
| 函数原型 | const joydata getremotedata() |
| 功能概述 | 获取手柄数据 |
| 参数 | 无 |
| 返回值 | joydata:手柄数据结构体 |
| 备注 |
使用示例
C++
AoLionDriver aoliondriver;
joydata remote_data;
aoliondriver.init("/dev/input/js0", 115200);
const joydata jdata=aoliondriver.getremotedata();
for (int i = 0; i < 14; i++)
std::cout << jdata.button[i] << std::endl;
std::cout << jdata.axes[0] << std::endl;
std::cout << jdata.axes[1] << std::endl;
Python
al = AoLionDriver()
al.init("/dev/input/js0", 115200)
jdata = al.getremotedata()
for i in range(14):
print(jdata.button[i])
print(jdata.axes[0])
print(jdata.axes[1])
7. Demo例程介绍
examples_cpp/example_low.cpp 和 examples_py/test_low.py中运行了一个Bumi的21个自由度跑步策略(policy/policy.onnx)的sim2real(算法模型实机部署)的代码,根据策略提供了部分强化学习部署接口
| 函数名 | loadModel |
|---|---|
| 函数原型 | bool loadModel(std::string modelpath) |
| 功能概述 | 加载自有模型 |
| 参数 |
|
| 返回值 | true:加载成功;false:加载失败 |
| 备注 |
| 函数名 | onnxdatainit |
|---|---|
| 函数原型 | void onnxdatainit() |
| 功能概述 | 初始化onnx数据 |
| 参数 | 无 |
| 返回值 | 无 |
| 备注 |
| 函数名 | getmodelparam |
|---|---|
| 函数原型 | bool getmodelparam() |
| 功能概述 | 从yaml文件中获取模型参数 |
| 参数 | 无 |
| 返回值 | true:读取yaml文件成功;false:读取yaml文件失败 |
| 备注 |
| 函数名 | setparameter |
|---|---|
| 函数原型 | void setparameter(Command &cmd,bool* isfirst) |
| 功能概述 | 设置xyz整机控制参数 |
| 参数 |
|
| 返回值 | 无 |
| 备注 |
| 函数名 | updatestateestimation |
|---|---|
| 函数原型 | bool updatestateestimation() |
| 功能概述 | 更新状态,包括关节角度,IMU数据等从yaml文件中获取模型参数 |
| 参数 | 无 |
| 返回值 | true:读取yaml文件成功;false:读取yaml文件失败 |
| 备注 |
| 函数名 | computeObservation |
|---|---|
| 函数原型 | void computeObservation() |
| 功能概述 | 计算观测系数 |
| 参数 | 无 |
| 返回值 | 无 |
| 备注 |
| 函数名 | computeActions |
|---|---|
| 函数原型 | void computeActions() |
| 功能概述 | 计算最终的动作 |
| 参数 | 无 |
| 返回值 | 无 |
| 备注 |
手柄操作流程
| 使用步骤 | |
|---|---|
+ | 全身关节回0位进入阻尼模式 |
LB & - | 四肢微微弯曲,进入策略前准备模式 |
LB & X | 进入策略控制跑步模式 |
(七)音频开发
音频开发介绍
MediaController 通过 DDS Topic 与运控板语音模块建立通信链路,实现 Bumi 音频外设(扬声器、麦克风等)的控制,同时提供语音交互 Agent 配置及数据流管理能力。
注意 仅EDU版本的Bumi可以开发MediaController 开源接口如下:
状态控制与获取接口:控制唤醒、休眠、模块重启,运⾏状态获取,错误信息获取;
通⽤配置接口:通⽤参数配置和获取接口,包括:⽆对话休眠超时时间、唤醒词、唤醒回复词,休眠回复词,以及⾳视频数据流控制;
⾳频接口:⾳频流推送与获取,⾳频控制指令(暂停恢复,⾳量调节等)
视频接口,视频流推送与获取,视频控制指令(暂停恢复等)
MediaController架构图


(1)媒体服务状态与数据上报
当客户端 SDK 与机器人媒体服务程序建立连接后,媒体服务程序会持续向客户端推送机器人实时媒体状态信息,包括:
-
内部音视频数据流持续获取(只有不带算力板的Bumi可以获取内部视频流)
-
agent部分配置信息上报 (第一次主动获取,后面发生改变后上报)
-
脱敏加工视频流获取(带算力板的版本需持续发布外部视频流给音视频交互系统)
(2)媒体数据流及配置数据下发
-
发布 外部音频流 数据给到agent输入 或 给到内部扬声器输出
-
发布 外部视频流 数据给到agent识别
-
agent部分配置信息修改,如:音量,超时时间,唤醒词,唤醒回复词,休眠回复词,数据流导向开关等
采集信息输入输出数据当前仅支持:channels=8,sample_rate=16000,format=2(小端16位)

播放信息输入输出数据当前仅支持:channels=2,sample_rate=16000,format=2(小端16位)

采集数据和播放数据为交错排列
MediaController启动流程图

MediaController 常用参数
DDS报文头Header结构
| 参数名称 | 定义原型 | 成员 | 说明 |
|---|---|---|---|
| Header | | message_id | DDS 报文ID |
| timestamp_us | us时间戳 | ||
| sn | 当前Bumi设备的SN编号 |
系统状态控制
| SystemControlType | |
|---|---|
| 枚举 | 说明 |
| TO_WAKEUP | 唤醒音视频交互系统agent |
| TO_SLEEP | 休眠音视频交互系统agent |
| TO_RESET | 重启音视频交互系统agent |
系统状态
| 参数名称 | 定义原型 | 成员 | 说明 |
|---|---|---|---|
| SystemStatus | | header | DDS 报文头 |
| value | agent状态 | ||
| reason | 状态原因 |
| WorkStatus | |
|---|---|
| 枚举 | 说明 |
| READY | 就绪状态 |
| SLEEPED | 休眠状态 |
| WAKEUPED | 唤醒状态 |
| EXIT | 退出状态 |
| StatusChangeReason | |
|---|---|
| 枚举 | 说明 |
| SYSTEM_LAUNCH | 系统启动 |
| CMD_RESET | 指令重启 |
| AUDIO_WAKEUPED | 语音唤醒 |
| CMD_WAKEUPED | 指令唤醒 |
| AUDIO_SLEEPED | 语音休眠 |
| CMD_SLEEPED | 指令休眠 |
| TIMEOUT_SLEEPED | 超时休眠 |
| ERROR_SLEEPED | 错误休眠 |
语音唤醒指通过实际人机语音交互触发;指令唤醒指通过DDS或其他指令形式触发;
系统错误
| 参数名称 | 定义原型 | 成员 | 说明 |
|---|---|---|---|
| SystemStatus | | header | DDS 报文头 |
| code | 错误码 | ||
| message | 错误信息 |
音频流数据
| 参数名称 | 定义原型 | 成员 | 说明 |
|---|---|---|---|
| AudioStream | | header | DDS 报文头 |
| timestamp_us | 时间戳(us) | ||
| channels | 通道数 | ||
| sample_rate | 采样率 | ||
| format | 数据格式 | ||
| duration_ms | 时间(ms) | ||
| audio_data | 音频数据 |
视频流数据
| 参数名称 | 定义原型 | 成员 | 说明 |
|---|---|---|---|
| VideoStream | | header | DDS 报文头 |
| timestamp_us | 时间戳(us) | ||
| format | 格式: 1: YUYV 目前仅支持YUYV格式 | ||
| width | 帧横向像素 | ||
| height | 帧纵向像素 | ||
| fps | 帧率 | ||
| video_data | 帧图像数据 |
MediaController 常用接口
| MediaController接口 | ||
|---|---|---|
| 接口名称 | 接口描述 | 返回类型 |
| Instance | 获取MediaController单例指针 | 对象指针 |
| init | MediaController对象初始化 | bool |
| set_system_control | 设置语音交互系统控制状态 | 无 |
| subscribe_system_status | 订阅音视频交互系统状态信息 | 无 |
| subscribe_system_error | 订阅音视频交互系统错误状态信息 | 无 |
| get_volume | 获取当前音视频交互系统音量 范围:0~200 | int |
| set_volume | 设置当前音视频交互系统音量 范围:0~200 | 无 |
| get_timeout | 获取无响应进入休眠时间 | int |
| set_timeout | 设置无响应进入休眠时间 | 无 |
| get_audio_cue_enable | 获取音视频交互系统提示音是否开启状态 | bool |
| set_audio_cue_enable | 设置音视频交互系统提示音是否开启状态 | 无 |
| get_internal_capture_audio_data_to_agent_enable | 获取内部麦克风采集音频流输入到agent 是否开启状态 | bool |
| set_internal_capture_audio_data_to_agent_enable | 设置内部麦克风采集音频流输入到agent 是否开启状态 | 无 |
| get_external_custom_audio_data_to_agent_enable | 获取外部音频流输入给agent是否开启状态 | bool |
| set_external_custom_audio_data_to_agent_enable | 设置外部音频流输入给agent是否开启状态 | 无 |
| get_internal_agent_audio_data_to_playback_enable | 获取agent音频流输出到内部扬声器是否开启状态 | bool |
| set_internal_agent_audio_data_to_playback_enable | 设置agent音频流输出到内部扬声器是否开启状态 | 无 |
| get_external_custom_audio_data_to_playback_enable | 获取外部音频流输出到内部扬声器是否开启状态 | bool |
| set_external_custom_audio_data_to_playback_enable | 设置外部音频流输出到内部扬声器是否开启状态 | 无 |
| get_internal_capture_video_data_to_agent_enable | 获取内部视频流输入给agent是否开启状态 | bool |
| set_internal_capture_video_data_to_agent_enable | 设置内部视频流输入给agent是否开启状态 | 无 |
| get_external_custom_video_data_to_agent_enable | 获取外部视频流输入给agent是否开启状态 | bool |
| set_external_custom_video_data_to_agent_enable | 设置外部视频流输入给agent是否开启状态 | 无 |
| get_external_custom_audio_data_to_agent_use_internal_3a | 获取外部音频流输入给agent采用内部3a算法是否开启状态 | bool |
| set_external_custom_audio_data_to_agent_use_internal_3a | 设置外部音频流输入给agent采用内部3a算法是否开启状态 | 无 |
| get_wakeup_response_words | 获取唤醒回复词 | string |
| set_wakeup_response_words | 设置唤醒回复词 | 无 |
| get_sleep_response_words | 获取休眠回复词 | string |
| set_sleep_response_words | 设置休眠回复词 | 无 |
| get_wakeup_words | 获取所有唤醒词 | string |
| add_wakeup_words | 添加唤醒词 | bool |
| reset_wakeup_words | 恢复出厂默认唤醒词 | 无 |
| subscribe_internal_audio_capture | 订阅内部麦克风采集到的音频流 | 无 |
| subscribe_internal_audio_playback | 订阅机器人内部扬声器播放的音频流 | 无 |
| subscribe_internal_video_capture<br /> | 订阅机器人内camera采集的视频流(仅不带算力板的Bumi可用) | VideoStream结构体<br /> |
| subscribe_internal_video_desensed | 订阅音视频交互系统加工后的脱敏视频流(带算力板的Bumi需要持续发布外部视频流可用) | VideoStream结构体 |
| pause_video_capture | 暂停机器人内部camera数据采集(仅不带算力板的Bumi可用) | 无 |
| resume_video_capture | 恢复机器人内部camera数据采集(仅不带算力板的Bumi可用) | 无 |
| publish_external_video_stream | 发布外部视频流给到音视频交互系统 | 无 |
| publish_external_audio_stream | 发布外部音频流输入给agent | 无 |
| publish_external_audio_playback_stream | 发布外部音频流输出给内部扬声器 | 无 |
| pause_audio_capture | 暂停内部麦克风音频流采集 | 无 |
| resume_audio_capture | 恢复内部麦克风音频流采集 | 无 |
| pause_audio_playback | 暂停内部扬声器音频流输出 | 无 |
| resume_audio_playback | 恢复内部扬声器音频流输出 | 无 |
所有的set agent配置接口(如:改音量,改数据开关等)调用频率不能小于500ms,否则可能会导致语音交互系统崩溃,如果出现此问题,请联系松延售后
获取MediaController对象单例
| 函数名 | instance |
|---|---|
| 函数原型 | static MediaController *Instance() |
| 功能概述 | 获取 MediaController单例 |
| 参数 | 无 |
| 返回值 | MediaController对象单例指针 |
| 备注 |
C++示例:
MediaController *ctrl = MediaController::Instance();
Python示例:
ctrl = MediaController.instance()
MediaController对象初始化
| 函数名 | init |
|---|---|
| 函数原型 | bool init() |
| 功能概述 | MediaController对象初始化 |
| 参数 | 无 |
| 返回值 | bool |
| 备注 |
C++示例:
ctrl->init()
Python示例:
ctrl.init()
设置音视频交互系统状态
| 函数名 | set_system_control |
|---|---|
| 函数原型 | void set_system_control(media::SystemControlType type, bool is_need_reply); |
| 功能概述 | 设置音视频交互系统状态(唤醒、休眠、重启) |
| 参数 | - type:系统状态 - is_need_reply:是否需要触发 唤醒/休眠 回复词 |
| 返回值 | 无 |
| 备注 |
C++示例:
ctrl->set_system_control(media::SystemControlType::TO_WAKEUP, true);
Python示例:
ctrl.set_system_control(media::SystemControlType::TO_WAKEUP, true);
订阅音视频交互系统系统状态信息
| 函数名 | subscribe_system_status |
|---|---|
| 函数原型 | void subscribe_system_status(SystemstatusCallback callback); |
| 功能概述 | 订阅音视频交互系统状态信息 |
| 参数 | - callback:当状态改变时,需要触发的回调 |
| 返回值 | 无 |
| 备注 |
C++示例:
ctrl->subscribe_system_status([&](const media::SystemStatus &status){
printf("status is %d \r\n" , static_cast<int>(status.value));
});
Python示例:
def on_status_switch(status):
print(status.value)
ctrl.subscribe_system_status(on_status_switch)
订阅音视频交互系统系统错误信息
| 函数名 | subscribe_system_error |
|---|---|
| 函数原型 | void subscribe_system_error(SystemerrorCallback callback); |
| 功能概述 | 订阅音视频交互系统系统错误信息 |
| 参数 | - callback:当有错误信息dds报文所触发的回调 |
| 返回值 | 无 |
| 备注 |
C++示例:
ctrl->subscribe_system_error([&](const media::SystemError &error){
printf("status is %s \r\n", error.message.c_str());
});
Python示例:
def on_error(error):
print(error.message)
ctrl.subscribe_system_error(on_error)
获取当前音量
| 函数名 | get_volume |
|---|---|
| 函数原型 | int get_volume() |
| 功能概述 | 获取当前音视频交互系统音量 |
| 参数 | 无 |
| 返回值 | int,音量值,范围:0~200 |
| 备注 |
C++示例:
int volume = ctrl->get_volume();
std::cout << volume << std::endl;
Python示例:
volume = ctrl.get_volume()
print(volume)
设置当前音量
| 函数名 | set_volume |
|---|---|
| 函数原型 | void set_volume(int volume) |
| 功能概述 | 设置当前音视频交互系统音量 |
| 参数 | volume:音量值,范围:0~200 |
| 返回值 | 无 |
| 备注 |
C++示例:
ctrl->set_volume(100);
Python示例:
ctrl.set_volume(100)
获取无响应进入休眠时间
| 函数名 | get_timeout |
|---|---|
| 函数原型 | int get_timeout() |
| 功能概述 | 获取无响应进入休眠时间 |
| 参数 | 无 |
| 返回值 | int,超时时间(ms) |
| 备注 |
C++示例:
int timeout = ctrl->get_timeout();
std::cout << timeout << std::endl;
Python示例:
timeout = ctrl.get_timeout()
print(timeout)
设置无响应进入休眠时间
| 函数名 | set_timeout |
|---|---|
| 函数原型 | void set_timeout(int timeout) |
| 功能概述 | 设置无响应进入休眠时间 |
| 参数 | timeout:超时时间(ms) |
| 返回值 | 无 |
| 备注 |
C++示例:
ctrl->set_timeout(3000);
Python示例:
ctrl.set_timeout(3000)
获取提示音是否开启
| 函数名 | get_audio_cue_enable |
|---|---|
| 函数原型 | bool get_audio_cue_enable() |
| 功能概述 | 获取音视频交互系统提示音是否开启状态 |
| 参数 | 无 |
| 返回值 | bool |
| 备注 |
C++示例:
bool enabled = ctrl->get_audio_cue_enable();
std::cout << (enabled ? "true" : "false") << std::endl;
Python示例:
enabled = ctrl.get_audio_cue_enable()
print(enabled)
设置提示音是否开启
| 函数名 | set_audio_cue_enable |
|---|---|
| 函数原型 | void set_audio_cue_enable(bool enable) |
| 功能概述 | 设置音视频交互系统提示音是否开启状态 |
| 参数 | enable:true开启,false关闭 |
| 返回值 | 无 |
| 备注 |
C++示例:
ctrl->set_audio_cue_enable(true);
Python示例:
ctrl.set_audio_cue_enable(True)
获取内部麦克风采集音频流输入到agent是否开启
| 函数名 | get_internal_capture_audio_data_to_agent_enable |
|---|---|
| 函数原型 | bool get_internal_capture_audio_data_to_agent_enable() |
| 功能概述 | 获取内部麦克风采集音频流输入到agent是否开启状态 |
| 参数 | 无 |
| 返回值 | bool |
| 备注 |
C++示例:
bool enabled = ctrl->get_internal_capture_audio_data_to_agent_enable();
std::cout << (enabled ? "true" : "false") << std::endl;
Python示例:
enabled = ctrl.get_internal_capture_audio_data_to_agent_enable()
print(enabled)
设置内部麦克风采集音频流输入到agent是否开启
| 函数名 | set_internal_capture_audio_data_to_agent_enable |
|---|---|
| 函数原型 | void set_internal_capture_audio_data_to_agent_enable(bool enable) |
| 功能概述 | 设置内部麦克风采集音频流输入到agent是否开启状态 |
| 参数 | enable:true开启,false关闭 |
| 返回值 | 无 |
| 备注 |
C++示例:
ctrl->set_internal_capture_audio_data_to_agent_enable(true);
Python示例:
ctrl.set_internal_capture_audio_data_to_agent_enable(True)
获取外部音频流输入给agent是否开启
| 函数名 | get_external_custom_audio_data_to_agent_enable |
|---|---|
| 函数原型 | bool get_external_custom_audio_data_to_agent_enable() |
| 功能概述 | 获取外部音频流输入给agent是否开启状态 |
| 参数 | 无 |
| 返回值 | bool,true表示已开启,false表示已关闭 |
| 备注 |
C++示例:
bool enabled = ctrl->get_external_custom_audio_data_to_agent_enable();
std::cout << (enabled ? "true" : "false") << std::endl;
Python示例:
enabled = ctrl.get_external_custom_audio_data_to_agent_enable()
print(enabled)
设置外部音频流输入给agent是否开启
| 函数名 | set_external_custom_audio_data_to_agent_enable |
|---|---|
| 函数原型 | void set_external_custom_audio_data_to_agent_enable(bool enable) |
| 功能概述 | 设置外部音频流输入给agent是否开启状态 |
| 参数 | enable:true开启,false关闭 |
| 返回值 | 无 |
| 备注 |
C++示例:
ctrl->set_external_custom_audio_data_to_agent_enable(true);
Python示例:
ctrl.set_external_custom_audio_data_to_agent_enable(True)
获取agent音频流输出到内部扬声器是否开启
| 函数名 | get_internal_agent_audio_data_to_playback_enable |
|---|---|
| 函数原型 | bool get_internal_agent_audio_data_to_playback_enable() |
| 功能概述 | 获取agent音频流输出到内部扬声器是否开启状态 |
| 参数 | 无 |
| 返回值 | bool,true表示已开启,false表示已关闭 |
| 备注 |
C++示例:
bool enabled = ctrl->get_internal_agent_audio_data_to_playback_enable();
std::cout << (enabled ? "true" : "false") << std::endl;
Python示例:
enabled = ctrl.get_internal_agent_audio_data_to_playback_enable()
print(enabled)
设置agent音频流输出到内部扬声器是否开启
| 函数名 | set_internal_agent_audio_data_to_playback_enable |
|---|---|
| 函数原型 | void set_internal_agent_audio_data_to_playback_enable(bool enable) |
| 功能概述 | 设置agent音频流输出到内部扬声器是否开启状态 |
| 参数 | enable:true开启,false关闭 |
| 返回值 | 无 |
| 备注 |
C++示例:
ctrl->set_internal_agent_audio_data_to_playback_enable(true);
Python示例:
ctrl.set_internal_agent_audio_data_to_playback_enable(True)
获取外部音频流输出到内部扬声器是否开启
| 函数名 | get_external_custom_audio_data_to_playback_enable |
|---|---|
| 函数原型 | bool get_external_custom_audio_data_to_playback_enable() |
| 功能概述 | 获取外部音频流输出到内部扬声器是否开启状态 |
| 参数 | 无 |
| 返回值 | bool,true开启,false关闭 |
| 备注 |
C++示例:
bool enabled = ctrl->get_external_custom_audio_data_to_playback_enable();
std::cout << (enabled ? "true" : "false") << std::endl;
Python示例:
enabled = ctrl.get_external_custom_audio_data_to_playback_enable()
print(enabled)
设置外部音频流输出到内部扬声器是否开启
| 函数名 | set_external_custom_audio_data_to_playback_enable |
|---|---|
| 函数原型 | void set_external_custom_audio_data_to_playback_enable(bool enable) |
| 功能概述 | 设置外部音频流输出到内部扬声器是否开启状态 |
| 参数 | enable:true开启,false关闭 |
| 返回值 | 无 |
| 备注 |
C++示例:
ctrl->set_external_custom_audio_data_to_playback_enable(true);
Python示例:
ctrl.set_external_custom_audio_data_to_playback_enable(True)
获取内部视频流输入给agent是否开启
| 函数名 | get_internal_capture_video_data_to_agent_enable |
|---|---|
| 函数原型 | bool get_internal_capture_video_data_to_agent_enable() |
| 功能概述 | 获取内部视频流输入给agent是否开启状态 |
| 参数 | 无 |
| 返回值 | bool,true表示已开启,false表示已关闭 |
| 备注 |
C++示例:
bool enabled = ctrl->get_internal_capture_video_data_to_agent_enable();
std::cout << (enabled ? "true" : "false") << std::endl;
Python示例:
enabled = ctrl.get_internal_capture_video_data_to_agent_enable()
print(enabled)
设置内部视频流输入给agent是否开启
| 函数名 | set_internal_capture_video_data_to_agent_enable |
|---|---|
| 函数原型 | void set_internal_capture_video_data_to_agent_enable(bool enable) |
| 功能概述 | 设置内部视频流输入给agent是否开启状态 |
| 参数 | enable:true开启,false关闭 |
| 返回值 | 无 |
| 备注 |
C++示例:
ctrl->set_internal_capture_video_data_to_agent_enable(true);
Python示例:
ctrl.set_internal_capture_video_data_to_agent_enable(True)
获取外部视频流输入给agent是否开启
| 函数名 | get_external_custom_video_data_to_agent_enable |
|---|---|
| 函数原型 | bool get_external_custom_video_data_to_agent_enable() |
| 功能概述 | 获取外部视频流输入给agent是否开启状态 |
| 参数 | 无 |
| 返回值 | bool,true表示已开启,false表示已关闭 |
| 备注 |
C++示例:
bool enabled = ctrl->get_external_custom_video_data_to_agent_enable();
std::cout << (enabled ? "true" : "false") << std::endl;
Python示例:
enabled = ctrl.get_external_custom_video_data_to_agent_enable()
print(enabled)
设置外部视频流输入给agent是否开启
| 函数名 | set_external_custom_video_data_to_agent_enable |
|---|---|
| 函数原型 | void set_external_custom_video_data_to_agent_enable(bool enable) |
| 功能概述 | 设置外部视频流输入给agent是否开启状态 |
| 参数 | enable:true开启,false关闭 |
| 返回值 | 无 |
| 备注 |
C++示例:
ctrl->set_external_custom_video_data_to_agent_enable(true);
Python示例:
ctrl.set_external_custom_video_data_to_agent_enable(True)
获取外部音频流输入给agent采用内部3a算法是否开启
| 函数名 | get_external_custom_audio_data_to_agent_use_internal_3a |
|---|---|
| 函数原型 | bool get_external_custom_audio_data_to_agent_use_internal_3a() |
| 功能概述 | 获取外部音频流输入给agent采用内部3a算法是否开启状态 |
| 参数 | 无 |
| 返回值 | bool,true表示已开启,false表示已关闭 |
| 备注 |
C++示例:
bool enabled = ctrl->get_external_custom_audio_data_to_agent_use_internal_3a();
std::cout << (enabled ? "true" : "false") << std::endl;
Python示例:
enabled = ctrl.get_external_custom_audio_data_to_agent_use_internal_3a()
print(enabled)
设置外部音频流输入给agent采用内部3a算法是否开启
| 函数名 | set_external_custom_audio_data_to_agent_use_internal_3a |
|---|---|
| 函数原型 | void set_external_custom_audio_data_to_agent_use_internal_3a(bool enable) |
| 功能概述 | 设置外部音频流输入给agent采用内部3a算法是否开启状态 |
| 参数 | enable:true开启,false关闭 |
| 返回值 | 无 |
| 备注 |
C++示例:
ctrl->set_external_custom_audio_data_to_agent_use_internal_3a(true);
Python示例:
ctrl.set_external_custom_audio_data_to_agent_use_internal_3a(True)
获取唤醒回复词
| 函数名 | get_wakeup_response_words |
|---|---|
| 函数原型 | string get_wakeup_response_words() |
| 功能概述 | 获取唤醒回复词 |
| 参数 | 无 |
| 返回值 | string,当前唤醒回复词 |
| 备注 |
C++示例:
std::string words = ctrl->get_wakeup_response_words();
std::cout << words << std::endl;
Python示例:
words = ctrl.get_wakeup_response_words()
print(words)
设置唤醒回复词
| 函数名 | set_wakeup_response_words |
|---|---|
| 函数原型 | void set_wakeup_response_words(string words) |
| 功能概述 | 设置唤醒回复词 |
| 参数 | words:唤醒回复词内容 |
| 返回值 | 无 |
| 备注 |
C++示例:
ctrl->set_wakeup_response_words("我在");
Python示例:
ctrl.set_wakeup_response_words("我在")
获取休眠回复词
| 函数名 | get_sleep_response_words |
|---|---|
| 函数原型 | string get_sleep_response_words() |
| 功能概述 | 获取休眠回复词 |
| 参数 | 无 |
| 返回值 | string,当前休眠回复词 |
| 备注 |
C++示例:
std::string words = ctrl->get_sleep_response_words();
std::cout << words << std::endl;
Python示例:
words = ctrl.get_sleep_response_words()
print(words)
设置休眠回复词
| 函数名 | set_sleep_response_words |
|---|---|
| 函数原型 | void set_sleep_response_words(string words) |
| 功能概述 | 设置休眠回复词 |
| 参数 | words:休眠回复词内容 |
| 返回值 | 无 |
| 备注 |
C++示例:
ctrl->set_sleep_response_words("好的,我先休息了");
Python示例:
ctrl.set_sleep_response_words("好的,我先休息了")
获取所有唤醒词
| 函数名 | get_wakeup_words |
|---|---|
| 函数原型 | string get_wakeup_words() |
| 功能概述 | 获取所有唤醒词 |
| 参数 | 无 |
| 返回值 | string,当前所有唤醒词 |
| 备注 |
每个唤醒词之间必须有换行符(\n)
C++示例:
std::string words = ctrl->get_wakeup_words();
std::cout << words << std::endl;
Python示例:
words = ctrl.get_wakeup_words()
print(words)
添加唤醒词
| 函数名 | add_wakeup_words |
|---|---|
| 函数原型 | bool add_wakeup_words(const std::string &words); |
| 功能概述 | 添加新的唤醒词 |
| 参数 | - words:新唤醒词字符串 |
| 返回值 | bool:是否通过内部正则表达式添加成功 |
| 备注 | 正则表达式:(^(((([a-z]+) )?([^\s]+) ))+@(.+)$) [拼音(包含声母韵母] @对应名称例:b ù m ī @布米 |
C++示例:
if (ctrl->add_wakeup_words("b ù m ī @布米"))
std::cout << "添加成功" << std::endl;
else
std::cout << "添加失败" << std::endl;
Python示例:
if ctrl.add_wakeup_words("b ù m ī @布米"):
print("添加成功")
else:
print("添加失败")
重置唤醒词
| 函数名 | reset_wakeup_words |
|---|---|
| 函数原型 | void reset_wakeup_words(); |
| 功能概述 | 恢复默认出厂唤醒词 |
| 参数 | 无 |
| 返回值 | 无 |
| 备注 |
C++示例:
ctrl->reset_wakeup_words();
Python示例:
ctrl.reset_wakeup_words();
订阅机器人内部麦克风采集到的音频流
| 函数名 | subscribe_internal_audio_capture |
|---|---|
| 函数原型 | void subscribe_internal_audio_capture(AudiostreamCallback callback); |
| 功能概述 | 订阅机器人内部麦克风采集到的音频流 |
| 参数 | - callback:处理音频流数据的回调函数 |
| 返回值 | 无 |
| 备注 | 采集到的数据为8通道数据,前四个通道为Bumi头顶四个麦克风,第五第六通道为预留通道,第七第八通道为扬声器回采 |
C++示例:
ctrl->subscribe_internal_audio_capture(
[&](const media::AudioStream &stream) {
std::lock_guard<std::mutex> lk(mtx);
if (channels == 0) {
channels = stream.channels;
sample_rate = stream.sample_rate;
}
pcm.insert(pcm.end(), stream.audio_data.begin(),
stream.audio_data.end());
});
Python示例:
def on_audio(stream):
with lock:
if channels_ref[0] == 0:
channels_ref[0] = stream.channels
sample_rate_ref[0] = stream.sample_rate
pcm_all.extend(stream.audio_data)
ctrl.subscribe_internal_audio_capture(on_audio)
订阅机器人内部扬声器播放的音频流
| 函数名 | subscribe_internal_audio_playback |
|---|---|
| 函数原型 | void subscribe_internal_audio_playback(AudiostreamCallback callback); |
| 功能概述 | 订阅机器人内部扬声器播放的音频流 |
| 参数 | - callback:处理音频流数据的回调函数 |
| 返回值 | 无 |
| 备注 | 采集到的数据为Bumi本体扬声器的2通道数据 |
C++示例:
ctrl->subscribe_internal_audio_playback(
[&](const media::AudioStream &stream) {
std::lock_guard<std::mutex> lk(mtx);
if (channels == 0) {
channels = stream.channels;
sample_rate = stream.sample_rate;
}
pcm.insert(pcm.end(), stream.audio_data.begin(),
stream.audio_data.end());
});
Python示例:
def on_audio(stream):
with lock:
if channels_ref[0] == 0:
channels_ref[0] = stream.channels
sample_rate_ref[0] = stream.sample_rate
pcm_all.extend(stream.audio_data)
ctrl.subscribe_internal_audio_playback(on_audio)
订阅机器人内camera采集的视频流(仅不带算力板Bumi可用此接口)
| 函数名 | subscribe_internal_video_capture |
|---|---|
| 函数原型 | void subscribe_internal_video_capture(VideostreamCallback callback); |
| 功能概述 | 订阅机器人内camera采集的视频流 |
| 参数 | - callback:处理视频流数据的回调函数 |
| 返回值 | 无 |
| 备注 | 仅不带算力板的Bumi可用 |
C++示例:
ctrl->subscribe_internal_video_capture(
[&](const media::VideoStream &stream) {
printf(
"[DEBUG] video frame: %ux%u format=%u data=%zu bytes\n",
stream.width, stream.height, stream.format,
stream.video_data.size());
if (got.exchange(true))
return;
save_video_frame("internal_video_capture", stream);
});
Python示例:
def on_video(stream):
if got.is_set():
return
result[0] = stream
got.set()
ctrl.subscribe_internal_video_capture(on_video)
订阅音视频交互系统加工后的脱敏视频流
| 函数名 | subscribe_internal_video_desensed |
|---|---|
| 函数原型 | void subscribe_internal_video_desensed(VideostreamCallback callback); |
| 功能概述 | 订阅音视频交互系统加工后的脱敏视频流(带算力板的Bumi需要持续发布外部视频流可用) |
| 参数 | - callback:处理视频流数据的回调函数 |
| 返回值 | 无 |
| 备注 | 带算力板的Bumi需要先持续发布外部视频流才可使用 |
C++示例:
ctrl->subscribe_internal_video_desensed(
[&](const media::VideoStream &stream) {
printf(
"[DEBUG] video frame: %ux%u format=%u data=%zu bytes\n",
stream.width, stream.height, stream.format,
stream.video_data.size());
if (got.exchange(true))
return;
save_video_frame("internal_video_desensed", stream);
});
Python示例:
def on_video(stream):
if got.is_set():
return
result[0] = stream
got.set()
ctrl.subscribe_internal_video_desensed(on_video)
获取机器人内部麦克风采集到的音频流
| 函数名 | get_audio_capture_data |
|---|---|
| 函数原型 | AudioStream get_audio_capture_data() |
| 功能概述 | 获取机器人内部麦克风采集到的音频流 |
| 参数 | 无 |
| 返回值 | AudioStream结构体 |
| 备注 | 采集到的数据为8通道数据,前四个通道为Bumi头顶四个麦克风,第五第六通道为预留通道,第七第八通道为扬声器回采 |
C++示例:
AudioStream audio = ctrl->get_audio_capture_data();
std::cout << "channels: " << audio.channels << std::endl;
std::cout << "sample_rate: " << audio.sample_rate << std::endl;
Python示例:
audio = ctrl.get_audio_capture_data()
print(f"channels: {audio.channels}")
print(f"sample_rate: {audio.sample_rate}")
获取机器人内部扬声器播放的音频流
| 函数名 | get_audio_playback_data |
|---|---|
| 函数原型 | AudioStream get_audio_playback_data() |
| 功能概述 | 获取机器人内部扬声器播放的音频流 |
| 参数 | 无 |
| 返回值 | AudioStream结构体 |
| 备注 | 采集到的数据为Bumi本体扬声器的2通道数据 |
C++示例:
AudioStream audio = ctrl->get_audio_playback_data();
std::cout << "channels: " << audio.channels << std::endl;
std::cout << "sample_rate: " << audio.sample_rate << std::endl;
Python示例:
audio = ctrl.get_audio_playback_data()
print(f"channels: {audio.channels}")
print(f"sample_rate: {audio.sample_rate}")
获取机器人内camera采集的视频流(仅不带算力板Bumi可用此接口)
| 函数名 | get_video_capture_data |
|---|---|
| 函数原型 | VideoStream get_video_capture_data() |
| 功能概述 | 获取机器人内camera采集的视频流 |
| 参数 | 无 |
| 返回值 | VideoStream结构体 |
| 备注 | 仅不带算力板的Bumi可用 |
C++示例:
VideoStream video = ctrl->get_video_capture_data();
std::cout << "width: " << video.width << std::endl;
std::cout << "height: " << video.height << std::endl;
Python示例:
video = ctrl.get_video_capture_data()
print(f"width: {video.width}")
print(f"height: {video.height}")
获取音视频交互系统加工后的脱敏视频流
| 函数名 | get_video_capture_desensed_data |
|---|---|
| 函数原型 | VideoStream get_video_capture_desensed_data() |
| 功能概述 | 获取音视频交互系统加工后的脱敏视频流(带算力板的Bumi需要持续发布外部视频流可用) |
| 参数 | 无 |
| 返回值 | VideoStream结构体 |
| 备注 | 带算力板的Bumi需要先持续发布外部视频流才可使用 |
C++示例:
VideoStream video = ctrl->get_video_capture_desensed_data();
std::cout << "width: " << video.width << std::endl;
std::cout << "height: " << video.height << std::endl;
Python示例:
video = ctrl.get_video_capture_desensed_data()
print(f"width: {video.width}")
print(f"height: {video.height}")
暂停机器人内部camera数据采集
| 函数名 | pause_video_capture |
|---|---|
| 函数原型 | void pause_video_capture() |
| 功能概述 | 暂停机器人内部camera数据采集(仅不带算力板的Bumi可用) |
| 参数 | 无 |
| 返回值 | 无 |
| 备注 | 仅不带算力板的Bumi可用 |
C++示例:
ctrl->pause_video_capture();
Python示例:
ctrl.pause_video_capture()
恢复机器人内部camera数据采集
| 函数名 | resume_video_capture |
|---|---|
| 函数原型 | void resume_video_capture() |
| 功能概述 | 恢复机器人内部camera数据采集(仅不带算力板的Bumi可用) |
| 参数 | 无 |
| 返回值 | 无 |
| 备注 | 仅不带算力板的Bumi可用 |
C++示例:
ctrl->resume_video_capture();
Python示例:
ctrl.resume_video_capture()
发布外部视频流给到音视频交互系统
| 函数名 | publish_external_video_stream |
|---|---|
| 函数原型 | void publish_external_video_stream(VideoStream stream) |
| 功能概述 | 发布外部视频流给到音视频交互系统 |
| 参数 | stream:VideoStream结构体,包含视频帧数据 |
| 返回值 | 无 |
| 备注 |
C++示例:
VideoStream stream;
// 填充stream数据 ...
ctrl->publish_external_video_stream(stream);
Python示例:
stream = VideoStream()
# 填充stream数据 ...
ctrl.publish_external_video_stream(stream)
发布外部音频流输入给agent
| 函数名 | publish_external_audio_stream |
|---|---|
| 函数原型 | void publish_external_audio_stream(AudioStream stream) |
| 功能概述 | 发布外部音频流输入给agent |
| 参数 | stream:AudioStream结构体,包含音频数据 |
| 返回值 | 无 |
| 备注 |
C++示例:
AudioStream stream;
// 填充stream数据 ...
ctrl->publish_external_audio_stream(stream);
Python示例:
stream = AudioStream()
# 填充stream数据 ...
ctrl.publish_external_audio_stream(stream)
发布外部音频流输出给内部扬声器
| 函数名 | publish_external_audio_playback_stream |
|---|---|
| 函数原型 | void publish_external_audio_playback_stream(AudioStream stream) |
| 功能概述 | 发布外部音频流输出给内部扬声器 |
| 参数 | stream:AudioStream结构体,包含音频数据 |
| 返回值 | 无 |
| 备注 |
C++示例:
AudioStream stream;
// 填充stream数据 ...
ctrl->publish_external_audio_playback_stream(stream);
Python示例:
stream = AudioStream()
# 填充stream数据 ...
ctrl.publish_external_audio_playback_stream(stream)
暂停内部麦克风音频流采集
| 函数名 | pause_audio_capture |
|---|---|
| 函数原型 | void pause_audio_capture() |
| 功能概述 | 暂停内部麦克风音频流采集 |
| 参数 | 无 |
| 返回值 | 无 |
| 备注 |
C++示例:
ctrl->pause_audio_capture();
Python示例:
ctrl.pause_audio_capture()
恢复内部麦克风音频流采集
| 函数名 | resume_audio_capture |
|---|---|
| 函数原型 | void resume_audio_capture() |
| 功能概述 | 恢复内部麦克风音频流采集 |
| 参数 | 无 |
| 返回值 | 无 |
| 备注 |
C++示例:
ctrl->resume_audio_capture();
Python示例:
ctrl.resume_audio_capture()
暂停内部扬声器音频流输出
| 函数名 | pause_audio_playback |
|---|---|
| 函数原型 | void pause_audio_playback() |
| 功能概述 | 暂停内部扬声器音频流输出 |
| 参数 | 无 |
| 返回值 | 无 |
| 备注 |
C++示例:
ctrl->pause_audio_playback();
Python示例:
ctrl.pause_audio_playback()
恢复内部扬声器音频流输出
| 函数名 | resume_audio_playback |
|---|---|
| 函数原型 | void resume_audio_playback() |
| 功能概述 | 恢复内部扬声器音频流输出 |
| 参数 | 无 |
| 返回值 | 无 |
| 备注 |
C++示例:
ctrl->resume_audio_playback();
Python示例:
ctrl.resume_audio_playback()
Demo 测试用例
SDK 提供了两个完整的示例程序,功能一致,分别用 C++ 和 Python 实现:
- C++:
examples_cpp/example_media.cpp编译后运行
./build/example_media <command> [args]
- Python:
examples_py/test_media.py运行
python3 test_media.py <command> [args]
所有输出文件默认保存在 SDK 根目录的 out/ 文件夹下。
用例列表
- 发布外部视频流作为 agent 输入
python3 test_media.py external_video [cam_id]
./build/example_media external_video [cam_id]
打开 USB 摄像头(cam_id 可选,C++ 版默认自动检测 /dev/video4→video2→video0,Python 版默认使用设备4),将 YUYV 格式视频帧通过 publish_external_video_stream 持续推送给 agent。按 Ctrl+C 停止,自动保存最后一帧为 out/external_video.png。
- 获取 agent 加工后的脱敏视频流截取一张图片
python3 test_media.py desensed_video
./build/example_media desensed_video
通过 get_video_capture_desensed_data 获取音视频交互系统脱敏处理后的视频流,截取一帧保存为 out/desensed_video.png。前置条件:需先运行 external_video 推送外部视频流,否则无法获取脱敏帧。
- 录制内部 speaker 播放的音频流
python3 test_media.py playback_audio
./build/example_media playback_audio
通过 get_audio_playback_data 持续采集机器人内部扬声器播放的音频数据,录制 10 秒后保存为 WAV 文件(C++: out/example_media_speaker.wav,Python: out/bumi_speaker.wav)。
- 录制内部 mic 采集的音频流
python3 test_media.py capture_audio
./build/example_media capture_audio
通过 get_audio_capture_data 持续采集机器人内部麦克风的音频数据(8 通道),录制 10 秒后保存为 WAV 文件(C++: out/example_media_mic.wav,Python:out/bumi_mic.wav)。如需通过接口播报,需将 8 通道数据转换为 2 通道。
- 发布外部音频流作为 agent 输入并采集回复
python3 test_media.py external_audio_ai <wav>
./build/example_media external_audio_ai <wav>
先调用 wakeup 唤醒 agent,然后通过 publish_external_audio_stream 将 WAV 文件的音频流逐帧发送给 agent 识别,同时通过 get_audio_playback_data 录制 agent 的语音回复(最长 10 秒),保存为 WAV 文件(C++: out/example_media_ai_reply.wav,Python: out/bumi_ai_reply.wav)。完成后调用 sleep 休眠 agent。
- 发布外部音频流作为 speaker 输出
python3 test_media.py external_audio_speaker <wav>
./build/example_media external_audio_speaker <wav>
通过 publish_external_audio_playback_stream 将 WAV 文件的音频流逐帧发送给机器人扬声器播放。C++ 版还支持不传文件参数时使用实时麦克风输入直接转发到扬声器。
- 获取内部视频流截取一张图片(非算力板机型)
python3 test_media.py internal_video
./build/example_media internal_video
通过 get_video_capture_data 获取机器人内部摄像头采集的视频流,截取一帧保存为 out/internal_video.png。仅不带算力板的 Bumi 可用。
(八)相机例程
EDU版本Bumi(BumiEDU_Pro、BumiEDU_MAX、BumiEDU_Tailor)相机硬件直接到算力板上,可以直接访问算力板上硬件接口获取数据
Intel D435i 相机例程请参考: https://github.com/IntelRealSense/librealsense
(九)快速开发
以下所有操作都是在Bumi算力板上进行,算力板本身已经安装好所需编译环境也可以通过docker部署编译环境
外挂开发部署环境请看:SDK编译环境部署流程
有线连接算力板 SSH登录
ssh noetix@192.168.55.101
无线连接算力板 SSH登录(无线IP可通过手机AppWfii连接中查看,算力板使用的运控板的Wifi模块)
ssh -p 2222 noetix@[机器人WIFI-IP]
1. SDK目录结构
.
├── build.sh # 编译脚本
├── CMakeLists.txt
├── config # 模型配置文件 DDS配置文件等
├── examples_cpp # C++ 示例代码
├── examples_py # python 示例代码
├── include # 头文件目录
├── lib # 库文件目录
├── LICENSE
├── policy # 模型策略文件目录
├── README.md
└── src # 源文件目录
2. docker开发环境镜像部署
注意:此镜像包为aarch64架构,仅在aarch64架构电脑上可部署
- 解压压缩包
tar -zxvf noetix_dds.tar.gz
解压出来后,压缩包内会有noetix_dds.tar 开发镜像文件 noetix_dds.yaml 配置部署文件
version: "3.8"
services:
noetix_dds:
image: noetix_dds:arm64
container_name: noetix_dds
network_mode: host
volumes:
- /home/noetix/work:/home/noetix/work:rw # 挂载工作目录
# /home/noetix/work 冒号前这部分要改成用户的工作目录,创建一个/home/noetix/work/路径目录
stdin_open: true
tty: true
- 部署
docker load -i noetix_dds.tar
docker images # 确认noetix_dds arm64 镜像是否存在
mkdir -p /home/noetix/work # 创建工作目录, 用户自行选择
docker compose -f noetix_dds.yaml up -d # 部署
docker ps # 检查 noetix_dds 是否存在
- 进入dock容器
docker exec -it noetix_dds /bin/bash
后续将DDS SDK 放入工作目录即可开始开发
3. 编译SDK
cd noetix_sdk_bumi
./build.sh # 一键编译脚本
编译成功后会在SDK根目录下生成可执行文件 example_low 和 example_high ,并且在build目录下生成highcontrol_py 以及 lowcontrol_py pybind库,供python调用
4. 启动程序
C++
cd noetix_sdk_bumi
sudo ./build/example_high # or sudo ./build/example_low
Python
cd noetix_sdk_bumi
python3 examples_py/test_low.py # python3 examples_py/test_high.py
调试过程中,请全程使用机器人吊架,以免错误程序失控造成损失
(十)常见问题及注意事项
- DDS客户端demo:运行报错(1)
ARM架构:
error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory
libssl1.1_1.1.1f-1ubuntu2.16_arm64.deb
sudo dpkg -i libssl1.1_1.1.1f-1ubuntu2.16_arm64.deb
X86架构:
error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory
libssl1.1_1.1.1f-1ubuntu2_amd64.deb
sudo dpkg -i libssl1.1_1.1.1f-1ubuntu2_amd64.deb
