0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

智能机器人手臂–第2部分:编程

张霞 来源:DevicePlus 作者:DevicePlus 2023-02-24 14:30 次阅读

这篇文章来源于DevicePlus.com英语网站的翻译稿。点击此处阅读本文的第1部分>

poYBAGPzGIOAMw0hAAOrhHk78es321.jpg

智能机器人手臂–第1部分:机械结构和接线中,我们已经将机械手臂的本体组装在一起。机械手臂搭载了一个网络摄像头和一个麦克风,以进行人脸和物体识别以及语音识别。这款在短短15小时内开发出来的机器人手臂在MakeMIT硬件马拉松项目中排名前10。

该机器人手臂的主要功能是结合语音命令检测彩色物体(例如红球或蓝球)、拾取物体、进行人脸识别,并将物体移交给指定的人物/用户。为了成功实现这些功能,我们集成了多个平台,比如OpenCV、Microsoft Cognitive Services Speech、Speaker Recognition API以及Open Weather API。

硬件

根据第1部分:

Arduino Uno

麦克风

网络摄像头

伺服电机

软件

Arduino IDE

Visual Studio

JARVIS [https://github.com/isacandrei/Jarvis-Rocket]

第1步:制作App

我们已经设法打造了一个能够处理语音命令的机器人手臂。人们说出要求后,该手臂会找到目标物体并将其交给指定人物(机器人可以区分不同的人)。此外,它还可以播放在线音乐或告诉您当前的天气情况。

该应用程序的软件部分用Visual Studio 2015完成。Visual Studio简单易用,并且提供了很多功能。其中一个功能就是Emgu CV——一个用于调用OpenCv函数的包裹函数库。此功能通过Visual Studio Windows Forms实现,在处理图像时非常重要。

如果想启动项目,您只需在电脑上安装Emgu CV即可。具体步骤如下:

1. 下载EmguCV
您可以点击本页 “构建示例”下方的超链接下载Emgu CV工程:

pYYBAGPzGIWAMKvtAADX7Y1ztLY889.jpg

图1: 如何下载EmguCV

2. 添加文件
由于您需要使用添加库,因此应将它们包含在Visual Studio中。OpenCV基于C/C++语言开发,如果您想在C#中使用,那么需要添加DLL(动态链接库)文件——处理视频时必须包含DLL文件。参考文件位于Visual Studio菜单的Solution Explorer处.

poYBAGPzGIeACqPDAAGrLaVr2EM360.jpg

图2: 参考文件位置

如果您想添加更多文件,请点击References -> Add references,然后从下载的文件中选择以下内容:

pYYBAGPzGImAahSYAAKbDP_IQPo229.jpg

图3: 参考管理器(Reference Manager)

更多信息可以参考以下链接:https://www.emgu.com/wiki/index.php/Setting_up_EMGU_C_Sharp

3. 示例

在下载的库中,您可以找到更多使用视频处理(运动检测、人脸检测和摄像头捕捉)的程序代码示例.

poYBAGPzGIuAHAavAAHXUrykcCE732.jpg

图4: OpenCV应用示例

4. Arduino程序

Arduino代码具有4个命令:up/down负责控制伺服电机;reset是指在出现问题时重置机器人手臂位置;某个部件没有动作时则使用do nothing。程序具有四个自由度:

circle – 手臂可以旋转;

base – 调整网络摄像头的倾斜度;

elbow– 旨在获取手臂的最佳位置;

wrist – 调整抓握力.

每个伺服电机都有一个给定命令,并且使用不同引脚进行控制:Elbow使用引脚7;Base使用引脚8;Circle使用引脚9;Wrist使用引脚10。对于伺服电机控制,C#应用程序通过串行传输发送4个字母,每个状态对应于一个具体的电机控制指令:

if(cmd == ‘A’) state = 1; → control(1, posCircle);
if(cmd == ‘B’) state = 2; →control(2, posBase);
if(cmd == ‘C’) state = 3; → control(3, posElbow);
if(cmd == ‘D’) state = 4; →control(4, posGH);

根据伺服电机的运动角度,代码分为控制和命令指令。

Case 1中,Circle(旋转)运动的命令为left/right(左/右)。

Case 1:

      switch (cmd)
      {
          case '0':
              Left();
              Break;
          case '1':
               //do nothing
              break;
          case '2':
              Right();
              break;
          case '3':
              posCircle = 0;
              break;
      }
      state = 0;
      break;

Case 2和Case 3中,我们考虑基座和肘部的伺服电机,这意味着他们可以上/下(up/down)引导手臂;遇到错误时,机器人手臂会把自己设置为posBase = 50;posElbow = 50;

Case 2:

      switch (cmd)
      {
          case '0':
              downBase();
              break;
			  
          case '1':
              //do nothing
              break;
			  
          case '2':
              upBase();
              break;
			  
          case '3':
              posBase = 50;
              break;
      }
      state = 0;
      break;

Case 3:

      switch (cmd)
      {
          case '0':
              downElbow();
              break;
			  
          case '1':
              //do nothing
              break;
			  
          case '2':
              upElbow();
              break;
			  
          case '3':
              posElbow = 50;
              break;
			  
          case '4':
              posElbow = 10;
              break;
      }
      state = 0;
      break;

Case 4中,我们需要控制爪钳,这个非常简单——将其初始位置设置为posGH = 50;

请将以下代码添加到Arduino UNO中,以进行机器人手臂控制:

// States for the RoboticArm:
//0 Down on the left
//1 Pause
//2 Top on the right
//3 Reset


#include 

Servo Circle; //1
Servo Base; //2
Servo Elbow;  //3
Servo Wrist; //4

int posCircle = 0;
int posBase = 50;
int posElbow = 50;
int posGH = 50;

int state = 0;

void setup() {
  Serial.begin(9600);
  Elbow.attach(7);
  Base.attach(8);
  Circle.attach(9);
  Wrist.attach(10);
  delay(1000);
  control(1, posCircle);
  control(2, posBase);
  control(3, posElbow);
  control(4, posGH);
}

void loop() 
{

if(Serial.available() > 0)
{
char cmd = Serial.read();

switch (state) {
    case 0:
     if(cmd == 'A') state = 1;
     if(cmd == 'B') state = 2;
     if(cmd == 'C') state = 3;
     if(cmd == 'D') state = 4;
    
      break;
      
    case 1:
            
             switch (cmd)
             {
              case '0':
              Left();
              break;
			  
              case '1':
              //do nothing
              break;
			  
              case '2':
              Right();
              break;
			  
              case '3':
              posCircle = 0;
              break;
             }
             state = 0;
      break;
      
      case 2:
            
             switch (cmd)
             {
              case '0':
              downBase();
              break;
			  
              case '1':
              //do nothing
              break;
			  
              case '2':
              upBase();
              break;
			  
              case '3':
              posBase = 50;
              break;
             }
             state = 0;
      break;
      
      case 3:
       
             switch (cmd)
             {
              case '0':
              downElbow();
              break;
			  
              case '1':
              //do nothing
              break;
			  
              case '2':
              upElbow();
              break;
			  
              case '3':
              posElbow = 50;
              break;
			  
              case '4':
              posElbow = 10;
              break;
             }
             state = 0;
      break;
      
      case 4:
          
             switch (cmd)
             {
              case '0':
              break;
			  
              case '1':
              break;
			  
              case '2':
              break;
			  
              case '3':
              posGH = 50;
              break;
             }
             state = 0;
      break;
   
  }
  
}
       
}

void control(int motor, int angle)
{
switch (motor) {
    case 1:
    if(angle >= 0) if(angle <= 140) Circle.write(angle + 10);                         
    break;
    
    case 2:
    if(angle >= 0) if(angle <= 60) Base.write(140 - angle);
    break;

    case 3:
    if(angle >= 0) if(angle <= 70) Elbow.write(80 - angle);
    break;

    case 4:
    if(angle >= 0) if(angle <= 65) Wrist.write(75 - angle);
    break; 
  }  
}

void Left()
{
if(posCircle <= 136)
{
  posCircle = posCircle + 4;
}
else posCircle = 140;
control(1, posCircle);
}

void Right()
{
if(posCircle >= 4)
{
  posCircle = posCircle - 4;
}
else posCircle = 0;
control(1, posCircle);
}

///////////////////////////////////
void downElbow()
{
if(posElbow >= 4)
{
  posElbow = posElbow - 4;
}
else posElbow = 0;
control(3, posElbow);
}

void upElbow()
{
if(posElbow <= 66)
{
  posElbow = posElbow + 4;
}
else posElbow = 70;
control(3, posElbow);
}
//////////////////////////////////////
void downBase()
{
if(posBase >= 4)
{
  posBase = posBase - 4;
}
else posBase = 0;
control(2, posBase);
}

void upBase()
{
if(posBase <= 56)
{
  posBase = posBase + 4;
}
else posBase = 60;
control(2, posBase);
}

第2步:如何制作演示App

为了制作一个类似的应用程序,我们需要知道如何使用C#编写应用程序。由于Windows Forms App很简单,并且拥有在线文档,需要时可以随时获取,因此我们采用了该App。对于这个项目,我们需要Visual Studio和.NET framework(您可以在这里下载这两个程序)。下载并安装文件后,我们就可以开始制作应用程序。

首先,我们需要创建一个新工程。创建新工程的步骤如下:点击FileNewProjectWindows Forms App(.NET Framework)。

poYBAGPzGI-AGm4eAAJ3rqKE-AU880.jpg

图5: 如何在Visual Studio中制作App

此时系统会显示一个带有窗体的窗口——这是应用程序自动生成的格式。右侧(Properties)是表格属性,您可以根据自己的偏好进行调整。左侧(Toolbox)提供应用程序使用的功能,比如按钮、复选框、串口等。

pYYBAGPzGJGAf5qNAAG5D9FAxXE351.jpg

图6: Visual Studio中的App属性

对于测试演示,我们可以制作这样一个应用程序:点击按钮,系统显示一条文本信息。

双击Toolbox(工具箱)中的按钮,程序会在左上角自动添加一个按钮。该按钮会被命名为“button1”,因为.NET Framework会对按钮类实例进行自动编号。在button1属性中,我们可以将Text从button1改为Click here!现在,我们需要编写代码,以便让按钮起作用(双击图形界面上的按钮):

namespace WindowsFormsApp3
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("App made for DevicePlus");
        }
    }
}

