API(Python)
Python 接口说明
fd_api — 机器人外设控制 Python 接口定义
一、概述
fd_api 提供机器人外设(升降、头部、腰部、手部)的 Python 便捷接口封装。基于 ROS 2 rclpy 运行时, 通过简洁的 Python API 实现控制指令下发与状态读取 / 订阅。
核心模块
Control 控制类
升降 · 头部 · 腰部 · 手部
升降 · 头部 · 腰部 · 手部
State 状态类
同步缓存读取 + 异步回调订阅
同步缓存读取 + 异步回调订阅
类型枚举
HeadType · HandType · HandBackend
HeadType · HandType · HandBackend
角度转换
腰部编码器 ↔ 角度互转工具
腰部编码器 ↔ 角度互转工具
架构分层
上层应用程序
from fd_api import Control, State
▼
from fd_api import Control, State
fd_api Python 模块
Control · State · types · waist_angle
▼
Control · State · types · waist_angle
ROS 2(rclpy)通信层
发布 Topic · 订阅 Topic
▼
发布 Topic · 订阅 Topic
机器人硬件外设
升降 · 头部 · 腰部 · 手部
升降 · 头部 · 腰部 · 手部
二、安装与导入
编译构建
colcon build --packages-select fd_api
导入语句
from fd_api import State, Control, HeadType, HandType, HandBackend
from fd_api.waist_angle import waist_encoder_to_deg, waist_deg_to_encoder
使用前提:确保已在 ROS 2 工作空间下完成编译(
colcon build), 并执行 source install/setup.bash 加载环境。三、Python 类型定义
3.1 枚举类型
| 类型 | 枚举值 | 说明 |
|---|---|---|
HeadType |
kLower(0) · kUpper(1) |
下头(yaw)/ 上头(pitch) |
HandType |
kLeft(0) · kRight(1) · kBoth(2) |
左手 / 右手 / 双手 |
HandBackend |
kRohand(0) · kInspire(1) · kBoth(2) |
RoHand 灵巧手 / Inspire 仿生灵巧手 / 双后端 |
3.2 腰部角度编码器转换
| 函数 | 转换 | 范围 |
|---|---|---|
waist_encoder_to_deg(enc) |
编码器值 → 角度 (°) | 编码器 262144 ~ 310000 → 角度 0° ~ 35° |
waist_deg_to_encoder(deg) |
角度 (°) → 编码器值 | 角度 0° ~ 35° → 编码器 262144 ~ 310000 |
说明:腰部编码器值与角度呈线性映射关系。 编码器 262144 对应 0°(后仰极限),310000 对应 35°(前倾极限)。
四、Control 控制接口
Control 类提供机器人外设的指令下发接口, 包含初始化、升降控制、头部控制、腰部控制、手部控制。
4.1 初始化
init(options_dict) |
初始化控制节点。参数:node_name(节点名)、hand_backend(手后端类型)、hand_type(手类型)、waist_servo_id(腰部舵机 ID)、inspire_gripper_id(Inspire 夹爪 ID) |
# === 初始化示例 ===
from fd_api import Control, State, HeadType, HandType, HandBackend
ctrl = Control()
ctrl.init({
"node_name": "my_control",
"hand_backend": HandBackend.kInspire,
"hand_type": HandType.kBoth,
"waist_servo_id": 3,
"inspire_gripper_id": 1,
})
print("Control 初始化完成")
4.2 升降控制
lift_up(spd) |
升降上升(速度模式),spd 为速度值 |
lift_down(spd) |
升降下降(速度模式),spd 为速度值 |
lift_pos(spd, pos_mm) |
升降位置控制,spd 速度,pos_mm 目标位置(毫米) |
lift_stop() |
升降停止 |
# === 升降速度控制示例 ===
# 上升:速度 0.05 m/s
ctrl.lift_up(0.05)
print("升降上升中...")
# 下降:速度 -0.05 m/s
ctrl.lift_down(0.05)
print("升降下降中...")
# 停止
ctrl.lift_stop()
print("升降已停止")
# === 升降位置控制示例 ===
ctrl.lift_pos(0.05, 200.0) # 速度 0.05m/s, 目标位置 200mm
print("升降移动至 200mm 位置")
速度模式超时:升降速度模式(
lift_up / lift_down)下, 须 周期发送(建议间隔 < 500ms),否则驱动自动停止。4.3 头部控制
head_pos(head_type, pos_deg) |
头部角度控制,head_type 为 HeadType,pos_deg 为目标角度(度) |
head_stop(head_type) |
头部停止 |
| 头部类型 | 运动方向 | 角度范围 |
|---|---|---|
HeadType.kLower |
下头(yaw — 左右旋转) | -45° ~ +45° |
HeadType.kUpper |
上头(pitch — 俯仰) | -15° ~ +25° |
# === 头部控制示例 ===
# 下头(yaw)转到 30 度
ctrl.head_pos(HeadType.kLower, 30.0)
print("下头转到 30°")
# 上头(pitch)转到 10 度
ctrl.head_pos(HeadType.kUpper, 10.0)
print("上头转到 10°")
# 停止下头
ctrl.head_stop(HeadType.kLower)
print("下头已停止")
自动限幅:头部角度超出范围时将自动限幅至边界值。
4.4 腰部控制
waist_front(spd, acc, dec) |
腰部前倾(速度模式),参数:速度、加速度、减速度 |
waist_back(spd, acc, dec) |
腰部后仰(速度模式),参数:速度、加速度、减速度 |
waist_pos(spd, acc, dec, pos_deg) |
腰部位置控制,pos_deg 为目标角度(度),范围 0°~35° |
waist_stop() |
腰部停止 |
# === 腰部控制示例 ===
# 速度模式:前倾
ctrl.waist_front(720, 100, 100)
print("腰部前倾中...")
# 速度模式:后仰
ctrl.waist_back(720, 100, 100)
print("腰部后仰中...")
# 位置模式:转到 15 度
ctrl.waist_pos(720, 100, 100, 15.0)
print("腰部转至 15°")
# 停止
ctrl.waist_stop()
print("腰部已停止")
角度范围:腰部位置控制范围为 0°~35°,超出将自动限幅。
4.5 手部控制
hand_move(hand_type, value) |
手部动作控制,hand_type 为 HandType,value 为数值列表 [v1, v2, ...] |
hand_stop(hand_type) |
手部停止 |
| 手后端 | value 说明 |
|---|---|
| RoHand | 6 个数值,对应各自由度位置 |
| Inspire | 取首值作为夹爪开合控制 |
# === 手部控制示例 ===
# RoHand 手部:传入 6 个关节值
ctrl.hand_move(HandType.kLeft, [0.0, 0.5, 0.3, 0.1, 0.0, 0.0])
print("左手动作已发送")
# Inspire 夹爪:取首值控制开合
ctrl.hand_move(HandType.kRight, [500.0])
print("右手夹爪已控制")
# 停止左手
ctrl.hand_stop(HandType.kLeft)
print("左手已停止")
手后端选择:通过
init() 的 hand_backend 参数指定, 可选 HandBackend.kRohand、HandBackend.kInspire 或 HandBackend.kBoth。五、State 状态接口
State 类提供机器人外设状态的读取与订阅功能。 支持同步缓存读取与异步回调订阅两种模式。
5.1 初始化
init(options_dict) |
初始化状态节点。参数:node_name(节点名)、callback_thread_count(回调线程数)、waist_servo_id(腰部舵机 ID)、inspire_gripper_id(Inspire 夹爪 ID) |
# === State 初始化示例 ===
state = State()
state.init({
"node_name": "my_state",
"callback_thread_count": 2,
"waist_servo_id": 3,
"inspire_gripper_id": 1,
})
print("State 初始化完成")
5.2 同步读取接口
| 方法 | 返回值 | 说明 |
|---|---|---|
lift_get_current_pos() |
float |
读取升降当前位置 (mm) |
head_get_current_pos(type) |
float |
读取头部当前位置 (deg),type 为 HeadType |
waist_get_current_pos() |
float |
读取腰部当前位置 (deg) |
hand_get_current_pos(type) |
list[float] |
读取手部当前位置,type 为 HandType |
# === 同步读取状态示例 ===
lift_pos = state.lift_get_current_pos()
print(f"当前升降位置: {lift_pos:.1f} mm")
head_lower = state.head_get_current_pos(HeadType.kLower)
print(f"下头角度: {head_lower:.1f} deg")
head_upper = state.head_get_current_pos(HeadType.kUpper)
print(f"上头角度: {head_upper:.1f} deg")
waist_pos = state.waist_get_current_pos()
print(f"腰部角度: {waist_pos:.1f} deg")
hand_pos = state.hand_get_current_pos(HandType.kLeft)
print(f"左手位置: {hand_pos}")
5.3 异步订阅接口
| 方法 | 返回值 | 说明 |
|---|---|---|
lift_sub_current_pos(callback) |
sub_id |
订阅升降位置变化 |
head_sub_current_pos(callback) |
sub_id |
订阅头部位置变化 |
waist_sub_current_pos(callback) |
sub_id |
订阅腰部位置变化 |
hand_sub_current_pos(type, callback) |
sub_id |
订阅手部位置变化,type 为 HandType |
# === 异步订阅状态示例 ===
def on_lift_pos(mm):
print(f"升降位置更新: {mm:.1f} mm")
sub_id = state.lift_sub_current_pos(on_lift_pos)
print(f"已订阅升降位置, sub_id={sub_id}")
# 取消订阅
state.unsubscribe(sub_id)
print("已取消订阅")
回调线程安全:异步订阅的回调函数在独立线程池中执行, 注意回调函数内部的线程安全性。订阅返回
sub_id 可用于取消订阅。5.4 取消订阅
unsubscribe(sub_id) |
取消指定 ID 的订阅,返回 bool 表示是否成功 |
5.5 完整使用示例
# === 完整示例:初始化 → 控制 → 读取 → 订阅 ===
import time
from fd_api import Control, State, HeadType, HandType, HandBackend
def main():
# 1. 初始化 Control
ctrl = Control()
ctrl.init({
"node_name": "demo_control",
"hand_backend": HandBackend.kInspire,
"hand_type": HandType.kBoth,
"waist_servo_id": 3,
"inspire_gripper_id": 1,
})
# 2. 初始化 State
state = State()
state.init({
"node_name": "demo_state",
"callback_thread_count": 2,
"waist_servo_id": 3,
"inspire_gripper_id": 1,
})
# 3. 控制示例
ctrl.lift_up(0.05) # 升降上升
time.sleep(1)
ctrl.lift_stop() # 停止升降
ctrl.head_pos(HeadType.kLower, 30.0) # 下头转 30°
ctrl.waist_pos(720, 100, 100, 10.0) # 腰部转 10°
ctrl.hand_move(HandType.kLeft, [0.0, 0.5, 0.3]) # 左手动作
# 4. 状态读取
lift_mm = state.lift_get_current_pos()
print(f"升降位置: {lift_mm:.1f} mm")
head_deg = state.head_get_current_pos(HeadType.kLower)
print(f"下头角度: {head_deg:.1f} deg")
# 5. 异步订阅
def on_lift(mm):
print(f"升降位置更新: {mm:.1f} mm")
sub_id = state.lift_sub_current_pos(on_lift)
time.sleep(0.5)
state.unsubscribe(sub_id)
print("Demo 运行完毕")
if __name__ == "__main__":
main()
六、测试工具
fd_api 包内含一个 Python 交互测试节点,可用于验证各接口功能:
# 编译
colcon build --packages-select fd_api
# 运行测试节点
ros2 run fd_api api_test_node_for_python_api.py
测试内容:该测试节点覆盖 Control 初始化、升降、头部、腰部、手部控制, 以及 State 初始化、同步读取、异步订阅等主要接口路径。
七、注意事项
① 速度模式须周期发送:升降速度模式(
lift_up / lift_down)下, 驱动在约 500ms 内未收到新速度命令会自动停止, 上位机须 周期性调用(建议间隔 < 500ms)。② 头部角度自动限幅:
head_pos() 传入的角度值若超出范围, 驱动将自动限幅至边界值。HeadType.kLower:-45° ~ +45°HeadType.kUpper:-15° ~ +25°③ 腰部位置控制范围:
waist_pos() 的 pos_deg 参数 有效范围为 0°~35°,超出将自动限幅。④ 实机运行前确认:请确认机器人外设节点已启动且机器人处于安全状态, 避免意外动作导致损坏或伤害。
