跳到内容 跳到主导航 跳到页脚

机械臂控制

一、简介

本文档介绍 RobotApi 中机械臂(手臂)相关接口的使用方法。这组接口提供了对机器人左臂、右臂、双臂的运动控制、位置查询、实时监控能力。

支持机型: 本文档涉及的所有手臂控制 API 仅支持豹小秘 Pro 机型。其他机型调用相关接口将无法正常执行。

能力概述:

  1. 运动控制
    1. 左臂 / 右臂的相对角度移动、绝对角度移动
    2. 双臂同步相对移动、绝对移动(保证左右臂同步执行)
    3. 重置左臂 / 右臂 / 双臂到默认位置(垂直于地面)
    4. 停止左臂 / 右臂 / 双臂运动
  2. 状态查询
    1. 查询左臂 / 右臂当前位置(角度、电机位置、速度)
    2. 查询手臂是否可移动(摆臂功能是否启用)
  3. 实时监控
    1. 注册 / 取消注册手臂位置实时监听器,持续接收位置变化数据

关键说明:

  • 所有运动接口均通过 CommandListener 异步回调返回执行结果
    • result == Definition.RESULT_SUCCEEDmessage == Definition.SUCCEED 视为成功
    • 其他情况均为失败,包含超时、硬件异常等
  • 角度单位:,正值向前,负值向后; 表示手臂垂直于地面
  • 角度有效范围:-30° ~ +130°(向后最大 30°,向前最大 130°);超出范围的目标角度会被限位裁剪
  • 默认位置(重置接口的目标位置):(垂直地面)
  • 速度参数取值范围:1 ~ 60;传 0 时按默认值 30 运动;超出范围的取值不保证行为
  • 资源占用:armLeftXxx 占用 RESOURCE_ARM_LEFTarmRightXxx 占用 RESOURCE_ARM_RIGHT,双臂接口同时占用左右臂资源;同一资源若被前一个未结束的命令占用,新命令会返回资源冲突错误。如果业务侧能自行保证调用顺序不重叠,无需额外处理;若调用时机不可控(例如用户多次快速点击),建议在每次发起运动前先调用对应的停止接口(armLeftStop / armRightStop / armDualStop),可有效避免冲突。

二、运动控制 API

2.1 左臂相对角度移动

方法名称:armLeftRelMove

调用方式:

RobotApi.getInstance().armLeftRelMove(reqId, angle, speed, new CommandListener() {
    @Override
    public void onResult(int result, String message, String extraData) {
        if (result == Definition.RESULT_SUCCEED && Definition.SUCCEED.equals(message)) {
            // 成功
        } else {
            // 失败(包含超时、硬件异常等)
        }
    }
});

参数:

  • reqId:int 类型,命令 id
  • angle:int 类型,相对角度(单位:度,正值向前,负值向后,如 50 表示向前移动 50°,-50 表示向后移动 50°);目标位置(当前角度 + angle)必须落在 -30° ~ +130° 范围内,否则会被限位裁剪
  • speed:int 类型,速度(取值 1~60,传 0 按默认 30 执行)
  • listenerCommandListener 回调,可为 null

2.2 左臂绝对角度移动

方法名称:armLeftAbsMove

调用方式:

RobotApi.getInstance().armLeftAbsMove(reqId, angle, speed, new CommandListener() {
    @Override
    public void onResult(int result, String message, String extraData) {
        if (result == Definition.RESULT_SUCCEED && Definition.SUCCEED.equals(message)) {
            // 移动到目标角度成功
        } else {
            // 失败
        }
    }
});

参数:

  • reqId:int 类型,命令 id
  • angle:int 类型,目标绝对角度(单位:度,有效范围 -30° ~ +130°,超出会被裁剪);如 45 表示移动到 45°,-30 表示移动到 -30°
  • speed:int 类型,速度(取值 1~60,传 0 按默认 30 执行)
  • listenerCommandListener 回调,可为 null

2.3 右臂相对角度移动

方法名称:armRightRelMove

调用方式:

RobotApi.getInstance().armRightRelMove(reqId, angle, speed, new CommandListener() {
    @Override
    public void onResult(int result, String message, String extraData) {
        if (result == Definition.RESULT_SUCCEED && Definition.SUCCEED.equals(message)) {
            // 成功
        } else {
            // 失败
        }
    }
});

