机械臂

1.arm_set_speed - 手臂速度百分比

方法: ctrl.arm_set_speed(side, speed_pct)

C++ 签名: bool arm_set_speed(ArmSide side, std::int32_t speed_pct);

参数:

  • side:机械臂侧别,fd_robot::ArmSide 枚举
    • ArmSide::kLeft:左臂
    • ArmSide::kRight:右臂(single 单臂机型可能忽略侧别)
  • speed_pct:速度百分比,int32_t 类型,范围约 1 ~ 100

返回值:

  • bool:操作结果
    • true:指令发送成功
    • false:指令发送失败

使用示例:

C++
#include "fd_api/control.h"
#include <cstdio>

int main() {
    fd_robot::Control ctrl;
    fd_robot::Control::Options opts;
    opts.node_name = "fd_api_control";
    if (!ctrl.Init(opts)) {
        return 1;
    }

    // 设置左臂速度为 50%
    bool ok = ctrl.arm_set_speed(fd_robot::ArmSide::kLeft, 50);
    if (ok) {
        printf("左臂速度设置成功\n");
    } else {
        printf("左臂速度设置失败\n");
    }
    return 0;
}

2.arm_move_joints - 手臂关节运动(弧度)

方法: ctrl.arm_move_joints(side, joints_rad)

C++ 签名: bool arm_move_joints(ArmSide side, const std::vector<float> &joints_rad);

参数:

  • side:机械臂侧别,fd_robot::ArmSide 枚举(kLeft / kRight)
  • joints_rad:目标关节角数组,std::vector<float> 类型,单位:弧度 (rad),长度须等于该侧 DOF

返回值:

  • bool:操作结果
    • true:指令发送成功
    • false:指令发送失败

使用示例:

C++
#include "fd_api/control.h"
#include <cstdio>
#include <vector>

int main() {
    fd_robot::Control ctrl;
    fd_robot::Control::Options opts;
    opts.node_name = "fd_api_control";
    if (!ctrl.Init(opts)) {
        return 1;
    }

    // 左臂 7 关节运动到目标弧度
    std::vector<float> joints = {0.0f, -0.5f, -1.0f,
                                    -1.5f, 0.0f, 0.5f, 0.0f};
    bool ok = ctrl.arm_move_joints(fd_robot::ArmSide::kLeft, joints);
    if (ok) {
        printf("关节运动指令发送成功\n");
    } else {
        printf("关节运动指令发送失败\n");
    }
    return 0;
}

注意: 入参长度须等于该侧 DOF(由机型 robot_profile 的 dof1/dof2 决定,缺省 7;部分机型为 6)。dual 双臂模式下通常需先收到关节状态后再下发。

3.arm_move_joints_deg - 手臂关节运动(角度)

方法: ctrl.arm_move_joints_deg(side, joints_deg)

C++ 签名: bool arm_move_joints_deg(ArmSide side, const std::vector<float> &joints_deg);

参数:

  • side:机械臂侧别,fd_robot::ArmSide 枚举(kLeft / kRight)
  • joints_deg:目标关节角数组,std::vector<float> 类型,单位:度 (°),长度须等于该侧 DOF

返回值:

  • bool:操作结果
    • true:指令发送成功
    • false:指令发送失败

使用示例:

C++
#include "fd_api/control.h"
#include <cstdio>
#include <vector>

int main() {
    fd_robot::Control ctrl;
    fd_robot::Control::Options opts;
    opts.node_name = "fd_api_control";
    if (!ctrl.Init(opts)) {
        return 1;
    }

    // 左臂 7 关节运动到目标角度(度)
    std::vector<float> joints = {0.0f, -30.0f, -60.0f,
                                    -90.0f, 0.0f, 30.0f, 0.0f};
    bool ok = ctrl.arm_move_joints_deg(fd_robot::ArmSide::kLeft, joints);
    if (ok) {
        printf("关节运动指令发送成功\n");
    } else {
        printf("关节运动指令发送失败\n");
    }
    return 0;
}

4.arm_joint_jog - 手臂单关节点动

方法: ctrl.arm_joint_jog(side, joint_1_to_n, direction, speed_pct)

C++ 签名: bool arm_joint_jog(ArmSide side, int joint_1_to_n, int direction, std::int32_t speed_pct);

