Aegis Quadruped Robot SDK
Aegis 四足机器人 SDK
Aegis (product codename D1) is FF's quadruped robot-dog lineup, covering point-foot, wheeled-foot, EDU, and Pro/Ultra variants. A single self-contained wheel controls walking, stunts, and the full telemetry suite — with no extra vendor software to install.
Aegis(产品代号 D1)是 FF 四足机器狗产品线,覆盖点足、轮足、EDU、Pro/Ultra 多个机型。 一个自包含 wheel 即可控制行走、特技和全套遥测 —— 不需要安装任何额外厂商软件。
01Overview & capability matrix概览与能力矩阵
Every capability call follows the uniform form robot.<capability>.<action>(). A capability the platform doesn't support will
raise CapabilityNotSupported — an explicit error, never a faked success.
所有能力调用都是 robot.<能力>.<动作>() 的统一形式。平台不支持的能力会
raise CapabilityNotSupported —— 明确报错,绝不假装成功。
| Capability能力域 | Method方法 | Status状态 | Notes说明 |
|---|---|---|---|
motion | cmd_vel() Velocity control速度控制 | ✅ live | Forward / strafe / turn, hardware-verified前进 / 横移 / 转向,真机验证 |
stand() / damping() | ✅ live | Stand / damping soft e-stop站立 / 阻尼软急停 | |
do_preset() Stunt特技 | ✅ live | Shake hand / jump / backflip / two-leg stand, etc., see Stunt actions握手 / 跳跃 / 后空翻 / 双腿站立等,见 特技动作 | |
stop() | ✅ live | Stop moving停止移动 | |
attitude_control() In-place attitude原地姿态 | ✅ live | Quadruped-only: in-place pitch / yaw / roll / stance height, see Motion control四足专属:原地俯仰 / 转头 / 侧倾 / 站高,见 运动控制 | |
state | battery() / status() | ✅ live | Battery, robot posture state machine电量、机器人姿态状态机 |
pose() Pose位姿 | ✅ live | World-frame position + Euler angles世界系位置 + 欧拉角 | |
joint_states() Joint telemetry关节遥测 | ✅ live | 12 joints point-foot / 16 joints wheeled-foot, see variant differences点足 12 关节 / 轮足 16 关节,见 机型差异 | |
get_imu() | ✅ live | Full IMU — quaternion + rpy + body angular velocity + body linear acceleration (via vendor SDK backend)完整 IMU —— 四元数 + rpy + 机体角速度 + 机体线加速度(经厂商 SDK 后端) | |
get_body_state() | ✅ live | Center-of-mass position + rpy + body/world velocity (CoM position also via pose())重心位置 + rpy + 机体/世界速度(重心位置也可经 pose()) | |
vision | frame() Grab frame取帧 | 🟡 partial🟡 部分 | Interface ready, coverage in progress接口就绪,覆盖完善中 |
display | set_led() | 🟡 partial🟡 部分 | LED effects; quadruped has no face screen, expression interfaces N/ALED 灯效;四足无面屏,表情类接口不适用 |
navigation | goto() etc.等 | 🟡 partial🟡 部分 | Patrol navigation stack integration in progress巡检导航栈对接中 |
audio | — | ⏳ planned⏳ 规划 | TTS / playback plannedTTS / 播放规划中 |
arm / checkin | — | ❌ | Quadruped has no arm; check-in N/A for this form factor四足无机械臂;考勤不适用本形态 |
variant.
variant 自动加载。
02Installation安装
The devkit's wheels/ directory ships Python 3.10 wheels for two architectures:
devkit 的 wheels/ 目录提供两个架构的 Python 3.10 wheel:
| wheel | Install on装在哪 | Purpose用途 |
|---|---|---|
ff_sdk-0.1.0a2-cp310-cp310-linux_aarch64.whl | The robot itself机器人本体 | Program runs on the robot (recommended, lowest latency)程序跑在机器人上(推荐,延迟最低) |
ff_sdk-0.1.0a2-cp310-cp310-linux_x86_64.whl | Linux dev machineLinux 开发机 | Remote control / development & debugging远程控制 / 开发调试 |
# On the robot (aarch64)
pip install wheels/ff_sdk-0.1.0a2-cp310-cp310-linux_aarch64.whl
# On the Linux dev machine (x86_64)
pip install wheels/ff_sdk-0.1.0a2-cp310-cp310-linux_x86_64.whl
# verify
python -c "import ff_sdk; print(ff_sdk.__version__)"
# 在机器人上(aarch64)
pip install wheels/ff_sdk-0.1.0a2-cp310-cp310-linux_aarch64.whl
# 在 Linux 开发机上(x86_64)
pip install wheels/ff_sdk-0.1.0a2-cp310-cp310-linux_x86_64.whl
# 验证
python -c "import ff_sdk; print(ff_sdk.__version__)"
03Quickstart快速开始
Step 1 · No robot needed: dry-run
第 1 步 · 不需要真机:dry-run
With FF_SDK_DRY_RUN=1 set, the SDK skips all real low-level calls and every API returns a sensible placeholder result —
useful for getting familiar with the API and validating your business logic:
设置 FF_SDK_DRY_RUN=1 后,SDK 跳过所有真实底层调用,每个 API 返回合理的占位结果 ——
用来熟悉 API、验证业务逻辑:
FF_SDK_DRY_RUN=1 python examples/01_hello_connect.py
Step 2 · Connect to a real robot
第 2 步 · 连接真机
import asyncio, ff_sdk
async def main():
dog = await ff_sdk.connect("D1-DEMO")
try:
report = dog.diagnose() # health check first
print(report)
await dog.motion.stand() # stand up
await asyncio.sleep(4)
await dog.motion.cmd_vel(linear=0.3) # move forward 0.3 m/s
await asyncio.sleep(2)
await dog.motion.stop()
battery = await dog.state.battery()
print(f"battery {battery.percent:.0%}")
await dog.motion.do_preset("shake_hand") # shake-hand stunt
await asyncio.sleep(dog.motion.preset_timeout("shake_hand"))
await dog.motion.damping() # finish: damping (soft e-stop)
finally:
await dog.close()
asyncio.run(main())
import asyncio, ff_sdk
async def main():
dog = await ff_sdk.connect("D1-DEMO")
try:
report = dog.diagnose() # 先体检
print(report)
await dog.motion.stand() # 站立
await asyncio.sleep(4)
await dog.motion.cmd_vel(linear=0.3) # 前进 0.3 m/s
await asyncio.sleep(2)
await dog.motion.stop()
battery = await dog.state.battery()
print(f"电量 {battery.percent:.0%}")
await dog.motion.do_preset("shake_hand") # 握手特技
await asyncio.sleep(dog.motion.preset_timeout("shake_hand"))
await dog.motion.damping() # 收尾:阻尼(软急停)
finally:
await dog.close()
asyncio.run(main())
backflip) require 2m clearance all around + a full battery. On any anomaly, immediately call
await dog.e_stop() or physically press the e-stop. Make it a habit to finish with damping().
backflip 后空翻)要求四周 2m 空旷 + 满电。任何异常立即
await dog.e_stop() 或物理按下急停。收尾习惯性调用 damping()。
04Connect & configure连接与配置
connect()
target identifies your robot in the form D1-<serial>; for simulation use mujoco://d1.
target 用 D1-<序列号> 形式标识你的机器人;仿真用 mujoco://d1。
Network modes
网络模式
| Mode模式 | How to connect怎么连 | What to put in hosthost 填什么 |
|---|---|---|
| Hotspot direct热点直连 (default)(默认) | Connect your computer to the robot's built-in WiFi hotspot电脑连机器人自带 WiFi 热点 | Leave blank (default hotspot gateway)不用填(默认热点网关) |
| Ethernet / LAN以太网 / 局域网 | Robot joins your router机器人接入你的路由器 | FF_SDK_D1_HOST=<robot-ip> |
The hotspot name / password for each model is on the body label or in the included manual.
各型号热点名称 / 密码见机身标签或随机说明书。
Environment variables
环境变量
| Variable变量 | Default默认 | Notes说明 |
|---|---|---|
FF_SDK_D1_HOST | Hotspot gateway热点网关 | Robot IP (required in LAN mode)机器人 IP(局域网模式必填) |
FF_SDK_D1_VARIANT | zsl-1w | Variant: zsl-1 point-foot / zsl-1w wheeled-foot, see Variant adaptation机型变体:zsl-1 点足 / zsl-1w 轮足,见 机型适配 |
FF_SDK_D1_FEEDBACK_PORT | 8080 | Telemetry feedback listen port遥测反馈监听端口 |
FF_SDK_DRY_RUN | Off关 | Set to 1 to enter dry-run mode设 1 进入干跑模式 |
FF_SDK_TRANSPORT_TIMEOUT | 5.0 | Per-operation timeout (seconds)单次操作超时(秒) |
FF_SDK_LOG_DIR | /var/log/ff_sdk | Log directory日志目录 |
Config object
Config 对象
import ff_sdk
from ff_sdk import Config
# Option 1: all defaults / env vars
dog = await ff_sdk.connect("D1-DEMO")
# Option 2: explicit Config (platform-specific items go in extra)
cfg = Config.from_env()
cfg.extra["d1_host"] = "192.168.1.100"
cfg.extra["d1_variant"] = "zsl-1"
dog = await ff_sdk.connect("D1-DEMO", config=cfg)
# Option 3: pure-code construction
cfg = Config(transport_timeout=5.0, dry_run=False,
extra={"d1_variant": "zsl-1"})
dog = await ff_sdk.connect("D1-DEMO", config=cfg)
import ff_sdk
from ff_sdk import Config
# 方式 1:全用默认 / 环境变量
dog = await ff_sdk.connect("D1-DEMO")
# 方式 2:显式 Config(平台特定项放 extra)
cfg = Config.from_env()
cfg.extra["d1_host"] = "192.168.1.100"
cfg.extra["d1_variant"] = "zsl-1"
dog = await ff_sdk.connect("D1-DEMO", config=cfg)
# 方式 3:纯代码构造
cfg = Config(transport_timeout=5.0, dry_run=False,
extra={"d1_variant": "zsl-1"})
dog = await ff_sdk.connect("D1-DEMO", config=cfg)
05Session & lifecycleSession 与生命周期
The Session returned by connect() is your single entry point for all interaction with the robot:
connect() 返回的 Session 是你与机器人的全部交互入口:
| Member成员 | Type类型 | Notes说明 |
|---|---|---|
session.motion / .state / … | Capability accessor能力访问器 | Raises CapabilityNotSupported when unsupported不支持时 raise CapabilityNotSupported |
session.capabilities() | set[str] | Set of capability-domain names this robot supports这台机器人支持的能力域名集合 |
session.diagnose() | DiagnosticReport | Synchronous health check: online status of each link同步健康体检:各链路在线状态 |
await session.e_stop(reason) | — | Emergency stop; subsequent motion calls are rejected紧急停止,之后的动作调用会被拒绝 |
session.session_state | Enum枚举 | IDLE / CONNECTING / CONNECTED / DEGRADED / ESTOPPED / DISCONNECTED / FAULT |
session.uptime | float | Seconds since the session was established会话建立以来的秒数 |
await session.close() | — | Disconnect and release resources断开连接、释放资源 |
Recommended: async with
推荐写法:async with
async with await ff_sdk.connect("D1-DEMO") as dog:
await dog.motion.stand()
...
# leaving the with block auto-closes; exceptions won't leak the connection
async with await ff_sdk.connect("D1-DEMO") as dog:
await dog.motion.stand()
...
# 离开 with 块自动 close(),异常也不会泄漏连接
print(dog.capabilities())
# {'motion', 'state', ...}
if "motion" in dog.capabilities():
await dog.motion.stand()
print(dog.capabilities())
# {'motion', 'state', ...}
if "motion" in dog.capabilities():
await dog.motion.stand()
06motion · Motion control运动控制
Velocity control
速度控制
| Parameter参数 | Unit单位 | Meaning含义 |
|---|---|---|
linear | m/s | Forward (negative = reverse)前进(负值后退) |
angular | rad/s | Yaw turn (positive = left)偏航转向(正值左转) |
lateral | m/s | Lateral movement横向移动 |
cmd_vel is a velocity command, not a displacement command. To keep the robot walking = resend the command periodically;
to stop = await motion.stop(). For the safe approach, see the example cookbook/safety_watchdog.py.
cmd_vel 是速度指令而不是位移指令。让机器人持续行走 = 周期性重发指令;
停下 = await motion.stop()。安全做法见示例 cookbook/safety_watchdog.py。
Posture control
姿态控制
| Method方法 | Notes说明 |
|---|---|
await motion.stand() | Stand (~4s)站立(约 4s) |
await motion.damping() | Damping mode — a limp-joint "soft e-stop"; recommended to always call at the end阻尼模式 —— 关节松软的“软急停”,推荐收尾必调 |
await motion.stop() | Stop moving (stay standing)停止移动(保持站立) |
await motion.cmd_twist(twist) | The Twist dataclass form of cmd_velcmd_vel 的 Twist 数据类形式 |
await state.pose() | Current pose (Pose) — read via state.pose(); motion.current_pose is not provided (raises CapabilityNotSupported)当前位姿(Pose)—— 走 state.pose() 读取;motion.current_pose 未提供(会 raise CapabilityNotSupported) |
In-place attitude control · D1-only
原地姿态控制 · 仅 D1
Quadruped-only. Tilts / turns / raises the body in place without walking. All four terms are velocities (roll/pitch/yaw in rad/s, height in m/s), each clamped to ±0.5. Supported on both zsl-1 (point-foot) and zsl-1w (wheeled-foot).
四足专属。不走路、原地俯仰 / 转头 / 侧倾 / 升降身体。四个量都是速度(roll/pitch/yaw 单位 rad/s,height 单位 m/s),各自钳在 ±0.5。zsl-1(点足)与 zsl-1w(轮足)均支持。
| Parameter参数 | Unit单位 | Meaning含义 |
|---|---|---|
pitch_vel | rad/s | Pitch — nod up / down俯仰 —— 抬头 / 低头 |
yaw_vel | rad/s | Yaw — turn head left / right转头 —— 左 / 右 |
roll_vel | rad/s | Roll / peek — lean left / right侧倾 / 探头 —— 左 / 右 |
height_vel | m/s | Stance height — raise / lower站高 —— 升 / 降 |
dog_task UDP fallback, send the STAY mode command first. On the fallback, pitch/yaw are continuous but peek & stance height are discrete button pulses (approximated by direction, not magnitude).
dog_task UDP 兜底时需先发 STAY 模式指令。兜底路径下 pitch/yaw 连续,但 peek 与 stance 是离散按键脉冲(按方向近似,非按幅度)。
if not hasattr(robot.motion, "attitude_control"):
print("attitude_control is D1 (quadruped) only")
return
# enter in-place (STAY) mode first, then drive the 4 velocity terms
await robot.motion.attitude_control(pitch_vel=-0.3) # nod down
await robot.motion.attitude_control(yaw_vel=0.3) # turn head left
await robot.motion.attitude_control(roll_vel=0.4, height_vel=0.3) # peek + raise
await robot.motion.attitude_control() # back to neutral
if not hasattr(robot.motion, "attitude_control"):
print("attitude_control 仅 D1(四足)可用")
return
# 先进原地(STAY)模式,再驱动 4 个速度量
await robot.motion.attitude_control(pitch_vel=-0.3) # 低头
await robot.motion.attitude_control(yaw_vel=0.3) # 向左转头
await robot.motion.attitude_control(roll_vel=0.4, height_vel=0.3) # 探头 + 升高
await robot.motion.attitude_control() # 回到中立
Joint-level interface
关节级接口
| Method方法 | Notes说明 |
|---|---|
await state.joint_states() | Read current joint position / velocity / effort dict — joint telemetry goes through state.joint_states(); motion.read_joint_state is not provided (raises CapabilityNotSupported)读取当前关节位置 / 速度 / 力矩字典 —— 关节遥测走 state.joint_states();motion.read_joint_state 未提供(会 raise CapabilityNotSupported) |
motion.joint_stream(q_func, rate_hz=50.0, …) | High-frequency joint stream: send target joint positions per q_func(t) cycle (advanced, mind safety). ⏳ Planned — currently not available on Aegis (raises CapabilityNotSupported)高频关节流:按 q_func(t) 周期下发目标关节位置(进阶,注意安全)。⏳ 规划中,当前 Aegis 不可用(会 raise CapabilityNotSupported) |
07Stunt actions特技动作
Invoked via motion.do_preset(name); motion.known_presets()
lists all actions supported by the current variant at runtime.
通过 motion.do_preset(name) 调用;motion.known_presets()
可在运行时列出当前机型支持的全部动作。
| name | Action动作 | Est. time预计耗时 | Notes注意 |
|---|---|---|---|
stand / stand_up | Stand站立 | ~4s | |
lie_down | Lie down趴下 | ~3s | |
damping / passive | Damping (soft e-stop)阻尼(软急停) | ~1s | Recommended to always call at the end推荐收尾必调 |
shake_hand | Shake hand握手 | ~10s | Don't interrupt mid-action全程别打断 |
jump | Jump in place原地跳 | ~4s | Leave overhead space上方留空间 |
front_jump | Forward jump前跳 | ~4s | Leave 1m ahead前方留 1m |
backflip | Backflip后空翻 | ~5s | ⚠️ 2m clearance all around + full battery⚠️ 四周 2m 空旷 + 满电 |
two_leg_stand | Two-leg stand双腿站立 | ~4s | Use cancel_two_leg_stand to recover配合 cancel_two_leg_stand 恢复 |
recover | Fall recovery摔倒恢复 | ~3s |
res = await dog.motion.do_preset("shake_hand")
# wait the suggested duration for the action to finish before sending the next command
await asyncio.sleep(dog.motion.preset_timeout("shake_hand"))
print(dog.motion.known_presets()) # all action names supported by the current variant
res = await dog.motion.do_preset("shake_hand")
# 用建议时长等动作做完,再发下一条指令
await asyncio.sleep(dog.motion.preset_timeout("shake_hand"))
print(dog.motion.known_presets()) # 当前机型支持的全部动作名
08state · State telemetry状态遥测
| Method方法 | Returns返回 | Notes说明 |
|---|---|---|
await state.battery() | BatteryState | percent(0–1) / voltage / is_charging |
await state.status() | RobotStatus | IDLE / STANDING / MOVING / LYING / DAMPING / CHARGING / ESTOPPED / FAULT … |
await state.pose() | Pose | World-frame x,y,z (m) + roll,pitch,yaw (rad)世界系 x,y,z(米)+ roll,pitch,yaw(弧度) |
await state.joint_states() | JointStates | names / positions / velocities / efforts; 12 joints point-foot, 16 joints wheeled-footnames / positions / velocities / efforts,点足 12 关节、轮足 16 关节 |
from ff_sdk.core.exceptions import CapabilityNotSupported
try:
joints = await dog.state.joint_states()
print(f"{len(joints.names)} joints")
for name, pos in zip(joints.names, joints.positions):
print(f" {name}: {pos:+.3f} rad")
except CapabilityNotSupported as e:
# some wheeled-foot factory firmware doesn't support joint telemetry (motion control unaffected)
print(f"this variant/firmware doesn't support joint telemetry: {e}")
from ff_sdk.core.exceptions import CapabilityNotSupported
try:
joints = await dog.state.joint_states()
print(f"{len(joints.names)} 个关节")
for name, pos in zip(joints.names, joints.positions):
print(f" {name}: {pos:+.3f} rad")
except CapabilityNotSupported as e:
# 部分轮足已出厂固件不支持关节遥测(运动控制不受影响)
print(f"该机型/固件不支持关节遥测: {e}")
State polling cadence
状态轮询节奏
examples/state/watch_status.py.
examples/state/watch_status.py 的节流写法。
09Other capabilities其他能力
vision (🟡 partial)(🟡 部分)
Grab a single frame / continuously stream. CameraFrame contains data(bytes) / width / height / encoding. The interface is ready; variant coverage is being completed.
取单帧 / 持续取流。CameraFrame 含 data(bytes) / width / height / encoding。接口就绪,机型覆盖完善中。
display (🟡 LED)(🟡 LED)
The quadruped has no face screen, so expression interfaces like show_expression raise CapabilityNotSupported on this platform.
四足无面屏,show_expression 等表情类接口在本平台 raise CapabilityNotSupported。
navigation (🟡 partial)(🟡 部分)
Patrol navigation stack integration is in progress; availability is governed by what session.capabilities() returns at runtime.
巡检导航栈对接中;可用性以 session.capabilities() 运行时返回为准。
10Variant adaptation机型适配(variant)
The Aegis lineup has several models, but to you as a developer the API is identical — you only need to pick the right
variant parameter.
Aegis 产品线有多个型号,对开发者来说 API 完全一样,只需选对一个
variant 参数。
Which one do I have?
我手上是哪台?
| What to check看什么 | Point-foot点足 | Wheeled-foot轮足 / 轮狗 |
|---|---|---|
| Foot end足端 | 4 rubber foot pads4 个橡胶脚垫 | 4 drive wheels4 个驱动轮 |
| Locomotion移动方式 | Stepping gait迈步行走 | Wheeled glide + stepping hybrid轮式滑行 + 迈步混合 |
| Joint count关节数 | 12 (3 per leg)12(每腿 3 个) | 16 (3 per leg + wheel)16(每腿 3 个 + 轮) |
| Model产品型号 | Form形态 | variant | Adaptation status适配状态 |
|---|---|---|---|
| Standard标准版 (point-foot batch)(点足批次) | Point-foot点足 | zsl-1 | ✅ hardware-verified✅ 真机验证 (stand / walk / stunt / full telemetry)(站立 / 行走 / 特技 / 全遥测) |
| Standard标准版 (wheeled-foot batch)(轮足批次) | Wheeled-foot轮足 | zsl-1w | ✅ hardware-verified✅ 真机验证 (motion + state telemetry)(运动 + 状态遥测) |
| EDUEDU 版 (education)(教育版) | Point-foot点足 | zsl-1 | 🟡 adapted🟡 已适配, same control path as point-foot, pending regression testing,与点足同一控制路径,待回归测试 |
| Pro / Ultra | Point-foot点足 | zsl-1 | 🟡 adapted🟡 已适配, pending regression testing,待回归测试 |
How to set variant (pick one of three)
variant 怎么填(三选一)
# Option 1: env var (recommended, no code change)
export FF_SDK_D1_VARIANT=zsl-1 # point-foot / EDU / Ultra
export FF_SDK_D1_VARIANT=zsl-1w # wheeled-foot (default when unset)
# 方式 1:环境变量(推荐,不改代码)
export FF_SDK_D1_VARIANT=zsl-1 # 点足 / EDU / Ultra
export FF_SDK_D1_VARIANT=zsl-1w # 轮足(不设时的默认值)
cfg = Config.from_env()
cfg.extra["d1_variant"] = "zsl-1"
dog = await ff_sdk.connect("D1-DEMO", config=cfg)
cfg = Config.from_env()
cfg.extra["d1_variant"] = "zsl-1"
dog = await ff_sdk.connect("D1-DEMO", config=cfg)
session.diagnose() tells you exactly which link didn't come up — it won't damage the robot.
session.diagnose()
会明确告诉你哪条链路没起来 —— 不会损坏机器人。
11Deploy to robot部署到机器人
| Deployment部署方式 | Notes说明 | Recommendation推荐度 |
|---|---|---|
| Run on the robot跑在机器人上 | scp the program to the robot, loopback control, lowest latency程序 scp 到机器人,本机回环控制,延迟最低 | ★★★ recommended★★★ 推荐 |
| Run on a Linux dev machine跑在 Linux 开发机 | Dev machine joins the robot hotspot, remote control开发机连机器人热点,远程控制 | ★★ (advanced setup, contact support)★★(进阶配置,联系支持) |
| Run on Windows / Mac跑在 Windows / Mac | Dry-run only (the motion library is Linux-only)仅 dry-run(底层运动库是 Linux 库) | ★ for learning / writing code★ 学习 / 写代码用 |
For getting the program onto the robot, auto-start on boot (systemd), and the upgrade flow, see docs/deployment.md inside the devkit.
C++ developers should look at the devkit's cpp/README.md (headers + dual-arch prebuilt libs + examples).
程序上机、开机自启(systemd)与升级流程详见 devkit 内 docs/deployment.md。
C++ 开发者请看 devkit 的 cpp/README.md(头文件 + 双架构预编译库 + 示例)。
12Cross-platform Skills跨平台 Skills
ff_sdk.skills.* are high-level actions you write once and run on every platform —
internally they automatically pick the most suitable implementation per platform:
ff_sdk.skills.* 是写一次、所有平台都能跑的高层动作 ——
内部自动按平台选择最合适的实现:
from ff_sdk import skills
result = await skills.wave(dog) # auto-mapped to shake-hand on Aegis
result = await skills.bow(dog) # auto-mapped to a nod
result = await skills.greet(dog, "friend") # wave + (on platforms with audio) greeting
print(result) # {"ok": True, "message": "...", "platform": "..."}
from ff_sdk import skills
result = await skills.wave(dog) # Aegis 上自动映射为握手
result = await skills.bow(dog) # 自动映射为点头
result = await skills.greet(dog, "朋友") # 招手 + (支持语音的平台)打招呼
print(result) # {"ok": True, "message": "...", "platform": "..."}
Cross-robot code should prefer skills; only drop down to motion.do_preset directly for platform-specific details.
跨机器人代码应优先用 skills;平台专属细节才直接调 motion.do_preset。
13Errors & diagnostics异常与诊断
Exception hierarchy
异常层级
| Exception异常 | When it's raised什么时候抛 |
|---|---|
FfSdkError | Root class of all SDK exceptions所有 SDK 异常的根类 |
ConfigError | Config invalid or incomplete配置无效或不完整 |
ConnectionError | Can't establish / lost connection无法建立 / 失去连接 |
TransportError | Wire-level failure (socket / RPC timeout)线路级故障(socket / RPC 超时) |
TimeoutError | Operation exceeded its deadline操作超过截止时间 |
PlatformError | Low-level error translated by the platform adapter平台适配层翻译的底层错误 |
CapabilityNotSupported | This platform / variant / firmware doesn't support this capability该平台 / 机型 / 固件不支持此能力 |
EStopActiveError | Emergency stop active; motion rejected紧急停止激活中,动作被拒绝 |
StateError | Current state disallows the operation (charging / OTA / fault)当前状态不允许该操作(充电 / OTA / 故障中) |
import ff_sdk
from ff_sdk.core.exceptions import (
CapabilityNotSupported, EStopActiveError, StateError)
try:
await dog.motion.stand()
except CapabilityNotSupported as e:
print(f"this variant doesn't support: {e}")
except EStopActiveError:
print("e-stop active; clear the hazard before resetting")
except StateError as e:
print(f"current state disallows: {e}") # e.g. charging
import ff_sdk
from ff_sdk.core.exceptions import (
CapabilityNotSupported, EStopActiveError, StateError)
try:
await dog.motion.stand()
except CapabilityNotSupported as e:
print(f"此机型不支持: {e}")
except EStopActiveError:
print("急停激活中,请先排除险情再复位")
except StateError as e:
print(f"当前状态不允许: {e}") # 例如正在充电
diagnose(): check first, then act
diagnose():先体检,再动作
report = dog.diagnose()
print(report)
# online status of every link (control / telemetry / motion backend) at a glance
# always the first debugging step — look here, don't guess
report = dog.diagnose()
print(report)
# 各链路(控制通道 / 遥测通道 / 运动后端)在线状态一目了然
# 排错第一步永远是看这个,而不是猜
14Example index示例索引
All examples in the devkit's examples/ run as-is (dry-run first, then real robot):
devkit 的 examples/ 全部可直接运行(先 dry-run 后真机):
| Example示例 | Contents内容 |
|---|---|
01_hello_connect.py | First connection + diagnose + emergency stop第一次连接 + 诊断 + 紧急停止 |
02_diagnose.py | Health report walkthrough体检报告详解 |
03_estop.py | Emergency stop + callback + reset紧急停止 + 回调 + 重置 |
d1/udp_walk.py | Full walking demo (stand → forward → turn → damping)完整行走演示(站立 → 前进 → 转向 → 阻尼) |
d1/presets_and_telemetry.py | Variant selection + stunts + joint telemetry机型选择 + 特技 + 关节遥测 |
motion/cmd_vel.py / stand_damping.py / do_preset.py | Motion control trio运动控制三件套 |
state/read_battery.py / watch_status.py | Battery / status monitoring电量 / 状态监听 |
cookbook/safety_watchdog.py | Safety watchdog (strongly recommended reading first)安全看门狗(强烈推荐先读) |
cookbook/multi_robot.py | Concurrent multi-robot control多机器人并发控制 |
cookbook/record_trajectory.py | Trajectory recording轨迹记录 |
cookbook/sim_to_real.py | Sim-to-real migration仿真到真机迁移 |
15FAQ / TroubleshootingFAQ / 排错
| Symptom现象 | Likely cause可能原因 | Fix解决 |
|---|---|---|
diagnose shows the motion backend offlinediagnose 显示运动后端 offline | Wrong variant (point-foot robot set to wheeled-foot)variant 填错(点足机器填了轮足) | Switch variant per the variant table and reconnect按 机型表 换 variant 重连 |
| Stand command sent, no response站立指令发了没反应 | Robot still in damping / e-stop state机器人还在阻尼 / 急停状态 | Run do_preset("stand") first, check state.status()先 do_preset("stand"),看 state.status() |
Wheeled-foot joint_states errors轮足 joint_states 报错 | Factory firmware limitation已出厂固件限制 | Use the try/except CapabilityNotSupported pattern用 try/except CapabilityNotSupported 兼容写法 |
| Can't connect to the robot连不上机器人 | Not on the robot hotspot / wrong host没连到机器人热点 / host 填错 | Check WiFi; set FF_SDK_D1_HOST in LAN mode确认 WiFi;局域网模式设 FF_SDK_D1_HOST |
| Commands occasionally dropped指令偶尔丢 | WiFi link jitterWiFi 链路抖动 | Run the program on the robot itself (loopback is most stable)程序跑到机器人本体上(本机回环最稳) |