使用myCobot 280机械臂校准OAK智能深度相机

news2024/11/27 12:59:18

编辑:OAK中国
首发:oakchina.cn
喜欢的话,请多多👍⭐️✍
内容可能会不定期更新,官网内容都是最新的,请查看首发地址链接。

▌前言

Hello,大家好,这里是OAK中国,我是助手君。

本次使用的机械臂来自我们的朋友@大象机器人,测试模拟工厂在OAK相机出厂前的校准工作。大家如果没有机械臂,也可以手动校准(教程),效果差别不会特别大。本次校准使用的OAK相机是OAK-D-Lite,其他型号的双目OAK相机也可参考此教程校准。

myCobot 280机械臂校准OAK-D-Lite智能深度相机

▌机械臂环境

  • arduino mega 2560 *1
  • USB串口调试器 *1

参考文档烧写机械臂的驱动、设置arduino开发环境、以及设备的连接,ATOM驱动烧写4.1版本。

▌设备连接

机械臂与arduino的连接参考上一步的文档。

USB串口调试器是用来触发每一张图片的动作,需要rx和tx交叉接,接到rx0和tx0上,还有一个GND也要接。

OAK连接到电脑,固定到机械臂末端。

▌arduino烧写

烧写时检查rx0和tx0不要被占用(即烧写时不要接USB串口调试器),烧写以下代码:

#include <MyCobotBasic.h>
#include <ParameterList.h>
#include <SoftwareSerial.h>
MyCobotBasic myCobot;

void setup()
{  

    Serial.begin(4800);
    myCobot.setup();
    delay(100);
    myCobot.powerOn();
    delay(100);
}