参数:

  • reqId:int 类型,命令 id
  • angle:int 类型,相对角度(单位:度,正值向前,负值向后;右臂自动镜像处理);目标位置必须落在 -30° ~ +130° 范围内,否则会被限位裁剪
  • speed:int 类型,速度(取值 1~60,传 0 按默认 30 执行)
  • listenerCommandListener 回调,可为 null

2.4 右臂绝对角度移动

方法名称:armRightAbsMove

调用方式:

RobotApi.getInstance().armRightAbsMove(reqId, angle, speed, new CommandListener() {
    @Override
    public void onResult(int result, String message, String extraData) {
        if (result == Definition.RESULT_SUCCEED && Definition.SUCCEED.equals(message)) {
            // 成功
        } else {
            // 失败
        }
    }
});

参数:

  • reqId:int 类型,命令 id
  • angle:int 类型,目标绝对角度(单位:度,有效范围 -30° ~ +130°,超出会被裁剪);右臂自动镜像处理
  • speed:int 类型,速度(取值 1~60,传 0 按默认 30 执行)
  • listenerCommandListener 回调,可为 null

2.5 双臂相对角度移动(同步)

方法名称:armDualRelMove

调用方式:

RobotApi.getInstance().armDualRelMove(reqId, leftAngle, rightAngle, speed, new CommandListener() {
    @Override
    public void onResult(int result, String message, String extraData) {
        if (result == Definition.RESULT_SUCCEED && Definition.SUCCEED.equals(message)) {
            // 成功
        } else {
            // 失败
        }
    }
});

参数:

  • reqId:int 类型,命令 id
  • leftAngle:int 类型,左臂相对角度(正值向前,负值向后);目标位置必须落在 -30° ~ +130°
  • rightAngle:int 类型,右臂相对角度(正值向前,负值向后);目标位置必须落在 -30° ~ +130°
  • speed:int 类型,速度(取值 1~60,传 0 按默认 30 执行)
  • listenerCommandListener 回调,可为 null

说明: 该接口保证左右臂同步执行,比单独调用左右臂接口更可靠。


2.6 双臂绝对角度移动(同步)

方法名称:armDualAbsMove

调用方式:

RobotApi.getInstance().armDualAbsMove(reqId, leftAngle, rightAngle, speed, new CommandListener() {
    @Override
    public void onResult(int result, String message, String extraData) {
        if (result == Definition.RESULT_SUCCEED && Definition.SUCCEED.equals(message)) {
            // 成功
        } else {
            // 失败
        }
    }
});

