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

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

3天内不再提示

Delta并联机械臂实现电磁铁搬运功能

jf_72402704 来源:jf_72402704 作者:jf_72402704 2023-03-09 08:43 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

1. 功能说明

R037样机是一款Delta并联机械臂。本文示例将利用Delta并联机械臂实现不同点定点搬运磁铁物料的效果。

pYYBAGQJK5uAMbQAAABfJhtrhgI745.jpg

2. 结构说明

Delta并联机械臂,其驱动系统采用精度较高的42步进电机;传动系统为丝杠和万向球节;执行末端为搭载电磁铁的圆盘支架。

pYYBAGQJKVuAICV5AARGsH-mE1k584.png

3. Delta机械臂运动学算法

这里给大家介绍一种Delta并联机械臂的运动轨迹解法,通过控制电机的转动参数,最终求解出电磁铁圆盘支架的运动轨迹规律,样机采用R037b

poYBAGQJKXCAN-wXAAFL45E1Q-E081.png

该机械臂由3个丝杠平台构成,通过并联的方式同时控制同一个端点的运动;三个丝杠位于一个正三角形边线的中心位置,连杆采用球头万向节连杆结构。

poYBAGQJK5uAbxf6AAAgQMq7HqM453.png

① 首先我们建立一个空间直角坐标系,该直角坐标系以三个丝杠平台在俯视图方向投影的内切圆心为原点,x轴与tower1和tower3之间的连线平行,y轴过tower2,其中z=0的平面设置在三个限位开关所在平面。

pYYBAGQJK5yAcdU1AAAbthQ72rE760.png

② 建立坐标系之后,我们可以得出3个限位开关Z轴投影的坐标为A=(-msin(60°),mcos(60°),0);B=(0,m,0);C=(msin(60°),mcos(60°),0);其中m为在xy投影面上正三角形的内切圆心到B点的距离。

poYBAGQJK5yALokLAAAZKm0y0Ts252.png

③确定各限位开关的位置(即确定各丝杠平台上滑块的初始位置),丝杠平台的运动可简化为如下:【其中N点为滑块初始位置,Q点为端点初始位置,P为Q点在丝杠平台上Z轴的投影;N1,P1,Q1点为丝杠平台运动后的位,T点为某一固定点,假设为delta机械臂上端点在Z向可以运动的最大值在丝杠平台Z向的投影点】

pYYBAGQJK52AFulfAAAfxhEVPf0396.png

④逆运动学是根据Q1点的位置确定NN1的距离。

在图中有几个可以通过测量得到已知值,分别是连杆长度NQ/N1Q1、NT的距离、终点Q1点的坐标;假设我们输入的量是终点Q1的坐标(X1,Y1,Z1);这里需要注意的是Z1坐标为负值,为了方便理解在后面的推导中我们都对Z1取绝对值。

我们需要计算的是NN1的距离:

poYBAGQJK52Aa3sOAAABFroLaNQ461.png

其中Q1的Z坐标与P1的Z坐标一致,所以NP1为已知量为Q1的Z坐标值Z1,即可以将上面的公式改为:

pYYBAGQJK52AGjT5AAABMBclx8I351.png

这里我们只需要计算出N1P1的值即可:

poYBAGQJK56AYwnjAAABpFtA0Q0366.png

其中NIQ1为连杆长度,可通过测量得知,所以这里面需要我们计算出Q1P1。

⑤求出Q1P1:【该长度我们可以通过两点坐标距离公式得出,借助俯视图投影进行计算】

pYYBAGQJK56AZDiqAAAc2FDp9gM993.png

为方便计算Q1P1,图中我们将N,N1,P,P1,T点都投影到Z为0的点,则Q1(X1,Y1,0)。

根据点坐标公式可得:

poYBAGQJK5-AQDjGAAACiKVuAGQ210.png

综上所述:

pYYBAGQJK5-ASqq9AAAC6OUQZ4o422.png

注意前面我们对Z1取了一次绝对值,实际Z1为负值,

所以最终推导公式为:

poYBAGQJK5-AAMfnAAAC-qjn1AI040.png

这样我们就求出了NN1(丝杠移动距离)与Q1(执行端运动的终点)坐标的关系。

4. 功能实现

4.1 电子硬件

在这个示例中,我们采用了以下硬件,请大家参考:

主控板 Basra主控板(兼容Arduino Uno)
扩展板 Bigfish2.1
SH-ST扩展板
传感器 触碰传感器
电机 步进电机
电池 11.1v动力电池
其它 电磁铁、USB线

