Skip to main content

三个基本控制动作

注意: 使用以下 API 前,请先导入 pymycobot 库并初始化机械臂对象:

from pymycobot.mycobot280 import MyCobot280

mc = MyCobot280('/dev/ttyAMA0', 1000000)

零、这一节你会学到什么

在这一节里,你将学会用代码控制机械臂做三件最基础也最有用的事情:让它移动到指定位置(坐标控制)、让它感知和控制外界设备(IO 控制)、让它用夹爪抓取物体(夹爪控制)。掌握这三个动作,你就已经能完成像"把桌子上的积木搬到另一个位置"这样的真实任务了。

本节代码量极少,5 分钟就能跑完——但如果只是跑完就关掉,那可亏大了!真正好玩的在后面 😏

本节自由探索项目

🕺 手势舞挑战:学会了坐标控制和 IO 控制,不如让机械臂给你跳一支舞?用本节和上一节的知识,编排一段机械臂「手势舞」——让一个机械臂跟着节奏比划,可能还是有点意思的?

其实呢,本节后面的吸盘和夹爪 demo,我故意没把全部步骤写出来 😈。为什么?因为你需要学会一件比"跟着教程做"更重要的事:自己去官方文档里翻翻找找,"反复(re)寻找(search)"你需要的信息——没错,这就是 research(研究) 的真正样子。不是背答案,而是自己找答案。

📖 自己动手,丰衣足食官方文档:myCobot 280 pi (2023)。我只能帮你到这儿了,后面的路靠你自己啦~ 🦆✨

能够拥有独立“研究”的能力,最大的好处,就是你能凭借自己、去到任何你想去的地方。


唯一能够限制你的,就是想象力和执行力。

——就是我说的

一、坐标控制

高中生导读

想象你在玩一个3D游戏。游戏里每个角色都有一个位置,用三个数字表示:前后(x)、左右(y)、上下(z)。这就是直角坐标系

但机械臂比游戏角色多了一个能力。它的"头部"不仅能到达某个位置,还能在那个位置上朝向不同的方向。就像你拿着手机拍照,站在同一个位置,但手机可以上下左右转动。这三个转动角度就是 [rx, ry, rz],叫做欧拉坐标

所以机械臂的完整坐标是六个数字:[x, y, z, rx, ry, rz]。前三个告诉它"去哪里",后三个告诉它"到了之后朝哪个方向"。

1.1 概述

坐标控制主要用于实现智能规划路线,让机械臂从一个位置到另一个指定位置。分为 [x, y, z, rx, ry, rz],其中 [x, y, z] 表示的是机械臂头部在空间中的位置(该坐标系为直角坐标系),[rx, ry, rz] 表示的是机械臂头部在该点的姿态(该坐标系为欧拉坐标)。

算法的实现以及欧拉坐标的表示需要一定的学术知识,这里不对其过多的讲解,我们只要懂得直角坐标系就可以很好地使用这个函数了。

注意: 在设置坐标时,不同系列的机械臂关节构造有所不同。同一组坐标,不同系列的机械臂会展示不同的姿态。

myCobot 280 坐标系示意图

1.2 坐标控制 API

1.2.1 send_coord(id, coord, speed)

  • 功能: 发送单个坐标值给机械臂进行移动
  • 参数说明:
    • id:代表机械臂的坐标,表示方法 1-6。如 X 轴可以填写 1,Y 填写 2,以此类推
    • coord:输入您想要到达的坐标值
    • speed:表示机械臂运动的速度,范围是 1-100
  • 返回值: 1
坐标 ID对应轴范围(mm / °)
1x-281.45 ~ 281.45
2y-281.45 ~ 281.45
3z-70 ~ 412.67
4rx-180 ~ 180
5ry-180 ~ 180
6rz-180 ~ 180

1.2.2 get_coords()

  • 功能: 获取当前坐标和姿态
  • 返回值: list 包含坐标和姿态的列表,长度为 6,依次为 [x, y, z, rx, ry, rz]

