29. 跳转至

29. 使用示例#

客户端初始化 AirbotClient.__init__(host: str = "localhost", port: int = 50051)
from arm_sdk import AirbotClient   # 从arm_sdk包中导入AirbotClient类

def main():
    client_arm = AirbotClient(host="localhost", port=50051)  # 在初始化AirbotClient类时,会自动连接机械臂服务端,服务端地址和端口为:localhost:50051
    client_arm.close() # 释放连接,安全退出

if __name__ == "__main__":
    main()
获取当前机械臂关节数据 get_arm_joint_state() -> Optional[ArmJointState]
from arm_sdk import AirbotClient  # 从arm_sdk包中导入AirbotClient类
import time

def main():
    with AirbotClient() as arm:  # 推荐使用上下文管理 Client 生命周期
        arm.acquire_control()  # 获取控制权限
        arm.enter_gravity_compensation_mode()  # 进入重力补偿状态

        try:
            while True:
                state = arm.get_arm_joint_state()  # 获取关节状态
                if state:
                    print(state)
                time.sleep(0.01)
        except KeyboardInterrupt:
            print("\n[INFO] Interrupted by user, exiting...")

if __name__ == "__main__":
    main()
获取当前机械臂电机数据 get_arm_motor_state() -> Optional[ArmMotorState]
from arm_sdk import AirbotClient  # 从arm_sdk包中导入AirbotClient类
import time


def main():
    with AirbotClient() as arm:  # 推荐使用上下文管理 Client 生命周期
        arm.acquire_control()  # 获取控制权限
        arm.enter_gravity_compensation_mode()  # 进入重力补偿状态

        try:
            while True:
                state = arm.get_arm_motor_state()  # 获取电机状态
                if state:
                    print(state)
                time.sleep(0.01)
        except KeyboardInterrupt:
            print("\n[INFO] Interrupted by user, exiting...")


if __name__ == "__main__":
    main()
获取当前末端执行器关节数据 get_eef_joint_state() -> Optional[EEFJointState]
from arm_sdk import AirbotClient  # 从arm_sdk包中导入AirbotClient类
import time


def main():
    with AirbotClient() as arm:  # 推荐使用上下文管理 Client 生命周期
        arm.acquire_control()  # 获取控制权限
        arm.enter_gravity_compensation_mode()  # 进入重力补偿状态

        try:
            while True:
                state = arm.get_eef_joint_state()  # 获取末端执行器状态
                if state:
                    print(state)
                time.sleep(0.01)
        except KeyboardInterrupt:
            print("\n[INFO] Interrupted by user, exiting...")


if __name__ == "__main__":
    main()
获取当前末端执行器电机数据 get_eef_motor_state() -> Optional[EEFMotorState]
from arm_sdk import AirbotClient  # 从arm_sdk包中导入AirbotClient类
import time


def main():
    with AirbotClient() as arm:  # 推荐使用上下文管理 Client 生命周期
        arm.acquire_control()  # 获取控制权限
        arm.enter_gravity_compensation_mode()  # 进入重力补偿状态

        try:
            while True:
                state = arm.get_eef_motor_state()  # 获取末端执行器电机状态
                if state:
                    print(state)
                time.sleep(0.01)
        except KeyboardInterrupt:
            print("\n[INFO] Interrupted by user, exiting...")


if __name__ == "__main__":
    main()
获取当前机械臂末端的笛卡尔空间位姿 get_end_pose() -> Optional[CartesianPose]
from arm_sdk import AirbotClient  # 从arm_sdk包中导入AirbotClient类
import time


def main():
    with AirbotClient() as arm:  # 推荐使用上下文管理 Client 生命周期
        arm.acquire_control()  # 获取控制权限
        arm.enter_gravity_compensation_mode()  # 进入重力补偿状态

        try:
            while True:
                state = arm.get_end_pose()  # 获取末端位姿
                if state:
                    print(state)
                time.sleep(0.01)
        except KeyboardInterrupt:
            print("\n[INFO] Interrupted by user, exiting...")


if __name__ == "__main__":
    main()
获取当前机械臂服务端的运行状态 get_service_state() -> Optional[ServiceState]
from arm_sdk import AirbotClient  # 从arm_sdk包中导入AirbotClient类
import time


