使用myCobot 280 Jeston Nano进行物体精确识别追踪

news2024/11/25 2:20:38

前言

我们在YouTube上看到有人使用机械臂实现物体跟踪功能的视频时,深受启发,对这个项目产生了浓厚的兴趣,并决定独立开发一个类似的程序。

我们的目标是开发一个能够准确识别和跟踪物体的机械臂系统,以便在实际应用中发挥作用,这个项目涉及到许多技术和算法,包括视觉识别、手眼协同和机械臂控制等方面。

机械臂的介绍 mycobot280-JetsonNano

操作使用的机械臂是myCobot280-Jetson Nano

这是一款大象机器人公司生产的小六轴机械臂,以JetsonNano为微处理器,ESP32为辅助控制,UR协作形结构。myCobot280 JetsonNano,本体重量1030g, 负载250g,工作半径280mm,设计紧凑便携,小巧但功能强大,操作简单,能与人协同、安全工作。

Jetson Nano

Jetson Nano是英伟达推出的一款嵌入式人工智能计算机,它采用了NVIDIA Maxwell GPU和四核ARM Cortex-A57处理器,性能强大。Jetson Nano支持多种人工智能框架和工具,如TensorFlow、PyTorch、Caffe和MXNet等。此外,Jetson Nano还具有多种输入输出接口,如HDMI、USB、GPIO等,方便开发人员进行硬件连接和控制。

由于Jetson Nano具有强大的计算性能和专门为人工智能开发设计的特点,支持多种深度学习框架,如TensorFlow、PyTorch和Caffe等,可以更方便地进行人工智能应用开发,它成为了开发人员进行人工智能应用开发的理想平台之一。

开发过程

下图是项目的开发流程图

相机捕捉目标

在我开始开发之前,我首先进行了一些调研和实验。我使用了一个相机来捕捉物体的图像,并使用OpenCV库来识别和跟踪Aruco码。尝试过多种的方法,物体的识别需要让机器进行学习,我们要识别的目标,这样会增加项目开发的时间,最后决定用aruco码来进行识别,这样可以快速捕捉到aruco码,进行下一步开发。

Aruco码

下面是实现的代码:

def show_video_v2(self):
        # self.robot.init_robot()
        xyz = np.array([0,0,0])
        LIST = []
        num_count = 0
        list_len = 5
        # cmax = [180, 80, 240]
        # cmin = [130, -80, 200]
        cmax = [150, -150, 300]
        cmin = [-150, -250, 200]

        while cv2.waitKey(1) < 0:
            success, img = self.cap.read()
            if not success:
                print("It seems that the image cannot be acquired correctly.")
                break
            # transfrom the img to model of gray
            gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
            # Detect ArUco marker.
            corners, ids, rejectImaPoint = cv2.aruco.detectMarkers(
                gray, self.aruco_dict, parameters=self.aruco_params
            )

            if len(corners) > 0:
                if ids is not None:
                    # get informations of aruco
                    ret = cv2.aruco.estimatePoseSingleMarkers(
                        # '''https://stackoverflow.com/questions/53303730/what-is-the-value-for-markerlength-in-aruco-estimateposesinglemarkers'''
                        corners, 0.025, self.camera_matrix, self.dist_coeffs
                    )
                    # rvec:rotation offset,tvec:translation deviator
                    (rvec, tvec) = (ret[0], ret[1])
                    
                    (rvec - tvec).any()
                    xyz = tvec[0, 0, :] * 1000
                    rpy = rvec[0,0,:]

                    camera = np.array([xyz[0], xyz[1], xyz[2]])

                    if num_count > list_len:
                        target = model_track(camera)
                        print("target", target)

                        for i in range(3):
                            if target[i] > cmax[i]:
                                target[i] = cmax[i]
                            if target[i] < cmin[i]:
                                target[i] = cmin[i]

                        pose = np.array([-103, 8.9, -164])
                        coord = np.concatenate((target.copy(), pose), axis=0)

                        # q1 = math.atan(xyz[0] / xyz[2])*180/np.pi
                        mc.send_coords(coord,50,0)
                        
                        
                        # print('target', coord)
                        num_count = 1
                    else:
                        num_count = num_count + 1
                    

                    for i in range(rvec.shape[0]):
                        # draw the aruco on img
                        cv2.aruco.drawDetectedMarkers(img, corners)
            cv2.imshow("show_video", img)

