转自:rohm,作者:Jan Gromes
这篇文章来源于DevicePlus.com英语网站的翻译稿。
六足机器人是最炫酷的机器人之一,但是通常价格昂贵。原因之一是它们由多个零部件组成,并且使用18个伺服,而这些都需要由某些微控制器来供电和驱动。在本教程中,我将展示如何通过使用3D打印所有零部件并仅使用12个伺服来构建您自己的Arduino六足机器人,或简称为Ardupod。准备好了吗?那让我们开始吧!
硬件
- • Arduino UNO (或其他可兼容Arduino的开发板)
- • Adafruit 16通道PWM扩展板(或模块;但是,此处强烈建议使用该扩展板,因为它的原型面积很小)
- • 12个带有金属齿轮的微型伺服(MG90S或其他同等规格产品)
- • 4.8V或6V电池(镍氢、锂离子等)
- • 60个M3螺栓+120个螺母和垫圈(仅用于身体,对于其他部件的安装您需要再另外添加)
- • 6个相同的圆珠笔弹簧
- • HC-SR04超声波测距模块(可选)
软件
- • Arduino IDE
- • SolidWorks或其他3D建模软件
- • AI千集(https://aiqianji.com/openoker/ArduPod)– 您在这里可以找到所有用于打印的 Arduino源代码和3D模型
其他工具
- • 3D 打印机
- • 非常建议使用万用表、烙铁和电钻等其他工具
设计
如上所述,本次所设计的六足机器人仅需要12个伺服来移动六条腿。这意味着每条腿只配有两个伺服,具有两个自由度(DOF)。与通常的每条腿有三个伺服相比,这种方法有几个优点。我们将需要更少的功率以及更少的处理时间来驱动伺服。但是,移除一个伺服也意味着我们牺牲了一个自由度,因此在对机器人进行稳定爬行的编程上会更具有挑战性。
为了弥补缺少一个伺服所带来的缺陷,所有腿部都有一个可以将伺服的角运动转换为腿部线性运动的机械系统。
该机制内含一个弹簧。弹簧的作用是对在打印过程中造成的所有误差进行补偿。另外,弹簧还可以提供更强大的支撑力,从而有助于实现更自然的爬行运动。您可以在任何地方获取弹簧。比如,圆珠笔里的小弹簧就可以用在这里,但是您可能需要稍微修剪一下长度。请确保您所获取的弹簧可以压缩,并且足够支撑机器人的重量。此外,在开始打印零部件之前,请确保弹簧适用于打印好的部件 leg_1和 leg_1_seg_1。
组装
接下来,欢迎进入本文中最难的部分:组装腿部。无论是在构建上还是编程上,这都属于相当高阶的一个项目。我们将假设打算制造这台机器人的人对于使用诸如电钻和烙铁之类的设备具有基本的操作技能。
图1:腿部组装概览
图2:腿部组装细节
图3:组装好的腿部
组装腿部时,请始终记得必须在每两个需要上下移动的塑料件之间放置一个垫圈。您可能需要用电钻调整孔的大小,保证螺栓能够自由旋转。同时,请注意每个螺栓需要两个螺母。
图4:连接腿部关节:塑料件(黑色)和金属件(浅灰色)
这对于保持整个支撑系统的正常工作十分重要。组装腿部时,请确保不要将底部螺母拧得太紧,并调整至使塑料部件仍可以自由移动。然后,顶部螺母要尽可能拧到最紧。底部螺母保证了所有部件的自由移动,而顶部螺母保证了所有部件的紧固连接。如果您的螺母拧的过松,那么腿部会变得非常不稳定;如果拧的过紧,将会对伺服带来不必要的负载。对腿部的调整可能要经过几次尝试才能完成。这是本教程中最重要的部分,因此请确保正确完成此步骤。
伺服通过一个小小的“三角臂”来固定在适当位置,这种三角臂通常用于将伺服齿轮轴连接到您想要移动的任何物体上。但是,在这种情况下,三角臂的位置将会被固定,以便当伺服运转时,它也会自行移动,从而使腿部移动。
请确保您使用的是金属齿轮伺服,而不是塑料齿轮伺服!在这种应用中如果使用塑料齿轮,不仅强度比金属的低,而且其齿轮也可能会很快就损坏。
图5:伺服附件细节。确保三角臂固定在适当位置。
伺服支架分为三部分,使其更易于打印。假设零部件是用丙烯晴丁二烯苯乙烯(ABS)打印的,那么可以使用丙酮来稍微溶解ABS,然后将这三部分粘在一起,再使其变干。或者,如果您有条件使用更高质量的3D打印机,也可以一次性打印出整个部件。
图6:伺服支架组装细节
六足机器人的剩余部分就没有那么复杂了:机身身体由两块板组成,我们可以在其上安装所需的所有电子设备、电池和传感器。您可以在打印之前设定好用于安装电子设备的孔,也可以在打印之后再钻孔。所有零部件和打印说明均可在 Github上获取。
图7:组装好的身体:“A”为上板,“B”为底板。您还可以看到安装在伺服上的超声波传感器。
成功!到这里,您已经完成了机器人的组装,完成了本教程中最困难的部分。如果出现了什么问题,请不要担心,再次进行尝试。如有必要,请尝试对打印件进行微调,然后查看是否有效。
接线
到目前为止,这是最简单的部分了,因为我们将使用 Adafruit PWM扩展板来完成大部分工作。我们把扩展板连接到 Arduino,然后把伺服连接到扩展板。如果您使用的模块无法直接连接到 Arduino,只需要将SDA、SCL以及 V+连接到 Arduino相应引脚即可(详细信息请参见下图)。
您可能已经注意到了,这里有一个放置电容器的位置,但是却没有电容器。不用担心,这是有意为之!当许多伺服同时运转时,电流峰值将达到几安培。电容器将用来消除这些尖峰。您可能需要这种电容器来确保所有伺服的电源稳定。对于这种目的,使用电解电容器是最合适的,但是对电容值的选择更多的是凭借猜测,而不是确切的科学计算。通常来说,电容值越大越好。电容器的电压应略高于电池电压,因此,如果使用6V电池为所有伺服供电,那么6.3V 4700µF应该可以满足需求。
图8:接线图
在扩展板上,您还会注意到有一个单独的电源端子。那是因为 Arduino本身无法提供足够的电流来一次运行一个以上或两个以上的伺服,需要将电池连接到此端子以及 Arduino电源输入端(VIN和GND引脚)。
就是这样,基本的接线已经完成!如果需要,您还可以添加更多模块和传感器,例如超声波测距仪。
图9:接线细节:建议将所有连接到同一条腿上的伺服的电缆困扎在一起。这样,您将就知道哪条电缆通向哪个伺服。而且,这样看起来也会比一团缠结的线缆更美观一些。
图10:带有 HC-SR04超声波传感器的接线图
在本教程中,我将添加一个超声波传感器,以使机器人能够在附近有障碍物的情况下移动。我之所以选择 HC-SR04,是因为它们非常便宜,并且易于与 Arduino一起使用。而且,这种特定传感器的形状类似于眼睛,您可以借此来分辨出机器人在看什么!
我将传感器安装在一个额外的伺服上(有关安装细节请参见图7)。对该传感器进行接线也非常简单,只是请注意不要将VCC引脚直接连接到电池上!如果您使用的是6V电池,这样连接可能会损坏传感器。将VCC引脚连接到 Arduino 5V输出端,并将GND连接到GND。您可以将TRIG和ECHO引脚连接到剩下的任何数字引脚上,但要记得在代码中对它们进行适当设置。我将它们连接到引脚3(TRIG)和引脚2(ECHO)上,因为我想在需要串行端口的情况下保持引脚0和1断开。
结论
现在,您应该已经完成了所有硬件的组装。接通电源之前,强烈建议您对所建立的每个连接进行测试和确认。
希望您到目前为止没有遇到很棘手的问题。如果您对该设计有任何改进的建议,请在 Github上与我交流!请继续关注本项目的第二部分,我们将进入到下一阶段,进一步研究分析逆动力学,并且对这个神奇的 Arduino六角机器人(或者Ardupod )进行编程。
接下来您将看到的是 ArduPod一次伸展所有腿部!
第二部分:编程
在本项目的第二部分中,我们将继续进行项目中相对容易的内容—编程。对六足机器人进行编程通常有两种不同的方法。第一种是仅仅弄清楚机器人向前行走的一系列伺服运转。显然,这是一个艰难却鲜见成效的工作—您所设计的代码无法直接应用于另一台六足机器人上。所以第二种被称为逆运动学的方法应运而生。但是首先,我们需要改进板载微控制器。
硬件
- • Arduino Mega
- • Adafruit 16通道PWM扩展板(或模块;但是,此处强烈建议使用该扩展板,因为它的原型面积很小)
- • 12个带有金属齿轮的微型伺服(MG90S或其他同等规格产品)
- • 4.8V或6V电池(镍氢、锂离子等)
- • 60个M3螺栓+120个螺母和垫圈(仅用于身体,对于其他部件的安装您需要再另外添加)
- • 6个相同的圆珠笔弹簧
- • HC-SR04超声波测距模块(可选)
软件
- • Arduino IDE
- • Github (https://aiqianji.com/openoker/ArduPod)– 您在这里可以找到所有用于打印的 Arduino源代码和3D模型
UNO -> Mega
在上一篇文章中,我们建议在本项目中使用Arduino UNO。但是,在使用UNO时我遇到了一个问题:它没有足够的SRAM内存来进行逆运动学模型正常运行时所需的所有计算。这些计算大多数是用浮点数来完成的。每个数字在使用时将占用4个字节的内存,是整型的两倍。虽然看起来不多,但是UNO只有2kB的RAM,其中一些还会被全局变量占用。如果我们为所有全局变量和其他局部变量保留0.5kB,那么将剩下1.5kB的可用内存,这仅能供384个浮点数占用。384可能看起来挺多,但是对于1K模型所产生的数据量是不够的(请阅读下面的“算法”部分找到相关原因)。所以我们必须想办法获取更大的内存。
实现该目的最简单的办法是将UNO更改为MEGA。MEGA和UNO是兼容的,所以对于原理图不用进行修改。另外,使用MEGA不仅可以为计算部分获取四倍多的RAM,还意味着将有八倍以上的闪存可用于我们的程序存储。我们很可能不会所有都用到,但是有更大的预留空间总是好的。以下是改进后的Fritzing原理图,如果您使用的是Arduino MEGA最新版本 (Rev 3),更换的过程很简单,跟断开UNO之后连接MEGA的过程一样。下面示意图以供参考。
图1:PWM扩展板改进后原理图
图2:PWM模块和HC-SR04超声波传感器改进后原理图
现在,我们来探究一些物理原理、所用到的大量数学知识以及少量代码。
逆运动学简介
可能有些人还记得,在高中的时候,物理课中有一部分内容叫做“运动学”。简单地说,这是力学领域中对一个目标对象(或一个点)运动的描述。这意味着在运动学中,您将使用数学公式和模型来对单个点的已知运动进行分析。顾名思义,逆运动学(IK)恰恰相反:通过一系列数学公式来反推并创建运动。
在机器人领域,通常使用的算法只能根据相应的端点运动来计算所有关节的运动。现在,您可以清楚地看到逆运动学在伺服运动编程部分的难题上所具有的优势——它是可以通用的。从理论上来说,仅一个算法就可以处理机器人所执行的任何运动。从使用者的角度来说,它非常易于使用—您只需要告诉机器人向左转90°,然后直行1米就可以了,而不必考虑每个伺服的位置。
模型
在以上段落中,一个词不断出现:一个(数学)模型。虽然听起来很难,但是对于六足机器人这个项目来说,模型非常简单:机器人能够机械性的所达到的任何位置都可以由一组七个点来定义。一个用于身体,另外六个用于腿部。如果您查看了AP_Utils库(可在AI千集上获取 https://aiqianji.com/openoker/ArduPod),特别是里面的AP_Utils.h,就会看到关于这些点的定义(包含在其他内容中):
struct body {float x;float y;float z;float facing;};
struct leg {uint8_t number;bool move;float phi;float z;};
您可以看到在AP_Utils类中它们被声明为私有结构。
body origin;leg legs[6];
将这些结构私有化有以下两个原因:
- 用户不应具有随意修改这些值的权限。这些结构的存在是为了追踪机器人的当前位置,因此,只有当机器人真正产生运动的时候这些结构才会发生变化。假如用户想要更改当前的原点的 z 坐标,会导致IK模型发生不可预测的变化—这显然是不可取的。
- 通常,将共有函数和一个类中的变量数量控制到最低,是一种良好的编程习惯(尤其在C++中)。因此这样做可以提高安全性,并利于API的轻松实现。
如果需要,我们可以将这些点可视化。现在,我们的整个机器人由七个点来表示(图3)。
图3:IK模型的图形表示。简而言之,这就是六足机器人“认为”它所看起来的样子。红点是身体,蓝点是腿。
这些结构用于追踪所有腿部的位置以及机器人本身的位置。您可能注意到了,腿部的位置仅由两个坐标来定义:phi 和 z。这是因为每条腿只有两个自由度,因此只能沿着两个轴进行移动。现在可以通过身体的x、y 和 z 坐标来对所有位置进行定义。每条腿的* phi* 和 z 坐标的范围是-1到1,并且仅确定了腿相对于身体的位置。尽管现在来看这种复杂性似乎是不必要的,但是实际上这比每次运动后计算每条腿的 x、y 和 z 坐标容易得多。phi 坐标表示水平运动,z表示垂直运动。
图4:带有phi轴和z轴的腿部细节
算法
现在,我们对于机器人有了足够简单的数学表达,但是还没有用它来做任何事。下一步就是研究如何通过仅仅修改该模型来实现伺服的运转。我们需要完成的程序是将输入作为一组点坐标,并将其转换为伺服的运行。
这时候另一个问题就出现了,而这次,仅仅替换成另一个Arduino无法解决。当启动伺服时,我们可能需要使大部分伺服同时运转。但是,Arduino(以及所有与此相关的AVRs)一次只能执行一项任务。这意味着如果我们如果想平稳地运转伺服,就需要一个一个进行启动。如果仅仅将伺服从一端直接运转到另一端,整个过程将非常不稳定。
解决该问题的一种方法是事先计算好所有伺服的位置,然后迭代这些数据,并对所有伺服进行设置。因为Arduino MEGA的时钟频率是16MHz,所以所有伺服虽然在实际过程中以很小的增量进行离散化运转,但是整体表现出来的运行过程是连续流畅的。尽管它们只是静态图像的集合,但是这和视频中所产生的连续运动的效果一致。人脑无法对视觉信息进行快速处理。如果我们在每一次位置变换之后添加一个50毫秒的延迟,则很明显,伺服运转实际上是由小的增量所组成的。
这也是我们必须更换Arduino的原因。如果我们想要运行每一个伺服,那么我们需要大量的内存来存储刚刚所计算出的坐标。如果我们运转所有的伺服,我们将需要600个浮点数来存储运动坐标,因为每个伺服都至少需要50个位置才能产生平滑连续的运转效果。600个浮点数大约是 2.3 kB的RAM—这已经超过了UNO的容量。
在AP_Utils库中,将位置转换为伺服运转状况的是traceLeg() 和 setLegs() 函数。traceLeg() 函数仅进行计算:当提供了目标末端的 *phi *和 z 坐标时,它将以坐标数组的形式创建一个路径。路径可以具有多种形状,当前支持的是线形(从一个点到另一个点的简单直线)、圆弧和椭圆弧。后两种路径可以使步行变得更加容易。第二种函数 setLegs() 将根据 traceLeg的结果来移动所有指定的支腿,但是,所有这些对常规用户是隐藏的。整个方案的重点是尽可能地方便用户使用。最终用户将无需直接设置 setLegs() ,而仅需调用与行走直接相关的函数即可。
现在我们开始进入IK编程的最后一步,即真正的行走。我们已经完成了所有基础工作:我们创建了一个模型来对所有事物进行追踪,我们可以运行多个伺服,甚至可以使伺服的运转变得相对平滑连续。在以下内容中,支腿的编号与下图中的编号相对应:
图5:支腿编号
该编号系统同时与您在库中找到的代码一致。
我们先从简单的操作开始:在场地上转向。通常,在为支腿设定新的位置时,您必须保证其中三条腿在地面上。这背后的原因很明显—除非您可以非常快地移动支腿,不然机器人将失去稳定性并跌倒。我们可以分几步使机器人转向:
1. 将支腿0、2和4移动到phi 坐标最大值处(最大水平角)。
图6:转向步骤1(支腿0、2和4)
2. 对支腿1、3和5进行相同操作。
图7:转向步骤2(支腿1、3和5)
3. 身体转向。这一步是通过沿与步骤1-3中相反的方向运行所有水平方向的伺服来完成的。因为所有的支腿都在地面上且不能移动,所以可以移动的只有身体。
图8:转向步骤3
对这些步骤进行重复执行后,机器人可以转弯80°。当然,只要不是在过程中一直保持 *phi *轴最大坐标位置,可以实现小于该角度的转向。得益于 traceLeg() 函数背后的巧妙算法,我们不必计算支腿的任何 z 坐标值—这些计算会自动进行,并形成圆或椭圆的形状。您可以在以下视频中观察到这一过程。
最后一步是行走。具体来说,我们希望它至少能向前行走。六足机器人的行走算法有很多种,但大多数算法都基于有三个自由度的支腿。我们的支腿只有两个自由度,因此我们必须自己进行一些设计。我所提出的方法虽然没有达到预期的速度,但是这种方法是最易于编程的,并且易于观察过程中的现象。
1. 首先,支腿0和3向前移动
图9:行走步骤1(支腿0和3)
2. 然后,支腿2和5向相同方向移动
图10:行走步骤2(支腿2和5)
3. 对支腿1和4进行相同操作
图11:行走步骤4(支腿1和4)
4. 现在,身体移动向前,开始重复执行整个过程。
图12:行走步骤4
基本避障功能
您可能已经注意到了,库中有一部分专门用于SR04超声波测距仪。这是为了获取有关机器人所处环境的一些信息。当然,一个固定不动的传感器是不够的,因此在上一篇文章中我们在一个额外的伺服上也安装了一个传感器。
我相信大多数尝试制造六足机器人的人对超声波测距仪的工作原理是有一定程度了解的。对于与该传感器的接口我建议您使用 AP_Utils::sr04_median 函数。它可以提供库中所有SR04函数最准确的结果。您甚至可以输出数据的单位,目前可以支持毫米、厘米和米!
重要提示: 请注意,您需要Adafruit PWM驱动程序库来使AP_Utils运行,您可以点击此处(https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library)下载。下载完成后,和其他Arduino库一样对其进行安装。
以下是一个非常简单的“自主”模式的示例,使用了到目前为止我们所讨论的所有内容:行走、转向和从SR04中读取距离。如果您认真阅读了这篇文章,那么应该能完全理解以下代码中最重要部分的内容。
Arduino 代码
#include <AP_Utils.h>
//define the pins that the SR04 is connected to
#define TRIG 3
#define ECHO 2
//create an instance of AP_Utils class
AP_Utils ardupod;
//you will have to supply your own offsets here
//see examples/calibration.ino for details
int offsets[16] = {5, 0, 0, -7, 10, -3, 6, -4, 3, -5, 10, -3, 0, 0, 0, 0};
void setup() {
//reset the robot
ardupod.begin(offsets);
}
void loop() {
//take one step directly forward
ardupod.walk(0, 1);
//if an obstacle is closer than 20 cm, we have to turn
if(sr04_median(TRIG, ECHO, CM, 100, 500) < 20.0) {
//turn 90 degrees to the right
ardupod.turn(90);
}
}
结论
恭喜您完成了这个最具挑战性的项目之一!做得很好!在尝试使您自己的Ardupod行走之前,请确认同时运行示例文件夹中的 calibration.ino 和 servo_test.ino。这对于正确设置所有伺服至关重要,这样伺服才不会被损坏!在下一篇文章中,我们可能对此项目进行最后一次探索,以对一些机械性能较差的点进行改善,以及,更重要的是,增加一些改进的功能,例如远程控制。
第三部分:远程控制
在本系列的第三部分也就是最后一部分,我们将为机器人添加最后一个部件:遥控器。此外,我们对支脚进行了一些细微的改进,使它们能够在任何类型的基底表面都能更加稳定。首先,我们会介绍经过细微修改的支腿机制,然后将HC-05蓝牙连接到Arduino以实现无线控制。最后,我们将编写一个Processing应用程序,这样我们就不必为ArduPod的每次移动使用书面指令了。
硬件
- • 第一部分获得的六足机器人
- • HC-05 蓝牙模块
- • 1 kΩ 电阻和 1.8 kΩ (or 2.2 kΩ) 电阻
软件
- • Arduino IDE
- • Processing 3.2.3
- • GitHub – 包含最新源代码
- • Release 1.0.0 – 或者,您可以在此处下载v1.0.0的源代码。如果GitHub上的代码有重要的API破坏性更新,这些代码仍然可以像本文描述的那样运行。
工具
- • 烙铁
改善支腿
我自己制造六足机器人的时候,面临的最大难题是支腿在光滑表面上很不稳定。通常,在支腿上添加某种防滑材料就可以很轻松地解决这个问题。但是,这个机器人的支腿与地面间的接触面积太小了。增大支腿与地面的接触面积对防滑效果大有帮助,同时还能改善支腿的整体稳定性。
图1:旧的支腿(左)和新的支腿(右)
在上图