当用户点击该按钮时,上述代码会显示一个文本。具体结果如图7所示。

poYBAGPzGJOAAT7zAAHHb9DJOC8121.jpg

图7: 演示App

第3步:App属性

凭借.NET、OpenCV和Microsoft API的功能,我们能够制作出完整的应用程序。对于该应用程序,我们需要按钮、串口和文本框。

黑色窗口会显示来自摄像头的图像,窗口中还会添加一个镜头框,框内显示人物名称。

左侧的白色窗口可以添加TTS API(文本转语音)的文本,提供反馈以检查工作,并检查说出的话语是否与显示的字词相符。

pYYBAGPzGJSALETeAADVya0e_9w762.jpg

图8: 机器人手臂应用程序

第4步:人脸识别

为了获得更好的程序结果,您需要在训练模式下添加多个脸部记录。训练是指通过拍摄多个脸部位置以获得最佳识别(不同拍摄角度、光线条件等)。您需要按下Record 10 Faces按钮,通过应用程序记录脸部画面。

在代码中,实现这个功能的语句为Face = Parent.faceClassifier;这通过EmguCV平台完成。人脸检测通过基于主成分分析(PCA)的复杂算法实现,系统会将检测到的脸部与训练后存储的图像进行多次比较。

pYYBAGPzGJaAS684AAIyg1gDxuQ495.jpg