复制

手眼标定

手眼标定是指在机器人领域中,确定机器人末端执行器(例如机械手臂)相对于机器人基座坐标系的位置和姿态。这个过程涉及到将机器人末端执行器与相机进行配对,然后通过捕捉执行器在相机视野中的位置和姿态来确定它在机器人基座坐标系中的位置和姿态。

手眼标定通常涉及到在机器人末端执行器和相机之间进行一系列的运动,以便收集足够的数据来计算出它们之间的变换矩阵。这个变换矩阵描述了机器人末端执行器相对于相机的位置和姿态,从而可以用来控制机器人的运动,使其能够准确地执行所需的任务。

在"eye-to-hand"手眼标定中,相机被视为一个不动的观察者("eye"),而机器人末端执行器则被视为在相机视野中移动的物体("hand")。机器人末端执行器在相机周围移动时,会收集到一系列的图像,这些图像包含了机器人末端执行器在不同位置和姿态下的图像信息。通过分析这些图像,可以计算出机器人末端执行器相对于相机的位置和姿态,从而完成手眼标定。

下面是处理坐标之间转换数据的代码

#函数用于计算相机间的相似性
def calculate_similarity(camera):
    n = camera.shape[0]
    total_similarity = 0
    for i in range(n):
        for j in range(i+1, n):
            vector_a = camera[i]
            vector_b = camera[j]
            dot_product = np.dot(vector_a, vector_b)
            norm_a = np.linalg.norm(vector_a)
            norm_b = np.linalg.norm(vector_b)
            similarity = dot_product / (norm_a * norm_b)
            total_similarity += similarity
    return total_similarity/n
# 函数用于计算相似性的变化率
def similarity_change_rate(new_similarity):
    global prev_similarity
    if prev_similarity is None:
        prev_similarity = new_similarity
        return 0
    else:
        change_rate = (new_similarity - prev_similarity) / prev_similarity
        prev_similarity = new_similarity
        return change_rate

#函数用于将旋转矩阵转换为欧拉角
def CvtRotationMatrixToEulerAngle(pdtRotationMatrix):
    pdtEulerAngle = np.zeros(3)

    pdtEulerAngle[2] = np.arctan2(pdtRotationMatrix[1, 0], pdtRotationMatrix[0, 0])

    fCosRoll = np.cos(pdtEulerAngle[2])
    fSinRoll = np.sin(pdtEulerAngle[2])

    pdtEulerAngle[1] = np.arctan2(-pdtRotationMatrix[2, 0], (fCosRoll * pdtRotationMatrix[0, 0]) + (fSinRoll * pdtRotationMatrix[1, 0]))
    pdtEulerAngle[0] = np.arctan2((fSinRoll * pdtRotationMatrix[0, 2]) - (fCosRoll * pdtRotationMatrix[1, 2]), (-fSinRoll * pdtRotationMatrix[0, 1]) + (fCosRoll * pdtRotationMatrix[1, 1]))

    return pdtEulerAngle
