Humanoid Platform · 人形
Master 人形机器人 SDK
Master(产品代号 X2)是 FF 紧凑型人形机器人。当前版本主打动作作品生态: 把动作工作室制作的自定义动作包上传到机器人并播放(舞蹈 / 表演动作), 配合电量、状态全套遥测。基础姿态与速度控制在路线图中逐步开放。
01概览与能力矩阵
| 能力域 | 方法 | 状态 | 说明 |
|---|---|---|---|
motion | do_preset() 播放上传动作 | ✅ live | 播放已上传的自定义动作作品(工作流) |
do_preset_uploaded() 上传并播放 | ✅ live | 一步完成上传 + 播放 | |
stop() | ✅ live | 停止 | |
stand() / damping() / cmd_vel() | ⏳ 规划 | 基础姿态 / 速度控制(下一阶段开放) | |
state | battery() / status() | ✅ live | 电量 / 状态机 |
joint_states() | ⏳ 规划 | 关节遥测 | |
vision | frame() | 🟡 部分 | 取帧接口完善中 |
audio | say() / play_wav() | ⏳ 规划 | TTS / 播放 |
display | — | ⏳ 规划 | 面屏表情 |
state.pose / navigation | — | ❌ | 本平台无 SLAM 位姿 |
arm | — | ❌ | 不单独暴露臂控(走全身动作作品) |
Master 的定位
Master 当前版本最强的能力是全身动作作品播放——配合动作工作室
(视频 → 动作训练 → 作品包)生态,开发者可以让机器人表演任意自制舞蹈 / 动作,
而不只是调用固定预置动作。
02安装
shell — 安装
# 在机器人上(aarch64)
pip install wheels/ff_sdk-0.1.0a0-cp310-cp310-linux_aarch64.whl
# 在 Linux 开发机上(x86_64)
pip install wheels/ff_sdk-0.1.0a0-cp310-cp310-linux_x86_64.whl
python -c "import ff_sdk; print(ff_sdk.__version__)"
03快速开始
hello_master.py
import asyncio, ff_sdk
async def main():
async with await ff_sdk.connect("X2-DEMO") as robot:
print(robot.diagnose()) # 体检:动作通道是否在线
print(robot.capabilities())
battery = await robot.state.battery()
print(f"电量 {battery.percent:.0%}")
status = await robot.state.status()
print(f"状态 {status}")
# 播放一个之前上传过的动作作品(名字 = <key>_<version>)
res = await robot.motion.do_preset("mydance_v1")
print(res)
asyncio.run(main())
安全须知
播放全身动作作品前确认机器人站立在四周 2m 空旷的平整地面,
动作包幅度未知时先在低速 / 小幅版本上验证。播放过程不要打断供电。
04连接与配置
connect()
async ff_sdk.connect(target: str, *, config: Config | None = None,
identity: Identity | None = None) -> Session
target 用 X2-<序列号> 形式。连接时 SDK 会自动探测动作通道
可达性,并把结果反映在 diagnose() 里。
环境变量
| 变量 | 默认 | 说明 |
|---|---|---|
FF_SDK_X2_MOTION_PROXY_URL | 自动探测 | 动作通道完整 URL 覆盖(如 http://<robot-ip>:<port>,跨网段时使用) |
FF_SDK_DRY_RUN | 关 | 设 1 干跑模式 |
FF_SDK_TRANSPORT_TIMEOUT | 5.0 | 单次操作超时(秒) |
FF_SDK_LOG_DIR | /var/log/ff_sdk | 日志目录 |
python — 显式指定动作通道
from ff_sdk import Config
cfg = Config.from_env()
cfg.extra["x2_motion_proxy_url"] = "http://192.168.1.50:5000"
robot = await ff_sdk.connect("X2-DEMO", config=cfg)
程序跑在哪
推荐与机器人同一局域网(或直接部署到机器人上)。dry-run 模式下任意电脑可运行,
所有动作调用返回占位结果。
05Session 与生命周期
| 成员 | 类型 | 说明 |
|---|---|---|
session.motion / .state / … | 能力访问器 | 不支持时 raise CapabilityNotSupported |
session.capabilities() | set[str] | 支持的能力域集合 |
session.diagnose() | DiagnosticReport | 健康体检(动作通道可达性等) |
await session.e_stop(reason) | — | 紧急停止 |
await session.close() | — | 断开连接 |
python
async with await ff_sdk.connect("X2-DEMO") as robot:
...
# 自动 close()
06motion · 运动控制
do_preset() —— 播放已上传的动作作品
async motion.do_preset(name: str, motion_type: str = "") -> MotionResult
| 参数 | 说明 |
|---|---|
name | 必须是 <key>_<version> 形式的已上传作品名(如 mydance_v1)。
没有下划线版本后缀的名字会被拒绝 —— 那是内置动作目录的命名(见 路线图)。 |
motion_type | 留空 = 模仿型动作;非空 = 基座型动作。按作品制作时的类型填。 |
do_preset_uploaded() —— 上传 + 播放一步到位
async motion.do_preset_uploaded(key: str, version: str, file_path: str,
motion_type: str = "foundation") -> MotionResult
把本地动作文件上传到机器人并立即播放。key 不要含下划线
(下划线是 key 与 version 的分隔符)。
python — 完整动作播放流程
# 路线 A:作品之前传过 → 直接按名字播
await robot.motion.do_preset("mydance_v1")
# 路线 B:新作品 → 上传并播放
await robot.motion.do_preset_uploaded(
key="mydance", version="v2",
file_path="./works/mydance_v2.bin",
motion_type="foundation",
)
# 停止
await robot.motion.stop()
动作作品从哪来?
动作作品由动作工作室生态产出:上传一段舞蹈视频 → 云端训练 → 导出机器人作品包。
SDK 负责“作品包 → 机器人”的最后一步。详见 动作作品工作流。
07动作作品工作流 ★
Master 的动作生态分三步:
| 步骤 | 谁来做 | 产物 |
|---|---|---|
| 1 · 制作 | 动作工作室(网页上传视频 / 音乐 → 训练) | 动作作品包(动作 + 配乐 + 表情) |
| 2 · 上传 | SDK do_preset_uploaded() 或工作室直传 | 机器人本地作品库新增 <key>_<version> |
| 3 · 播放 | SDK do_preset("<key>_<version>") | 机器人执行全身动作(含同步配乐 / 表情) |
命名规则
- 作品名 =
<key>_<version>,例如mydance_v1、kungfu_v3 key内不要用下划线(下划线保留为分隔符)- 同 key 多版本并存,按版本号选择播放
python — 作品版本管理示例
import ff_sdk
from ff_sdk.core.exceptions import CapabilityNotSupported
async def play_latest(robot, key: str, versions: list[str]):
"""按版本号从新到旧尝试播放,第一个成功的为准。"""
for ver in versions:
try:
res = await robot.motion.do_preset(f"{key}_{ver}")
if res.success:
return res
except CapabilityNotSupported:
continue
raise RuntimeError(f"作品 {key} 没有可播放的版本")
08state · 状态遥测
| 方法 | 状态 | 说明 |
|---|---|---|
await state.battery() | ✅ | BatteryState:percent(0–1) / voltage / is_charging |
await state.status() | ✅ | RobotStatus 状态机 |
await state.joint_states() | ⏳ | 关节遥测(规划中) |
await state.pose() | ❌ | 本平台无 SLAM,raise CapabilityNotSupported |
python — 播放前检查电量
battery = await robot.state.battery()
if battery.percent < 0.3:
print("电量低于 30%,全身动作建议先充电")
else:
await robot.motion.do_preset("mydance_v1")
09其他能力
vision(🟡 部分)
async vision.frame(source: str = "default") -> CameraFrame
取帧接口完善中,可用性以 capabilities() 运行时返回为准。
audio / display(⏳ 规划)
TTS 播报与面屏表情接口已定义,将在后续版本开放。当前调用会
raise CapabilityNotSupported。注意:动作作品包自带的配乐与表情不受影响
—— 它们随作品在机器人本体播放,不需要 audio/display 能力。
10跨平台 Skills
python
from ff_sdk import skills
# skills 在 Master 上自动选择可用的实现路径,
# 不可用时返回 {"ok": False, "message": ...} 而不是崩溃
result = await skills.wave(robot)
print(result) # {"ok": ..., "platform": "x2", ...}
写跨机器人代码时优先用 skills —— 同一行代码在 Aegis / Futurist / Navi 上都能跑。
11能力路线图
| 能力 | 当前 | 计划 |
|---|---|---|
| 上传动作作品播放 | ✅ live | — |
| 内置动作目录(招手 / 鞠躬 / 敬礼等) | ⏳ | 下一阶段经实时动作通道开放 do_preset("wave") 直调 |
stand() / damping() / cmd_vel() | ⏳ | 随实时控制通道开放 |
| 关节遥测 / 音频 / 表情 | ⏳ | 逐步开放 |
为什么有的预置动作现在调不了?
当前版本的动作通道只服务用户上传的自定义作品。内置动作目录走另一条
实时控制链路,将在后续 SDK 版本开放 —— 在那之前调用会得到带说明的
CapabilityNotSupported,不会静默失败。
12异常与诊断
| 异常 | 什么时候抛 |
|---|---|
FfSdkError | 所有 SDK 异常的根类 |
ConfigError | 配置无效 |
ConnectionError / TransportError / TimeoutError | 连接 / 线路 / 超时 |
PlatformError | 平台适配层翻译的底层错误 |
CapabilityNotSupported | 能力未开放 / 作品名不合规(错误信息会说明原因) |
EStopActiveError / StateError | 急停激活 / 状态不允许 |
python — MotionResult 检查
res = await robot.motion.do_preset("mydance_v1")
if not res.success:
print(f"播放失败: {res.message}")
print(res.details) # 服务端返回的细节,排错用
13示例索引
| 示例 | 内容 |
|---|---|
01_hello_connect.py | 第一次连接 + 诊断 + 紧急停止 |
02_diagnose.py | 体检报告详解 |
03_estop.py | 紧急停止 + 回调 + 重置 |
cookbook/context_manager.py | async with 上下文管理 |
cookbook/graceful_shutdown.py | 优雅关闭 |
cookbook/safety_watchdog.py | 安全看门狗 |
cookbook/diagnose_report.py | 诊断报告导出 |
14FAQ / 排错
| 现象 | 可能原因 | 解决 |
|---|---|---|
do_preset("wave") 被拒绝 | 内置动作目录尚未开放(见路线图) | 当前用上传作品(<key>_<version>),或用 skills.wave() |
| 作品播放返回失败 | 作品名拼错 / 该版本未上传 | 核对 <key>_<version>;用 do_preset_uploaded() 重传 |
| 连接成功但动作不响应 | 动作通道不可达(跨网段) | 看 diagnose();设 FF_SDK_X2_MOTION_PROXY_URL 指向机器人 |
state.pose() 报错 | 本平台无 SLAM | 预期行为,捕获 CapabilityNotSupported |