1.2.3 send_coords(coords, speed, mode)

  • 功能: 发送整体坐标和姿态,让机械臂头部从原来点移动到您指定点
  • 参数说明:
    • coords[x, y, z, rx, ry, rz] 的坐标值,长度为 6
    • speed:表示机械臂运动的速度,范围是 1-100
    • mode(int):取值限定 0 和 1
      • 0 表示机械臂头部移动的路径为非线性,即随机规划路线,只要机械臂头部以保持规定的姿态移动到指定点即可
      • 1 表示机械臂头部移动的路径为线性的,即智能规划路线让机械臂头部以直线的方式移动到指定点
  • 返回值: 1
直线运动注意

使用 mode=1 进行直线运动时,需确保目标点在机械臂可达范围内,且路径上无障碍物。若逆解无解,机械臂将报错停止。

1.2.4 set_tool_reference(coords)

  • 功能: 设置工具坐标系
  • 参数说明:
    • coords:六轴 [x, y, z, rx, ry, rz] 的坐标值,长度为 6。x, y, z 的范围为 -280 ~ 280,rx, ry, rz 的范围为 -314 ~ 314
  • 返回值: 1

1.2.5 get_tool_reference()

  • 功能: 获取工具坐标系
  • 返回值: 返回一个长度为 6 的坐标列表

1.2.6 set_world_reference(coords)

  • 功能: 设置世界坐标系
  • 参数说明:
    • coords:六轴 [x, y, z, rx, ry, rz] 的坐标值,长度为 6。x, y, z 的范围为 -280 ~ 280,rx, ry, rz 的范围为 -314 ~ 314
  • 返回值: 1

1.2.7 get_world_reference()

  • 功能: 获取世界坐标系
  • 返回值: 返回一个长度为 6 的坐标列表

1.2.8 set_reference_frame(rftype)

  • 功能: 设置基坐标系
  • 参数说明:
    • rftype:0 - 基坐标系(默认),1 - 世界坐标系
  • 返回值: 1

1.2.9 get_reference_frame()

  • 功能: 获取基坐标系
  • 返回值: 0 - 基坐标系,1 - 世界坐标系,-1 - 通信失败

1.2.10 set_end_type(end)

  • 功能: 设置末端坐标系
  • 参数说明:
    • end:0 - 法兰(默认),1 - 工具
  • 返回值: 1

1.2.11 get_end_type()

  • 功能: 获取末端坐标系
  • 返回值: 0 - 法兰(默认),1 - 工具,-1 - 通信失败

1.3 坐标控制完整案例

坐标控制示例
from pymycobot.mycobot280 import MyCobot280
import time

# MyCobot280 类初始化需要两个参数:串口号和波特率
# 初始化一个 MyCobot280 对象(PI 版本)
mc = MyCobot280("/dev/ttyAMA0", 1000000)

# 设置 fresh mode,确保获取最新数据
if mc.get_fresh_mode() != 1:
mc.set_fresh_mode(1)

# 获取当前头部的坐标以及姿态
coords = mc.get_coords()
print(coords)

# 智能规划路线,让头部以线性的方式到达 [57.0, -107.4, 316.3] 这个坐标,
# 以及保持 [-93.81, -12.71, -163.49] 这个姿态,速度为 80mm/s
mc.send_coords([57.0, -107.4, 316.3, -93.81, -12.71, -163.49], 80, 1)

# 设置等待时间 1.5 秒,让机械臂有足够时间移动到位
time.sleep(1.5)

# 智能规划路线,让头部以线性的方式到达 [-13.7, -107.5, 223.9] 这个坐标,
# 以及保持 [165.52, -75.41, -73.52] 这个姿态,速度为 80mm/s
mc.send_coords([-13.7, -107.5, 223.9, 165.52, -75.41, -73.52], 80, 1)

