当前位置:   article > 正文

机器人学|手机玻璃加工全自动化——AGV+机器人+视觉解决方案(含双目三维视觉SLAM建图、MATLAB的AGV路径规划导航避障、六轴机械手臂建模与路径规划仿真,附带源代码)_3d视觉+机器人路径规划

3d视觉+机器人路径规划

文章目录

前言

一、国内外移动操作机器人现状

二、方案概述

三、主要部件BOM清单

1.差动轮式AGV:

2.UR5系列机械臂

3.Cognex智能相机

4.加工台

5.控制系统

6.电源和电缆

四、技术点及工作流程

五、计算自动化方案与人工方案成本收回时间

1.自动化方案成本分析:

2.人工方案成本分析:

3.两种方案的比较及成本收回时间的计算:

六、主要技术点分析与实现方案及仿真实现(附带源代码在文件包中)

1.视觉SLAM建图

2.AGV路径规划与自主避障的自动导航技术

3.UR5机械臂路径规划


前言

目标:某企业为3C部件精密加工企业,其加工的零件为手机玻璃,要求加工精度为±0.01mm,目前为人工运输至加工中心加工,由人工采用千分表在大理石平台上逐个测量实现。企业为减少人工成本,提高生产效率,要求采用自动化生产线方式实现。试调研国内外移动操作机器人现状,并作出自动化解决方案,列出主要部件BOM清单,并列出AGV+机器人+视觉形成的解决方案,列出技术点,并尝试计算采用自动化方案与采用人工方案相比,何时收回自动化生产线改造成本。

备注:AGV采用差动轮式60Kg负载AGV,机械臂采用UR5系列,机器视觉采用cognex智能相机,AGV预计5万,UR5预计10万,cognex智能相机预计1万。


一、国内外移动操作机器人现状

在3C部件加工领域,尤其是手机玻璃等高精度零件的处理,对移动操作机器人的需求日益增长。这类机器人需要具备高精度、高稳定性和高效率的特点,以满足±0.01mm的加工精度要求。目前,国内外已有众多企业投入到移动操作机器人的研发和生产中,技术水平不断提升,市场应用前景广阔。

在国外,一些知名的机器人企业如ABB、KUKA、FANUC等已经推出了针对3C部件加工的移动操作机器人,这些机器人采用先进的运动控制技术、传感器技术和机器视觉技术,能够实现高精度、高稳定性的加工。同时,这些机器人还具备自动化、智能化的特点,能够与加工中心、磨床等设备无缝对接,实现整条生产线的自动化和智能化。

在国内,随着制造业转型升级的加速,越来越多的企业开始重视自动化生产线的建设和改造。移动操作机器人在国内的应用也逐渐普及,国内一些知名的机器人企业如新松、埃夫特、汇川等也推出了自己的移动操作机器人产品,这些机器人产品在精度、稳定性、智能化等方面也在逐步提升。

总的来说,移动操作机器人在国内外已经得到了广泛的应用和推广,技术水平不断提升,市场前景广阔。未来,随着技术的不断创新和进步,移动操作机器人将在3C部件加工领域发挥更加重要的作用。

二、方案概述

本方案采用差动轮式AGV、UR5系列机械臂和Cognex智能相机,构建一套完整的自动化生产线。该生产线能够实现手机玻璃的高精度、高效率加工,满足企业的需求。

具体来说,首先使用双目三维重建技术,实时计算相机位姿并建立稀疏的三维点云地图SLAM模式用于构建环境的地图,并确定小车相对于地图的位置。定位模式帮助小车实时定位自身的位置,并且在地图上进行准确定位。使用视觉传感器(如摄像头)来捕获物体的图像,并利用计算机视觉算法来识别和定位物体。将这些信息与SLAM系统构建的地图进行关联,从而确定物体在地图中的位置。使用三维SLAM系统输出的三维点云数据,可以通过投影转换为二维地图数据实现在二维地图上的视觉感知和定位任务,例如障碍物检测、路径规划等。然后使用AGV技术负责运输手机玻璃零件到加工中心让小车自主规划路径,避开障碍物,并安全地到达目标位置。相机固定在机械臂上,在抓取前需要使用九点标定法来确认相机与机械臂的坐标变换矩阵。通过智能相机和计算机视觉技术获取玻璃相对于相机坐标,坐标变换后UR5机械臂路径规划抓取玻璃并进行加工

