就在两年或者是一年前,还为网络上的机器人作品,羡慕不已,希望自己马上照着做一个,到底如何方便高效地去实现这些作品,是每个机器人爱好者都需解决的问题。看过了美国科教纪录片,其中有个台词:“打开您邻居的车库,看看里面有什么,一定有惊奇的发现!”是啊,发达国家科技迷们的车库里有小型数控机床、线切割机、折板机、电钻和虎钳,还有自制土火箭以及即将完工的喷火怪兽。我们是否有车库都是个问题,更不用说车库有什么。但是我们每个人都爱上制作,都有一张写字台,在这张写字台上,我们也可以制作机器人。于是我就在自己的桌子上制作了机器宠物,用的是乐高积木块和DFRobot公司的Arduino电控模块,对了,还有几颗自攻螺钉。写完这篇博客,会把这个作品拆掉,再利用这些积木,制作下一个作品,不断体验着科技带来的愉悦。
这个机器宠物有三个180度舵机提供动力,前腿和后腿的舵机一前一后纵向排列,它们的输出轴朝下,带动各自的两个支撑脚摆动。还有一个180度舵机连接在前腿部分和后腿部分之间,提供力矩来扭动步行器的腰部。
步行器宠物,我是“牵”着它,往前走的,我手里拿着Arduino控制器和XBee传感器扩展板,用几个舵机延长线,把控制器与舵机联系起来,再用几个小夹子,把舵机线捆扎在一起。
用乐高科技系列的积木搭建了步行器的机身,感觉还是不够卡通,于是又用乐高“英雄工厂”系列的积木,给步行器的头部和尾部装饰了一下,让人可以依稀感觉出它是什么。
这个机器爬虫的灵感来源于网路上一个机器海龟的作品,也有三个180度舵机驱动,作品的动作和行为也完全一致,所以有大量的网络资源,我们来实现一些机器人作品,应该是不难。但即使这样,每个人带来的作品还是有新意,给人一些不同的启迪。
爬虫结构相对简单,前腿舵机与后腿舵机按相反的方向转动,也就是说,后腿左脚向前时,前腿左脚是向后的。腰部舵机使步行器的身躯偏转到极限位置后,前后腿才同时移动到各自的极限位置,然后腰部舵机又向相反地方向偏转到极限位置,过一小会,前后腿接着也向上一步相反地方向转动到极限位置,以此循环。有趣的是这样重复,居然使爬虫向前走动起来,如果把三个舵机的转动方向的顺序逆向重新排列,爬虫也可以向后走。
#include "Servo.h"
//腰部、前腿、后腿舵机名称申明
Servo waist,front,back;
//舵机初始位置
#define wCenter 100
#define fCenter 100
#define bCenter 100
//舵机转动±范围最大值
#define wSwing 10
#define fSwing 20
#define bSwing 20
//步行器动作编号
#define FORWARD 0
#define BACKWARD 1
#define STOP 2
//舵机实时位置
int wPos,fPos,bPos;
//步行器三个舵机动作循环在时间上分成100个分隔,
int cycle;//舵机动作循环周期的实时分隔值(时间)
int dir;//存储步行器动作编号的变量
long start;//程序开始时的时间起点
//初始化
void setup()
{
//申明舵机连在Arduino控制板的数字端口号
waist.attach(3);
front.attach(10);
back.attach(9);
//舵机实时位置初始化到初始位置
wPos=wCenter;
fPos=fCenter;
bPos=bCenter;
//步行器动作初始化为“FORWARD”
dir=FORWARD;
//动作循环周期的实时分隔值初始化为0
cycle=0;
start=millis();
}
//步行器前进
void doForward(int cycle) {
//动作循环周期为100个时间分隔,一个周期里,有两种舵机动作,
//一是腰部舵机偏转10度,二是前后舵机调试偏转20度,
//腰部舵机先动作,迫使前后腿舵机的对角方向支撑脚抬起,
//然后,前后腿舵机在12或13分隔后同时向相反方向转动,
//从而迈出一个步伐,一个步伐花费25个时间分隔,
//一个循环周期会完成四个步伐,四个步伐花费100个时间分隔。
if (cycle<12) wPos=wCenter+wSwing;
else if (cycle<37) wPos=wCenter-wSwing;
else if (cycle<62) wPos=wCenter+wSwing;
else if (cycle<87) wPos=wCenter-wSwing;
else wPos=wCenter+wSwing;
if (cycle<25) fPos=fCenter+fSwing;
else if (cycle<50) fPos=fCenter-fSwing;
else if (cycle<75) fPos=fCenter+fSwing;
else fPos=fCenter-fSwing;
if (cycle<25) bPos=bCenter-bSwing;
else if (cycle<50) bPos=bCenter+bSwing;
else if (cycle<75) bPos=bCenter-bSwing;
else bPos=bCenter+bSwing;
}
//步行器后退
void doBackward(int cycle)
{
//步行器后退是前进的逆过程
doForward(100-cycle);
}
//步行器停止
void doStop(){
//舵机回到初始位置
wPos=wCenter;
fPos=fCenter;
bPos=bCenter;
}
//步行器更新下一个动作循环
void posUpdate() {
//进入下一个100分隔(时间)
cycle=(cycle+1)%100; // 100 step cycle
//根据具体时间值,确定步行器动作
switch(dir) {
case FORWARD: doForward(cycle); break;
case BACKWARD: doBackward(cycle); break;
case STOP: doStop(); break;
}
}
//主程序
void loop()
{
//更新为下一次动作循环
posUpdate();
//30ms,改变一次舵机的实时位置
waist.write(wPos);
front.write(fPos);
back.write(bPos);
delay(30);
//15s内,步行器前进;
//15s~30s,步行器后退;
//30s~45s内,步行器前进;
//45s~60s,步行器后退;
//程序运行60s后,步行器停止。
long t=millis()-start;
if (t <15000) dir=FORWARD;
else if (t < 30000) dir=BACKWARD;
else if (t < 45000) dir=FORWARD;
else if (t < 60000) dir=BACKWARD;
else dir=STOP;
}
记住,把HS-311舵机的那个输出轴连接器与安装板的输出轴圆盘零件装配好后,要用HS-311舵机的零件袋里的小螺钉把它们紧固起来,这样步行器行走起来,舵机输出轴上的乐高零件就不会脱落了。