# 函数用于将欧拉角转换为旋转矩阵
def CvtEulerAngleToRotationMatrix(ptrEulerAngle):
    ptrSinAngle = np.sin(ptrEulerAngle)
    ptrCosAngle = np.cos(ptrEulerAngle)

    ptrRotationMatrix = np.zeros((3, 3))
    ptrRotationMatrix[0, 0] = ptrCosAngle[2] * ptrCosAngle[1]
    ptrRotationMatrix[0, 1] = ptrCosAngle[2] * ptrSinAngle[1] * ptrSinAngle[0] - ptrSinAngle[2] * ptrCosAngle[0]
    ptrRotationMatrix[0, 2] = ptrCosAngle[2] * ptrSinAngle[1] * ptrCosAngle[0] + ptrSinAngle[2] * ptrSinAngle[0]
    ptrRotationMatrix[1, 0] = ptrSinAngle[2] * ptrCosAngle[1]
    ptrRotationMatrix[1, 1] = ptrSinAngle[2] * ptrSinAngle[1] * ptrSinAngle[0] + ptrCosAngle[2] * ptrCosAngle[0]
    ptrRotationMatrix[1, 2] = ptrSinAngle[2] * ptrSinAngle[1] * ptrCosAngle[0] - ptrCosAngle[2] * ptrSinAngle[0]
    ptrRotationMatrix[2, 0] = -ptrSinAngle[1]
    ptrRotationMatrix[2, 1] = ptrCosAngle[1] * ptrSinAngle[0]
    ptrRotationMatrix[2, 2] = ptrCosAngle[1] * ptrCosAngle[0]

    return ptrRotationMatrix

复制

机械臂控制

在这之后就是物体检测和机械臂的控制,将识别到的物体的坐标转换成机械臂的运动指令,这里用到的是pymycobot库来进行对机械臂的控制。

#用于进行视觉追踪并计算目标位置
def Visual_tracking280(coord, camera):
    pose_camera = camera[:3]
    angle_camear = camera[3:]
    r = CvtEulerAngleToRotationMatrix(angle_camear)
    # r = np.array([[1, 0, 0],
    #                  [0, 1, 0],
    #                  [0, 0, 1]])
    euler = np.radians(coord[3:])
    R = CvtEulerAngleToRotationMatrix(euler)
    offset = np.array([0, 0, -250])
    Roff = np.array([[1, 0, 0],
                     [0, -1, 0],
                     [0, 0, -1]])
    # Roff = np.array([[1, 0, 0],
    #                  [0, 1, 0],
    #                  [0, 0, 1]])
    vector = pose_camera + offset
    # print("R", R)
    # print("r", r)

    move_pos = np.dot(np.dot(R, r), Roff).dot(vector)
    pos = coord[:3] + move_pos
    # angle = np.array(CvtRotationMatrixToEulerAngle(np.dot(np.dot(R, r), Roff))) * 180/np.pi
    angle =  coord[3:]
    target = np.concatenate((pos, angle))
    return target
    
    #根据相机坐标计算目标位置
    def model_track(camera):
    model_pos = np.array([-camera[0], -camera[2], -camera[1]])
    camera_pos = np.array([-37.5, 416.6, 322.9])
    target_pos = model_pos + camera_pos
    # print("model_pos", model_pos)
    # print("target_pos", target_pos)
    return target_pos

复制

最后整理一下项目的逻辑关系,

让我们来看下效果如何。

总结:

在调试的过程中,我们发现跟踪的效果并不是非常流畅和灵敏。我们通过控制检测周期来调整流畅性,但是需要缓慢移动被跟踪的物体目标,才能达到更好的效果。仍然还有一些不足的地方,在相机固定的情况下,机械臂的本体可能会遮挡相机的视野,导致没有办法进行下一步跟踪,想到的解决方案是相机换个位置不被遮挡的位置(坐标换算那些都得重新计算)。如果你有更好的想法欢迎跟我们沟通!感谢你的耐心观看。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/716454.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot 整合Redis 实战篇

一、解决数据乱码问题&#x1f349; 在上篇文章中我们整合了redis&#xff0c;当我们存入一个对象时会发现redis中的数据存在乱码问题&#xff0c;这是jdk编码的问题 springboot整合redis时提供了两个模板工具类&#xff0c;StringRedisTemplate和RedisTemplate. 1.使用Red…