4.2 电路连接说明

① 硬件连接-电子元件

pYYBAGQJK6CALIDwAABG5D41dK0728.png

各轴步进电机与SH-ST步进电机扩展板的接线顺序如下(从上至下):
X:红蓝黑绿

Y:红蓝黑绿

Z:黑绿红蓝

② 硬件连接-限位传感器

poYBAGQJK6CAEaQFAABdeAtrUbI087.png

各个轴的限位传感器(触碰)与Bigfish扩展板的接线如下:
X:A0

Y:A3

Z:A4

③ 电磁铁连在Bigfish扩展板的D5、D6接口上。

4.3 编写程序

编程环境:Arduino 1.8.19

Delta机械臂有两种运动方式:第一种是自动运行搬运;第二种是用电脑发送指令,然后再根据指令运动。

这里仅列出Delta机械臂自动运行搬运(Delta.ino)的程序:【其它的程序源码详见 https://www.robotway.com/h-col-194.html 获取】

/*------------------------------------------------------------------------------------

  版权说明:Copyright 2023 Robottime(Beijing) Technology Co., Ltd. All Rights Reserved.

           Distributed under MIT license.See file LICENSE for detail or copy at

           https://opensource.org/licenses/MIT

           by 机器谱 2023-02-08 https://www.robotway.com/                                 

------------------------------------------------------------------------------------*/

#include "Arduino.h"

#include 

#include 

#include "Configuration.h"


AccelStepper stepper_x(1, 2, 5);      //tower1

AccelStepper stepper_y(1, 3, 6);      //tower2

AccelStepper stepper_z(1, 4, 7);      //tower3

//AccelStepper stepper_a(1, 12, 13);


MultiStepper steppers;


float delta[NUM_STEPPER];                         

float cartesian[NUM_AXIS] = {0.0, 0.0, 0.0};         //当前坐标

float destination[NUM_AXIS];                         //目标坐标

boolean dataComplete = false;


float down = -111;

float up = -105;


/*********************************************Main******************************************/

void setup() {

  Serial.begin(9600);

  pinMode(EN, OUTPUT);


  steppers.addStepper(stepper_x);

  steppers.addStepper(stepper_y);

  steppers.addStepper(stepper_z);


  stepperSet(1600, 400.0);

  stepperReset();

  delay(1000);


  Get_command(0, 0, down);

  Process_command();

 

  delay(1000);

}


void loop() {

  float r = 25;

  float x1 = 0.0;

  float y1 = 0.0;


  Get_command(25, 0, down);

  Process_command();

  delay(1000);

 

  for(int i=0;i<2;i++){

    for(float i=0.0;i<=360;i+=10){

      x1 = r * cos(i / 180 * 3.141592);

      y1 = r * sin(i / 180 * 3.141592);

     

      Get_command(x1, y1, down);

      Process_command();                                     

    }

  }

  delay(1000);


  for(int j=0;j<2;j++){

    for(float i=360.0;i>=0;i-=10){

      x1 = r * cos(i / 180 * 3.141592);

      y1 = r * sin(i / 180 * 3.141592);

     

      Get_command(x1, y1, down);

      Process_command();                                     

    }

  }

  delay(1000);




  Get_command(0, 0, down);

  Process_command();  

 

  test();

  delay(1000);

 

  stepperReset();

  delay(1000);

 

}


/***************************************Get_commond*******************************************/

void Get_command(float _dx, float _dy, float _dz){  

  destination[0] = _dx;

  destination[1] = _dy;

  destination[2] = _dz;

 

  if(destination[0] == 0 && destination[1] == 0 && destination[2] == 0){

      stepperReset();  

  }

  else

  {

      dataComplete = true;

  }

 

  if(serial_notes){

   Serial.print("destinationPosition: ");

   Serial.print(destination[0]);

   Serial.print(" ");

   Serial.print(destination[1]);

   Serial.print(" ");

   Serial.println(destination[2]);

  }


}


/***************************************Process_command***************************************/

void Process_command(){

  if(dataComplete){

    digitalWrite(EN, LOW);

   

    if(cartesian[0] == destination[0] && cartesian[1] == destination[1] && cartesian[2] == destination[2]){

      return;  

    }

    else

    {


      Line_DDA(destination[0], destination[1], destination[2]);

    }

   

  }

  dataComplete = false;

  digitalWrite(EN, HIGH);

}


/************************************************** DDA ************************************************/