def main():
    with AirbotClient() as arm:  # 推荐使用上下文管理 Client 生命周期
        arm.acquire_control()  # 获取控制权限
        arm.enter_gravity_compensation_mode()  # 进入重力补偿状态

        try:
            while True:
                state = arm.get_service_state()  # 获取服务端数据
                if state:
                    print(state)
                time.sleep(0.01)
        except KeyboardInterrupt:
            print("\n[INFO] Interrupted by user, exiting...")


if __name__ == "__main__":
    main()
获取当前机械臂的固件信息 get_firmware_info() -> Optional[ArmFirmwareInfo]
from arm_sdk import AirbotClient, ArmControlOptions, Controller


def main():
    with AirbotClient(port=50051) as arm:  # 推荐使用上下文管理 Client 生命周期
        try:
            fw_info = arm.get_firmware_info()  # 获取固件信息
            print(fw_info)

        except KeyboardInterrupt:
            pass
        finally:
            arm.close()


if __name__ == "__main__":
    main()
设置机械臂关节的最大运动速度与最大运动百分比 set_arm_speed(arm_speed: list[float]) -> bool
from arm_sdk import AirbotClient  # 从arm_sdk包中导入AirbotClient类
import math


def main():
    with AirbotClient() as arm:  # 推荐使用上下文管理 Client 生命周期
        arm.set_arm_speed(
            [1.0 * math.pi] * 6
        )  # 设置电机最大转速1.0 * pi

if __name__ == "__main__":
    main()
设置末端执行器的最大运动速度与最大运动百分比 set_eef_speed(eef_speed: list[float]) -> bool
from arm_sdk import AirbotClient  # 从arm_sdk包中导入AirbotClient类
import math


def main():
    with AirbotClient() as arm:  # 推荐使用上下文管理 Client 生命周期
        arm.set_eef_speed(
            1.0 * math.pi
        )  # 设置电机最大转速1.0 * pi

if __name__ == "__main__":
    main()
设置机械臂控制器 switch_controller(controller: Controller, timeout_ms: int = 1000) -> bool
from arm_sdk import AirbotClient, Controller  # 从arm_sdk包中导入AirbotClient类和Controller枚举类


def main():
    with AirbotClient() as arm:  # 推荐使用上下文管理 Client 生命周期
        arm.acquire_control()  # 获取控制权限

        arm.switch_controller(
            Controller.servo_control
        )  # 切换到servo控制器

if __name__ == "__main__":
    main()
进入重力补偿模式 enter_gravity_compensation_mode(timeout_ms: int = 1000) -> bool
from arm_sdk import AirbotClient  # 从arm_sdk包中导入AirbotClient类


def main():
    with AirbotClient() as arm:  # 推荐使用上下文管理 Client 生命周期
        arm.acquire_control()  # 获取控制权限

        arm.enter_gravity_compensation_mode() # 进入重力补偿模式

if __name__ == "__main__":
    main()
机械臂关节空间控制 move_joint(pos: float, options: ArmControlOptions, timeout_ms: int = 1000) -> bool
from arm_sdk import AirbotClient, Controller, ArmControlOptions
import math


def main():
    with AirbotClient() as arm:  # 推荐使用上下文管理 Client 生命周期
        arm.acquire_control()  # 获取控制权限

        options = ArmControlOptions()  # 初始化一个默认的ArmControlOptions数据结构

        arm.switch_controller(Controller.direct_control)  # 切换控制器为forward
        arm.set_arm_speed(
            [1.0 * math.pi] * 6
        )  # 设置电机最大转速1.0 * pi

        pos = [1.0, -1.0, 1.0, 0.0, 0.0, 0.0]  # 设置目标位置
        options.eff = [8.0, 8.0, 8.0, 8.0, 8.0, 8.0]  # 设置电机电流阈值

        arm.move_joint(pos, options)  # 发送控制指令


if __name__ == "__main__":
    main()

💡 机械臂关节空间控制中各控制器所需的 options 参数