Vue指令--v-if、v-show、v-for

目录 v-if和v-show指令的展示如下&#xff1a; v-for指令的展示如下&#xff1a; v-if和v-show指令的展示如下&#xff1a; v-if指令具有两个配套的指令v-else-if和v-else进行条件判断来决定是否渲染展示某元素 具体代码展示如下&#xff1a;&#xff08;代码中的注释值得一…

音视频入门知识学习

音视频入门知识学习 视频相关视频压缩空间冗余时间冗余视觉冗余信息熵冗余知识冗余 I帧 P帧 B帧 压缩思路I帧P帧B帧 H.264VCLNALNAL&#xff08;片&#xff08;宏块&#xff09;&#xff09; 音频概念采样和采样频率采样位数声道码率声音与音频数字音频相关特点时域冗余频域冗余…

Redis高可用——哨兵模式

Redis——哨兵模式 一、Redis 哨兵模式1.哨兵模式的作用2.故障转移机制3.主节点的选举 二、搭建Redis 哨兵模式1.修改 Redis 哨兵模式的配置文件&#xff08;所有节点操作&#xff09;2.启动哨兵模式3.查看哨兵信息4.故障模拟5.验证结果 一、Redis 哨兵模式 主从切换技术的方法…

【网络原理之一】应用层协议、传输层协议UDP和TCP,TCP的三次握手和四次挥手以及TCP的可靠和效率机制

应用层协议XML协议JSONHTTP 传输层协议UDP协议UDP的特点UDP协议格式 TCP协议TCP的特点TCP协议格式TCP的安全和效率机制确认应答(可靠机制)超时重传(可靠机制)连接管理(可靠机制)三次握手(连接过程)四次挥手(断开的过程)状态的转化 滑动窗口(效率机制)流量控制(可靠机制)拥塞控制…

遥感云大数据在灾害、水体与湿地领域典型案例及GPT模型

详情点击链接&#xff1a;遥感云大数据在灾害、水体与湿地领域典型案例实践及GPT模型 第一&#xff1a;基础 一&#xff1a;平台及基础开发平台 GEE平台及典型应用案例&#xff1b; GEE开发环境及常用数据资源&#xff1b; ChatGPT、文心一言等GPT模型 JavaScript基础&am…

企业如何认识数字化及数字化战略

随着信息和通信技术的发展&#xff0c;数字技术在各个领域广泛应用并深入影响生活、工作和社会的时代。在这个时代里&#xff0c;数字技术不仅改变了我们与世界互动的方式&#xff0c;还催生了全新的商业模式、服务和机会。 数字化时代的关键特征包括&#xff1a; 数字技术的…

Flutter开发微信小程序实战:构建一个简单的天气预报小程序

微信小程序是一种快速、高效的开发方式&#xff0c;Flutter则是一款强大的跨平台开发框架。结合二者&#xff0c;可以轻松地开发出功能丰富、用户体验良好的微信小程序。 这里将介绍如何使用Flutter开发一个简单的天气预报小程序&#xff0c;并提供相应的代码示例。 1. 准备工…

2023年最新Java八股文面试题,面试应该是够用了(吊打面试官)

前言大家先看一下互联网大厂各职级薪资对应表&#xff08;技术线&#xff09;&#xff0c;看看你想到哪个级别去&#xff01; 每个技术人都有个大厂梦&#xff0c;我觉得这很正常&#xff0c;并不是饭后的谈资而是每个技术人的追求。像阿里、腾讯、美团、字节跳动、京东等等的技…

小型企业如何进行高效的文档数据管理?

关键词&#xff1a;知识文档管理系统、群晖NAS、数据安全 我国小型企业数量占全国总数的98%以上&#xff0c;但企业在文档数据管理方面存在诸多问题。比如&#xff1a;文档管理混乱、文档共享不便利、传统的FTP传输文件文档安全难以保障等。 但由于市面上的文档管理产品价格高昂…

