用树莓派DIY六足行走的机器人

目前用 Arduino、树莓派做小车、无人机、机器人的不少。趣无尽分享一款在由Roland Pelayo做的一个“六足行走机器人”。这个树莓派动力机器人能自主运行,自动避障,且也能实现手动模式由智能手机控制。 来具体看下过程。

“六足行走”Hexapod Walker概念

这个六足行走者(Hexapod Walker)将遵循大多数动物和昆虫使用的三脚架步态。三脚架步态如下图所示:

Image courtesy of NC State University

在六足行走者中有很多方法来使用这种步态。
平衡了价格和性能后,我选择构建一个三伺服电机版本。然后我添加了另一台伺服电机,用于安装机器人的“眼睛”。
机器人将有三个运动:前进,后退,右转,左转。
任何运动都会涉及机器人向右或向左倾斜,然后移动由倾斜抬起的腿部。
以下是运动的图表(腿上的灰色意味着机器人的重量在该腿上)。



右转运动基本和左转运动相反。
为了使三伺服电动机设计成为可能,在第三伺服电机倾斜步行者的同时,前后相应的后腿需要互连。

这种六足步行者可以在两种模式下操作:
在第一种模式(自主)中,步行者可以自由漫游。如果它检测到障碍物,它将向后退两步,然后向右转。
第二种模式将允许用户使用连接到与机器人相同网络的任何智能电话来控制六足步行者的移动。
根据我的设计要求,我需要一个控制器,能够做到
1)可以同时控制四个伺服器
2)从障碍物检测传感器读取输入
3)连接到一个网络进行无线控制。

创建Arduino 六足步行者是诱人的也更容易,但要增加的无线连接成本,所以我决定用树莓派。
这是我设计的框架:

所需材料
在决定要使用的控制器之后,需要选择其余的组件。
Tower Pro SG-5010伺服电机(用于腿部和倾斜)x3
Tower Pro SG-90微型伺服电机(头部)x1
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)

	time.sleep(0.00001)

	GPIO.output(trig,0)

	

	while GPIO.input(echo) == 0:

		pulse_start = time.time()

	

	while GPIO.input(echo) == 1:

		pulse_end = time.time()



	pulse_duration = pulse_end - pulse_start

	

	distance = pulse_duration * 17150

	

	distance = round(distance, 2)

	

	if distance > 1 and distance < 35:

		obstacleDetected()

	else:

		forward()

		forward()

		forward()

	

	pi.set_servo_pulsewidth(head, 2100)

	time.sleep(0.5)

	return

	

def manualMode():

	

        move = str(sys.argv[2])



        if move == "F" or move == "f":

		print("Moving forward!")

		forward()

	elif move == "B" or move == "b":

		print("Moving backward!")

		backward()

	elif move == "L" or move == "l":

		print("Moving left!")

		left()

	elif move == "R" or move == "r":

		print("Moving right!")

		right()

	else:

		print("Invalid argument!")

	

	return

	

def main():

	opt = str(sys.argv[1])

	

	if opt == "A" or opt == "a":

		autoMode()

	elif opt == "M" or opt == "m":

		manualMode()

	

	return

		

while True:

	main()



GPIO.cleanup()

pi.stop()



你可以通过终端指令测试机器人的控制,例如让它向前行走可以用

python hexapod.py m f

当然正式使用是需要用手机控制的,在 Apache 上部署我写好了程序吧,访问我的 Github 获取。以下是WebUI的截图:

如何操作

  1. 找到树莓派的IP地址。
  2. 用手机浏览器访问这个IP,例如192.168.1.90/hexapod
  3. 使用WebUI操控机器人

Enjoy!

via

这是一篇发布于 7年 前的文章,其中的信息可能已经有所发展或是发生改变,请了解。


9 评论

发表评论

你的邮件地址不会公开


*