对应控制器 所需 options 参数 备注
Controller.direct_control options.eff 电机电流阈值
options.eef_eff 末端执行器力矩
Controller.servo_control options.eff 电机电流阈值
options.eef_pos 末端执行器目标位置(如果有末端执行器)
options.eef_eff 末端执行器电流阈值(如果有末端执行器)
Controller.planning_control
详情见附录4.3
options.eff 电机电流阈值
options.sampling_time 轨迹采样周期(秒)
options.allow_planning_time 最大规划时间
options.velocity_scaling_factor 速度缩放比例
options.acceleration_scaling_factor 加速度缩放比例
options.force_calc_lin 线性规划失败后是否启用插值策略强制规划
options.lin_interpolate_num 线性规划失败后插值点数
options.lin_hard_threshold 线性规划失败速度强阈值
options.circ_is_center 圆弧轨迹路径点是否为圆心
options.allow_blend_fail 运行融合失败
options.motion_type 规划模式,可选字符串 PTP 和 RRT_CONNECT
Controller.mit_control options.kp 电机kp
options.kd 电机kd
options.torque 电机力矩
options.eef_torque 末端执行器力矩
options.eef_kp 末端执行器kp
options.eef_kd 末端执行器kd
末端执行器关节空间控制 move_eef(pos: float, options: ArmControlOptions, timeout_ms: int = 1000) -> bool
from arm_sdk import AirbotClient, Controller, ArmControlOptions
import math


def main():
    with AirbotClient() as arm:  # 推荐使用上下文管理 Client 生命周期
        arm.acquire_control()  # 获取控制权限

        options = ArmControlOptions()  # 初始化一个默认的ArmControlOptions数据结构

        arm.switch_controller(Controller.direct_control) # 切换控制器为forward
        arm.set_eef_speed(
            math.pi
        )  # 设置电机最大转速1.0 * pi

        pos = 0.07  # 设置目标位置
        options.eef_eff = 6.0  # 设置电机电流阈值

        arm.move_eef(pos, options)  # 发送控制指令


if __name__ == "__main__":
    main()
机械臂笛卡尔空间控制 move_end_pose(pos: CartesianPose, options: ArmControlOptions, timeout_ms: int = 1000) -> bool
from arm_sdk import AirbotClient, Controller, ArmControlOptions, CartesianPose
import math


def main():
    with AirbotClient() as arm:  # 推荐使用上下文管理 Client 生命周期
        arm.acquire_control()  # 获取控制权限

        options = ArmControlOptions()  # 初始化一个默认的ArmControlOptions数据结构

        arm.switch_controller(Controller.direct_control) # 切换控制器为forward
        arm.set_arm_speed(
            [math.pi] * 6
        )  # 设置电机最大转速1.0 * pi

        pos = CartesianPose((0.4, 0.0, 0.3), (0.0, 0.0, 0.0, 1.0)) # 设置目标位姿
        options.eff = [8.0, 8.0, 8.0, 8.0, 8.0, 8.0]  # 设置电机电流阈值

        arm.move_end_pose(pos, options)  # 发送控制指令


if __name__ == "__main__":
    main()
机械臂笛卡尔空间直线轨迹规划控制 move_end_pose_linear(start: CartesianPose, target: CartesianPose, options: ArmControlOptions, timeout_ms: int = 1000) -> bool
from arm_sdk import AirbotClient, Controller, ArmControlOptions, CartesianPose
import math


def main():
    with AirbotClient() as arm:  # 推荐使用上下文管理 Client 生命周期
        arm.acquire_control()  # 获取控制权限

        options = ArmControlOptions()  # 初始化一个默认的ArmControlOptions数据结构

        arm.switch_controller(
            Controller.planning_control
        )  # 切换控制器为joint_trajectory
        arm.set_arm_speed(
            [1.0 * math.pi] * 6
        )  # 设置电机最大转速1.0 * pi

        start = CartesianPose((0.4, 0.0, 0.3), (0.0, 0.0, 0.0, -1.0))  # 设置起始点位姿
        target = CartesianPose((0.4, 0.1, 0.3), (0.0, 0.0, 0.0, -1.0))  # 设置目标位姿
        options.eff = [8.0, 8.0, 8.0, 8.0, 8.0, 8.0]  # 设置电机电流阈值
        options.sampling_time = 0.01  # 设置轨迹采样周期
        options.allow_planning_time = 5.0  # 设置最大规划时间
        options.velocity_scaling_factor = 0.1  # 设置速度缩放比例
        options.acceleration_scaling_factor = 1.0  # 设置加速度缩放比例
        options.force_calc_lin = False  # 设置force_calc_lin
        options.lin_hard_threshold = 10.0  # 设置奇异点速度硬阈值
        options.lin_interpolate_num = 5  # 设置奇异点直线插值点数

        arm.move_end_pose_linear(start, target, options)  # 发送控制指令


if __name__ == "__main__":
    main()
机械臂笛卡尔空间圆弧轨迹规划控制 move_end_pose_circle(start: CartesianPose, path: CartesianPose, target: CartesianPose, options: ArmControlOptions, timeout_ms: int = 1000) -> bool
from arm_sdk import AirbotClient, Controller, ArmControlOptions, CartesianPose
import math