# 设置等待时间 1.5 秒
time.sleep(1.5)

# 仅改变头部的 x 坐标,设置头部的 x 坐标为 -40。
# 让其智能规划路线让头部移动到改变后的位置,速度为 70mm/s
mc.send_coord(1, -40, 70)

二、IO 控制

高中生导读

IO 就是 Input/Output(输入/输出)。你可以把它理解为机械臂的感官和动作

  • 输入(Input):就像你的眼睛和皮肤能感受外界信息一样,机械臂通过输入引脚"感受"外部信号。比如检测有没有物体靠近、按钮有没有被按下。
  • 输出(Output):就像你的手能对外界做出动作一样,机械臂通过输出引脚"控制"外部设备。比如打开一个吸泵、点亮一盏灯。

机械臂上有两组 IO 引脚:一组在底座(Basic),一组在末端(Atom)。另外,因为这台机械臂用的是树莓派,所以还可以直接用树莓派的 GPIO 引脚。

2.1 概述

IO 即数据的输入与输出。在我们的机械臂的 Basic 和 Atom 上有多个 pin 脚,通过以下函数接口可以对其设置其输入输出模式。

myCobot IO 引脚图

2.2 Basic IO(底座)

2.2.1 get_basic_input(pin_no)

  • 功能: 获取底部引脚号的工作状态
  • 参数说明: pin_no:表示机械臂底部的具体引脚号
  • 返回值: pin_signal(int),当返回的值为 0 表示在工作状态运行,1 表示停止状态

2.2.2 set_basic_output(pin_no, pin_signal)

  • 功能: 设置底部引脚号的工作状态
  • 参数说明:
    • pin_no(int):设备底部标注的编号,仅取数字部分
    • pin_signal(int):输入 0 表示设置为运行状态,输入 1 表示停止状态
  • 返回值: 1

2.2.3 get_tof_distance()

  • 功能: 获取检测到的距离(需要外部距离检测器)
  • 返回值: 检测到的距离值,单位为 mm

2.3 Atom IO(末端)

2.3.1 set_pin_mode(pin_no, pin_mode)

  • 功能: 设置 Atom 中指定引脚的状态模式
  • 参数说明:
    • pin_no(int):机械臂末端的具体引脚号
    • pin_mode(int):限定 0~2
      • 0:设置为运行状态
      • 1:设置为停止状态
      • 2:设置为上拉模式
  • 返回值: 1

2.3.2 set_digital_output(pin_no, pin_signal)

  • 功能: 设置末端引脚号的工作状态
  • 参数说明:
    • pin_no(int):设备末端标注的编号,仅取数字部分
    • pin_signal(int):输入 0 表示设置为运行状态,输入 1 表示停止状态
  • 返回值: 1

2.3.3 get_digital_input(pin_no)

  • 功能: 获取末端引脚号的工作状态
  • 参数说明: pin_no:表示机械臂末端的具体引脚号
  • 返回值: pin_signal(int),当返回的值为 0 表示在工作状态运行,1 表示停止状态

2.4 树莓派 GPIO

当您的机械臂为树莓派版本时,您可以用到以下 API。

用法: 文件开头输入代码导入:

from pymycobot import MyCobot280
import RPi.GPIO as GPIO

2.4.1 gpio_init()

  • 功能: 初始化 GPIO 模块,设置 BCM 模式
  • 返回值: 1

2.4.2 set_gpio_mode(mode)

  • 功能: 设置树莓派 GPIO 引脚编号模式
  • 参数:
    • mode(str):输入 "BCM" 或者 "BOARD" 进入相应模式

2.4.3 set_gpio_output(pin_no, state)

  • 功能: 将引脚设置为高、低电平
  • 参数说明:
    • pin_no(int):引脚编号
    • state:0 设置为低电平,1 设置为高电平(吸泵低电平开启工作,高电平停止工作)
  • 返回值: 1