三、主要部件BOM清单

1.差动轮式AGV

重量:60Kg

负载:60Kg

移动速度:1800mm/s

控制精度:±0.1mm

功能:自动导航、定位、运输,将手机玻璃运输至机械臂加工区域。

2.UR5系列机械臂

负载:5Kg

重复定位精度:±0.05mm

运动范围:1600mm700mm700mm

功能:接收AGV运送来的手机玻璃,进行加工操作。采用Cognex智能相机进行定位和检测,确保加工精度。

控制器:用于控制机械臂的运动轨迹和姿态。

末端执行器:用于抓取手机玻璃,确保稳定和可靠的夹持。

3.Cognex智能相机

型号:Cognex In-Sight 5300

分辨率:530万像素

检测精度:±0.01mm

功能:对手机玻璃进行高精度检测和定位,确保机械臂加工的准确性。同时,可实时监测生产过程,提高生产效率。

镜头和光源:确保相机拍摄的图像清晰、准确,适用于高精度检测。

图像处理软件:用于处理相机拍摄的图像,进行高精度检测和定位。

4.加工台

台面:提供稳定的加工平台,确保手机玻璃在加工过程中不会移动。

定位系统:用于将手机玻璃准确定位在加工台上。

5.控制系统

主控制器:用于集中控制整个自动化生产线,包括AGV、机械臂、智能相机等设备的协调工作。

传感器和限位开关:用于监测设备的运行状态和位置,确保安全和准确的加工。

6.电源和电缆

电源:为整个自动化生产线提供稳定的电力供应。

电缆:用于传输控制信号、电力等,确保设备之间的通信和供电。

四、技术点及工作流程

1.使用双目三维重建技术,实时计算相机位姿并建立稀疏的三维点云地图SLAM模式用于构建环境的地图,并确定小车相对于地图的位置。

2.AGV接收手机玻璃,利用SLAM输出的二维地图数据,通过差动轮系统自主规划路径,避开障碍物自动导航至机械臂加工区域。

3.UR5机械臂路径规划从AGV上抓取手机玻璃,放置在加工台上。

4.Cognex智能相机对手机玻璃进行高精度检测和定位,并将数据反馈给机械臂。

5.机械臂根据相机反馈的数据进行精确加工,完成后将手机玻璃放回AGV。

6.AGV将加工完成后的手机玻璃运输至下一工序或存储区域。

7.重复以上步骤,实现自动化加工生产。

五、计算自动化方案与人工方案成本收回时间

1.自动化方案成本分析:

(1)差动轮式AGV

选择具有良好口碑和市场表现的AGV品牌,如Geek+等,根据实际需求配置适当的差动轮和控制器。成本方面,AGV及其配件的成本将根据型号、性能以及具体需求而有所不同。预计在中等配置下,AGV及其配件的成本可能在5万元左右。

(2)UR5系列机械臂
使用UR5机械臂是一个可靠的选择,它提供了高精度和灵活性。购买全新机械臂及其配件的成本可能在10万元左右

(3)Cognex智能相机
Cognex是工业视觉领域的知名品牌,其相机能够满足±0.01mm的高精度要求。预计成本在1万元左右根据工作流程判断,一个自动化生产线需要三个相机,两个用于SLAM建图,一个用于机械臂。

(4)加工台
根据实际需求定制加工台,确保其稳定性和精度。成本将根据材料、尺寸和加工要求而有所不同,预计在1-3万元之间,这里估算为2万

(5)控制系统
控制系统是整个自动化生产线的核心,需要选择可靠的工业控制器和传感器。成本可能在2-5万元之间。

(6)电源和电缆
电源和电缆的成本相对较低,但它们是保证生产线正常运行的关键因素。预计这部分成本在1-2万元之间。

(7)其他成本
此外,还需要考虑安装、调试、维护以及可能的培训成本。这些成本可能会根据实际情况有所波动。初步估计在5-10万元之间。

(8)总成本概算
综上所述,构建这套完整的自动化生产线的大致成本可能在30万元左右

2.人工方案成本分析:

(1)人力成本

假设每个工人每小时的工资为30元,每人每天工作8小时,每天可以加工100片手机玻璃(基于±0.01mm的精度要求,需要逐个测量)。则每人每天的人工成本为30 * 8 = 240元。而一个工人一天可以加工100片手机玻璃,所以加工一片手机玻璃的人工成本为2.4元。