图9: 人脸检测

蓝色矩形中的图像是需要存储的图像,因为它包含面部的独特特征。

我们需要在不同的位置和不同的光线下获取更多的面部特征:

poYBAGPzGJiAHoh_AAKqlp74jh8767.jpg

图10: 添加更多人脸进行训练

经过一系列面部检测拍摄,如果您认为之前记录的脸部图像不利于算法计算,那么可以点击Restart 1 Face按钮删除已经保存的文件,系统将不再检测该脸部信息。

如果要记录多个人、让机器人手臂可以区分许多个人,那么可以使用Delete Data按钮删除照片。

pYYBAGPzGJuAIMOBAAHaBH0M8FY129.jpg

图11:重启训练模式

录制更多图像后,该算法应该能够检测人脸,并在蓝框上方显示名称。机器人可以精确检测像眼镜这样的特征,因为这些特征属于区别性特征.

poYBAGPzGJ2AE3npAAG99720y8M314.jpg

图12: 训练之后的结果

第5步:天气API

通过天气API,我们可以根据以下方式收集城市数据:城市名称、城市ID、地理坐标甚至邮政编码。该API的优点是免费且易于使用。但是该API有一个限制:使用次数或者流量不能超过60次/分钟或50k/天,如果违反该规定,您的帐户将被封锁。