2.4.4 get_gpio_in(pin_no)

  • 功能: 获取引脚电平状态
  • 参数说明: pin_no(int):引脚编号
  • 返回值: 0 为低电平,1 为高电平

2.5 IO 控制完整案例(吸泵控制)

吸泵控制示例
from pymycobot.mycobot280 import MyCobot280
import time
import RPi.GPIO as GPIO
# 输入以上代码导入工程所需要的包

# MyCobot 类初始化需要两个参数:串口号和波特率
# 初始化一个 MyCobot 对象(树莓派版本)
mc = MyCobot280("/dev/ttyAMA0", 1000000)

# 初始化 GPIO,使用 BCM 编号模式
GPIO.setmode(GPIO.BCM)

# 设置 GPIO 20 为输出模式(控制吸泵)
GPIO.setup(20, GPIO.OUT)
# 设置 GPIO 21 为输出模式(控制泄气阀门)
GPIO.setup(21, GPIO.OUT)

# 开启吸泵(低电平工作)
GPIO.output(20, 0)

# 等待 2 秒,让吸泵吸附物体
time.sleep(2)

# 关闭吸泵(高电平停止)
GPIO.output(20, 1)
time.sleep(0.05)

# 打开泄气阀门,释放吸附的物体(低电平工作)
GPIO.output(21, 0)
time.sleep(1)

# 关闭泄气阀门
GPIO.output(21, 1)
time.sleep(0.05)
RPi.GPIO 依赖

使用树莓派 GPIO 功能需要安装 RPi.GPIO 库。如果尚未安装,请运行:

pip install RPi.GPIO

三、夹爪控制

高中生导读

夹爪就是机械臂的。就像你的手可以张开、合拢、抓住东西一样,夹爪也能做类似的动作。

在使用夹爪之前,需要先把夹爪安装到机械臂末端的 Atom 模块上。夹爪插在 Atom 的引脚上,连接好后就可以用 Python 代码控制它了。

常见的夹爪类型有:自适应夹爪(能自动适应物体形状)、平行夹爪(两爪平行开合)、柔性夹爪(适合抓易碎物品)等。

3.1 概述

使用 Python 控制夹爪之前,需要先在机械臂上安装连接好夹爪。不同夹爪适配不同的机械臂(具体适配信息请参考产品配件章节)。

注意:

MyCobot 280 自适应夹爪将夹爪插在 Atom 上面的引脚上,具体看下图:

夹爪连接示意图

3.2 夹爪控制 API

3.2.1 is_gripper_moving()

  • 功能: 判断夹爪是否正在运行
  • 返回值:
    • 0:表示机械臂的夹爪没有运行
    • 1:表示机械臂的夹爪正在运行
    • -1:表示出错

