机械臂末端执行器(夹爪)

1.hand_move - 手部移动

方法: ctrl.hand_move(value) / ctrl.hand_move(type, value)

C++ 签名:

  • bool hand_move(const std::vector<float> &value);  // 使用 Init 时配置的默认手型
  • bool hand_move(HandType type, const std::vector<float> &value);

参数:

  • type:手部类型,fd_robot::HandType 枚举,默认取 Options.hand_type
    • HandType::kLeft:左手
    • HandType::kRight:右手
    • HandType::kBoth:双手
  • value:手部控制值,std::vector<float> 类型
    • RoHand(HandBackend::kRohand):6 个 float 关节值
    • Inspire(HandBackend::kInspire):取首个整型开度值

返回值:

  • 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";
    opts.hand_backend = fd_robot::HandBackend::kInspire;  // 默认 Inspire
    opts.hand_type = fd_robot::HandType::kBoth;           // 默认双手
    if (!ctrl.Init(opts)) {
        return 1;
    }

    // RoHand:传入 6 个关节值
    std::vector<float> rohand_vals = {0.0f, 0.5f, 0.3f,
                                        0.1f, 0.0f, 0.0f};
    bool ok = ctrl.hand_move(fd_robot::HandType::kLeft, rohand_vals);
    if (ok) {
        printf("左手动作指令发送成功\n");
    } else {
        printf("左手动作指令发送失败\n");
    }

    // Inspire:取首个整型开度值
    std::vector<float> inspire_vals = {500.0f};
    ctrl.hand_move(fd_robot::HandType::kRight, inspire_vals);
    return 0;
}

注意: 手部驱动后端由 Options.hand_backend 决定(默认 HandBackend::kInspire)。RoHand 与 Inspire 的 value 取值规则不同,接口不可混用。

2.hand_stop - 手部停止

方法: ctrl.hand_stop(type) / ctrl.hand_stop()

C++ 签名:

  • bool hand_stop(HandType type);
  • bool hand_stop();  // 使用默认手型

参数:

  • type:手部类型,fd_robot::HandType 枚举,指定停止哪只手,默认取 Options.hand_type
    • HandType::kLeft:停止左手
    • HandType::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";
    opts.hand_type = fd_robot::HandType::kBoth;
    if (!ctrl.Init(opts)) {
        return 1;
    }

    // 停止左手
    ctrl.hand_stop(fd_robot::HandType::kLeft);

    // 使用默认手型(双手)停止
    ctrl.hand_stop();
    printf("手部已停止\n");
    return 0;
}

3.hand_get_current_pos - 获取手部位置/开度(同步读取)

方法: state.hand_get_current_pos(type, value)

C++ 签名: bool hand_get_current_pos(HandType type, std::vector<float> &value) const;

说明: 同步读取手部关节值或开度数组。

参数:

  • type:手部类型,fd_robot::HandType 枚举(kLeft / kRight,一般不用 kBoth)
  • value:出参,std::vector<float> & 类型,返回手部关节值或开度数组

返回值:

  • bool:表示是否已有有效缓存数据
    • true:已有数据,value 有效
    • false:尚无数据,value 不可信

使用示例:

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

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

    // 读取左手位置/开度
    std::vector<float> value;
    if (state.hand_get_current_pos(fd_robot::HandType::kLeft, value)) {
        for (size_t i = 0; i < value.size(); ++i) {
            printf("joint%d: %.3f\n", (int)(i + 1), value[i]);
        }
    }
    return 0;
}

4.hand_sub_current_pos - 订阅手部位置(异步回调)

方法: state.hand_sub_current_pos(type, cb)

C++ 签名: SubscriptionId hand_sub_current_pos(HandType type, HandPosCallback cb);  // cb: void(HandType, const std::vector<float>&)

参数:

  • type:手部类型,fd_robot::HandType 枚举,订阅哪只手
  • cb:回调函数,std::function<void(fd_robot::HandType, const std::vector<float>&)> 类型
    • HandType:标识哪只手
    • std::vector<float>:关节值或开度数组

返回值:

  • 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.hand_sub_current_pos(
        fd_robot::HandType::kLeft,
        [](fd_robot::HandType type, const std::vector<float>& value) {
            printf("手部位置更新,共 %zu 个值\n", value.size());
        });
    if (sid != 0) {
        printf("订阅成功,订阅ID:%llu\n", sid);
    }

    // 无需接收时取消订阅
    state.unsubscribe(sid);
    printf("已取消手部位置订阅\n");
    return 0;
}

建议:

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