在本教程中,我们选择根据城市ID调用API。每个城市都有一个ID,详细信息请参见https://bulk.openweathermap.org/sample/city.list.json.gz。扩展名.json用于在浏览器和服务器之间进行交换数据。只有当数据是文本格式时才能实现通信

我们已经将数据用作WebClient类——这使得文件下载更加轻松。在我们的例子中,构造函数WebClient用于初始化一个新的实例:

WebClient client = new WebClient();

我们需要将数据编码为UTF8格式,这意味着系统用8位块来表示字符,具体指令如下:client.Encoding = System.Text.Encoding.UTF8

如果互联网连接出现问题,无法建立连接时,程序会自动显示消息“Internet Connection failedthrow new WeatherDataServiceException”。通过throw我们可以创建一个异常。

在C#中,我们可以使用trycatch来解决部分代码无法成功的情况。

结合文本转语音API,如果用户询问天气情况,系统会发出以下声音:“The weather in Boston is(波士顿的天气是)…”。

第6步:语音合成

当您使用文本转语音API时,您需要一个可以快速处理的文件——这就是我们需要使用服务器的原因。对于BING API,我们需要授权令牌,具体信息请参阅https://api.cognitive.microsoft.com/sts/v1.0/issueToken

该API的有效期为10分钟。这是一个非常棒的计时器,可以计数到9,同时每9分钟更新一次连接。

如下图所示,您可以看到语音合成的最终结果是“Testing the app for Device Plus”。

pYYBAGPzGKKAD5RLAAIjRe6d1uA463.jpg

图13: 测试API

总体来说,这是一个有趣的项目。该项目让我懂得硬件和软件之间的良好同步对于实现最佳性能至关重要。使用Visual Studio的很多库使项目有点复杂,但最终结果令人满意。

我认为这种项目可以通过多种方式进行开发和改进,以满足每个用户的需求。

pYYBAGPzDmSAfn_UAAAF-_P5AGo881.jpg

Tiberia Todeila

Tiberia目前是布加勒斯特理工大学电气工程学院的大四学生。她非常热衷于智能家居设备的设计和开发,旨在让我们的日常生活更加轻松。

审核编辑黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 编程
    +关注

    关注

    88

    文章

    3615

    浏览量

    93731
  • 智能机器人
    +关注

    关注

    17

    文章

    868

    浏览量

    82292