(2)设备与材料成本

假设人工方案所需的设备(如大理石平台、千分表等)和材料成本为每年5万元,这包括了设备的折旧、维护和替换成本。

(3)其他成本

其他成本可能包括培训、管理、安全等方面的费用。假设这部分费用为每年10万元。

(4)总成本概算

单片成本:每片手机玻璃的人工成本为2.4元。

年固定成本:设备与材料成本为5万元,其他成本为10万元。

年总成本:年总成本 = 年固定成本+年加工量*单片人工成本。即年总成本 = 5万 + 365 * 100 * 2.4元 = 94.9万元。

3.两种方案的比较及成本收回时间的计算:

自动化方案:初步估计总成本在30万元左右

人工方案:年总成本为94.9万元。

为了计算自动化方案成本的回收时间,我们假设自动化方案的成本为C(30万元),人工方案的年总成本为A(94.9万元),则回收时间T可以用以下公式计算:

T = C / (A - C)

即T = (30万) / (94.9万 - (30万))。根据这个公式,我们可以大致计算出自动化方案成本的回收时间,可能在0.47年左右,即170天

因此,采用自动化方案与采用人工方案相比,预计在170左右可以收回自动化生产线改造的成本。

六、主要技术点分析与实现方案及仿真实现(附带源代码在文件包中)

1.视觉SLAM建图

使用双目三维重建技术,实时计算相机位姿并建立稀疏的三维点云地图,SLAM模式用于构建环境的地图,并确定小车相对于地图的位置。定位模式帮助小车实时定位自身的位置,并且在地图上进行准确定位。使用视觉传感器(如摄像头)来捕获物体的图像,并利用计算机视觉算法来识别和定位物体。将这些信息与SLAM系统构建的地图进行关联,从而确定物体在地图中的位置。使用三维SLAM系统输出的三维点云数据,可以通过投影转换为二维地图数据,实现在二维地图上的视觉感知和定位任务,例如障碍物检测、路径规划等。

双目三维SLAM的部分python代码:

  1. """
  2. The Kinect provides the color and depth images in an un-synchronized way. This means that the set of time stamps from the color images do not intersect with those of the depth images. Therefore, we need some way of associating color images to depth images.
  3. For this purpose, you can use the ''associate.py'' script. It reads the time stamps from the rgb.txt file and the depth.txt file, and joins them by finding the best matches.
  4. """
  5. import argparse
  6. import sys
  7. import os
  8. import numpy
  9. def read_file_list(filename):
  10. """
  11. Reads a trajectory from a text file.
  12. File format:
  13. The file format is "stamp d1 d2 d3 ...", where stamp denotes the time stamp (to be matched)
  14. and "d1 d2 d3.." is arbitary data (e.g., a 3D position and 3D orientation) associated to this timestamp.
  15. Input:
  16. filename -- File name
  17. Output:
  18. dict -- dictionary of (stamp,data) tuples
  19. """
  20. file = open(filename)
  21. data = file.read()
  22. lines = data.replace(","," ").replace("\t"," ").split("\n")
  23. list = [[v.strip() for v in line.split(" ") if v.strip()!=""] for line in lines if len(line)>0 and line[0]!="#"]
  24. list = [(float(l[0]),l[1:]) for l in list if len(l)>1]
  25. return dict(list)
  26. def associate(first_list, second_list,offset,max_difference):
  27. """
  28. Associate two dictionaries of (stamp,data). As the time stamps never match exactly, we aim
  29. to find the closest match for every input tuple.
  30. Input:
  31. first_list -- first dictionary of (stamp,data) tuples
  32. second_list -- second dictionary of (stamp,data) tuples
  33. offset -- time offset between both dictionaries (e.g., to model the delay between the sensors)
  34. max_difference -- search radius for candidate generation
  35. Output:
  36. matches -- list of matched tuples ((stamp1,data1),(stamp2,data2))
  37. """
  38. first_keys = first_list.keys()
  39. second_keys = second_list.keys()
  40. potential_matches = [(abs(a - (b + offset)), a, b)
  41. for a in first_keys
  42. for b in second_keys
  43. if abs(a - (b + offset)) < max_difference]
  44. potential_matches.sort()
  45. matches = []
  46. for diff, a, b in potential_matches:
  47. if a in first_keys and b in second_keys:
  48. first_keys.remove(a)
  49. second_keys.remove(b)
  50. matches.append((a, b))
  51. matches.sort()
  52. return matches
  53. if __name__ == '__main__':
  54. # parse command line
  55. parser = argparse.ArgumentParser(description='''
  56. This script takes two data files with timestamps and associates them
  57. ''')
  58. parser.add_argument('first_file', help='first text file (format: timestamp data)')
  59. parser.add_argument('second_file', help='second text file (format: timestamp data)')
  60. parser.add_argument('--first_only', help='only output associated lines from first file', action='store_true')
  61. parser.add_argument('--offset', help='time offset added to the timestamps of the second file (default: 0.0)',default=0.0)
  62. parser.add_argument('--max_difference', help='maximally allowed time difference for matching entries (default: 0.02)',default=0.02)
  63. args = parser.parse_args()
  64. first_list = read_file_list(args.first_file)
  65. second_list = read_file_list(args.second_file)
  66. matches = associate(first_list, second_list,float(args.offset),float(args.max_difference))
  67. if args.first_only:
  68. for a,b in matches:
  69. print("%f %s"%(a," ".join(first_list[a])))
  70. else:
  71. for a,b in matches:
  72. print("%f %s %f %s"%(a," ".join(first_list[a]),b-float(args.offset)," ".join(second_list[b])))

