ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

写生机器人(转)

2022-07-16 14:31:33  阅读:150  来源: 互联网

标签:直线 机器 写生 电机 机器人 持笔 步进 设计


我在《对编程感兴趣的程序员是否都对电路、单片机也怀有浓厚的兴趣? 》展示了前两年制作的一个写生机器人,不少网友表示感兴趣,故撰本文回顾制作历程及感悟。


1. 起源

在 2014 年,当时我已经开发软件算有二十多年(第一个主导的商业游戏项目《王子传奇》在1995年台湾发行)。然而,除了懂得一些简单的、中学物理课学到的电子知识,从来没接触过硬件开发。和读计算机相关专业的朋友不一样,我本科读的是认知科学(cognitive science,在香港大学属社会科学院),完全没有硬件方面的课。

因此,那个时候想学习一下硬件开发,扩阔视野。

最初,我在网上买了一套一百多块的 Arduino 入门套装,按着 [1] 的例子学习,如控制 LED/7段 LED、处理按钮/电位器输入、控制电机/舵机等。有赖 Arduino 团队的努力,开发环境和 API 都十分简单易用,熟悉 C/C++的程序员可轻松入门。

但经验告诉我,

要提升一门技术的水平,最好是从做一个项目中学习。

当时,我工作的部门(腾讯/IEG 互动娱乐事业群/研发部)正宣传举办第一届的《Intel杯创新大赛》,让IEG 同事创作作品,范围包括智能硬件、VR/AR 等,每年举办两次。我便鼓起勇气参加了。那么,做什么好呢?


2. 构思

我先考虑自己懂什么,以及想做些什么。

最后的构思源于以下的经历:

  1. 本科专业是认知科学,研究信息如何在大脑中形成及转录过程的跨领域学科;
  2. 对计算机图形学比较了解,有幸成为知乎计算机图形学的优秀回答者;
  3. 在《程序员可以学画画吗? 》提及我在业余学过基本素描油画
  4. 我想做一些会动的东西,因为以前做的软件,即使有动画及互动内容,都是困于屏幕之中。

我曾在 YouTube 看过一个绘画机器人的艺术项目 [2],我觉得和我上述的经历吻合,引发了一些思考。

Portrait drawing by Paul the robot [2]

我以前学画的时候,也会想一些问题,也和老师讨论过。

绘画是越写实越好么?不是。要写实的话,摄影更写实。绘画和摄影有相似的地方,但不能互相取代。

绘画(以下主要指写生)和摄影的主要区别是什么?画家在构图后,还可以选择要表达的重点。另外,写生是一个较长期的渐进过程,从整体粗略至局部细致,过程中不断观察比对画作和对象。这和摄影通常一次曝光(通常是几十分之一秒),然后显影很不一样。

也因此,同一对象、同一灯光、同一构图下,即使不同的摄影师也几乎得到相同的作品。而画家则会因当时对对象的不同观察和想法、不同的手法表现,得出独一无二的作品。这也许存在争议,纯粹是个人的一个想法。

我当时想到,如果要做一个机器人模仿人类进行写生,要怎么做才可以重现出这种区别,创作出独一无二的作品,而不只是用相机拍下然后打印?我想到 3 点:

  1. 模仿人的多关节肢体,使用真实绘画素材(如铅笔、走珠笔、绘图笔、秀丽笔、油漆笔),而非用打印机。虽然用 XY plotter 也可用上绘画素材,但完全不像人的手。
  2. 模仿人的视觉系统,可以持续观察写生对象及当前的画作,进行对比。
  3. 模仿人的渐进写生过程,而非完全的机械式输入处理输出。而且,对象可能会随时间改变(如人像、风景),作品可包含这些时间的变化。

我没怎么想商业价值,觉得这个机器人更像是一个互动的装置艺术。我希望每张作品都是独一无二的艺术品。

记得以前读认知科学时,要评估一些认知能力模型是否好,其中一个方法是用计算机去模拟出来,看看能否模仿生物的那些能力。所以从研究的角度来说,这个项目也许涉及艺术风格的模仿及研究。

不过,我并没有把上述的所有构思都实现。基于时间和能力所限,只是做一个非常简化的版本。


3. 设计

如果只做算法部分,或可购买现成的机器臂,或是组装现成的套件。但我没学过机械设计,希望借这个项目尝试一下。

当时常见到的玩具机器人和机器臂,一般都使用舵机(摇控模型的直流伺服电机/RC servo)作为致动器(actuator),而 [1] 的机器臂也是用这种构造。这种机器臂构造简单,控制也容易(用 PWM 信号控制目标角度),但缺点也是很明显的,角度不够精确,也难以控制转动的速度,画出来的作品抖动明显。