思科Cisco C9200交换机端口调配

前言 最近DNAC和交换机等网络设备之间的同步出现问题&#xff0c;在思科的BUG库里找到了相关信息&#xff0c;DNAC2.2.3.6版本的BUG&#xff0c;导致交换机端口的调配无法成功部署推送。但是因为业务的需求&#xff0c;需要对交换机进行端口调配。其和华为/华三的逻辑一致&…

让你不再好奇音频转换格式软件免费有哪些

小美&#xff1a;你好&#xff0c;最近我需要将一些音频文件转换成其他格式&#xff0c;但是不知道常用的音频转换工具有哪些&#xff0c;你有什么建议吗&#xff1f; 李明&#xff1a;当然&#xff0c;有很多音频转换工具可以选择。建议你关注下这篇文章&#xff0c;我将通过…

Bluez HCI Commands

在 lib/Hci.h 头文件中定义了很的我 HCI Commands&#xff0c;这些命令是分组的&#xff0c;每个组下面又提供了具体的命令&#xff0c;如&#xff1a; 其中 OGF 为 OpCode Group Flag&#xff0c;表明命令级别 OCF 为 OpCode Command Flag&#xff0c;表明要执行的命令 Hci…

泰迪智能科技基于产业技能生态链学生学徒制的双创工作室--促进学生高质量就业

据悉&#xff0c;6月28日&#xff0c;广东省人力资源和社会保障厅在广东岭南现代技师学院举行广东省“产教评”技能生态链建设对接活动。该活动以“新培养、新就业、新动能”为主题&#xff0c;总结推广“产教评”技能人才培养新模式&#xff0c;推行“岗位培养”学徒就业新形式…

【无标题】用Javascript编写魔方程序(详解)2023-7-4

第一步&#xff0c;先初始化魔方&#xff0c;如上图&#xff0c;可以很直观的看到魔方的6个面。直接贴代码 <!doctype html> <html><head><meta charset"utf-8"><meta name"viewport" content"widthdevice-width, initia…

微信小程序之Image那些事

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、使用场景二、使用方式1.动态读取image大小2.动态设置style3.动态赋值 总结 前言 小程序中 Image使用频率是非常高的 不同场景下 Image使用的属性也不一样 …

中级保育员专业知识卫生管理考试题库及答案

本题库是根据最新考试大纲要求&#xff0c;结合近年来考试真题的重难点进行汇编整理组成的全真模拟试题&#xff0c;考生们可以进行专项训练&#xff0c;查漏补缺巩固知识点。本题库对热点考题和重难点题目都进行了仔细的整理和编辑&#xff0c;相信考生在经过了针对性的刷题练…

【Redisson】Redisson--话题(订阅分发)

Redisson系列文章&#xff1a; 【Redisson】Redisson–基础入门【Redisson】Redisson–布隆(Bloom Filter)过滤器【Redisson】Redisson–分布式锁的使用&#xff08;推荐使用&#xff09;【分布式锁】Redisson分布式锁底层原理【Redisson】Redisson–限流器、【Redisson】Redi…

你知道ai绘画以图生图软件怎么使用吗?

小美&#xff1a;嗨&#xff0c;张华&#xff0c;你听说过这个令人难以置信的新技术“以图生图ai绘画”吗&#xff1f;它简直让人惊叹&#xff01; 张华&#xff1a;没有&#xff0c;我还没有听说过。什么是以图生图ai绘画&#xff1f; 小美&#xff1a;你看这些美丽的照片&a…

Apikit 自学日记:创建自动化测试项目

在API 自动化测试中&#xff0c;所有的测试用例都是以项目维度来进行管理&#xff0c;一个自动化测试项目可以从多个API文档项目中引用API信息来创建API测试用例。 点击左侧菜单栏&#xff0c;进入 API自动化测试 项目列表页&#xff0c;点击添加按钮&#xff1a; 在弹窗中输入…