OneRobotics A1 系列机械臂的官方预编译 SDK 与 Python 安装包。本手册是面向最终集成开发者的接口索引:以 C++ 接口为示例罗列三层公共面的全部函数与作用,完整签名 / 数据结构 / 可运行示例统一下沉到各语言子 README,请按需跳转:
c/README.md— 纯 C ABI 包(FFI / 纯 C 工程)c++/README.md— C++ SDK(namespace onero_api)python/README.md— Python 包(import oneroarm)demo/README.md— 三语言并列的可运行示例
版本:1.1.0 · 支持平台:Linux x86_64 / Linux arm64 / Linux riscv64 / Windows x86_64 · C++ 标准:C++17+ · Python:3.12
本手册仅为三层接口的速查索引,只列出函数与作用;完整规格与可运行工程分置于各子目录,集成时请按下表查阅:
需求 位置 内容 查阅接口完整规格 对应语言子 README: c/README.md·c++/README.md·python/README.md完整函数签名、参数约束、数据结构与字段表、错误码、默认值、安装步骤与故障排查 参考完整构建案例 demo/README.md及demo/源码各动作的 C / C++ / Python 可运行示例,含 CMake 一键构建、运行命令与无硬件下的预期行为,可直接作为集成模板 语言层选择与中断回调差异见 §1.2 三层公共接口。
- OneroArm API · 用户手册
OneroArm_API_for_Users/
├── README.md # 本手册(接口索引 + 速查表)
│
├── c/ # 纯 C ABI 包:FFI / 纯 C 工程
│ ├── include/onero_interface_c.h # 唯一公开头(自含数据类型,零 C++ 依赖)
│ ├── linux/{linux-x86_64, linux-arm64, linux-riscv64}/liboneroarm.so
│ ├── windows/windows-x86_64/{oneroarm.dll, oneroarm.lib}
│ ├── share/oneroarm_description/ # URDF + mesh,运行时 dladdr 自动定位
│ └── README.md
│
├── c++/ # C++ SDK 包:namespace onero_api
│ ├── include/
│ │ ├── onero_define.h # 数据类型 / 常量 / 错误码
│ │ └── onero_interface_cpp.h # 公开类(自动 #include "onero_define.h")
│ ├── linux/{linux-x86_64, linux-arm64, linux-riscv64}/liboneroarm.so
│ ├── windows/windows-x86_64/{oneroarm.dll, oneroarm.lib}
│ ├── share/oneroarm_description/
│ └── README.md
│
├── python/ # Python 包:conda channel + RISC-V 瘦 wheel
│ ├── conda_channel/linux/{linux-64, linux-aarch64, noarch}/
│ ├── conda_channel/windows/{win-64, noarch}/
│ ├── wheels/linux-riscv64/oneroarm-*.whl # RISC-V 专用瘦 wheel(cp312;conda-forge 无 riscv64 包)
│ └── README.md
│ # 安装后 import oneroarm;扩展模块、类型存根、
│ # share/oneroarm_description 一并落到 site-packages
│
├── demo/ # 三语言并列示例
│ ├── {full,movej,movep,movel,buffered_traj,can_frame,drag_teaching}_demo.{c,cpp,py}
│ ├── CMakeLists.txt # 极简分发:直接 IMPORTED target,无 find_package
│ └── README.md
│
└── scripts/
└── install_riscv_dependencies.sh # RISC-V 一次性源码编第三方依赖到 /opt/onero-deps
c/与c++/是两个真拆分包:预编译二进制liboneroarm.so/oneroarm.dll在两包内逐字节相同,差异只在include/:c/include/只有 1 个自含的纯 C 头;c++/include/有 2 个 C++ 头,onero_interface_cpp.h自动#include "onero_define.h",用户代码只需引前者。
share/oneroarm_description/在两个 SDK 包都内置一份;SDK 通过dladdr()/GetModuleFileNameW()取自身.so/.dll路径,按<libdir>/../share/oneroarm_description/自动定位 URDF/mesh,零配置即可工作。
功能完全等价,按工程语言挑一层即可:
| 层 | 入口符号 | 对应头 / 模块 | 适用场景 |
|---|---|---|---|
| C++ | onero_api::OneroArm / OneroDragTeaching |
c++/include/onero_interface_cpp.h(onero_define.h 自动 include) |
C++17+ 工程;额外暴露 interrupt_check 中断回调 |
| C ABI | onero_create_robot / onero_* 系列 |
c/include/onero_interface_c.h(extern "C" + 自含 POD) |
纯 C 工程;其他语言 FFI(Rust / Go / C# 等) |
| Python | oneroarm.OneroArm / oneroarm.OneroDragTeaching |
import oneroarm(pybind11 扩展) |
快速原型、数据采集、上层算法集成;不暴露 interrupt_check |
三层均对接同一个
liboneroarm.so/oneroarm.dll,业务行为完全一致;选谁取决于工程语言与是否需要中断回调。安装与集成方式见各语言子 README。
| 项 | 约定 |
|---|---|
| 关节角度 / 速度 / 力矩 | rad / rad·s⁻¹ / N·m,索引 0..dof-1,与 URDF 一致 |
| 笛卡尔位置 | m,基坐标系 |
| 笛卡尔姿态 | 单位四元数 (qw, qx, qy, qz),标量优先 |
| 时间步长 | s,拖动示教默认 0.01(100 Hz) |
speed_scale |
无量纲速度比例,建议 (0, 2.0],默认 1.0 |
trajectory_connect |
仅作用于 movej / movel / movep 的最后一个参数。0 = 立即执行(若已有累积段,先把缓冲段连成一条平滑轨迹执行,再走当前段);1 = 把当前段塞进内部 trajectory_buffer_,等 execute_buffered_trajectory() 或下一次 trajectory_connect=0 调用时一次性下发。这是 SDK 唯一的"轨迹缓冲"机制;与 send_trajectory* 无关(详见 §4.1)。 |
下图用于说明 URDF 中各坐标系与实际结构件的对应关系;A1 左臂与右臂均满足该关系,可按同一方式理解 link / joint 与 mesh 的绑定。
- 同一实例 / 句柄上的方法不是线程安全的;多线程必须由调用方串行化。
get_arm_state_cached是唯一为后台轮询设计的接口,不触发 CAN I/O。move*系列同步阻塞至运动完成或失败;enable/disable_motors同步等待硬件应答;cancel_trajectory异步终止。- C ABI 句柄由
onero_destroy_robot/onero_drag_teaching_destroy释放,释放后必须置空。C++ / Python 由实例析构自动完成。
| 值 | 名称 | 含义 |
|---|---|---|
0 |
SUCCESS |
成功 |
-1 |
INVALID_PARAMS |
参数错误(dof 不匹配 / 数组长度异常 / 速度越界等) |
-2 |
IK_FAILED |
笛卡尔目标的逆运动学求解失败 |
-3 |
COLLISION_DETECTED |
自碰撞检测告警 |
-4 |
EXECUTION_FAILED |
下发指令时硬件 / 通信异常 |
-5 |
TIMEOUT |
等待超时(含使能、应答超时等) |
定义在 onero_define.h / onero_interface_c.h(ONERO_ERR_RAW_FRAME_*)。
| 值 | 名称 | 含义 |
|---|---|---|
0 |
ONERO_CAN_OK |
成功 |
-10 |
ONERO_ERR_RAW_FRAME_INVALID_LEN |
payload 长度越界(必须 ∈ [0, 8]) |
-11 |
ONERO_ERR_RAW_FRAME_INVALID_ID |
CAN ID 越界(必须 ∈ [0x000, 0x7FF]) |
-12 |
ONERO_ERR_RAW_FRAME_RESERVED_ID |
CAN ID 落在 SDK 保留集(电机 / 夹爪 / 操纵杆 / 0x7FF) |
-13 |
ONERO_ERR_RAW_FRAME_PORT_NOT_OPEN |
串口未打开 / 句柄无效 |
-14 |
ONERO_ERR_RAW_FRAME_SEND_FAILED |
SLCAN 写串口失败 |
| 类别 | 含义 | 涉及方法 |
|---|---|---|
int = MoveResult |
0=SUCCESS,负数 = §2.3 错误码 |
enable_motors / disable_motors / movej / movel / movep / send_trajectory_point / send_trajectory / cancel_trajectory / execute_buffered_trajectory / clear_trajectory_buffer |
int = ONERO_ERR_RAW_FRAME_* |
0=OK,负数 = §2.4 错误码 |
send_can_frame / register_can_frame_callback / clear_can_frame_callback / pump_can_bus |
bool |
true=成功 |
is_hardware_connected / OneroDragTeaching::initialize / set_hardware / is_initialized |
int(拖动示教族) |
0=成功,非 0 = 失败 |
OneroDragTeaching::enable_motors / start_recording / stop_recording / start_replay / stop_replay / handle_command |
| 数据对象 | 失败回退为空容器 / 全零 Pose / count==0 / IDLE |
get_joint_positions(_from_motors) / get_joint_velocities / get_arm_state_from_motor(_cached) / get_end_effector_pose / OneroDragTeaching::get_state |
| 句柄 / Python 异常 | C ABI 返回 NULL;C++ valid()==false;Python 构造失败抛异常 |
onero_create_robot / onero_drag_teaching_create / OneroArm ctor / OneroDragTeaching ctor |
三层共享同一组字段(语义对齐,字段顺序不强求一致):
| 字段 | 必填 | 默认 | 说明 |
|---|---|---|---|
device |
✅ | "" |
串口设备路径。Linux /dev/ttyACM0,Windows COM3 |
robot_model |
✅ | "" |
机型名(子串包含、大小写敏感)。当前仅支持 a1_l / a1_r |
dof |
– | 7 |
自由度,仅支持 7 |
baud_rate |
– | 921600 |
串口波特率 |
urdf_path |
– | "" |
URDF 文件绝对路径。留空时由 model_description_path + version 自动定位 |
version |
– | "" |
URDF 子目录名(A1)。留空时按 robot_model 自动推断 |
mount_orientation |
– | vertical |
安装姿态:vertical 立装 / horizontal 卧装。装错将导致重力补偿方向错误 |
with_gripper |
– | false |
是否随臂注册 arm-owned 可选夹爪(复用同一串口 / CAN 会话,固定 CAN ID 0x08/0x18)。详见 §4.1「可选夹爪」 |
mit_kp[7] |
– | 全 0 |
MIT 比例增益。逐关节回退:==0 视为未传入,按 dof 注入默认 |
mit_kd[7] |
– | 全 0 |
MIT 微分增益。同上 |
model_description_path |
– | "" |
oneroarm_description 根目录。留空 → SDK 内置(推荐) |
零初始化要求:C ABI 的
onero_config_t必须先{0}/memset清零,否则栈上随机值会被误判为「用户传入的非 0 PD 增益」。C++ 结构体在头文件内声明默认值,onero_config_t cfg{}即安全。PD 默认增益(7-DOF):
kp = [150, 150, 150, 150, 30, 30, 30],kd = [4, 4, 4, 4, 1, 1, 1]。URDF/mesh 资源:默认零配置即可命中 SDK 内置
share/oneroarm_description/;如需自定义可设ONERO_DESCRIPTION_PATH或显式赋model_description_path。
字段细节、平台差异、构造范例请见各语言子 README。
使用方法:本节用 C++ 签名展示参数与作用;纯 C ABI / Python 函数名与 C++ 一一对应(C ABI 加
onero_前缀并以句柄为首参;Python 同名snake_case,参数同序),完整签名、数据结构、默认值请按需查阅:
- C++ —
c++/include/onero_interface_cpp.h、c++/include/onero_define.h- C ABI —
c/include/onero_interface_c.h- Python —
import oneroarm; help(oneroarm.OneroArm),或python/README.md完整构建案例:上述接口的端到端调用、编译与运行方式参见
demo/源码与demo/README.md,每组动作均提供 C / C++ / Python 三份可运行示例及 CMake 一键构建步骤。如需了解某个接口在 SDK 内部的具体实现(规划器、控制律、状态机),可阅读核心源码:
OneroArm_API_for_develop/C_API/src/onero_core.cpp等。
| C++ 签名 | 参数含义 | 作用 |
|---|---|---|
OneroArm(const onero_config_t& cfg) |
cfg:见 §三 |
RAII 构造:打开串口、加载 URDF、初始化运动控制;析构自动释放 |
bool valid() const |
— | 构造是否成功(串口打开 + 模型加载 OK) |
int enable_motors() |
— | 同步使能所有关节电机 (注意:使能时会自动回零位,需要在使能前将机械臂移动到接近零位) |
int disable_motors() |
— | 同步失能所有关节电机 (注意:失能会使的机械臂自由下落,在失能前请确保机械臂处于安全位置) |
- 在连续运动过程中不需要重复调用
enable_motors及disable_motors。 - 在失能后建议将实例销毁(析构)后阻塞一段时间(500ms以上),以确保电机稳定并没有残余CAN帧发送再连续使能。
| C++ 签名 | 参数含义 | 作用 |
|---|---|---|
int movej(const JointArray& target, double speed_scale=1.0, uint8_t trajectory_connect=0) |
target:目标关节角 (rad);speed_scale:速度比例 (0, 2.0];trajectory_connect:见 §2.1 |
关节空间运动到目标,内部按多项式 / 三次样条规划 |
int movel(const Pose& pose, double speed_scale=1.0, uint8_t trajectory_connect=0) |
pose:目标位姿 (m + 单位四元数);其他同上 |
笛卡尔直线运动(末端走直线,需求解 IK) |
int movep(const Pose& pose, double speed_scale=1.0, uint8_t trajectory_connect=0) |
同上 | 笛卡尔点到点(关节空间插值,自动避碰) |
选配,默认关闭,需
cfg.with_gripper = true随臂创建。复用OneroArm同一串口 / CAN 会话(固定 CAN ID0x08/0x18),不单独打开设备;enable_motors()只使能机械臂关节,夹爪需显式gripper()->enable()。C++ 经arm.gripper()(with_gripper=false时为nullptr)取控制器,Python 为arm.gripper属性(未开启时None)。夹爪状态 / 故障码只属于夹爪域,不改变机械臂dof或关节状态缓存。
| C++ 签名 | 参数含义 | 作用 |
|---|---|---|
bool has_gripper() const |
— | 是否随臂创建了夹爪控制器 |
OneroGripper* gripper() |
— | 取夹爪控制器;with_gripper=false 时为 nullptr |
int enable() / int disable() |
— | 使能 / 失能夹爪电机(固定 ID 0x08/0x18,与 enable_motors() 解耦) |
int set_position(double percent) |
percent:0..100 |
单帧位置保持 |
int move_position(double percent, double max_vel=100.0, double max_acc=250.0, double max_jerk=1000.0) |
percent:0..100;速度 / 加速度 / 加加速度上限 |
100 Hz 点到点 S 曲线规划 |
int force_control(double torque) |
torque:N |
下发夹爪 MIT 力矩,内部钳位 ±40 N |
GripperStatus status() |
— | 刷新并返回 position / velocity / force / error / valid |
GripperTactileStatus get_tactile() |
— | 刷新并返回两个触摸传感器各自的合力与 9 个测点快照 |
触觉:读取传感器
0x01/0x02的0x00..0x09,0x00写入total_force,0x01..0x09写入points;fx/fy按int8_t * 0.1N、fz按uint8_t * 0.1N解析。完整字段与示例见各语言子 README。
| C++ 签名 | 参数含义 | 作用 |
|---|---|---|
int execute_buffered_trajectory() |
— | 把所有 trajectory_connect=1 累积进 trajectory_buffer_ 的段连成一条平滑轨迹一次性下发 |
int clear_trajectory_buffer() |
— | 清空 trajectory_buffer_,所有缓冲段丢弃;不影响正在执行的运动 |
int cancel_trajectory() |
— | 异步打断当前正在执行的 move(无论是单段还是缓冲触发) |
重要:以下两个接口在 SDK 内部直接调用
motor_control_->control_mit(motors_[i], kps_[i], kds_[i], pos[i], vel[i], tau[i])给每个关节电机下发 MIT 力矩;力矩由调用方传入的(q, qd, qdd)经RigidBodyDynamics::InverseDynamics反算。SDK 不做任何插值 / 平滑 / 时间规划,也不入
trajectory_buffer_。调用方必须先用三次样条 / 五次多项式 / minimum-jerk 等方法把目标轨迹离散化、保证(q, qd, qdd)时间上连续,否则仿真机械臂关节会跳变。不要用
execute_buffered_trajectory来"触发"它们 —— 二者完全不耦合,前者只服务movej/movel/movep的trajectory_connect队列。
| C++ 签名 | 参数含义 | 作用 |
|---|---|---|
int send_trajectory_point(const JointArray& positions, const JointArray& velocities) |
单点:关节位置 / 速度(与 dof 等长) | 单点 MIT 下发;调用方应在外部以固定周期连续调用 |
int send_trajectory(const std::vector<TrajectoryPoint>& trajectory) |
一组 (位置, 速度, 加速度) | 逐点 MIT 下发;调用前必须自行规划好整段轨迹 |
低层力位混合(阻抗)接口,用于 teleop 数据采集、阻抗控制、模仿学习推断等。控制律
tau_motor = kp*(q - q_act) + kd*(dq - dq_act) + tau由电机在 MIT 模式下闭环执行。调用前先enable_motors();所有JointArray长度 =dof,需以 ≥100 Hz 持续下发,不要与movej/movel/movep在重叠时间窗内混用。
| C++ 签名 | 参数含义 | 作用 |
|---|---|---|
int control_mit(const JointArray& kp, const JointArray& kd, const JointArray& q, const JointArray& dq, const JointArray& tau) |
五个 JointArray,长度 = dof |
整臂 MIT 力位混合控制(每帧一次)。0 成功 / -1 参数错误 / -2 硬件未初始化 / -3 至少一关节 CAN 写入失败 |
int compute_gravity_torque(const JointArray& q, JointArray& out_tau) |
q 输入 / out_tau 输出 |
计算重力补偿力矩(含 robot_model 校准缩放),喂给 control_mit 的 tau。0 成功 / -1 q 长度错误 / -2 动力学模型未就绪 |
q走与get_arm_state_from_motor()一致的 SDK 关节空间,建议第一帧q=当前回读位置、dq=0、tau=0。C ABI 为onero_control_mit/onero_compute_gravity_torque。Python 例外:compute_gravity_torque(q)直接返回JointArray(而非 C/C++ 的「int返回 +out_tau出参」),模型未就绪 / 长度错误时抛ValueError。
| C++ 签名 | 参数含义 | 作用 |
|---|---|---|
JointArray get_joint_positions() |
— | 不触发 CAN I/O:返回上位机内部缓存 |
JointArray get_joint_positions_from_motors() |
— | 触发 CAN I/O 直接从电机读 |
JointArray get_joint_velocities() |
— | 触发 CAN I/O 读关节速度 |
ArmStateFromMotor get_arm_state_from_motor() |
— | 触发 CAN I/O,一次返回 (位置 / 速度 / 力矩) |
ArmStateFromMotor get_arm_state_cached() |
— | 推荐高频轮询用:控制循环内部缓存,不触发 I/O |
Pose get_end_effector_pose() |
— | 末端正运动学位姿 |
bool is_hardware_connected() |
— | 串口是否打开 |
| C++ 签名 | 参数含义 | 作用 |
|---|---|---|
int send_can_frame(uint16_t can_id, const uint8_t* payload, uint8_t len) |
can_id:11-bit 标准 ID(避开保留集);payload/len:0..8 字节 |
向同总线非保留 ID 发送原始帧 |
int register_can_frame_callback(CanFrameCallback cb) |
cb:std::function<void(uint16_t, const uint8_t*, uint8_t)> |
注册接收非保留 ID 帧的回调 |
int clear_can_frame_callback() |
— | 清除已注册的回调 |
int pump_can_bus(int timeout_ms) |
阻塞超时(ms),0 等价非阻塞 try-recv |
主动驱动一次串口 rx,避免 SLCAN 缓冲累积 |
| C++ 签名 | 参数含义 | 作用 |
|---|---|---|
OneroDragTeaching() |
— | 默认构造;后续需 initialize() + set_hardware() 才能用 |
bool initialize(int dof, const std::string& record_file, double time_step=0.01) |
dof / 录制文件路径 / 控制周期 (s) | 配置示教参数,分配缓冲 |
bool set_hardware(const std::string& device, const std::string& urdf_path, const std::string& robot_model, const std::string& mount_orientation="horizontal") |
串口 / URDF / 机型 / 安装姿态 | 绑定硬件并加载模型 |
bool set_hardware(..., const std::string& mount_orientation, bool with_gripper) |
同上 + with_gripper |
重载:额外用 with_gripper 选择带夹爪的重力补偿缩放占位参数(此重载下 mount_orientation 须显式给出)。C ABI 为 onero_drag_teaching_set_hardware_ex;Python 为 set_hardware(..., with_gripper=False) |
int enable_motors(bool restore_to_zero=true) |
是否先回零 | 使能并切到拖动示教模式 |
int start_recording() / int stop_recording() |
— | 开始 / 停止记录拖动轨迹 |
void set_replay_file(const std::string& f) |
重放源文件 | 配置重放数据来源 |
int start_replay() / int stop_replay() |
— | 开始 / 停止重放 |
int handle_command(int cmd) |
命令枚举 | 文本命令派发 |
void timer_callback() |
— | 控制循环 tick(外部周期调用) |
DragTeachingState get_state() |
— | IDLE / RECORDING / REPLAYING |
bool is_initialized() |
— | 是否已 initialize() |
void update_joint_state(const JointArray& pos, const JointArray& vel, const JointArray& eff) |
三个等长 JointArray | 注入外部观测,仅在自定义控制循环中使用 |
字段表、参数约束、完整 demo 与故障排查 →
c++/README.md/c/README.md/python/README.md。
C / C++ / Python 三层均提供 send_can_frame / register_can_frame_callback / clear_can_frame_callback / pump_can_bus 四个方法(签名仅随语言风格变化),共享以下行为约定:
- 物理总线:与电机 / 夹爪共用同一根 SLCAN 串口;可向同总线上的自定义节点(MCU / 传感器 / IO 板等)下发 11-bit 标准 CAN 帧并接收响应。
- 保留 ID 集:
0x01、0x02、0x03、0x04、0x05、0x06、0x07、0x08、0x11、0x12、0x13、0x14、0x15、0x16、0x17、0x7FF。发到保留 ID 的帧会被 SDK 拦截并返回ONERO_ERR_RAW_FRAME_RESERVED_ID,不会下发到总线;接收路径上保留 ID 帧仍走原解析,不会派发到用户回调。 - 回调线程:在 SDK 接收路径(即调用方运动控制线程 / 当前调用
pump_can_bus的线程)上同步执行。回调内禁止重入 SDK 任何发送 / 运动控制方法,否则会与外层 receive 自锁。 - payload 生命周期:C / C++ 回调中的
payload指针仅在回调期间有效,需要保留请自行拷贝;Python 回调收到的是已拷贝的bytes。 - 异常:Python 回调中抛出的异常会被 SDK 静默吞掉,避免回流到 SLCAN dispatch;业务侧应在回调内自行
try/except。 pump_can_bus(timeout_ms):0等价一次非阻塞 try-recv;典型用法是在move*之类运动控制空闲期主动调用,避免 SLCAN rx 缓冲区累积。
返回值见 §2.4。完整可运行示例见各语言子 README。
- 当前版本:1.1.0
- License:MIT
- 维护者:OneRobotics 团队
安装、详细字段表、参数约束、可运行示例与故障排查请按需跳转:
c/README.md/c++/README.md/python/README.md/demo/README.md。