我从 [3] 学习到一些致动器原理及传动系统,似乎步进电机(stepper motor)是更好的选择,可以用一个脉冲控制电机旋转一个很小的角度。那么我可以用编程的方法,精准地控制旋转速度。

我没有读机器臂相关的书,只是从需求去设计:

  1. 画在 A3 大小的纸张。一般的玩具机器臂没有这么大的移动范围。
  2. 容易制作。因为没有技术、设备。
  3. 成本比较低。

我想,最简单需要一个水平二维移动的手,再加上一个垂直移动的持笔装置。二维移动需要至少两个自由度(degree of freedom, DOF),加上垂直移动共 3 个 DOF。那么,需要模拟上臂、下臂和手三部分。

构造上,最简单的是把电机放到关节上,但步进电机一般比舵机重,而机器臂也要足够长,会不会太重?太重有两个问题:上臂的关节要承受因重力而生的大力矩,底座要很重才能平衡。

因此,我想到的方案是把电机都放在底座,通过带子传动。后来知道这些构件称为同步轮(synchornized wheel)和同步带(synchronized belt)。我想到这个设计还有 4 个好处:

  1. 手臂不用放置电机,使手臂轻很多,旋转两个关节所需的力矩变小。
  2. 上臂的关节不用直接使用步进电机的输出轴,而可以用上更粗、更坚固的轴,令系统更强健。
  3. 系统中最重的部件(步进电机)位于底座,而且可放在手臂的另一端,令重心接近第一关节,更稳定。
  4. 采用不同大小的同步轮,可作进一步减速,提升精确性。

要做设计,首先要知道有什么零件可以使用。我在网上找寻合适的零件,包括电机、传动和结构上的。我发现最平宜的结构是用板材配合立柱,用螺丝紧固。

然后绘画各部分的草图:

我最不了解的是各种轴承(bearing),没想到会这样复杂,不确定是否需要这么多轴承。设计时要匹配各种轴承的尺寸,我通过不断搜寻轴承目录,试各种尺寸的组合,才得出设计方案。同步轮也有同样问题,设计都是要配合现成能买到的规格。

另外,垂直移动的持笔装置也是设计的难点。我看到一些持笔装置是用舵机的,感觉不能很精确控制高度,而且持笔不够稳固。如果要用秀丽笔控制高度来画不同粗细,最好还是精确一点。最后我的方案是用直线轴承,轴承中放置铝管,铝管中固定笔枝,再配合小型的直线步进电机。直线步进电机常见于光驱,控制激光的轨道位置,可以非常精确。因为笔支不重,细小的直线步进电机已经足够,而且它的控制也和其他步进电机一样简单。

我没学过机械制图,只有 3dsMax、SketchUp的使用经验。我找了一下流行的相关设计软件,最后下载了 SolidWorks 的试用版本来学习。 SolidWorks 确实是十分容易使用,我花了两周左右(如没记错)的工余时间便学习并画出以下的设计图和渲染圖:

不过,我还是不太了解 SolidWorks 的约束系统,第一次画图应该有很多问题。而设计时,很多数值(例如光轴要多粗的、板材要多厚的、电机要多大力矩的)我也没有深究,应该都是高于实际的要求。我并没有做力学方面的模拟,做了的话应该可以再降低成本。


4. 机器臂制作

我在网上找公司按图切割铝合金板,并购买所有的部件。制作中还需要一些工序,所以后来也购买了电钻床和夹钳等工具。

如同模型一样,组装这个机器臂是很好玩的环节。在设计时,我并没有很在意组装次序,所以组装时发现确实是有点难度,试过错放漏放部件,要拆掉重来。

持笔的铝管需要固定笔枝,我采用的是在管铝上攻丝,这样也方便更换笔枝。第一次手工攻丝还是觉得有点难度,记得做了两枝铝管才成功。

主要部分完成组装后,就接上电机控制器和 Arduino 去测试。非常成功地旋转了!但是⋯⋯同步带不够紧!

当初设计时,我参考了一个网站,按同步带类型/长度、同步轮半径去计算轴距的长度。然而,没想到最后还是有点松。看了一些其他用同步带的设计,原来都要加一个可调的滑轮去控制松紧!没辨法之下,我要拆开部件钻孔,买立柱和轴承作为滑轮。

而且!我设计时没考虑到怎样检测手臂复位!我买的是没有角度回馈的步进电机,在开始时需要把手臂转到一个初始角度做复位。我唯有临时加上了两个微动开关去检测手臂是否到达初始角度。

红圈中的是后来加入的滑轮,黄圈中的是后来加入的微动开关

