目前用 Arduino、树莓派做小车、无人机、机器人的不少。趣无尽分享一款在由Roland Pelayo做的一个“六足行走机器人”。这个树莓派动力机器人能自主运行,自动避障,且也能实现手动模式由智能手机控制。 来具体看下过程。
这个六足行走者(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 是一个用于控制伺服电机的 Python 库,用 SSH 连接到树莓派安装它。
1
2
3
4
5
|
wget http: //abyz .co.uk /rpi/pigpio/pigpio .zip unzip pigpio.zip cd PIGPIO make sudo make install |
Pigpio 运行于后台,在使用 Pigpio 前,你需要先运行。
1
|
pigpiod |
设置 contrab:
1
|
sudo crontab -e |
在末尾添加
1
|
@reboot /usr/local/bin/pigpiod |
安装 apache for the Raspberry Pi 用于 WiFi 控制:
1
|
sudo apt-get install apache2 -y |
会创建一个目录 /var/www/html/,包含了控制页面。你可以用浏览器连接到树莓派了。RPi rover robot 可以让你在手机上控制树莓派。
以下是机器人控制程序。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
|
#!/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() |
你可以通过终端指令测试机器人的控制,例如让它向前行走可以用
1
|
python hexapod.py m f |
当然正式使用是需要用手机控制的,在 Apache 上部署我写好了程序吧,访问我的 Github:https://github.com/kurimawxx00/raspberry-pi-hexapod-walker 获取。以下是WebUI的截图:
Enjoy!