2.AGV路径规划与自主避障的自动导航技术

AGV全称是Automated Guided Vehicle,即自动引导车,它是一种可以自主运行的无人驾驶车辆,广泛应用于仓库、工厂等场合的物流运输。在AGV的运输路径规划中,Matlab是一个常用的工具。

使用Matlab进行AGV路径规划,通常需要先定义AGV的地图和障碍物信息,然后选择路径规划算法进行规划。常用的路径规划算法包括A*算法、Dijkstra算法、深度优先搜索算法等。

本方案采用A*路径规划算法,输入二维地图点阵,设定AGV起始点与目标点,设定移动障碍物路线与固定障碍物位置,实现自动避障和路径规划的功能。

这里我们模拟了一个加工车间的二维地图,设置了AGV的起始点和目标点,实现了它的自动导航,如图所示,其中蓝色路径为AGV移动路线,红色为移动障碍物路径。同时也得出了姿态角度的变化以及线速度和角速度的变化图。

AGV自动导航路径规划

MATLAB的AGV路径规划部分代码:

  1. clear
  2. close all
  3. figure
  4. %% 地图建模
  5. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6. %%
  7. MAX0 = [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  8. 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
  9. 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0;
  10. 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0;
  11. 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0;
  12. 0 0 1 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 0 0;
  13. 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0;
  14. 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0;
  15. 0 0 1 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 0 0;
  16. 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0;
  17. 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0;
  18. 0 0 1 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 0 0;
  19. 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0;
  20. 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0;
  21. 0 0 1 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 0 0;
  22. 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0;
  23. 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0;
  24. 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0;
  25. 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
  26. 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;];
  27. %%% 通道设置为 0 ;障碍点设置为 1 ;起始点设置为 2 ;目标点设置为 -1 。
  28. MAX=rot90(MAX0,3); %%%设置0,1摆放的图像与存入的数组不一样,需要先逆时针旋转90*3=270度给数组,最后输出来的图像就是自己编排的图像
  29. MAX_X=size(MAX,2); %%% 获取列数,即x轴长度
  30. MAX_Y=size(MAX,1); %%% 获取行数,即y轴长度
  31. MAX_VAL=10; %%% 返回由数字组成的字符表达式的数字值,就是函数用于将数值字符串转换为数值
  32. x_val = 1;
  33. y_val = 1;
  34. axis([1 MAX_X+1, 1 MAX_Y+1]) %%% 设置x,y轴上下限
  35. set(gca,'xtick',1:1:MAX_X+1,'ytick',1:1:MAX_Y+1,'GridLineStyle','-',...
  36. 'xGrid','on','yGrid','on')
  37. grid on; %%% 在画图的时候添加网格线
  38. hold on; %%% 当前轴及图像保持而不被刷新,准备接受此后将绘制的图形,多图共存
  39. n=0;%Number of Obstacles %%% 障碍的数量
  40. k=1; %%%% 将所有障碍物放在关闭列表中;障碍点的值为1;并且显示障碍点
  41. CLOSED=[];
  42. for j=1:MAX_X
  43. for i=1:MAX_Y
  44. if (MAX(i,j)==1)
  45. %%plot(i+.5,j+.5,'ks','MarkerFaceColor','b'); 原来是红点圆表示
  46. fill([i,i+1,i+1,i],[j,j,j+1,j+1],'k'); %%%改成 用黑方块来表示障碍物
  47. CLOSED(k,1)=i; %%% 将障碍点保存到CLOSE数组中
  48. CLOSED(k,2)=j;
  49. k=k+1;
  50. end
  51. end
  52. end
  53. Area_MAX(1,1)=MAX_X;
  54. Area_MAX(1,2)=MAX_Y;
  55. Obs_Closed=CLOSED;
  56. num_Closed=size(CLOSED,1);
  57. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  58. % 设置起始点和多个目标点
  59. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  60. %% 设置起始点、目标点
  61. %%% 选择目标位置
  62. pause(0.5); %%% 程序暂停1秒
  63. h=msgbox('请使用鼠标左键选择目标'); %%% 显示提示语 原句是:Please Select the Target using the Left Mouse button
  64. uiwait(h,5); %%% 程序暂停
  65. if ishandle(h) == 1 %%% ishandle(H) 将返回一个元素为 1 的数组;否则,将返回 0。
  66. delete(h);
  67. end
  68. xlabel('请使用鼠标左键选择目标','Color','black'); %%% 显示图x坐标下面的提示语 原句是:Please Select the Target using the Left Mouse button
  69. but=0;
  70. while (but ~= 1) %Repeat until the Left button is not clicked %%% 重复,直到没有单击“向左”按钮
  71. [xval,yval,but]=ginput(1); %%% ginput提供了一个十字光标使我们能更精确的选择我们所需要的位置,并返回坐标值。
  72. end
  73. xval=floor(xval); %%% floor()取不大于传入值的最大整数,向下取整
  74. yval=floor(yval);
  75. xTarget=xval;%X Coordinate of the Target %%% 目标的坐标
  76. yTarget=yval;%Y Coordinate of the Target
  77. plot(xval+.5,yval+.5,'go'); %%% 目标点颜色b 蓝色 g 绿色 k 黑色 w白色 r 红色 y黄色 m紫红色 c蓝绿色
  78. text(xval+1,yval+1,'Target') %%% text(x,y,'string')在二维图形中指定的位置(x,y)上显示字符串string
  79. %%% 选择起始位置
  80. h=msgbox('请使用鼠标左键选择AGV初始位置'); %%%原文 Please Select the Vehicle initial position using the Left Mouse button
  81. uiwait(h,5);
  82. if ishandle(h) == 1
  83. delete(h);
  84. end
  85. xlabel('请选择AGV初始位置 ','Color','black'); %%% 原文 Please Select the Vehicle initial position
  86. but=0;
  87. while (but ~= 1) %Repeat until the Left button is not clicked %%%重复,直到没有单击“向左”按钮
  88. [xval,yval,but]=ginput(1);
  89. xval=floor(xval);
  90. yval=floor(yval);
  91. end
  92. xStart=xval;%Starting Position
  93. yStart=yval;%Starting Position
  94. plot(xval+.5,yval+.5,'b^');
  95. text(xval+1,yval+1,'Start')
  96. xlabel('起始点位置标记为 △ ,目标点位置标记为 o ','Color','black');
  97. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  98. Start=[xStart yStart];
  99. Goal=[xTarget yTarget];
  100. [Line_path,distance_x,OPEN_num]=Astar_G_du(Obs_Closed,Start,Goal,MAX_X,MAX_Y);
  101. % 局部避障
  102. figure
  103. axis([1 MAX_X+1, 1 MAX_Y+1]) %%% 设置x,y轴上下限
  104. set(gca,'xtick',1:1:MAX_X+1,'ytick',1:1:MAX_Y+1,'GridLineStyle','-',...
  105. 'xGrid','on','yGrid','on');
  106. grid on;
  107. hold on;
  108. num_obc=size(Obs_Closed,1);
  109. for i_obs=1:1:num_obc
  110. x_obs=Obs_Closed(i_obs,1);
  111. y_obs=Obs_Closed(i_obs,2);
  112. fill([x_obs,x_obs+1,x_obs+1,x_obs],[y_obs,y_obs,y_obs+1,y_obs+1],'k');hold on;
  113. end
  114. plot( Line_path(:,1)+.5, Line_path(:,2)+.5,'b:','linewidth',2);
  115. plot(xStart+.5,yStart+.5,'b^');
  116. plot(Goal(1,1)+.5,Goal(1,2)+.5,'bo');
  117. pause(1);
  118. h=msgbox('设置移动障碍物的 起点');
  119. uiwait(h,5);
  120. if ishandle(h) == 1
  121. delete(h);
  122. end
  123. xlabel('设置移动障碍物的 起点','Color','black');
  124. but=0;
  125. while (but ~= 1) %Repeat until the Left button is not clicked
  126. [xval,yval,but]=ginput(1);
  127. end
  128. xval=floor(xval);
  129. yval=floor(yval);
  130. Obst_xS=xval;%X Coordinate of the Target
  131. Obst_yS=yval;%Y Coordinate of the Target
  132. plot(xval+.5,yval+.5,'k^');
  133. pause(1);
  134. h=msgbox('设置移动障碍物的 终点');
  135. uiwait(h,5);
  136. if ishandle(h) == 1
  137. delete(h);
  138. end
  139. xlabel('设置移动障碍物的 终点 ','Color','black');
  140. but=0;
  141. while (but ~= 1) %Repeat until the Left button is not clicked
  142. [xval,yval,but]=ginput(1);
  143. xval=floor(xval);
  144. yval=floor(yval);
  145. end
  146. Obst_xT=xval;%Starting Position
  147. Obst_yT=yval;%Starting Position
  148. plot(xval+.5,yval+.5,'ko');
  149. Obst_d_d_St=[Obst_xS Obst_yS];
  150. Obst_d_d_Ta=[Obst_xT Obst_yT];
  151. [Obst_d_path,Obst_d_distance_x,Obst_d_OPEN_num]=Astar_G(Obs_Closed,Obst_d_d_St,Obst_d_d_Ta,MAX_X,MAX_Y);
  152. Obst_d_path_X=[Obst_d_path;Obst_d_d_Ta];
  153. L_obst=0.01;% 设置移动障碍物的速度 0.1s内运动 L_obst m 速度为10*L_obst m/s
  154. Obst_d_d_line=Line_obst(Obst_d_path_X,L_obst);
  155. plot( Obst_d_d_line(:,1)+.5, Obst_d_d_line(:,2)+.5,'r','linewidth',1);
  156. pause(1);
  157. h=msgbox('设置未知静止障碍物 左键确定后继续设置,右键确定后结束');
  158. xlabel('设置未知静止障碍物 左键确定后继续设置,右键确定后结束','Color','blue');
  159. uiwait(h,10);
  160. if ishandle(h) == 1
  161. delete(h);
  162. end
  163. but=1;
  164. while but == 1
  165. [xval,yval,but] = ginput(1);
  166. xval=floor(xval);
  167. yval=floor(yval);
  168. MAX(xval,yval)=-2;%Put on the closed list as well
  169. %plot(xval+.5,yval+.5,'rp');
  170. fill([xval,xval+1,xval+1,xval],[yval,yval,yval+1,yval+1],[0.8 0.8 0.8]);
  171. end%End of While loop
  172. dg=0;%Dummy counter
  173. Obs_d_j=[0 0];
  174. for i=1:MAX_X
  175. for j=1:MAX_Y
  176. if(MAX(i,j) == -2)
  177. dg=dg+1;
  178. Obs_d_j(dg,1)=i;
  179. Obs_d_j(dg,2)=j;
  180. end
  181. end
  182. end
  183. path_node=Line_path;
  184. %% 机器人运动学模型
  185. %机器人初始方向角度 angle_node
  186. angle_node=-pi/2;
  187. % 机器人速度参数
  188. % Kinematic = [ 最高速度[m/s], 最高旋转速度[rad/s], 加速度[m/ss], 旋转加速度[rad/ss], 速度分辨率[m/s], 转速分辨率[rad/s] ]
  189. Kinematic=[2,toRadian(20.0),0.2,toRadian(50.0),0.01,toRadian(1)];
  190. % 评价函数系数设置 [heading,dist,velocity,predictDT]
  191. % [方位角评价函数系数, 障碍物距离评价函数系数, 当前速度大小评价函数系数, 预测是时间 (不变)]
  192. evalParam=[0.05, 0.2, 0.2, 3.0];
  193. Result_x=DWA_ct_dong(Obs_Closed,Obst_d_d_line,Obs_d_j,Area_MAX,Goal,Line_path,path_node,Start,angle_node,Kinematic,evalParam);
  194. %%%%%%%%%%% 画图
  195. figure
  196. axis([1 MAX_X+1, 1 MAX_Y+1]) %%% 设置x,y轴上下限
  197. set(gca,'xtick',1:1:MAX_X+1,'ytick',1:1:MAX_Y+1,'GridLineStyle','-',...
  198. 'xGrid','on','yGrid','on');
  199. grid on;
  200. hold on;
  201. for i_obs=1:1:num_obc
  202. x_obs=Obs_Closed(i_obs,1);
  203. y_obs=Obs_Closed(i_obs,2);
  204. fill([x_obs,x_obs+1,x_obs+1,x_obs],[y_obs,y_obs,y_obs+1,y_obs+1],'k');hold on;
  205. end
  206. plot( Line_path(:,1)+.5, Line_path(:,2)+.5,'b:','linewidth',1.5);
  207. plot(xStart+.5,yStart+.5,'b^');
  208. plot(Goal(1,1)+.5,Goal(1,2)+.5,'bo');
  209. plot( Obst_d_d_line(:,1)+.5, Obst_d_d_line(:,2)+.5,'r','linewidth',1);
  210. num_o=size(Obst_d_d_line,1);
  211. x_do=Obst_d_d_line(num_o,1);
  212. y_do=Obst_d_d_line(num_o,2);
  213. fill([x_do+0.15,x_do+0.85,x_do+0.85,x_do+0.15],[y_do+0.15,y_do+0.15,y_do+0.85,y_do+0.85],'y');
  214. num_lin=size(Line_path,1);
  215. for i_lin=2:1:num_lin-1
  216. plot(Line_path(i_lin,1)+.5,Line_path(i_lin,2)+.5,'r*');
  217. end
  218. % dong_num=size(Obs_d_j,1);
  219. % for i_d=1:1:dong_num
  220. % x_do=Obs_d_j(i_d,1);
  221. % y_do=Obs_d_j(i_d,2);
  222. % fill([x_do,x_do+1,x_do+1,x_do],[y_do,y_do,y_do+1,y_do+1],[0.8 0.8 0.8]);
  223. % end
  224. num_x=size(Result_x,1);
  225. Result_plot=[Result_x;Goal(1,1) Goal(1,2) Result_x(num_x,3) 0 0];
  226. plot(Result_x(:,1)+0.5, Result_x(:,2)+0.5,'b','linewidth',2);hold on;
  227. num_p=num_x+1;
  228. ti=1:1:num_p;
  229. figure
  230. plot(ti,Result_plot(:,3),'-b');hold on;
  231. legend('姿态角度')
  232. figure
  233. plot(ti,Result_plot(:,4),'-b');hold on;
  234. plot(ti,Result_plot(:,5),'-r');hold on;
  235. legend('线速度','角速度')
  236. S=0;
  237. for i=1:1:num_x %%%% 求路径所用的实际长度
  238. Dist=sqrt( ( Result_plot(i,1) - Result_plot(i+1,1) )^2 + ( Result_plot(i,2) - Result_plot(i+1,2))^2);
  239. S=S+Dist;
  240. end
  241. disp('路径长度')
  242. disp(S);
  243. S ;
  244. %
  245. % % 机器人的状态Result_x=[x(m),y(m),yaw(Rad),v(m/s),w(rad/s)]
  246. % i=1
  247. % figure
  248. % axis([0 2000, -0.4 0.8]) %%% 设置x,y轴上下限
  249. % set(gca,'xtick',0:100:2100,'ytick',-0.4:0.2:0.8,'GridLineStyle','-',...
  250. % 'xGrid','on','yGrid','on')
  251. % grid off;
  252. % xlabel('控制节点个数');hold on
  253. % ylabel('线速度(m/s) 角速度(rad/s)');hold on
  254. %
  255. % plot(ti,Result_plot(:,4),'-b','linewidth',1.5);hold on;
  256. % plot(ti,Result_plot(:,5),':r','linewidth',1.5);hold on;