def main():
    with AirbotClient() as arm:  # 推荐使用上下文管理 Client 生命周期
        arm.acquire_control()  # 获取控制权限

        options = ArmControlOptions()  # 初始化一个默认的ArmControlOptions数据结构

        arm.switch_controller(
            Controller.planning_control
        )  # 切换控制器为joint_trajectory
        arm.set_arm_speed(
            [1.0 * math.pi] * 6
        )  # 设置电机最大转速1.0 * pi

        start = CartesianPose((0.4, -0.2, 0.2), (0.0, 0.0, 0.0, 1.0)) # 设置起始点位姿 
        path = CartesianPose((0.6, 0.0, 0.2), (0.0, 0.0, 0.0, 1.0)) # 设置途经点位姿 
        target = CartesianPose((0.2, 0.3, 0.1), (0.0, 0.0, 0.0, 1.0)) # 设置目标点位姿 
        options.eff = [8.0, 8.0, 8.0, 8.0, 8.0, 8.0]  # 设置电机电流阈值
        options.sampling_time = 0.01  # 设置轨迹采样周期
        options.allow_planning_time = 5.0  # 设置最大规划时间
        options.velocity_scaling_factor = 0.1    # 设置速度缩放比例
        options.acceleration_scaling_factor = 1.0  # 设置加速度缩放比例
        options.circ_is_center = False  # 设置CIRC 中 path 是否为圆弧的圆心

        arm.move_end_pose_circle(start, path, target, options)  # 发送控制指令


if __name__ == "__main__":
    main()
机械臂关节空间多路点规划控制 move_joint_waypoints(waypoints: list[list[float]], options: ArmControlOptions, timeout_ms: int = 1000) -> bool
from arm_sdk import AirbotClient, Controller, ArmControlOptions, CartesianPose
import math


def main():
    with AirbotClient() as arm:  # 推荐使用上下文管理 Client 生命周期
        arm.acquire_control()  # 获取控制权限

        options = ArmControlOptions()  # 初始化一个默认的ArmControlOptions数据结构

        arm.switch_controller(
            Controller.planning_control
        )  # 切换控制器为joint_trajectory
        arm.set_arm_speed(
            [1.0 * math.pi] * 6
        )  # 设置电机最大转速1.0 * pi

        waypoints = []
        waypoints.append([1.0, -1.0, 1.0, 0.0, 0.0, 0.0])  # 设置waypoints1
        waypoints.append([0.0, -1.0, 1.0, 0.0, 0.0, 0.0])  # 设置waypoints2
        options.min_blend_radius = 0.001  # 设置混合最小半径
        options.sampling_time = 0.01  # 设置轨迹采样周期
        options.allow_planning_time = 5.0  # 设置最大规划时间
        options.velocity_scaling_factor = 0.1  # 设置速度缩放比例
        options.acceleration_scaling_factor = 1.0  # 设置加速度缩放比例
        options.allow_blend_fail = True  # 设置allow_blend_fail

        arm.move_joint_waypoints(waypoints, options)


if __name__ == "__main__":
    main()
机械臂笛卡尔空间多路点规划控制 move_end_pose_waypoints(waypoints: list[CartesianPose], options: ArmControlOptions, timeout_ms: int = 1000) -> bool
from arm_sdk import AirbotClient, Controller, ArmControlOptions, CartesianPose
import math


def main():
    with AirbotClient() as arm:  # 推荐使用上下文管理 Client 生命周期
        arm.acquire_control()  # 获取控制权限

        options = ArmControlOptions()  # 初始化一个默认的ArmControlOptions数据结构

        arm.switch_controller(
            Controller.planning_control
        )  # 切换控制器为joint_trajectory
        arm.set_arm_speed(
            [1.0 * math.pi] * 6
        )  # 设置电机最大转速1.0 * pi

        waypoints = []
        waypoints.append(
            CartesianPose(position=(0.4, 0.0, 0.3), orientation=(0.0, 0.0, 0.0, 1.0))
        )  # 设置waypoints1
        waypoints.append(
            CartesianPose(position=(0.4, 0.0, 0.1), orientation=(0.0, 0.0, 0.0, 1.0))
        )  # 设置waypoints2
        waypoints.append(
            CartesianPose(position=(0.4, 0.0, 0.5), orientation=(0.0, 0.0, 0.0, 1.0))
        )  # 设置waypoints3

        options.min_blend_radius = 0.005  # 设置混合最小半径
        options.sampling_time = 0.01  # 设置轨迹采样周期
        options.allow_planning_time = 5.0  # 设置最大规划时间
        options.velocity_scaling_factor = 0.1  # 设置速度缩放比例
        options.acceleration_scaling_factor = 1.0  # 设置加速度缩放比例
        options.allow_blend_fail = True  # 设置allow_blend_fail

        arm.move_end_pose_waypoints(waypoints, options)