3.2.2 set_gripper_state(flag, speed, type_1=None, is_torque=None)

  • 功能: 让夹爪以指定的速度进入到指定的状态
  • 参数:
    • flag(int):0 - 打开,1 - 关闭,254 - 释放
    • speed(int):0 ~ 100
    • type_1(int):
      • 1:自适应夹爪(默认是自适应夹爪)
      • 2:五指灵巧手
      • 3:平行夹爪
      • 4:柔性夹爪
    • is_torque(int):夹爪是否是力控类型,如果没有类型参数,则可以省略此参数。(注意:仅当末端 Atom 固件版本 ≥ 6.5 时才支持该参数
      • 0:非力控夹爪
      • 1:力控夹爪
  • 返回值: 1 - 完成

3.2.3 set_gripper_value(gripper_value, speed, gripper_type=None, is_torque=None)

  • 功能: 让夹爪以指定的速度转动到指定的位置
  • 参数:
    • gripper_value(int):0 ~ 100
    • speed(int):0 ~ 100
    • gripper_type(int):
      • 1:自适应夹爪(默认是自适应夹爪)
      • 3:平行夹爪
      • 4:柔性夹爪
    • is_torque(int):夹爪是否是力控类型,如果没有类型参数,则可以省略此参数。(注意:仅当末端 Atom 固件版本 ≥ 6.5 时才支持该参数
      • 0:非力控夹爪
      • 1:力控夹爪
  • 返回值: 1 - 完成

3.2.4 get_gripper_value(gripper_type=None)

  • 功能: 获取夹爪的当前位置数据信息
  • 参数说明:
    • gripper_type:夹爪类型,默认是自适应夹爪
      • 1:自适应夹爪
      • 3:平行夹爪
      • 4:柔性夹爪
  • 返回值: 夹爪的数据信息

3.2.5 set_HTS_gripper_torque(torque)

  • 功能: 设置自适应夹爪力矩
  • 参数说明:
    • torque:150 ~ 900
  • 返回值: 0 - 设置失败,1 - 设置成功

3.2.6 get_HTS_gripper_torque()

  • 功能: 获取自适应夹爪力矩
  • 返回值: 150 ~ 900

3.2.7 get_gripper_protect_current()

  • 功能: 获取夹爪保护电流
  • 返回值: 1 ~ 500

3.2.8 init_gripper()

  • 功能: 初始化夹爪
  • 返回值: 0 - 初始化失败,1 - 初始化成功

3.2.9 set_gripper_protect_current(current)

  • 功能: 设置夹爪保护电流
  • 参数说明:
    • current:1 ~ 500
  • 返回值: 0 - 初始化失败,1 - 初始化成功

3.3 夹爪控制完整案例

夹爪控制示例
from pymycobot.mycobot280 import MyCobot280
import time
# 输入以上代码导入工程所需要的包

def gripper_test(mc):
print("Start check IO part of api\n")

# 检测夹爪是否正在移动
flag = mc.is_gripper_moving()
print("Is gripper moving: {}".format(flag))
time.sleep(1)

# 设置关节点 1,让其转动到 2048 这个位置
mc.set_encoder(1, 2048, 20)
time.sleep(2)

# 设置六个关节位,让机械臂以 20 的速度转动到该位置
mc.set_encoders([1024, 1024, 1024, 1024, 1024, 1024], 20)
time.sleep(3)

# 以 70 的速度让夹爪到达 100 状态(完全打开)
mc.set_gripper_value(100, 70)
time.sleep(3)

# 以 70 的速度让夹爪到达 0 状态(完全闭合)
mc.set_gripper_value(0, 70)
time.sleep(3)

# 设置夹爪的状态,让其以 70 的速度快速打开爪子
mc.set_gripper_state(0, 70)
time.sleep(3)

# 设置夹爪的状态,让其以 70 的速度快速收拢爪子
mc.set_gripper_state(1, 70)
time.sleep(3)

# 获取夹爪的值并打印
print("")
print(mc.get_gripper_value())


if __name__ == "__main__":
# MyCobot 类初始化需要两个参数:串口号和波特率
# 初始化一个 MyCobot280 对象(PI 版本)
mc = MyCobot280('/dev/ttyAMA0', 1000000)

# 让机械臂移动到零位(所有关节设为 2048)
mc.set_encoders([2048, 2048, 2048, 2048, 2048, 2048], 20)
time.sleep(3)

# 运行夹爪测试函数
gripper_test(mc)
力控夹爪

当 Atom 固件版本 ≥ 6.5 时,可使用力控模式。在 set_gripper_state()set_gripper_value() 中设置 is_torque=1 即可启用力控,夹爪会在遇到阻力时自动停止,适合抓取易碎物品。

四、试着把它们组合起来

到这一步,你已经掌握了机械臂编程中最核心的三个基本动作:告诉它**"去哪里"、让它"感知和控制外界",以及用"手"抓取物体**。试着把这些动作组合起来——比如先移动到一个位置,打开夹爪,下降,夹住物体,抬起来,再移动到另一个位置放下。只要会组合这三个动作,你就能让机械臂完成很多看起来"很智能"的实际任务了。