void loop()
{
  if (Serial.available()) {
    int read1;
    read1 = Serial.read();
//    Serial.println("read1");
//    Serial.println(read1);
    if (read1 == 1){
        myCobot.writeAngle(1, 17.40, 50);
        delay(1000);
        myCobot.writeAngle(2, -121.64, 50);
        delay(1000);
        myCobot.writeAngle(3, 42.27, 50);
        delay(1000);
        myCobot.writeAngle(4, 73.21, 50);
        delay(1000);
        myCobot.writeAngle(5, -11.51, 50);
        delay(1000);
        myCobot.writeAngle(6, 21.79, 50);
        delay(4000);
        Serial.write(1);
    } else if (read1 == 2){
        //2
        myCobot.writeAngle(1, 43.41, 50);
        delay(1000);
        myCobot.writeAngle(2, -118.03, 50);
        delay(1000);
        myCobot.writeAngle(3, 44.73, 50);
        delay(1000);
        myCobot.writeAngle(4, 58.62, 50);
        delay(1000);
        myCobot.writeAngle(5, -60.20, 50);
        delay(1000);
        myCobot.writeAngle(6, 32.08, 50);
        delay(4000);
        Serial.write(2);
    } else if (read1 == 3){
        //3
        myCobot.writeAngle(1, 43.24, 50);
        delay(1000);
        myCobot.writeAngle(2, -121.81, 50);
        delay(1000);
        myCobot.writeAngle(3, 45.08, 50);
        delay(1000);
        myCobot.writeAngle(4, 63.89, 50);
        delay(1000);
        myCobot.writeAngle(5, -55.98, 50);
        delay(1000);
        myCobot.writeAngle(6, 31.72, 50);
        delay(4000);
        Serial.write(3);
    } else if (read1 == 4){
        //4
        myCobot.writeAngle(1, 47.02, 50);
        delay(1000);
        myCobot.writeAngle(2, -116.36, 50);
        delay(1000);
        myCobot.writeAngle(3, 45.61, 50);
        delay(1000);
        myCobot.writeAngle(4, 58.09, 50);
        delay(1000);
        myCobot.writeAngle(5, -52.29, 50);
        delay(1000);
        myCobot.writeAngle(6, 31.81, 50);
        delay(4000);
        Serial.write(4);
    } else if (read1 == 5){
        //5
        myCobot.writeAngle(1, -15.55, 50);
        delay(1000);
        myCobot.writeAngle(2, -121.28, 50);
        delay(1000);
        myCobot.writeAngle(3, 74.35, 50);
        delay(1000);
        myCobot.writeAngle(4, 28.56, 50);
        delay(1000);
        myCobot.writeAngle(5, 35.59, 50);
        delay(1000);
        myCobot.writeAngle(6, 8.70, 50);
        delay(4000);
        Serial.write(5);
    } else if (read1 == 6){
        //6
        myCobot.writeAngle(1, -17.22, 50);
        delay(1000);
        myCobot.writeAngle(2, -114.08, 50);
        delay(1000);
        myCobot.writeAngle(3, 49.83, 50);
        delay(1000);
        myCobot.writeAngle(4, 54.84, 50);
        delay(1000);
        myCobot.writeAngle(5, 32.69, 50);
        delay(1000);
        myCobot.writeAngle(6, 12.65, 50);
        delay(4000);
        Serial.write(6);
    } else if (read1 == 7){
        //7
        myCobot.writeAngle(1, -14.32, 50);
        delay(1000);
        myCobot.writeAngle(2, -105.90, 50);
        delay(1000);
        myCobot.writeAngle(3, 31.90, 50);
        delay(1000);
        myCobot.writeAngle(4, 64.51, 50);
        delay(1000);
        myCobot.writeAngle(5, 25.31, 50);
        delay(1000);
        myCobot.writeAngle(6, 12.65, 50);
        delay(4000);
        Serial.write(7);
    } else if (read1 == 8){
        //8
        myCobot.writeAngle(1, 2.10, 50);
        delay(1000);
        myCobot.writeAngle(2, -47.19, 50);
        delay(1000);
        myCobot.writeAngle(3, 33.39, 50);
        delay(1000);
        myCobot.writeAngle(4, -22.23, 50);
        delay(1000);
        myCobot.writeAngle(5, 4.83, 50);
        delay(1000);
        myCobot.writeAngle(6, 17.84, 50);
        delay(4000);
        Serial.write(8);
    } else if (read1 == 9){
        //9
        myCobot.writeAngle(1, 0.61, 50);
        delay(1000);
        myCobot.writeAngle(2, -47.81, 50);
        delay(1000);
        myCobot.writeAngle(3, 32.95, 50);
        delay(1000);
        myCobot.writeAngle(4, -19.51, 50);
        delay(1000);
        myCobot.writeAngle(5, 2.72, 50);
        delay(1000);
        myCobot.writeAngle(6, 15.11, 50);
        delay(4000);
        Serial.write(9);
    } else if (read1 == 10){
        // A
        myCobot.writeAngle(1, 9.84, 50);
        delay(1000);
        myCobot.writeAngle(2, -69.87, 50);
        delay(1000);
        myCobot.writeAngle(3, 33.31, 50);
        delay(1000);
        myCobot.writeAngle(4, 11.16, 50);
        delay(1000);
        myCobot.writeAngle(5, -5.0, 50);
        delay(1000);
        myCobot.writeAngle(6, 22.58, 50);
        delay(4000);
        Serial.write(10);
    } else if (read1 == 11){
        // B
        myCobot.writeAngle(1, 3.51, 50);
        delay(1000);
        myCobot.writeAngle(2, -140.36, 50);
        delay(1000);
        myCobot.writeAngle(3, 33.66, 50);
        delay(1000);
        myCobot.writeAngle(4, 113.64, 50);
        delay(1000);
        myCobot.writeAngle(5, 2.37, 50);
        delay(1000);
        myCobot.writeAngle(6, 18.45, 50);
        delay(4000);
        Serial.write(11);
    } else if (read1 == 12){
        // C
        myCobot.writeAngle(1, 4.04, 50);
        delay(1000);
        myCobot.writeAngle(2, -140.18, 50);
        delay(1000);
        myCobot.writeAngle(3, 33.31, 50);
        delay(1000);
        myCobot.writeAngle(4, 116.45, 50);
        delay(1000);
        myCobot.writeAngle(5, 2.37, 50);
        delay(1000);
        myCobot.writeAngle(6, 17.40, 50);
        delay(4000);
        Serial.write(12);
    } else if (read1 == 13){
        // D
        myCobot.writeAngle(1, 3.51, 50);
        delay(1000);
        myCobot.writeAngle(2, -140.27, 50);
        delay(1000);
        myCobot.writeAngle(3, 33.31, 50);
        delay(1000);
        myCobot.writeAngle(4, 107.31, 50);
        delay(1000);
        myCobot.writeAngle(5, 2.37, 50);
        delay(1000);
        myCobot.writeAngle(6, 14.50, 50);
        delay(4000);
        Serial.write(13);
    } else if (read1 == 14){
      // E
      myCobot.setFreeMove();
    } else if (read1 == 15){
      // F
      Angles  angles = myCobot.getAngles();
      delay(200);
      
      for (int i = 0; i < 6; i++) {
          Serial.println(angles[i]);
      }
    }
 }

}

▌启动OAK

https://github.com/Marco-ardu/depthai/tree/lite_calibration

定格角度commit: e6a0c9f43e2e18f2c31d70a1cb248a867d3e5ede

自动校准commit: 52f8e08887738ce8ab348a586cacc64bec0881dd

依赖(建议创建虚拟环境安装)

python -m pip install -r requirements.txt

启动

python calibrate.py -s 2 -brd oak-d-lite -db -rd

▌找定格角度

XCOM V2.6.exe下载