void Line_DDA(float x1, float y1, float z1)

{

  float x0, y0, z0;         // 当前坐标点

  float cx, cy;             // x、y 方向上的增量

 

  x0 = cartesian[0];y0 = cartesian[1];z0 = cartesian[2];

   

  int steps = abs(x1 - x0) > abs(y1 - y0) ? abs(x1 - x0) : abs(y1 - y0);

 

  cx = (float)(x1 - x0) / steps;

  cy = (float)(y1 - y0) / steps;

 

  for(int i = 0; i <= steps; i++)

  {

    cartesian[0] = x0 - cartesian[0];

    cartesian[1] = y0 - cartesian[1];

    cartesian[2] = z1 - cartesian[2];


    calculate_delta(cartesian);

   

    stepperSet(1350.0, 50.0);

    stepperMove(delta[0], delta[1], delta[2]);

 

    cartesian[0] = x0;

    cartesian[1] = y0;

    cartesian[2] = z1;

 

    x0 += cx;

    y0 += cy;

   

    if(serial_notes){

      Serial.print("currentPosition: ");

      for(int i=0;i<3;i++){

         Serial.print(cartesian[i]);

         Serial.print(" ");

      }   

      Serial.println();

      Serial.println("-------------------------------------------------");

    }


  }


}


/***************************************calculateDelta****************************************/

void calculate_delta(float cartesian[3])

{

  if(cartesian[0] == 0 && cartesian[1] == 0 && cartesian[2] == 0){

      delta[0] = 0; delta[1] =0; delta[2] = 0;

  }

  else

  {

      delta[TOWER_1] = sqrt(delta_diagonal_rod_2

                       - sq(delta_tower1_x-cartesian[X_AXIS])

                       - sq(delta_tower1_y-cartesian[Y_AXIS])

                       ) + cartesian[Z_AXIS];

      delta[TOWER_2] = sqrt(delta_diagonal_rod_2

                       - sq(delta_tower2_x-cartesian[X_AXIS])

                       - sq(delta_tower2_y-cartesian[Y_AXIS])

                       ) + cartesian[Z_AXIS];

      delta[TOWER_3] = sqrt(delta_diagonal_rod_2

                       - sq(delta_tower3_x-cartesian[X_AXIS])

                       - sq(delta_tower3_y-cartesian[Y_AXIS])

                       ) + cartesian[Z_AXIS];


     for(int i=0;i<3;i++){

        delta[i] = ((delta[i] - 111.96) * stepsPerRevolution / LEAD);

     }

  }


  if(serial_notes){

      Serial.print("cartesian x="); Serial.print(cartesian[X_AXIS]);

      Serial.print(" y="); Serial.print(cartesian[Y_AXIS]);

      Serial.print(" z="); Serial.println(cartesian[Z_AXIS]);

   

      Serial.print("delta tower1="); Serial.print(delta[TOWER_1]);       

      Serial.print(" tower2="); Serial.print(delta[TOWER_2]);

      Serial.print(" tower3="); Serial.println(delta[TOWER_3]);

  }


}


/****************************************stepperMove******************************************/

void stepperMove(long _x, long _y, long _z){             

    long positions[3];

    positions[0] = _x;                        //steps < 0, 向下运动 ; steps > 0, 向上运动

    positions[1] = _y;

    positions[2] = _z;


    steppers.moveTo(positions);

    steppers.runSpeedToPosition();


    stepper_x.setCurrentPosition(0);

    stepper_y.setCurrentPosition(0);

    stepper_z.setCurrentPosition(0);

}


/****************************************stepperSet******************************************/

void stepperSet(float _v, float _a){

  stepper_x.setMaxSpeed(_v);                  //MaxSpeed: 650

  stepper_x.setAcceleration(_a);  

  stepper_y.setMaxSpeed(_v);

  stepper_y.setAcceleration(_a);

  stepper_z.setMaxSpeed(_v);

  stepper_z.setAcceleration(_a);


}


/****************************************stepperReset******************************************/