这两个失误说明,经验还是很重要的。不过,第一次做这方面的设计,能正常地动起来,我已经很满足了。而且整个手臂很坚固,旋转也很顺滑细致,单凭想像力去做的设计还算不错吧。

经过简单测试(用固定频率旋转两个轴),设置步进电机驱动器使用16 微步进(micro stepping)模式没什么问题,能实现两个关节 旋转,最高 末端精度(距离底座半径越大精度越低)。这样已经足够了,编程随便画些东西!

很久以后我发图出来,才有网友说这不是SCARA嘛。啊?我真不知道。如果有导师指导应该会好很多,不过胡猜瞎试也是另一种乐趣。

三菱的SCARA机器臂

5. 绘画直线算法

除了画点以外,最简单的图形应该是直线。我比较熟悉在光栅图像里画线的方法,最近也写过一篇《用 C 语言画直线》。然而,Bresenham 画线算法源于控制 XY plotter,不能用在旋转关节。

设计机械臂硬件的时候,我也没有仔细去想怎样编程,心想:「应该没什么问题吧,到时再想。」

我不但没学过机械设计,也没学过控制。在图形学中学过逆向运动学(inverse kinematics),可以把目标的世界坐标转换成关节的角度。但似乎不行,我不知道世界坐标中应该步进多长的距离,两个旋转角度又怎样用多个单步、什么频率?

这次我也没有直接去找相关专著找答案。我觉得这应该不会是十分困难的问题,我尝试自行想个算法解决。

分析一下,先不考虑频率,我们每个离散步只能有 8 种输出:每个轴顺时针步进/逆时针步进/待机,但不会两个轴同时待机, [公式] 。那么,我们可以分别对 8 种输出,计算出旋转后的末端世界坐标。然后,找出向直线方向移动(不应回头)而又最接近直线的一种输出!

我实验用这个算法,画各种角度的直线、正方形,效果也不错! ⋯⋯但是有点抖。

这是因为,每次移动的距离是不一样的,但我都只是简单地延迟相同的间隔,所以直线上的移动速度并不平均。这并不难解决,只要按该步的欧氏距离及目标速度,就能计算出该步的延迟时间。实验也成功显示这样会减少抖动。

还有一个问题,就是开始和结束的时候的抖动。这是因为我们开始时从静止突然加速到目标速度,结束时则相反。解决方法是引入线性加速度,让笔从慢至快、快至慢地移动。以下实际上是第二届比赛前录制的视频,但能演示画直线的动作:

<iframe allowfullscreen="allowfullscreen" class="css-uwwqev" data-mce-fragment="1" frameborder="0" src="https://video.zhihu.com/video/928749126110298112?player=%7B%22autoplay%22%3Afalse%2C%22shouldShowPageFullScreenButton%22%3Atrue%7D" title="video"></iframe>  

6. 第一届Intel杯创新大赛

因为当时已接近第一届的比赛日子,我决定这一届只提交机器臂的部分。我继续写了个简单的 SVG 解析器,把 Bezier 曲线分割成线段绘画。下面是画一幅 SVG 的过程片段:

<iframe allowfullscreen="allowfullscreen" class="css-uwwqev" data-mce-fragment="1" frameborder="0" src="https://video.zhihu.com/video/928757235193114624?player=%7B%22autoplay%22%3Afalse%2C%22shouldShowPageFullScreenButton%22%3Atrue%7D" title="video"></iframe>  

最后做 presentation、演讲、即场演示,赢得第一届Intel杯创新大赛一等奖!

从最初构想至第一届创新大赛比赛日大约历时一年,但实际上有很多个月都没有搞,估计大约花了三个月左右的工余时间。由于工具和硬件都在公司,而我晚上又坐班车回家,所以除了设计阶段在家里进行,其他都是用午饭时间搞的。

此阶段的制作成本(不包括工具)一览:

[公式]

下篇讲述继续参加第二届创新大赛,加入 Intel RealSense 和实现素描算法,以及对这个项目的感悟。


参考

[1] McRoberts, Michael, Brad Levy, and Cliff Wootton. Beginning Arduino. New York.: Apress, 2010.《Arduino从基础到实践》,杨继志、郭敬译,电子工业出版社,2013。(已有中文版第二版)

[2] Tresset, Patrick, and Frederic Fol Leymarie. "Portrait drawing by Paul the robot." Computers & Graphics 37.5 (2013): 348-363.

[3] Roberts, Dustyn. Making Things Move DIY Mechanisms for Inventors, Hobbyists, and Artists. McGraw Hill Professional, 2010. 《Maker机械电子创意实现与项目制作》,郭洪红译, 科学出版社,2013。

标签:直线,机器,写生,电机,机器人,持笔,步进,设计
来源: https://www.cnblogs.com/FrostyForest/p/16484162.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有