-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathJamRacerMain.py
308 lines (255 loc) · 12 KB
/
JamRacerMain.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
#!/usr/bin/env python
"""
Doug Barry 2015-2016
Simple user interface code to control Arexx Dagu i-racer using Raspberry Pi and Wii Balance Board for RaspberryJam at
University of Greenwich Medway campus, Christmas 2015. This work was entirely performed during my own free time.
"""
__author__ = '[email protected] (Doug Barry)'
import time
import pygame
from pygame.locals import *
from JamRacerConfig import *
from InputWiiFitBoard import *
from OutputSphero import *
from OutputiRacer import *
from ObjectMotion import *
from InputXBox360Joypad import *
from Helpers import *
from JamRacerDisplay import *
import logging
from JamRacerJoystickHandler import *
from InputTrustUSBGamepad import *
from InputPyGameGenericJoystick import *
from OutputLegoMindstormsNXT import *
global app
class JamRacerApp(object):
'''Main Application'''
def __init__(self):
self._mydisplay = None
self._configuration = None
self._joystick_handler = None
self._controllers_wiifitboard = []
self._controllers_joystick = []
self._actors_sphero = []
self._actors_iracer = []
self._actors_legonxt = []
self._actor_controller_connection = []
self._time_since_robot_update = 0
def main(self):
'''Main method'''
#Init logging
logging.basicConfig(filename='JamRacer.log',level=logging.DEBUG)
logging.info("Program startup")
#Get PyGame Going
pygame.init()
#Load Configuration
logging.info("Getting configuration")
self._configuration = JamRacerConfig.JamRacerConfig()
logging.info("Starting PyGame")
self._mydisplay = JamRacerDisplay()
self._mydisplay.Setup()
self._mydisplay.Update()
#Init input methods
logging.info("Initialise Controllers")
# Prep/connect controllers/actors
self.__initialise_controller_joystick()
self.__initialise_controller_wiiboard()
#Init remote controlled vehicles
logging.info("Initialise Actors")
self.__initialise_actor_sphero()
self.__initialise_actor_iracer()
self.__initialise_actor_legonxt()
logging.info("Connecting actors to controllers")
wiifitboard_num = 0
joystick_num = 0
#Perform automated association of inputs to outputs. This needs work.
logging.debug("Configuring iRacers")
for iracer in self._actors_iracer:
controller = None
if len(self._controllers_wiifitboard) > 0:
if wiifitboard_num < len(self._controllers_wiifitboard):
if self._controllers_wiifitboard[wiifitboard_num] is not None:
controller = self._controllers_wiifitboard[wiifitboard_num]
wiifitboard_num += 1
if controller is None:
if joystick_num < len(self._controllers_joystick):
if self._controllers_joystick[joystick_num] is not None:
controller = self._controllers_joystick[joystick_num]
joystick_num += 1
if controller is not None:
acc = ActorControllerConnection(iracer,controller,MTYPE_CARSTEER)
self.__add_actor_controller_connection(acc)
logging.debug("Configuring Spheros")
for sphero in self._actors_sphero:
controller = None
if controller is None:
if joystick_num < len(self._controllers_joystick):
if self._controllers_joystick[joystick_num] is not None:
controller = self._controllers_joystick[joystick_num]
joystick_num += 1
if controller is not None:
acc = ActorControllerConnection(sphero,controller,MTYPE_COMPASS)
self.__add_actor_controller_connection(acc)
logging.debug("Configuring LegoNXTs")
for legonxt in self._actors_legonxt:
controller = None
if len(self._controllers_wiifitboard) > 0:
if wiifitboard_num < len(self._controllers_wiifitboard):
if self._controllers_wiifitboard[wiifitboard_num] is not None:
controller = self._controllers_wiifitboard[wiifitboard_num]
wiifitboard_num += 1
if controller is None:
if joystick_num < len(self._controllers_joystick):
if self._controllers_joystick[joystick_num] is not None:
controller = self._controllers_joystick[joystick_num]
joystick_num += 1
if controller is not None:
acc = ActorControllerConnection(legonxt,controller,MTYPE_TANKSTEER)
self.__add_actor_controller_connection(acc)
logging.debug("Starting direct control mode")
#Some primitive task scheduling stuff
self._time_since_robot_update = current_milli_time()
#Main loop
while True:
#Poll WFB
self.__update_controller_wiifitboard()
#Poll keyboard
self.g_keys = pygame.event.get()
#Check for quit key
for event in self.g_keys:
if (event.type == KEYDOWN):
if (event.key == K_ESCAPE):
self.quit()
return
elif (event.type == QUIT):
self.quit()
return
# Check WFB again, it has to be polled really fast to keep up with the data, or a backlog causes problems
self.__update_controller_wiifitboard()
# Update actors, but not too quickly!
if self._time_since_robot_update < (current_milli_time() - 100):
self.__update_controller_joystick()
for acc in self._actor_controller_connection:
motion = acc.controller.get_motion(acc.motion_type)
# logging.debug("Robot motion: motion_type=" + str(acc.motion_type) +" controller=" + acc.controller.name +" direction=" + str(motion.direction) + " speed=" + str(motion.speed))
acc.actor.output_motion(motion)
self._mydisplay.Clear()
self._mydisplay.Update()
self._time_since_robot_update = current_milli_time()
# we are leaving the program
if self._configuration.actor_sphero_enabled:
for sphero in self._actors_sphero:
sphero.stop()
if self._configuration.actor_iracer_enabled:
for iracer in self._actors_iracer:
iracer.stop()
# end main
def quit(self,message = ''):
sys.exit(message)
def __initialise_controller_joystick(self):
'''Initialise joysticks'''
if self._configuration.controller_joystick_enabled:
try:
self._joystick_handler = JamRacerJoystickHandler()
self._controllers_joystick = self._joystick_handler.joysticks
except Exception as ex:
self.controller_joystick_enabled = False
logging.debug("No joysticks initialised")
logging.debug(ex)
pass
else:
self._configuration.controller_joystick_enabled = False
def __initialise_controller_wiiboard(self):
'''Initialise WFB'''
if self._configuration.controller_wiiboard_enabled:
for bluetooth_address in self._configuration.WiiBoards:
logging.info('Attempting to start Wii Fit Board controller with Bluetooth MAC Address %s' % bluetooth_address)
try:
wiiboard = WiiFitBoard(bluetooth_address)
wiiboard.connect()
self._controllers_wiifitboard.append(wiiboard)
except Exception as ex:
logging.info('Wii Fit Board connection failed to Bluetooth MAC Address %s' % bluetooth_address)
logging.debug(ex)
pass
if len(self._controllers_wiifitboard) == 0:
logging.info("Wii Fit Board controllers disabled")
self.controller_wiiboard_enabled = False
def __initialise_actor_sphero(self):
'''Initialise Spheros'''
if self._configuration.actor_sphero_enabled:
for bluetooth_address in self._configuration.Spheros:
logging.info('Attempting to start Sphero robot with Bluetooth MAC Address %s' % bluetooth_address)
try:
sphero = Sphero(bluetooth_address)
sphero.connect()
sphero.set_rgb(SpheroColour(0,64,0))
self._actors_sphero.append(sphero)
except Exception as eargs:
logging.info('Sphero connection failed to Bluetooth MAC Address %s' % bluetooth_address)
pass
if len(self._actors_sphero) == 0:
logging.info("Sphero actors disabled")
self._configuration.actor_sphero_enabled = False
def __initialise_actor_iracer(self):
'''Initialise Arexx iRacer Dagu cars'''
if self._configuration.actor_iracer_enabled:
for bluetooth_address in self._configuration.iRacers:
logging.info('Attempting to start iRacer robot with Bluetooth MAC Address %s' % bluetooth_address)
try:
iracer = iRacer(bluetooth_address)
iracer.connect()
self._actors_iracer.append(iracer)
except Exception as eargs:
logging.info('iRacer connection failed to Bluetooth MAC Address %s' % bluetooth_address)
logging.debug(eargs)
pass
if len(self._actors_iracer) == 0:
logging.info("iRacer actors disabled")
self._configuration.actor_iracer_enabled = False
def __initialise_actor_legonxt(self):
'''Initialise Lego NXT bricks'''
if self._configuration.actor_legonxt_enabled:
for bluetooth_address in self._configuration.LegoNXTs:
logging.debug('Attempting to start LegoNXT robot with Bluetooth MAC Address %s' % bluetooth_address)
try:
legonxt = LegoNXT(bluetooth_address)
legonxt.connect(MTYPE_CARSTEER)
legonxt.test_motors_quick()
self._actors_legonxt.append(legonxt)
except Exception as ex:
logging.debug('LegoNXT connection failed to Bluetooth MAC Address %s' % bluetooth_address)
logging.debug(ex)
pass
if len(self._actors_legonxt) == 0:
logging.info('LegoNXT actors disabled')
self._configuration.actor_legonxt_enabled = False
def __update_controller_wiifitboard(self):
if self._configuration.controller_wiiboard_enabled:
for wiifitboard in self._controllers_wiifitboard:
wiifitboard.update()
def __update_controller_joystick(self):
if self._configuration.controller_joystick_enabled:
for joystick in self._controllers_joystick:
joystick.update()
def __add_actor_controller_connection(self, actor_controller_connection):
logging.info("Adding actor<-controller connection. A:" + actor_controller_connection.actor.name + " C:" + actor_controller_connection.controller.name)
self._actor_controller_connection.append(actor_controller_connection)
class ActorControllerConnection(object):
'''Class used to associate inputs to outputs'''
def __init__(self, actor, controller, motion_type):
self._actor = actor
self._controller = controller
self._motion_type = motion_type
@property
def actor(self):
return self._actor
@property
def controller(self):
return self._controller
@property
def motion_type(self):
return self._motion_type
#Launch app
app = JamRacerApp()
app.main()