参数:

  • side:机械臂侧别,fd_robot::ArmSide 枚举(kLeft / kRight)
  • joint_1_to_n:关节序号,int 类型,范围 1 ~ N(N = 该侧 DOF)
  • direction:点动方向,int 类型,正负含义由驱动实现约定
  • speed_pct:速度百分比,int32_t 类型,范围约 1 ~ 100

返回值:

  • bool:操作结果
    • true:指令发送成功
    • false:指令发送失败

使用示例:

C++
#include "fd_api/control.h"
#include <cstdio>

int main() {
    fd_robot::Control ctrl;
    fd_robot::Control::Options opts;
    opts.node_name = "fd_api_control";
    if (!ctrl.Init(opts)) {
        return 1;
    }

    // 左臂第 3 关节正向点动,速度 30%
    bool ok = ctrl.arm_joint_jog(fd_robot::ArmSide::kLeft, 3, 1, 30);
    if (ok) {
        printf("点动指令发送成功\n");
    } else {
        printf("点动指令发送失败\n");
    }
    return 0;
}

5.arm_joint_step_deg - 手臂单关节步进

方法: ctrl.arm_joint_step_deg(side, joint_1_to_n, direction, step_deg)

C++ 签名: bool arm_joint_step_deg(ArmSide side, int joint_1_to_n, int direction, float step_deg);

参数:

  • side:机械臂侧别,fd_robot::ArmSide 枚举(kLeft / kRight)
  • joint_1_to_n:关节序号,int 类型,范围 1 ~ N(N = 该侧 DOF)
  • direction:步进方向,int 类型,-1 减角度,+1 加角度
  • step_deg:步长,float 类型,单位:度 (°),建议约 0.5 ~ 5.0

返回值:

  • bool:操作结果
    • true:指令发送成功
    • false:指令发送失败

使用示例:

C++
#include "fd_api/control.h"
#include <cstdio>

int main() {
    fd_robot::Control ctrl;
    fd_robot::Control::Options opts;
    opts.node_name = "fd_api_control";
    if (!ctrl.Init(opts)) {
        return 1;
    }

    // 左臂第 3 关节正向步进 5 度
    bool ok = ctrl.arm_joint_step_deg(fd_robot::ArmSide::kLeft, 3, 1, 5.0f);
    if (ok) {
        printf("步进指令发送成功\n");
    } else {
        printf("步进指令发送失败\n");
    }
    return 0;
}

6.arm_power_on - 单臂上电

方法: ctrl.arm_power_on(side)

C++ 签名: bool arm_power_on(ArmSide side);

参数:

  • side:机械臂侧别,fd_robot::ArmSide 枚举(kLeft / kRight)。single 单臂机型忽略侧别

返回值:

  • bool:操作结果
    • true:指令发送成功
    • false:指令发送失败

使用示例:

C++
#include "fd_api/control.h"
#include <cstdio>

int main() {
    fd_robot::Control ctrl;
    fd_robot::Control::Options opts;
    opts.node_name = "fd_api_control";
    if (!ctrl.Init(opts)) {
        return 1;
    }

    // 左臂上电
    bool ok = ctrl.arm_power_on(fd_robot::ArmSide::kLeft);
    if (ok) {
        printf("左臂上电指令发送成功\n");
    } else {
        printf("左臂上电指令发送失败\n");
    }
    return 0;
}

注意: 机械臂控制无反应时,优先检查是否已上电;若因急停导致掉使能,需重新调用上电接口。

7.arm_power_on_both - 双臂上电

方法: ctrl.arm_power_on_both()

C++ 签名: bool arm_power_on_both();

说明: dual 双臂模式下同时上电;single 单臂模式下上电单臂。

参数:

  • 无

返回值:

  • bool:操作结果
    • true:指令发送成功
    • false:指令发送失败

使用示例:

C++
#include "fd_api/control.h"
#include <cstdio>

int main() {
    fd_robot::Control ctrl;
    fd_robot::Control::Options opts;
    opts.node_name = "fd_api_control";
    if (!ctrl.Init(opts)) {
        return 1;
    }

    // 双臂上电
    bool ok = ctrl.arm_power_on_both();
    if (ok) {
        printf("双臂上电指令发送成功\n");
    } else {
        printf("双臂上电指令发送失败\n");
    }
    return 0;
}

8.arm_power_off_both - 双臂下电

方法: ctrl.arm_power_off_both()