void stepperReset(){

  digitalWrite(EN, LOW);

 

  if(cartesian[2] != 0){

    Get_command(0, 0, cartesian[2]);

    Process_command();

    digitalWrite(EN, LOW);

  }

 

  while(digitalRead(SENSOR_TOWER1) && digitalRead(SENSOR_TOWER2) && digitalRead(SENSOR_TOWER3)){

    stepperMove(10, 10, 10);

  }


  stepperSet(1200.0, 100.0);

  stepperMove(-400, 0, 0);

  while(digitalRead(SENSOR_TOWER1)){

    stepperMove(10, 0, 0);

   

  }


  stepperMove(0, -400, 0);

  while(digitalRead(SENSOR_TOWER2)){

    stepperMove(0, 10, 0);

  }


  stepperMove(0, 0, -400);

  while(digitalRead(SENSOR_TOWER3)){

    stepperMove(0, 0, 10);

  }


  for(int i=0;i<3;i++){

     cartesian[i] = 0.0;

  }  


  if(serial_notes) Serial.println("resetComplete!");


  digitalWrite(EN, HIGH);

}


/*************************************************** electromagnet *************************************************************/

void putUp(){

   digitalWrite(9, HIGH);

   digitalWrite(10, LOW);

}


void putDown(){

   digitalWrite(9, LOW);

   digitalWrite(10, LOW);

}


/**************************************************   test    ******************************************************************/

void test(){

    Get_command(0, 0, down);

    Process_command();

    delay(500);

    putUp();

 

    Get_command(0, 0, up);

    Process_command();  

    Get_command(25, 0, up);

    Process_command();


    Get_command(25, 0, down);

    Process_command();  

    putDown();

    delay(500);

    putDown();

    putUp();


    Get_command(25, 0, up);

    Process_command();   

    Get_command(0, 25, up);

    Process_command();   


    Get_command(0, 25, down);

    Process_command();

    putDown();  

    delay(500);

    putDown();

    putUp();


    Get_command(0, 25, up);

    Process_command();   

    Get_command(-25, 0, up);

    Process_command();   


    Get_command(-25, 0, down);

    Process_command();  

    putDown();

    delay(500);

    putUp();


    Get_command(-25, 0, up);

    Process_command();   

    Get_command(0, -25, up);

    Process_command();   


    Get_command(0, -25, down);

    Process_command();  

    putDown();

    delay(500);

    putUp();


    Get_command(0, -25, up);

    Process_command();   

    Get_command(25, 0, up);

    Process_command();   


    Get_command(25, 0, down);

    Process_command();   

    putDown();

    delay(500);

    putUp();


    Get_command(25, 0, up);

    Process_command();   

    Get_command(0, 0, up);

    Process_command();   


    Get_command(0, 0, down);

    Process_command();   

    delay(500);

    putDown();

}

5. 扩展

下图是另一种外观的Delta机械臂(R037c),控制原理完全一样。

pYYBAGQJK6GAAjttAABPVE8ct9U363.jpg

