本文分享一款在由Roland Pelayo做的一个“六足行走机器人”。这个树莓派动力机器人能自主运行,自动避障,且也能实现手动模式由智能手机控制。 来具体看下过程。
“六足行走”Hexapod Walker概念
这个六足行走者(Hexapod Walker)将遵循大多数动物和昆虫使用的三脚架步态。三脚架步态如下图所示:
Image courtesy of NC State University
在六足行走者中有很多方法来使用这种步态。
平衡了价格和性能后,我选择构建一个三伺服电机版本。然后我添加了另一台伺服电机,用于安装机器人的“眼睛”。
机器人将有三个运动:前进,后退,右转,左转。
任何运动都会涉及机器人向右或向左倾斜,然后移动由倾斜抬起的腿部。
以下是运动的图表(腿上的灰色意味着机器人的重量在该腿上)。
右转运动基本和左转运动相反。
为了使三伺服电动机设计成为可能,在第三伺服电机倾斜步行者的同时,前后相应的后腿需要互连。
这种六足步行者可以在两种模式下操作:
在第一种模式(自主)中,步行者可以自由漫游。如果它检测到障碍物,它将向后退两步,然后向右转。
第二种模式将允许用户使用连接到与机器人相同网络的任何智能电话来控制六足步行者的移动。
根据我的设计要求,我需要一个控制器,能够做到
1)可以同时控制四个伺服器
2)从障碍物检测传感器读取输入
3)连接到一个网络进行无线控制。
创建Arduino 六足步行者是诱人的也更容易,但要增加的无线连接成本,所以我决定用树莓派。
这是我设计的框架:
所需材料
在决定要使用的控制器之后,需要选择其余的组件。
3 x Tower Pro SG-5010伺服电机(用于腿部和倾斜)
1 x Tower Pro SG-90微型伺服电机(头部)
1 x Raspberry Pi 2 (带USB WiFi加密狗 )或Raspberry Pi 3
HC-SR04超声波传感器 – 这是障碍物检测传感器。
压克力板
1/2“x 1/8”铝棒
螺丝和螺母
电池。伺服应该有和树莓派有不同的电源,我的树莓派用了个小充电宝。
开始我们的教程
六足机器人主要由三个部分构成:主体(平台),行走足以及头部。
搭建平台
H这是一个可用于构建步行者身体的示例布局。我用亚克力板作为我的平台。腿的细节如下。
接腿
这是一个腿的布局。我使用了1/2″ x 1/8 ″的铝条。
腿应该足够坚硬,以支撑六足步行者的重量。请不要塑料!
这是倾斜的腿:
安装树莓派和头部
我在亚克力板上打了孔,然后用螺丝和螺母连接树莓派。
头部由超声波传感器和连接到电路板的微型伺服电机组成。我用热胶将微型伺服与传感器连接起来:
看下腿部运动细节:
连线
以下是我连接对应表:
tilt servo - > GPIO4
right leg -> GPIO21
left leg -> GPIO6
head -> GPIO26
HC-SR04 trigger - > GPIO23
HC-SR04 echo - > GPIO24
因为树莓派的GPIO不能接受大于3.3V的电压,所以需要为树莓派的回波连接添加一个分压器。
我还添加了一个带有公头和母头的电路板,使接线更清洁。
这是全组合六足步行者:
软件
Pigpio 用于伺服控制
Pigpio 是一个用于控制伺服电机的 Python 库,用 SSH 连接到树莓派安装它。
wget http://abyz.co.uk/rpi/pigpio/pigpio.zip
unzip pigpio.zip
cd PIGPIO
make
sudo make install
Pigpio 运行于后台,在使用 Pigpio 前,你需要先运行。
pigpiod
设置 contrab:
sudo crontab -e
在末尾添加
@reboot /usr/local/bin/pigpiod
Apache 用于服务端
安装 apache for the Raspberry Pi 用于 WiFi 控制:
sudo apt-get install apache2 -y
会创建一个目录 /var/www/html/,包含了控制页面。你可以用浏览器连接到树莓派了。RPi rover robot 可以让你在手机上控制树莓派。
Python 程序
以下是机器人控制程序。
#!/usr/bin/python
import RPi.GPIO as GPIO
import pigpio
import time
import sys
import os
import signal
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
tilt = 4
br = 21
bl = 6
trig = 23
echo = 24
head = 26
GPIO.setup(trig, GPIO.OUT)
GPIO.setup(echo, GPIO.IN)
pi = pigpio.pi()
def backward():
pi.set_servo_pulsewidth(tilt, 800)
time.sleep(0.15)
pi.set_servo_pulsewidth(bl, 800)
time.sleep(0.15)
pi.set_servo_pulsewidth(tilt, 2000)
time.sleep(0.15)
pi.set_servo_pulsewidth(br, 1800)
time.sleep(0.15)
pi.set_servo_pulsewidth(tilt, 1500)
time.sleep(0.15)
pi.set_servo_pulsewidth(bl, 1500)
time.sleep(0.15)
pi.set_servo_pulsewidth(br, 1500)
time.sleep(0.15)
return;
def forward():
pi.set_servo_pulsewidth(tilt, 800)
time.sleep(0.15)
pi.set_servo_pulsewidth(bl, 1800)
time.sleep(0.15)
pi.set_servo_pulsewidth(tilt, 2000)
time.sleep(0.15)
pi.set_servo_pulsewidth(br, 800)
time.sleep(0.15)
pi.set_servo_pulsewidth(tilt, 1500)
time.sleep(0.15)
pi.set_servo_pulsewidth(bl, 1500)
time.sleep(0.15)
pi.set_servo_pulsewidth(br, 1500)
time.sleep(0.15)
return;
def left():
pi.set_servo_pulsewidth(tilt, 800)
time.sleep(0.15)
pi.set_servo_pulsewidth(bl, 1800)
time.sleep(0.15)
pi.set_servo_pulsewidth(tilt, 2000)
time.sleep(0.15)
pi.set_servo_pulsewidth(br, 1800)
time.sleep(0.15)
pi.set_servo_pulsewidth(tilt, 1500)
time.sleep(0.15)
pi.set_servo_pulsewidth(bl, 1500)
time.sleep(0.15)
pi.set_servo_pulsewidth(br, 1500)
time.sleep(0.15)
return;
def right():
pi.set_servo_pulsewidth(tilt, 800)
time.sleep(0.15)
pi.set_servo_pulsewidth(bl, 800)
time.sleep(0.15)
pi.set_servo_pulsewidth(tilt, 2000)
time.sleep(0.15)
pi.set_servo_pulsewidth(br, 800)
time.sleep(0.15)
pi.set_servo_pulsewidth(tilt, 1500)
time.sleep(0.15)
pi.set_servo_pulsewidth(bl, 1500)
time.sleep(0.15)
pi.set_servo_pulsewidth(br, 1500)
time.sleep(0.15)
return;
def stop():
pi.set_servo_pulsewidth(tilt, 0)
time.sleep(0.15)
pi.set_servo_pulsewidth(bl, 0)
time.sleep(0.15)
pi.set_servo_pulsewidth(br, 0)
time.sleep(0.15)
return
def obstacleDetected():
backward()
backward()
backward()
backward()
backward()
right()
right()
right()
return
def turnHead():
pi.set_servo_pulsewidth(head, 700)
time.sleep(0.5)
pi.set_servo_pulsewidth(head, 2100)
time.sleep(0.5)
pi.set_servo_pulsewidth(head, 1500)
time.sleep(0.5)
return
def autoMode():
print ("Running in auto mode!")
turnHead()
time.sleep(0.5)
GPIO.output(trig, 0)
time.sleep(0.5)
GPIO.output(trig,1)