这篇文章转载来自SWITCH SCIENCE的SuzukiSumiya,本篇文章转载已获作者授权。

原文链接来自:https://www.switch-science.com/blogs/magazine/jetson-maker-faire-tokyo-2023

1.引言
这篇文章来自SWITCH SCIENCE的SuzukiSumiya 在Maker Faire Tokyo 2023上演示了通过模拟人手臂的姿态来控制机械臂。演示的内容是使用USB摄像头通过图像识别估计手臂,并将机械臂制作成类似的手臂形状。

视频链接:https://youtu.be/h1H6pSvhQxQ

该项目主要使用Ultralytics YOLOv8来进行姿态的估计,结合机器视觉和机械臂的控制等功能。本篇文章我们将复写这个项目,一步一步的开始如何建立起这个项目。

2.技术介绍
YOLOv8介绍
Ultralytics YOLOv8 是一种尖端、最先进 (SOTA) 模型,它建立在先前 YOLO 版本成功的基础上,并引入了新功能和改进,以进一步提高性能和灵活性。 YOLOv8 的设计目标是快速、准确且易于使用,使其成为各种对象检测和跟踪、实例分割、图像分类和姿态估计任务的绝佳选择。https://docs.ultralytics.com/

YOLOv8,作为这一系列的最新版本,包含以下特点和改进:

更快的检测速度:YOLO 系列以其快速的检测速度而闻名,每个后续版本都在这方面进行了优化。
更高的准确性:通过使用更先进的神经网络架构和学习算法,YOLOv8 可能会提高物体检测的准确性。
更好的泛化能力:改进的算法可能更有效地处理不同类型的图像数据,包括在复杂背景和不同光照条件下的检测。
适应性和可扩展性的增强:新版本可能会提供更多的定制选项和设置,使其能够更好地适应不同的应用场景和需求。
优化的资源使用:对计算效率的改进可能会使 YOLOv8 在资源有限的设备上运行得更好,如在移动设备或嵌入式系统中。
简单点说,给它一张图片识别,YOLOv8能够快速的识别出图片中的物体,并且将它标记出来。

机械臂支持多平台开发Linux,Windows,MacOS,并且控制接口全部开源支持目前市面上主流的编程语言python,c++/c#等。

python-pymycobot mycobot系列的控制库https://github.com/elephantrobotics/pymycobot

https://developer.nvidia.com/buy-jetson?product=all&location=JP

开发过程
开发环境:
软件:

操作系统:Linux

编译语言:Python

python 库:

import cv2
import math
import time
from ultralytics import YOLO
from pymycobot.mycobot import MyCobot

yolov8模型:yolov8n-pose.pt

https://docs.ultralytics.com/tasks/pose/

硬件:

USB 摄像头*1

myCobot 280 M5Stack *1

Jetson Orin Nano*1

显示器,键盘鼠标*1

代码实现
yolov8姿态估计模型-yolov8n-pose

yolov8有训练好的姿态估计模型,可以直接使用。姿态估计是一项任务,其涉及识别图像中特定点的位置,通常被称为关键点。这些关键点可以代表物体的各种部位,如关节、地标或其他显著特征。关键点的位置通常表示为一组2D [x, y] 或3D [x, y, visible] 坐标。

简单使用的方法:

import torch
from ultralytics.yolov8 import YOLO
import cv2

#引入模型
model = YOLO('yolov8n-pose.pt')
#打开图片
img = cv2.imread('image.jpg')
# 将图片引入模型
results = model(img)

# 展示结果
for r in results:
    im_array = r.plot()  # 绘制包含预测结果的BGR numpy数组
    im = Image.fromarray(im_array[..., ::-1])  # RGB PIL图像
    im.show()  # 显示图像
    im.save('results.jpg')  # 保存图像


在项目中需要获取人手比的手腕,肘部和肩部的x,y坐标来进行计算角度,然后将相同的角度发送到mycobot的第二第三关节。

Code:

