-
Notifications
You must be signed in to change notification settings - Fork 0
/
daemon.py
executable file
·353 lines (291 loc) · 8.56 KB
/
daemon.py
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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
#!/usr/bin/python3
import os, time
import warnings
import evdev
import gpiozero
import rovercom
import hbridge
import servo
hasvision = False
import vision
thisfilepath = os.path.dirname(__file__)
# Global Autopilot bool:
autopilot = False
# steering var:
# -1 = steering left
# 0 = steering center
# 1 = steering right
steering = 0 # (center)
laststeering = 0 # used to detect steering changes
steering_servo = gpiozero.Servo(27)
# throttle var:
# full throttle in reverse = -100
# stopped = 0
# full throttle forwards = 100
throttle = 0
hasDistanceSensor = False
distance_sensor = None
obj_dist = -1
#try:
distance_sensor = gpiozero.DistanceSensor(echo=17, trigger=4, max_distance=4, partial=True)
for x in range(1, 8):
print(distance_sensor.distance)
time.sleep(1)
if int(distance_sensor.distance * 100) > 0:
print('Distance sensor activated.')
hasDistanceSensor = True
break
#except:
# hasDistanceSensor = False
# print('No distance sensor found. Disabling ultrasonic features...')
hasGameController = False
game_controller = None
devices = [evdev.InputDevice(fn) for fn in evdev.list_devices()]
for thisdev in devices:
if 'gamepad' in lower(device.name):
game_controller = evdev.InputDevice(thisdev.fn)
hasGameController = True
start_time = time.time()
status = rovercom.status_fifo()
def checkforvisioncommand():
# 0 forward
# 1 left
# 2 right
nn_result = vision.get_next_decision()
if nn_result == 0:
return 'steer center'
elif nn_result == 1:
return 'steer left'
elif nn_result == 2:
return 'steer right'
# unexpected result from artificial neural network--return ''
return ''
def checkgamepad():
global game_controller
ev = game_controller.read_one()
# no event in queue:
if ev == None:
return None
# debug for now:
print('New bluetooth game controller event:')
print('Type' + str(ev.type))
print('Code' + str(ev.code))
print('Value' + str(ev.value))
key = ''
if key == 'up':
return 'move forward'
if key == 'down':
return 'move backwards'
if key == 'up left':
c = []
c.append('move forward')
c.append('steer left')
return c
if key == 'up right':
c = []
c.append('move forward')
c.append('steer right')
return c
if key == 'down left':
c = []
c.append('move backwards')
c.append('steer left')
return c
if key == 'down right':
c = []
c.append('move backwards')
c.append('steer right')
return c
def checkultrasonic():
global start_time
global hasDistanceSensor
global throttle
global obj_dist
if (time.time() - start_time) < 1:
return
if hasDistanceSensor == True:
obj_dist = round(distance_sensor.distance * 100)
#print(obj_dist)
else:
obj_dist = 400
start_time = time.time()
if obj_dist <= 200 and obj_dist > 100:
# slow down
if throttle > 85:
return 'throttle ' + str(85)
elif obj_dist <= 100 and obj_dist > 75:
# slow down more
if throttle > 75:
return 'throttle ' + str(75)
elif obj_dist <= 75 and obj_dist > 50:
# crawl
if throttle > 60:
return 'throttle ' + str(60)
elif obj_dist <= 50:
# zero throttle (temp stop)
return 'throttle ' + str(0)
return None
def processacommand(cmd):
global throttle, steering, hasDistanceSensor, autopilot
lcmd = cmd.lower()
args = cmd.split()
largs = lcmd.split()
# logic for processing commands (add new ones here):
if lcmd == 'quit':
exit()
if lcmd == 'poweroff':
print('Powering off--good bye!')
os.system('poweroff')
if lcmd == 'stop':
print('stop')
# stop resets steering and sets throttle to zero:
steering = 0
throttle = 0
return
if lcmd == 'hard stop':
# emergency stop
c = []
c.append('throttle -75')
c.append('wait 1')
c.append('stop')
processcommand(c)
if largs[0] == 'wait':
if len(args) > 1:
time.sleep(args[1])
else:
time.sleep(1)
if largs[0] == 'move':
if len(args) > 1:
if largs[1] == 'left':
print('move left')
throttle = 75
steering = -1
elif largs[1] == 'forward':
print('move forward')
throttle = 100
#steering = 0
elif largs[1] == 'right':
print('move right')
throttle = 75
steering = 1
elif largs[1] == 'backwards':
print('move backwards')
throttle = -100
#steering = 0
return
if largs[0] == 'steerval':
if len(args) > 1:
print('steerval ' + args[1])
steering = int(args[1])
if largs[0] == 'steerdeg':
if len(args) > 1:
print('steerdeg ' + args[1])
steering = servo.deg_to_val(int(args[1]))
if largs[0] == 'steer':
if len(args) > 1:
if largs[1] == 'left':
print('steer left')
steering = -1
elif largs[1] == 'center':
print('steer center')
steering = 0
elif largs[1] == 'right':
print('steer right')
steering = 1
return
if largs[0] == 'throttle':
if len(args) > 1:
print('Setting throttle to ' + args[1])
throttle = int(args[1])
return
if largs[0] == 'disable':
if largs[1] == 'distancesensor':
print('distance sensor disabled')
hasDistanceSensor = False
if largs[0] == 'slow':
if largs[1] == 'down':
throttle = throttle - 10
if throttle < 0:
throttle = 0
if largs[0] == 'speed':
if largs[1] == 'up':
throttle = throttle + 10
if throttle > 100:
throttle = 100
if largs[0] == 'increase':
if largs[1] == 'throttle':
throttle = throttle + 10
if throttle > 100:
throttle = 100
if largs[0] == 'decrease':
if largs[1] == 'throttle':
throttle = throttle - 10
if throttle < -100:
throttle = -100
if largs[0] == 'autopilot':
if largs[1] == 'on':
autopilot = True
print('autopilot on')
elif largs[1] == 'off':
autopilot = False
print('autopilot off')
def processcommand(cmd):
if cmd == None:
return
cmds = []
if isinstance(cmd, str):
cmds.append(cmd)
for thiscmd in cmds:
processacommand(thiscmd)
def do_init():
rovercom.init_fifos()
print('Rover Daemon')
hbridge.motor_off()
hbridge.set_throttle(0)
print('Init complete.')
def mainloop():
global hasDistanceSensor, obj_dist, throttle, steering, laststeering, autopilot
laststatus = None
while (1):
cmd = rovercom.checkforcommand()
if cmd == '':
time.sleep(.25)
else:
#print('Received command: ' + cmd)
processcommand(cmd)
# check distance senor (if equipped)
if hasDistanceSensor == True:
processcommand( checkultrasonic() )
# game controller (if equipped)
if hasGameController == True:
processcommand( checkgamepad() )
if autopilot == True:
vcmd = checkforvisioncommand()
#print(vcmd)
processcommand(vcmd)
# control motor:
hbridge.set_throttle(throttle)
# set steering:
if steering != laststeering:
servo.set_steering_servo_val(steering_servo, steering)
laststeering = steering
# build status
curstatus = ''
c90 = round(steering)
if c90 == -1:
curstatus = '<- '
elif c90 == 0:
if throttle < 0:
curstatus = '\/ '
elif throttle > 0:
curstatus = '/\ '
elif c90 == 1:
curstatus = '-> '
curstatus += 's_' + str(throttle) + '%'
curstatus += ' d_' + str(obj_dist)
if laststatus != curstatus:
status.setstatus(curstatus)
laststatus = curstatus
if __name__ == '__main__':
do_init()
mainloop()