C++ 签名: bool arm_power_off_both();

说明: dual 双臂模式下同时下电;single 单臂模式下下电单臂。

参数:

  • 无

返回值:

  • bool:操作结果
    • true:指令发送成功
    • false:指令发送失败

使用示例:

C++
#include "fd_api/control.h"
#include <cstdio>

int main() {
    fd_robot::Control ctrl;
    fd_robot::Control::Options opts;
    opts.node_name = "fd_api_control";
    if (!ctrl.Init(opts)) {
        return 1;
    }

    // 双臂下电
    bool ok = ctrl.arm_power_off_both();
    if (ok) {
        printf("双臂下电指令发送成功\n");
    } else {
        printf("双臂下电指令发送失败\n");
    }
    return 0;
}

9.arm_stop - 单臂停止(下电)

方法: ctrl.arm_stop(side)

C++ 签名: bool arm_stop(ArmSide side);

参数:

  • side:机械臂侧别,fd_robot::ArmSide 枚举(kLeft / kRight)

返回值:

  • bool:操作结果
    • true:指令发送成功
    • false:指令发送失败

使用示例:

C++
#include "fd_api/control.h"
#include <cstdio>

int main() {
    fd_robot::Control ctrl;
    fd_robot::Control::Options opts;
    opts.node_name = "fd_api_control";
    if (!ctrl.Init(opts)) {
        return 1;
    }

    // 左臂停止(下电)
    bool ok = ctrl.arm_stop(fd_robot::ArmSide::kLeft);
    if (ok) {
        printf("左臂停止指令发送成功\n");
    } else {
        printf("左臂停止指令发送失败\n");
    }
    return 0;
}

10.arm_move_axis_delta - 手臂沿轴平移

方法: ctrl.arm_move_axis_delta(side, axis, distance_m)

C++ 签名: bool arm_move_axis_delta(ArmSide side, char axis, float distance_m);

说明: 机械臂末端沿基坐标系指定轴做笛卡尔相对运动,依赖 arm_api_base 指向的 fd_arm_http 服务。

参数:

  • side:机械臂侧别,fd_robot::ArmSide 枚举(kLeft / kRight)
  • axis:平移轴,char 类型,如 'x' / 'y' / 'z'
  • distance_m:平移距离,float 类型,单位:米 (m),正负表示方向

返回值:

  • bool:操作结果
    • true:请求成功
    • false:请求失败

使用示例:

C++
#include "fd_api/control.h"
#include <cstdio>

int main() {
    fd_robot::Control ctrl;
    fd_robot::Control::Options opts;
    opts.node_name = "fd_api_control";
    if (!ctrl.Init(opts)) {
        return 1;
    }

    // 左臂末端沿基坐标系 x 轴正方向移动 0.05m
    bool ok = ctrl.arm_move_axis_delta(fd_robot::ArmSide::kLeft, 'x', 0.05f);
    if (ok) {
        printf("平移请求成功\n");
    } else {
        printf("平移请求失败\n");
    }
    return 0;
}

11.arm_move_to_target - 手臂笛卡尔目标点

方法: ctrl.arm_move_to_target(side, x, y, z)

C++ 签名: bool arm_move_to_target(ArmSide side, float x, float y, float z);