if __name__ == "__main__":
    main()
机械臂回零 return_zero() -> bool
from arm_sdk import AirbotClient, Controller, ArmControlOptions, CartesianPose


def main():
    with AirbotClient() as arm:  # 推荐使用上下文管理 Client 生命周期
        arm.acquire_control()  # 获取控制权限
        arm.return_zero() # 发送回零指令


if __name__ == "__main__":
    main()
机械臂急停与恢复 set_arm_emergency_stop(mode: bool) -> bool
from arm_sdk import AirbotClient
import time


def main():
    with AirbotClient() as arm:  # 推荐使用上下文管理 Client 生命周期
        arm.acquire_control()  # 急停需要获取控制权限
        arm.set_arm_emergency_stop(mode=True)  # 急停
        time.sleep(5.0)
        arm.set_arm_emergency_stop(mode=False)  # 恢复控制


if __name__ == "__main__":
    main()
清除机械臂电机错误码 clear_arm_motor_err() -> bool
from arm_sdk import AirbotClient, Controller
import time


def main():
    client = AirbotClient(port=50051)  # 在初始化AirbotClient类时,会自动连接机械臂服务端,默认host为localhost,服务端地址和端口为:localhost:50051 
    client.acquire_control()  # 需要获取控制权限
    client.clear_arm_motor_err() # 清除机械臂电机错误码


if __name__ == "__main__":
    main()
清除末端执行器电机错误码 clear_eef_motor_err() -> bool
from arm_sdk import AirbotClient, Controller
import time


def main():
    client = AirbotClient(port=50051)  # 在初始化AirbotClient类时,会自动连接机械臂服务端,默认host为localhost,服务端地址和端口为:localhost:50051 
    client.acquire_control()  # 需要获取控制权限
    client.clear_eef_motor_err() # 清除末端执行器电机错误码


if __name__ == "__main__":
    main()
使用工具函数实现一控一
from arm_sdk import AirbotClient, Controller, ArmControlOptions, utilities
import time


def main():
    port_play: int = 50051,
    port_replay: int = 50052,
    pendant_model: str = "REPLAY",
    gripper_model: str = "G2",
    eff: tuple[float, float, float, float, float, float] = (
        8.0,
        8.0,
        8.0,
        8.0,
        8.0,
        8.0,
    ),
    hz: float = 50.0,
    duration_s: float = 0.0,
    client_arm = AirbotClient(port=port_play)
    client_replay = AirbotClient(port=port_replay)

    dt = 1.0 / max(hz, 1.0)

    try:
        ok = client_arm.acquire_control()
        if not ok:
            raise RuntimeError(
                "Failed to acquire control for PLAY (another client may be controlling)."
            )

        client_arm.switch_controller(
            Controller.servo_control
        )  # 切换控制器为servo_control
        client_arm.set_arm_speed(
            [1.0 * math.pi] * 6
        )  # 设置机械臂电机最大转速 1.0 * pi
        client_arm.set_eef_speed(
            1.0 * math.pi
        )  # 设置末端执行器电机最大转速 1.0 * pi

        options_arm = ArmControlOptions()
        options_arm.eff = list(eff)

        t0 = time.time()

        while True:
            if duration_s > 0.0 and (time.time() - t0) >= duration_s:
                break

            states = client_replay.get_arm_joint_state()
            pos = states.angles

            states_eef = client_replay.get_eef_joint_state()

            pendant_pos = states_eef.eef_pos

            gripper_pos = utilities.map_pendant_to_gripper(
                pos=pendant_pos,
                from_pendant=pendant_model,
                to_gripper=gripper_model,
            )
            print("Gripper pos: ", gripper_pos)
            print("EEF pos: ", pendant_pos)

            options_arm.eef_pos = gripper_pos
            options_arm.eef_eff = 10.0

            client_arm.move_joint(list(pos), options_arm)

            time.sleep(dt)

    except KeyboardInterrupt:
        pass
    finally:
        client_arm.close()
        client_replay.close()


if __name__ == "__main__":
    main()