收藏 人收藏

    评论

    相关推荐

    机器人手臂5种不同的运动组合

    一般机器人手臂有3个自由度,即手臂的伸缩、左右回转和升降 (或俯仰)运动。手臂回转和升降运动是通过机座的立柱实现的,立柱的横向移动即为手臂的横移。
    的头像 发表于 04-18 09:48 1.8w次阅读
    <b class='flag-5'>机器人手臂</b>5种不同的运动组合

    关于蓝牙控制Atmel制造的机器人手臂的介绍

    蓝牙控制并且指导机器人手臂动作
    的头像 发表于 07-09 03:22 3503次阅读

    机器人手臂的典型机构有哪些

    机器人手臂的伸缩、横向移动均属于直线运动。
    发表于 07-08 11:42 6.8w次阅读
    <b class='flag-5'>机器人手臂</b>的典型机构有哪些

    怎样使用Android手机的蓝牙控制机器人手臂

    在这个项目中,我将向您展示如何构建Arduino&amp; amp;使用Android手机的蓝牙控制机器人手臂。该机器人手臂可以在手动模式下操作,也可以在全自动模式下进行编程
    的头像 发表于 07-29 09:11 8488次阅读

    在未来机器人手臂将可以替代人类的双手

    随着5G技术的普及,即将迎来AI人工智能时代,很多场景将是无人自动化的控制生产运作,这样我们需要更多的机器人手臂机器人手臂可以将执行工作的手臂与思考工作的头脑分离。
    发表于 09-17 09:41 2019次阅读

    Hibot机器人手臂Float Arm可用于哪些应用环境

    能代替“脏乱、危险、严重”的工作的机器人手臂“Float Arm”
    的头像 发表于 04-20 16:06 5466次阅读

    中国科大展示软体机器人手臂在日常生活中的巨大应用潜力

    软体机器人手臂由于具有本质柔顺性和连续变形特性,在智能制造、医疗康复,家庭服务等领域有巨大的研究价值和广泛的应用前景。最新一期的机器人顶刊《The International Journal
    的头像 发表于 04-13 11:49 3182次阅读

    机器人手臂使用哪种型号的泰和承比较合适

    机器人手臂的伸缩、横向移动均属于直线运动。实现手臂往复直线运动的机构形式比较多,常用的有活塞油(气)缸、齿轮齿条机构、丝杠螺母机构以及连杆机构等。由于活塞油(气)缸的体积小、重量轻,因而在机器人
    发表于 03-17 17:16 626次阅读

    构建可帮助人们做早餐的桌面智能机器人手臂

    电子发烧友网站提供《构建可帮助人们做早餐的桌面智能机器人手臂.zip》资料免费下载
    发表于 12-28 10:36 3次下载
    构建可帮助人们做早餐的桌面<b class='flag-5'>智能</b><b class='flag-5'>机器人手臂</b>

    Arduino机器人手臂

    方案介绍MARK 1是可编程的Arduino机器人手臂。但是,还不止这些,该机械臂可以由手势控制。硬件部件:Arduino UNO    ×    1个    伺服马达MG996R×    6    5V电池组×    1个    PCA9685具有I
    发表于 12-30 14:42 3次下载

    利用Parallax激光传感器制作Arduino激光机器人2部分

    2部分中,我们将添加机器人工作所需的其他系统部件,比如伺服器和激光测距仪(LRF),并编写一个程序,让机器人能够自主移动。
    的头像 发表于 02-24 09:43 1041次阅读
    利用Parallax激光传感器制作Arduino激光<b class='flag-5'>机器人</b>—<b class='flag-5'>第</b><b class='flag-5'>2</b><b class='flag-5'>部分</b>

    最酷的Kickstarter机器人 2部分 – 以往成果

    本文是最酷Kickstarter资助的机器人项目系列文章的2部分
    的头像 发表于 02-28 15:20 947次阅读
    最酷的Kickstarter<b class='flag-5'>机器人</b> <b class='flag-5'>第</b><b class='flag-5'>2</b><b class='flag-5'>部分</b> – 以往成果

    用于Arduino Due的DIY Braccio机器人手臂护罩

    电子发烧友网站提供《用于Arduino Due的DIY Braccio机器人手臂护罩.zip》资料免费下载
    发表于 06-14 15:07 0次下载
    用于Arduino Due的DIY Braccio<b class='flag-5'>机器人手臂</b>护罩

    如何创建FPGA控制的机器人手臂

    机器人技术处于工业 4.0、人工智能和边缘革命的前沿。让我们看看如何创建 FPGA 控制的机器人手臂
    的头像 发表于 10-24 17:15 1106次阅读
    如何创建FPGA控制的<b class='flag-5'>机器人手臂</b>

    如何创建FPGA控制的机器人手臂

    机器人技术处于工业 4.0、人工智能和边缘革命的前沿。让我们看看如何创建 FPGA 控制的机器人手臂
    的头像 发表于 10-24 17:26 1342次阅读
    如何创建FPGA控制的<b class='flag-5'>机器人手臂</b>?