说明: 机械臂末端运动到笛卡尔坐标点,依赖 arm_api_base(默认 http://127.0.0.1:8000)。

参数:

  • side:机械臂侧别,fd_robot::ArmSide 枚举(kLeft / kRight)
  • x / y / z:目标位置,float 类型,单位:米 (m)

返回值:

  • bool:操作结果
    • true:请求成功
    • false:请求失败

使用示例:

C++
#include "fd_api/control.h"
#include <cstdio>

int main() {
    fd_robot::Control ctrl;
    fd_robot::Control::Options opts;
    opts.node_name = "fd_api_control";
    if (!ctrl.Init(opts)) {
        return 1;
    }

    // 左臂末端移动到笛卡尔点 (0.5, 0.1, 0.3)
    bool ok = ctrl.arm_move_to_target(fd_robot::ArmSide::kLeft,
                                          0.5f, 0.1f, 0.3f);
    if (ok) {
        printf("目标点运动请求成功\n");
    } else {
        printf("目标点运动请求失败\n");
    }
    return 0;
}

12.arm_move_to_location - 手臂预置位置名运动

方法: ctrl.arm_move_to_location(side, location_name)

C++ 签名: bool arm_move_to_location(ArmSide side, const std::string &location_name);

说明: 机械臂运动到已配置的预置位置(名称),依赖 arm_api_base。

参数:

  • side:机械臂侧别,fd_robot::ArmSide 枚举(kLeft / kRight)
  • location_name:预置位置名,std::string 类型,须已预先配置

返回值:

  • bool:操作结果
    • true:请求成功
    • false:请求失败

使用示例:

C++
#include "fd_api/control.h"
#include <cstdio>

int main() {
    fd_robot::Control ctrl;
    fd_robot::Control::Options opts;
    opts.node_name = "fd_api_control";
    if (!ctrl.Init(opts)) {
        return 1;
    }

    // 左臂运动到预置位置 "after_grasp"
    bool ok = ctrl.arm_move_to_location(fd_robot::ArmSide::kLeft,
                                          "after_grasp");
    if (ok) {
        printf("预置位置运动请求成功\n");
    } else {
        printf("预置位置运动请求失败\n");
    }
    return 0;
}

13.arm_move_joints_traj - 手臂关节轨迹运动

方法: ctrl.arm_move_joints_traj(side, traj)

C++ 签名: bool arm_move_joints_traj(ArmSide side, const std::vector<std::vector<float>> &traj);

说明: 按多点关节轨迹运动,轨迹由多个关节角序列组成。

参数:

  • side:机械臂侧别,fd_robot::ArmSide 枚举(kLeft / kRight)
  • traj:轨迹点序列,std::vector<std::vector<float>> 类型,每个轨迹点为关节角数组(单位:弧度),每点长度 = 该侧 DOF

返回值:

  • bool:操作结果
    • true:指令发送成功
    • false:指令发送失败

使用示例:

C++
#include "fd_api/control.h"
#include <cstdio>
#include <vector>

int main() {
    fd_robot::Control ctrl;
    fd_robot::Control::Options opts;
    opts.node_name = "fd_api_control";
    if (!ctrl.Init(opts)) {
        return 1;
    }

    // 左臂 7 关节两点轨迹运动(弧度)
    std::vector<std::vector<float>> traj = {
        {0.0f, -0.5f, -1.0f, -1.5f, 0.0f, 0.5f, 0.0f},
        {0.1f, -0.4f, -0.9f, -1.4f, 0.1f, 0.6f, 0.1f},
    };
    bool ok = ctrl.arm_move_joints_traj(fd_robot::ArmSide::kLeft, traj);
    if (ok) {
        printf("轨迹运动指令发送成功\n");
    } else {
        printf("轨迹运动指令发送失败\n");
    }
    return 0;
}

14.arm_get_joint_angles - 获取机械臂关节角(同步读取)

方法: state.arm_get_joint_angles(side, rad_out)

C++ 签名: bool arm_get_joint_angles(ArmSide side, std::vector<float> &rad_out) const;

说明: 同步读取关节角(弧度),输出数组长度等于该侧 DOF。本接口仅 C++ 提供,Python State 暂未封装。

参数:

  • side:机械臂侧别,fd_robot::ArmSide 枚举(kLeft / kRight)
  • rad_out:出参,std::vector<float> & 类型,返回关节角,单位:弧度 (rad)

返回值:

  • bool:是否有有效数据
    • true:已有数据,rad_out 有效
    • false:尚无数据,rad_out 不可信

使用示例:

C++
#include "fd_api/state.h"
#include <cstdio>
#include <vector>

int main() {
    fd_robot::State state;
    if (!state.Init()) {
        return 1;
    }

    // 读取左臂关节角(弧度)
    std::vector<float> rad;
    if (state.arm_get_joint_angles(fd_robot::ArmSide::kLeft, rad)) {
        for (size_t i = 0; i < rad.size(); ++i) {
            printf("joint%d: %.3f rad\n", (int)(i + 1), rad[i]);
        }
    }
    return 0;
}

15.arm_sub_joint_angles - 订阅机械臂关节角(异步回调)

方法: state.arm_sub_joint_angles(side, cb)

C++ 签名: SubscriptionId arm_sub_joint_angles(ArmSide side, ArmJointRadCallback cb);  // cb: void(const std::vector<float>& rad)

说明: 关节角更新时在回调线程中调用回调。本接口仅 C++ 提供,Python State 暂未封装。

参数:

  • side:机械臂侧别,fd_robot::ArmSide 枚举(kLeft / kRight)
  • cb:回调函数,std::function<void(const std::vector<float>&)> 类型,入参为关节角数组,单位:弧度 (rad)

返回值:

  • SubscriptionId:订阅ID,类型为 uint64_t。可用于后续取消订阅;空回调返回 0(失败)

使用示例:

C++
#include "fd_api/state.h"
#include <cstdio>
#include <vector>

int main() {
    fd_robot::State state;
    if (!state.Init()) {
        return 1;
    }

    // 订阅左臂关节角(回调在线程池中执行)
    fd_robot::SubscriptionId sid = state.arm_sub_joint_angles(
        fd_robot::ArmSide::kLeft,
        [](const std::vector<float>& rad) {
            printf("左臂关节角更新,共 %zu 个关节\n", rad.size());
        });
    if (sid != 0) {
        printf("订阅成功,订阅ID:%llu\n", sid);
    }

    // 无需接收时取消订阅
    state.unsubscribe(sid);
    return 0;
}

16.arm_get_end_pose - 获取机械臂末端位姿(同步读取)

方法: state.arm_get_end_pose(side, out)

C++ 签名: bool arm_get_end_pose(ArmSide side, ArmEndPose &out) const;

说明: 同步读取末端位置与四元数姿态。本接口仅 C++ 提供,Python State 暂未封装。其中 fd_robot::ArmEndPose 结构:position[3](位置 x,y,z,单位 m)、orientation[4](姿态四元数 x,y,z,w)。

参数:

  • side:机械臂侧别,fd_robot::ArmSide 枚举(kLeft / kRight)
  • out:出参,fd_robot::ArmEndPose & 类型,返回末端位姿

返回值:

  • bool:是否有有效数据
    • true:已有数据,out 有效
    • false:尚无数据,out 不可信

使用示例:

C++
#include "fd_api/state.h"
#include <cstdio>

int main() {
    fd_robot::State state;
    if (!state.Init()) {
        return 1;
    }

    // 读取左臂末端位姿
    fd_robot::ArmEndPose pose;
    if (state.arm_get_end_pose(fd_robot::ArmSide::kLeft, pose)) {
        printf("位置: (%.3f, %.3f, %.3f) m\n",
               pose.position[0], pose.position[1], pose.position[2]);
        printf("姿态: (%.3f, %.3f, %.3f, %.3f)\n",
               pose.orientation[0], pose.orientation[1],
               pose.orientation[2], pose.orientation[3]);
    }
    return 0;
}

17.arm_sub_end_pose - 订阅机械臂末端位姿(异步回调)

方法: state.arm_sub_end_pose(side, cb)

C++ 签名: SubscriptionId arm_sub_end_pose(ArmSide side, ArmEndPoseCallback cb);  // cb: void(const ArmEndPose&)

说明: 末端位姿更新时在回调线程中调用回调。本接口仅 C++ 提供,Python State 暂未封装。

参数:

  • side:机械臂侧别,fd_robot::ArmSide 枚举(kLeft / kRight)
  • cb:回调函数,std::function<void(const fd_robot::ArmEndPose&)> 类型

返回值:

  • SubscriptionId:订阅ID,类型为 uint64_t。可用于后续取消订阅;空回调返回 0(失败)

使用示例:

C++
#include "fd_api/state.h"
#include <cstdio>

int main() {
    fd_robot::State state;
    if (!state.Init()) {
        return 1;
    }

    // 订阅左臂末端位姿(回调在线程池中执行)
    fd_robot::SubscriptionId sid = state.arm_sub_end_pose(
        fd_robot::ArmSide::kLeft,
        [](const fd_robot::ArmEndPose& pose) {
            printf("末端位姿更新: (%.3f, %.3f, %.3f) m\n",
                   pose.position[0], pose.position[1], pose.position[2]);
        });
    if (sid != 0) {
        printf("订阅成功,订阅ID:%llu\n", sid);
    }

    // 无需接收时取消订阅
    state.unsubscribe(sid);
    return 0;
}

建议:

  • 订阅的回调在线程池中执行,注意线程安全
  • 无需接收位姿更新时及时取消订阅,避免不必要的回调
  • 可与 arm_get_end_pose 同步读取配合使用