启动OAK相机之后,可以看到三个相机的画面,以及画面上黑色的框,先调整棋盘格到机械臂的距离,能够保证棋盘格在三个画面里就可以了,不能太远,大概距离是50cm-60cm,具体根据真实环境调整。

确认USB串口调试器已经连接好

打开XCOM软件,配置如下,波特率根据上面的arduino代码设置的填写

在这里插入图片描述
在这里插入图片描述

串口输出E让机械臂自由移动,然后移动机械臂将棋盘格移动到框内(在大致大概即可),然后串口输出F,获取定格角度;点击相机画面,然后键盘输入空格,进入下一张,如果失败,说明当前位置不正确,重新调整位置,一共13张。

▌自动校准

在获得13张图片的定格角度之后,填写到上面的arduino代码中,重新烧写代码。

OAK关闭后,切换到自动校准的commit。

启动相机,点击相机画面,键盘输入s,即可开始自动校准。

▌结果

出现以下图像即表示校准成功!
在这里插入图片描述
大部分的测试校准都能成功,但偶尔会出现以下错误。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
校准会出现以上错误,网上查了校准的原理,这个错误原因是rgb画面在检测的那一帧模糊导致检测的角点过少,无法构建对应的方程去解出校准参数。

▌参考资料

https://docs.oakchina.cn/en/latest/
https://www.oakchina.cn/selection-guide/


OAK中国
| OpenCV AI Kit在中国区的官方代理商和技术服务商
| 追踪AI技术和产品新动态

戳「+关注」获取最新资讯↗↗

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

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

相关文章

第三站:函数(第三幕)递归训练

目录 一、编写一个函数实现n的k次方&#xff0c;使用递归实现。&#xff08;k为整数&#xff09; 二、写一个递归函数DigitSum(n)&#xff0c;输入一个非负整数&#xff0c;返回组成它的数字之和 三、编写一个函数 reverse_string(char * string)&#xff08;递归实现&#x…

WebDAV之葫芦儿·派盘+墨阅

墨阅 支持webdav方式连接葫芦儿派盘。 是一款专注于帮助用户离线缓存网页文档图书漫画的免费工具APP。您可以利用墨阅收集来自互联网网站平台的公开文章,图片,漫画等,可以对网页样式进行调整,支持自定义动作,批量离线等功能方便用户日常离线。目前支持小说,markdown,图…

公众号搜题系统

公众号搜题系统 本平台优点&#xff1a; 多题库查题、独立后台、响应速度快、全网平台可查、功能最全&#xff01; 1.想要给自己的公众号获得查题接口&#xff0c;只需要两步&#xff01; 2.题库&#xff1a; 查题校园题库&#xff1a;查题校园题库后台&#xff08;点击跳转…

语义分割之RTFormer介绍

语义分割之RTFormer介绍 论文链接&#xff1a;https://arxiv.org/abs/2210.07124 代码地址&#xff1a;https://github.com/PaddlePaddle/PaddleSeg ViT以来&#xff0c;Transformer作为特征提取器在语义分割领域证明了自己&#xff0c;但是由于Transformer的核心 muti-self-…

苹果电脑提高工作效率alfred 5中文

Mac电脑上哪个效率工具好用呢&#xff1f;alfred 5是最强大的效率启动工具之一&#xff0c;丰富的插件资源、简单的上手成本&#xff0c;会是你提高 Mac 使用效率的得力助手。可通过热键&#xff0c;关键字&#xff0c;文本扩展等提高您的效率。搜索您的Mac和网络&#xff0c;并…

Sprint产品待办列表的优先级要怎么排?

在梳理产品待办事项列表的过程中&#xff0c;产品负责人需要先做优先级排列&#xff0c;保证我们在一定的时间盒内能够交付需要优先级最高、最具价值的用户故事。 那这个用户故事的优先级要怎么排列&#xff0c;我们怎样选择用户故事的实现顺序&#xff1f; 有一个实践可以推…

力扣(LeetCode)816. 模糊坐标(C++)

模拟 一次遍历 sss &#xff0c;尝试对遍历到的位置进行分割。对分割点左右字符串 ltltlt , rtrtrt 分别构造子串。 构造子串的规则: 整数不以 000 开头&#xff0c;(特例)单独的 000 可以作为整数。小数不以 000 结尾。小数的整数位是 000 &#xff0c;则整数位不能组成新数…

怎么给PDF添加页面?推荐三个PDF如何插入页面小妙招

在我们生活中&#xff0c;平时接触PDF文件可能没有接触Word文件那么的多。像处理PDF文件这种问题上并没有Word文件那么的容易&#xff0c;毕竟PDF它不易进行内容编辑。这时候如果有小伙伴需要对PDF文件进行修改或者进行插入页面&#xff0c;但是PDF文件是无法直接进行修改的。那…

做期货的阶段(做期货的几个阶段)