``python
if keypoints_tensor is not None and keypoints_tensor.size(1) > 0:
     # 提取特定关键点的坐标和置信度
        x_mimi = keypoints_tensor[0][3][0]
        y_mimi = keypoints_tensor[0][3][1]
        conf_mimi = confidence_score[0][3]

        x_kosi = keypoints_tensor[0][13][0]
        y_kosi = keypoints_tensor[0][13][1]
        conf_kosi = confidence_score[0][13]

        x_kata = keypoints_tensor[0][5][0]
        y_kata = keypoints_tensor[0][5][1]
        conf_kata = confidence_score[0][5]

        x_hizi = keypoints_tensor[0][7][0]
        y_hizi = keypoints_tensor[0][7][1]
        conf_hizi = confidence_score[0][7]

        x_te = keypoints_tensor[0][9][0]
        y_te = keypoints_tensor[0][9][1]
        conf_te = confidence_score[0][9]

然后计算腰部到肩部之间的角度,这个角度主要关注的是上半身的一个简化模型,可能用于模拟肩部的运动或整个上半身的倾斜。  

```python
#计算AB之间的向量
vector_AB = (x_kata - x_hizi, y_kata - y_hizi)
#用函数计算这个向量的角度
angle_rad1 = math.atan2(vector_AB[1], vector_AB[0])
#将角度从弧度转为度
angle_deg1 = math.degrees(angle_rad1)
#计算后调整的角度值用于控制机械臂
mycobot1 = int(angle_deg1)-90

接下来在计算手部,肘部,肩部三个关键点形成的角度,这个角度涉及更复杂的姿势分析,因为它包括了从手部到膝部再到肩部的整个链条,结合这两种角度的计算,可以让机械臂模仿人体姿势更加精准和自然。

            x1=x_te #手部的x,y
            y1=y_te

            x2=x_hizi #肘部的X,Y
            y2=y_hizi

            x3=x_kata # 肘部的x,y
            y3=y_kata


            #定义三个做标点
            point1 = (x1, y1)
            point2 = (x2, y2)
            point3 = (x3, y3)
            # 计算向量
            vector1 = (x2 - x1, y2 - y1)
            vector2 = (x3 - x2, y3 - y2)
            # 计算向量长度 
            length1 = math.sqrt(vector1[0] ** 2 + vector1[1] ** 2)
            length2 = math.sqrt(vector2[0] ** 2 + vector2[1] ** 2)
            # 计算点积
            dot_product = vector1[0] * vector2[0] + vector1[1] * vector2[1]
            # 计算角度(弧度)
            angle_rad = math.atan2(vector2[1], vector2[0]) - math.atan2(vector1[1], vector1[0])
        # 如果角度向右弯曲则为 0 度
        # 如果角度从右向左转动则为 180 度
        # 如果在一条直线上,则为 -90 度(或 +90 度,以哪个为准)

          if angle_rad > math.pi:
                angle_rad -= 2 * math.pi
            elif angle_rad < -math.pi:
                angle_rad += 2 * math.pi
            # 将角度转换为度数
            mycobot2 = int(math.degrees(angle_rad))

最后将获取到的角度,通过条件判断控制机械臂进行手臂的模拟运动。

#机械臂在计算的mycobot1,mycobot2可接受的范围内分别是是 -180 至 180 度和 -155 至 155 度            
if -180 <= mycobot1 and mycobot1 <= 180 and -155 <= mycobot2 and mycobot2 <= 155 and conf_hizi >= 0.75:
             #符合条件led灯会变蓝
                mc.send_angles ([90,-mycobot1,mycobot2,0,-90,0],100)
                mc.set_color(0, 0, 255)
                print("A点的角度(度数法):", conf_hizi)
            else:# 不符合条件LED等会变红
                print("A点的角度(度数法):", conf_hizi)
                mc.set_color(255, 0, 255)


总结
SuzukiSumiya在maker faire tokyo 2023上展示了Jetson Orin Nano 和mycobot以及yolov8-pose相结合实现了一个非常有趣的demo。可以学到多个方面的知识和技能,包括计算机视觉、机器人编程、数学计算,以及如何将这些元素结合起来创建一个交互式的系统。
下面的视频是对SuzukiSumiya做这个项目的一个访谈。

https://www.youtube.com/watch?v=DB5WiUQVhek

如果你有什么其他有趣的项目,也可以联系我们,我们会分享你的项目在各个平台让大家都关注到。