参数:

  • reqId:int 类型,命令 id
  • leftAngle:int 类型,左臂目标绝对角度(有效范围 -30° ~ +130°
  • rightAngle:int 类型,右臂目标绝对角度(有效范围 -30° ~ +130°
  • speed:int 类型,速度(取值 1~60,传 0 按默认 30 执行)
  • listenerCommandListener 回调,可为 null

2.7 重置左臂到默认位置

方法名称:resetLeftArmToDefault

调用方式:

RobotApi.getInstance().resetLeftArmToDefault(reqId, new CommandListener() {
    @Override
    public void onResult(int result, String message, String extraData) {
        if (result == Definition.RESULT_SUCCEED && Definition.SUCCEED.equals(message)) {
            // 重置成功
        } else {
            // 失败
        }
    }
});

参数:

  • reqId:int 类型,命令 id
  • listenerCommandListener 回调

说明: 默认位置为左臂垂直于地面的姿态(即 )。


2.8 重置右臂到默认位置

方法名称:resetRightArmToDefault

调用方式:

RobotApi.getInstance().resetRightArmToDefault(reqId, new CommandListener() {
    @Override
    public void onResult(int result, String message, String extraData) {
        if (result == Definition.RESULT_SUCCEED && Definition.SUCCEED.equals(message)) {
            // 重置成功
        } else {
            // 失败
        }
    }
});

参数:

  • reqId:int 类型,命令 id
  • listenerCommandListener 回调

说明: 默认位置为右臂垂直于地面的姿态(即 )。


2.9 重置双臂到默认位置(同步)

方法名称:resetBothArmsToDefault

调用方式:

RobotApi.getInstance().resetBothArmsToDefault(reqId, new CommandListener() {
    @Override
    public void onResult(int result, String message, String extraData) {
        if (result == Definition.RESULT_SUCCEED && Definition.SUCCEED.equals(message)) {
            // 重置成功
        } else {
            // 失败
        }
    }
});

参数:

  • reqId:int 类型,命令 id
  • listenerCommandListener 回调

说明: 同时将左右臂重置到默认位置。相比分别调用 resetLeftArmToDefaultresetRightArmToDefault,该接口可以保证两臂同步执行。


三、停止控制 API

3.1 停止左臂运动

方法名称:armLeftStop

调用方式:

RobotApi.getInstance().armLeftStop(reqId);

参数:

  • reqId:int 类型,命令 id

说明: 该接口会同时释放 RESOURCE_ARM_LEFT 资源,无回调。


3.2 停止右臂运动

方法名称:armRightStop

调用方式:

RobotApi.getInstance().armRightStop(reqId);

参数:

  • reqId:int 类型,命令 id

说明: 该接口会同时释放 RESOURCE_ARM_RIGHT 资源,无回调。


3.3 停止双臂运动

方法名称:armDualStop

调用方式:

RobotApi.getInstance().armDualStop(reqId);

参数:

  • reqId:int 类型,命令 id

说明: 同时停止左右臂运动并释放对应资源,无回调。


四、状态查询 API

4.1 查询左臂位置

方法名称:getLeftArmPosition

调用方式:

RobotApi.getInstance().getLeftArmPosition(reqId, new CommandListener() {
    @Override
    public void onResult(int result, String message, String extraData) {
        if (result == Definition.RESULT_SUCCEED && Definition.SUCCEED.equals(message)) {
            try {
                JSONObject json = new JSONObject(extraData);
                String arm = json.optString(Definition.JSON_ARM);     // Definition.ARM_LEFT
                int angle = json.optInt(Definition.JSON_ARM_ANGLE);   // 角度(单位:度)
                int speed = json.optInt(Definition.JSON_ARM_SPEED);   // 当前速度
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }
});

参数:

  • reqId:int 类型,命令 id
  • listenerCommandListener 回调,通过 extraData 返回 JSON 字符串:
    • arm:手臂标识,左臂固定为 "left"Definition.ARM_LEFT
    • angle:当前角度(度)
    • speed:当前速度

4.2 查询右臂位置

方法名称:getRightArmPosition

调用方式:

RobotApi.getInstance().getRightArmPosition(reqId, new CommandListener() {
    @Override
    public void onResult(int result, String message, String extraData) {
        if (result == Definition.RESULT_SUCCEED && Definition.SUCCEED.equals(message)) {
            try {
                JSONObject json = new JSONObject(extraData);
                String arm = json.optString(Definition.JSON_ARM);     // Definition.ARM_RIGHT
                int angle = json.optInt(Definition.JSON_ARM_ANGLE);
                int speed = json.optInt(Definition.JSON_ARM_SPEED);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }
});

参数:

  • reqId:int 类型,命令 id
  • listenerCommandListener 回调,通过 extraData 返回 JSON 字符串,格式同左臂查询,arm 固定为 "right"Definition.ARM_RIGHT

4.3 查询手臂是否可移动

方法名称:isArmMovable

调用方式:

RobotApi.getInstance().isArmMovable(reqId, new CommandListener() {
    @Override
    public void onResult(int result, String message, String extraData) {
        if (result == Definition.RESULT_SUCCEED && Definition.SUCCEED.equals(message)) {
            try {
                JSONObject json = new JSONObject(extraData);
                boolean movable = json.optBoolean(Definition.JSON_ARM_MOVABLE);
                // movable == true 表示摆臂功能当前已启用,可以执行手臂运动
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }
});

参数:

  • reqId:int 类型,命令 id
  • listenerCommandListener 回调,通过 extraData 返回 JSON:{"movable": true/false}

说明:

  • 对于支持机械臂的机型,若同时接入了胸前大屏等外设,系统会根据当前状态动态决定是否允许摆臂;该开关仅可在系统设置页面修改,提供三种模式:
    • 智能检测(默认):自动识别屏幕连接状态。接入屏幕时手臂不摆动,未接入时正常摆动。
    • 关闭摆动:手臂始终不摆动,适合外接屏幕时使用,避免手臂与屏幕碰撞。
    • 开启摆动:手臂持续可摆动,适合领位、跳舞等互动场景,建议在未外接屏幕时使用。
  • 该接口返回的是「当前是否真正可摆臂」的最终结果,已综合考虑系统设置与外接屏状态。
  • movable == false 时,调用手臂运动接口不会真正执行,仅返回失败结果,不会引发其他副作用。
  • 业务如需提示用户当前手臂不可用,可在进入相关页面时调用一次该接口;中途无需反复检查。

五、实时监控 API

5.1 注册手臂位置监听器

方法名称:registerArmPositionListener

调用方式:

StatusListener listener = new StatusListener() {
    @Override
    public void onStatusUpdate(String type, String data) {
        try {
            JSONObject json = new JSONObject(data);
            String arm = json.optString(Definition.JSON_ARM);     // Definition.ARM_LEFT 或 Definition.ARM_RIGHT
            int angle = json.optInt(Definition.JSON_ARM_ANGLE);
            int speed = json.optInt(Definition.JSON_ARM_SPEED);
            if (Definition.ARM_LEFT.equals(arm)) {
                // 左臂位置更新
            } else if (Definition.ARM_RIGHT.equals(arm)) {
                // 右臂位置更新
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
};

RobotApi.getInstance().registerArmPositionListener(listener);

参数:

  • listenerStatusListener 状态监听器
    • onStatusUpdate(String type, String data)data 为 JSON 字符串,字段同 getLeftArmPosition / getRightArmPositionarmanglespeed

说明:

  • 注册成功后将持续接收左右臂位置变化数据,直到调用 unregisterArmPositionListener 取消
  • 取消注册时只需传入同一个 listener 实例即可,无需保存返回值

5.2 取消注册手臂位置监听器

方法名称:unregisterArmPositionListener

调用方式:

RobotApi.getInstance().unregisterArmPositionListener(listener);

参数:

  • listener:注册时使用的同一个 StatusListener 实例

注意: 在 Activity / Fragment 销毁时务必取消注册,避免内存泄漏。


六、附录

6.1 回调结果判断模板

所有运动控制接口均推荐使用以下方式判断结果:

new CommandListener() {
    @Override
    public void onResult(int result, String message, String extraData) {
        if (result == Definition.RESULT_SUCCEED && Definition.SUCCEED.equals(message)) {
            // 成功
        } else {
            // 失败:result 可能为超时、硬件异常等错误码
            // message 描述具体失败原因
        }
    }
}

6.2 资源占用说明

接口占用资源
armLeftRelMove / armLeftAbsMove / resetLeftArmToDefault / armLeftStopRESOURCE_ARM_LEFT
armRightRelMove / armRightAbsMove / resetRightArmToDefault / armRightStopRESOURCE_ARM_RIGHT
armDualRelMove / armDualAbsMove / resetBothArmsToDefault / armDualStopRESOURCE_ARM_LEFT + RESOURCE_ARM_RIGHT

当资源被占用时(如左臂正在执行另一动作),新的命令会返回资源冲突错误码,需要先停止冲突命令或等待执行完毕。

冲突规避建议:

  • 业务自行保证调用顺序:若业务可以确保上一次手臂命令结束后才发起下一次(例如等待 CommandListener.onResult 回调),则无需额外处理。
  • 调用时机不可控时:例如用户连续点击、外部事件驱动等场景,可在每次发起运动前先调用对应的停止接口,再发起新动作,可有效规避资源冲突。
// 示例:发起左臂运动前,先停止左臂
RobotApi.getInstance().armLeftStop(0);
RobotApi.getInstance().armLeftAbsMove(0, 90, 30, new CommandListener() {
    @Override
    public void onResult(int result, String message, String extraData) {
        // 处理结果
    }
});

// 双臂同理
RobotApi.getInstance().armDualStop(0);
RobotApi.getInstance().armDualAbsMove(0, 0, 0, 30, listener);

6.3 完整示例

完整调用示例请参考 RobotSample 工程中的: com.ainirobot.robotos.fragment.ArmControlFragment

该示例覆盖了本文档列出的所有 API 调用方式。

这篇文章是否有帮助?

0