审核编辑黄宇

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

    关注

    2

    文章

    170

    浏览量

    15621
  • Delta
    +关注

    关注

    1

    文章

    30

    浏览量

    13423
  • 机械臂
    +关注

    关注

    13

    文章

    582

    浏览量

    25957
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    Delta并联机器人高速抓放应用解决方案:基于BL350与EtherCAT的硬实时控制

    在 食品、药品、电子元器件 等行业的包装与分拣产线上,Delta并联机器人(又称“蜘蛛手”)因其高速度、高重复定位精度,已成为实现高效 抓放作业 的核心装备。然而,随着生产节拍要求的不断提升(如
    的头像 发表于 12-01 17:56 1546次阅读

    复合机器人对比传统AGV和机械的优势何在?

    复合机器人对比传统AGV和机械的优势,核心在于它突破了单一设备的功能局限,实现了“移动+操作”的深度协同,尤其在上下料和物料转运场景中优势显著。经世智能复合机器人:重新定义上下料与物
    的头像 发表于 11-21 15:32 949次阅读
    复合机器人对比传统AGV和<b class='flag-5'>机械</b><b class='flag-5'>臂</b>的优势何在?

    协作机械产品介绍

    多元需求比邻星协作机械拥有出色的负载表现,别看其外观设计精巧,却能轻松承载较重的物品 。在工业生产中,无论是搬运大型零部件,还是在精密电子制造环节中对微小元器件进行精准操作,它都能稳定运行,重复定位精度极高
    发表于 08-07 17:20 0次下载

    DELTA机械手多物料视觉分拣的应用

    正运动DELTA机械手多物料视觉分拣解决方案
    的头像 发表于 06-24 11:16 518次阅读
    <b class='flag-5'>DELTA</b><b class='flag-5'>机械</b>手多物料视觉分拣的应用

    Lake Shore 643电磁铁电源无法开机深度维修案例剖析与解决方案

    近期北京某企业送修一台电磁铁电源 Lake Shore 643,报修的故障是仪器内部进水不开机。对仪器进行初步检测,确定故障与客户报修一致。
    的头像 发表于 05-10 11:51 451次阅读
    Lake Shore 643<b class='flag-5'>电磁铁</b>电源无法开机深度维修案例剖析与解决方案

    视觉运控一体机在DELTA并联机械手动态跟随抓取的应用

    正运动DELTA并联机械手动态跟随抓取解决方案
    的头像 发表于 04-29 10:34 504次阅读
    视觉运控一体机在<b class='flag-5'>DELTA</b><b class='flag-5'>并联机械</b>手动态跟随抓取的应用

    上升沿时间在10ns以内的电磁铁驱动电路请教

    最近需要做一个电磁铁的驱动电路,具体要求如下: 1、输出脉冲的电压6V或-6V,电流120mA。还希望后期能控修改输出电压至7-10V 2、希望能够根据输入的ttl信号决定输出6V还是-6V 3
    发表于 04-15 16:09

    阿童木高速重载并联机器人效能拉满

    在工业自动化领域,并联机器人凭借高速度优势,广泛应用于轻小散乱物料搬运分拣与上下料环节,也正如此,并联机器人长期被贴上“轻型敏捷”的标签:3C电子产线上精准灵巧分拣电子元器件,广大制药企业药品自动化
    的头像 发表于 03-18 09:22 1026次阅读

    案例分析,搬运机械手如何选择电机?

          在选择搬运机械手的电机时,需要考虑多个因素以确保电机的性能满足机械手的运行需求。以下是一个详细的案例分析,说明如何为搬运机械手选
    的头像 发表于 01-21 16:44 1466次阅读
    案例分析,<b class='flag-5'>搬运</b><b class='flag-5'>机械</b>手如何选择电机?

    完美CP来啦!当AGV遇上机械

    AGV+机械复合机器人逐渐打开市场,实现物料自动搬运、上下料、分拣等“无人搬运”。结合信息系统运作,调度人员下达指令,
    的头像 发表于 01-16 18:12 771次阅读
    完美CP来啦!当AGV遇上<b class='flag-5'>机械</b><b class='flag-5'>臂</b>!

    深度解析!RK3568 加持机械是如何实现颜色识别与抓取的?

    ;2、掌握机械识别颜色抓取积木的实现方法。三、实验原理颜色识别抓取积木功能实现识别出不同颜色的积木,
    的头像 发表于 01-15 08:07 1236次阅读
    深度解析!RK3568 加持<b class='flag-5'>机械</b><b class='flag-5'>臂</b>是如何<b class='flag-5'>实现</b>颜色识别与抓取的?

    DELTA并联机械手视觉方案荣获2024年度机器人应用典型案例奖

    基于机器视觉运动控制一体机在DELTA视觉柔振上下料领域的应用
    的头像 发表于 01-13 16:42 666次阅读
    <b class='flag-5'>DELTA</b><b class='flag-5'>并联机械</b>手视觉方案荣获2024年度机器人应用典型案例奖

    翼菲并联机器人通过MTBF 20000小时认证

    经过严格而全面的测试,翼菲并联机器人成功通过MTBF(平均无故障工作时间)20000小时认证,这一里程碑式的成就,不仅标志着翼菲机器人在可靠性方面达到了国际领先水平,更是国内并联机器人行业首次完成
    的头像 发表于 12-29 14:17 1369次阅读

    PPEC inside 超导 / 磁铁电源,以搭积木的方式快速满足您的磁铁供电需求

    AC380V供电、水冷散热、RS485通讯接口,方便与外部设备连接和通信,适用于电磁铁、线圈等感性负载。为满足多样化输出需求,产品机箱提供全高机柜和半高机柜两种选择。全
    的头像 发表于 12-16 18:05 108次阅读
    PPEC inside 超导 / <b class='flag-5'>磁铁</b>电源,以搭积木的方式快速满足您的<b class='flag-5'>磁铁</b>供电需求

    RK3568国产实验箱+人工智能机械:跳舞、叠罗汉、夹方块、积木搬运案例全解!

    基于语音控制实现机械特定动作的方法。三、实验原理程序功能通过语音控制机械
    的头像 发表于 12-12 19:01 1849次阅读
    RK3568国产实验箱+人工智能<b class='flag-5'>机械</b><b class='flag-5'>臂</b>:跳舞、叠罗汉、夹方块、积木<b class='flag-5'>搬运</b>案例全解!