3.UR5机械臂路径规划

下面是九点标记获取坐标变换矩阵(图中为举例结果):

UR5机械臂路径规划:

九点标记获取坐标变换矩阵HomMat2D的halcon代码:

  1. read_image (ProfileImage, '12.bmp')
  2. **圈定9点区域
  3. * draw_rectangle1(3600, Row11, Column1, Row2, Column2)
  4. * gen_rectangle1(Rectangle, Row11, Column1, Row2, Column2)
  5. gen_rectangle1 (ROI_0, 330.384, 356.221, 798.412, 825.73)
  6. Rectangle:=ROI_0
  7. reduce_domain(ProfileImage, Rectangle, ImageReduced)
  8. threshold(ImageReduced, Region, 0, 50)
  9. connection(Region, ConnectedRegions)
  10. select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 0, 500)
  11. sort_region(SelectedRegions, SortedRegions, 'character', 'true', 'column')
  12. **求取9点中心坐标
  13. area_center(SortedRegions, Area, Row, Col)
  14. **手动让机械臂依次走过标定板9个点,记录对应点XY坐标
  15. Col1:=[0.46,0.502,0.54,0.462,0.502,0.54,0.462,0.502,0.542]
  16. Row1:=[-0.109,-0.11,-0.11,-0.069,-0.070,-0.071,-0.029,-0.030,-0.031]
  17. **求取变换矩阵
  18. vector_to_hom_mat2d(Row, Col, Row1, Col1, HomMat2D)
  19. **存储
  20. serialize_hom_mat2d (HomMat2D, SerializedItemHandle)
  21. file:='121.txt'
  22. open_file (file, 'output_binary', FileHandle)
  23. fwrite_serialized_item (FileHandle, SerializedItemHandle)
  24. close_file (FileHandle)
  25. ***********************************************************************
  26. **读取
  27. open_file (file, 'input_binary', FileHandle)
  28. fread_serialized_item (FileHandle, SerializedItemHandle2)
  29. deserialize_hom_mat2d (SerializedItemHandle2, HomMat2D_2)
  30. close_file (FileHandle)
  31. Col3:=Col[0]
  32. Row3:=Row[0]
  33. **应用测试
  34. affine_trans_point_2d(HomMat2D_2, Row3,Col3, Qy,Qx)