如何自己做好期货 学习交易大致有三阶段&#xff1a;直观直觉阶段&#xff0c;看到涨就做多&#xff0c;看到跌就做空&#xff0c;结果半赢半输&#xff1b;学习积累的阶段&#xff0c;看到涨跌不觉涨跌&#xff0c;想得很多&#xff0c;结果赢少赔多&#xff1b;领悟后再次直…

软件架构师考试的真实感受

近1个半月&#xff0c;因准备了软件架构师的考试&#xff0c;停了BLOG&#xff0c;今天想写点东西作为阶段性的沉淀。 节奏紧 和软设比起来&#xff0c;最直观的感受就是节奏紧&#xff0c;软设上午通常能够提前一个小时考完&#xff0c;加上下午2点才开考&#xff0c;中间有…

Java UML 类图

继承 继承&#xff1a;重用父类的某些功能 缺点&#xff1a;强耦合 耦合&#xff1a;修改一方&#xff0c;会影响另一方 应用&#xff1a;是否需要“向上转型” 接口 行为的抽象、可跨越不同的类 不包含实现实现类需完全实现可实现多个接口 是一种“自顶向下”的设计&…

C++多态(1)

目录1. 多态的概念2. 多态的定义和实现2.1 多态的构成条件2.1.1 重写2.2.2 指针或者引用2.2 虚函数重写的两个例外2.3 多态里的一个不规范的地方2.4 重载、重写&#xff08;覆盖&#xff09;、隐藏&#xff08;重定义&#xff09;的对比3. C11 override 和 final1. 多态的概念 …

QSS编辑器QssEditor之三:Ribbon控件与换肤

一.Ribbon控件 Ribbon控件即Office样式UI,Ribbon控件有许多开源实现,例如:Qt优秀开源项目之三:SARibbon SARibbon功能强大,但以学习为目的的话,我们可以自己去实现一个简单的。基本思路是自定义QTabWidget,然后通过QSS调整样式。 如上图所示,我们可以实现一个类QHRi…

IP数据报首部字段、TCP报文段首部字段

文章目录 IP数据报首部字段IP数据报格式TCP报文段首部字段IP数据报首部字段 首部字段功能1.版本是IPv4还是IPv62.首部长度IP数据报首部的长度3.服务类型4.总长度IP数据报的总长度。若总长度>该网段的MTU,则需要分片。分片后IP数据报的总长度必然发生改变。5.标识保证IP分组…

C++--模板

目录 泛型编程 函数模板 函数模板概念 函数模板格式 函数模板的原理 函数模板的实例化 模板参数的匹配原则 类模板 类模板的定义格式 类模板的实例化 非类型模板参数 模板的特化 概念 函数模板特化 类模板特化 泛型编程 不再是针对某种类型&#xff0c;而是能适…

[python]用flask框架搭建微信公众号的后台

用flask框架搭建微信公众号的后台 最近用python写了点爬虫&#xff0c;为了要让爬取的数据能够随时显示在我眼前&#xff0c;并实时根据我的指令返回数据。于是采用微信公众号做这个显示窗口&#xff0c;既能发送指令也能显示简单的相关数据。 准备工具 python3.x环境 pycharm…

vue3与vue2的不同内容

一、main.js入口文件的不同 // 引入的不再是构造函数&#xff0c;引入了一个名为creacteApp的工厂函数 import { createApp } from vue import ./style.css import App from ./App.vue // 创建应用示例对象--->app const app createApp(App) //把组件APP挂载到#app节点上 …

疫情可视化(后续)

前言 这是疫情可视化最开始的文章&#xff0c;有需要了解的可前往查看&#xff1a;https://blog.csdn.net/xi1213/article/details/126824752。 本来说有时间就把这个项目完结了的&#xff0c;结果后面一直有事拖着&#xff0c;直到现在十一月份了才搞完。老样子&#xff0c;先…

拓端tecdat|R语言代做时间序列和ARIMA模型预测拖拉机销售的制造案例研究

全文链接&#xff1a;http://tecdat.cn/?p5421 原文出处&#xff1a;拓端数据部落公众号 相关视频&#xff1a;在Python和R语言中建立EWMA&#xff0c;ARIMA模型预测时间序列 本文是我们通过时间序列和ARIMA模型预测拖拉机销售的制造案例研究示例的延续。您可以在以下链接中找…

2023第二届中国绿色包装创新峰会|低碳与数字化时代的绿色包装

峰会背景 随着中国市场包装使用量的激增&#xff0c;中国已成为全球最大的包装市场&#xff0c;环境中废弃包装所导致的生态负担也同步加剧。但随着消费者可持续发展意识的显著增强&#xff0c;企业环保意识的提升以及国家强制性环保政策的出台&#xff0c;包装可持续发展变得…