机械手臂轨迹规划方法:

  1. figure(f)
  2. [q ,qd, qdd]=jtraj(init_ang,targ_ang,step); %五次多项式轨迹,得到关节角度,角速度,角加速度,50为采样点个数
  3. grid on
  4. T=robot2.fkine(q); %根据插值,得到末端执行器位姿
  5. nT=T.T;
  6. plot3(squeeze(nT(1,4,:)),squeeze(nT(2,4,:)),squeeze(nT(3,4,:)));%输出末端轨迹
  7. title('输出末端轨迹');
  8. robot2.plot(q); %动画演示
  9. %% 求解位置、速度、加速度变化曲线
  10. f = 4
  11. figure(f)
  12. subplot(3,2,[1,3]); %subplot 对画面分区 三行两列 占用1到3的位置
  13. plot3(squeeze(nT(1,4,:)),squeeze(nT(2,4,:)),squeeze(nT(3,4,:)));%输出末端轨迹
  14. robot2.plot(q); %动画演示
  15. figure(f)
  16. subplot(3, 2, 2);
  17. i = 1:6;
  18. plot(q(:,1));
  19. title('位置');
  20. grid on;
  21. figure(f)
  22. subplot(3, 2, 4);
  23. i = 1:6;
  24. plot(qd(:,1));
  25. title('速度');
  26. grid on;
  27. figure(f)
  28. subplot(3, 2, 6);
  29. i = 1:6;
  30. plot(qdd(:,1));
  31. title('加速度');
  32. grid on;
  33. t = robot2.fkine(q); %运动学正解
  34. rpy=tr2rpy(t); %t中提取位置(xyz)
  35. figure(f)
  36. subplot(3,2,5);
  37. plot2(rpy);
  38. %% ctraj规划轨迹 考虑末端执行器在两个笛卡尔位姿之间移动
  39. f = 5
  40. T0 = robot2.fkine(init_ang); %运动学正解
  41. T1 = robot2.fkine(targ_ang); %运动学正解
  42. Tc = ctraj(T0,T1,step); %得到每一步的T阵
  43. tt = transl(Tc);
  44. figure(f)
  45. plot2(tt,'r');
  46. title('直线轨迹');

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/136790
推荐阅读
  

闽ICP备14008679号