source: remote_control/puzzlebox_brainstorms_remote_control.py @ 87

Last change on this file since 87 was 87, checked in by sc, 11 years ago

remote_control/puzzlebox_brainstorms_network_client_thinkgear.py:

  • adjustment to debug output for clarity

remote_control/puzzlebox_brainstorms_network_client.py:

  • warning output on timeout waiting for server connections
  • adjustment to debug output for clarity

remote_control/puzzlebox_brainstorms_remote_control.py:

  • adjustment to debug output for clarity

remote_control/puzzlebox_brainstorms_client_interface.py:

  • forward driving halted when disconnected from ThinkGear? server
  • keyboard shortcuts added to direction buttons
  • virtual button presses drawn when driving activated by direction
  • better handling of speed changes in updateSpeed
  • speed dropped to 100 if NXT power threshold exceeded

remote_control/puzzlebox_brainstorms_configuration.ini:

  • ThinkGear? Connect Server Emulator configuration added
  • default Relaxation speed boosts tweaked

remote_control/interface/qt4_form.py:

  • faulty keyboard shortcuts removed

remote_control/puzzlebox_brainstorms_configuration.py:

  • ThinkGear? Connect Server Emulator configuration
  • default Relaxation speed boosts tweaked

remote_control/puzzlebox_brainstorms_client_interface_network.py:

  • initial checkin

remote_control/puzzlebox_brainstorms_client_interface_local.py:

  • initial checking
  • not properly establishing client/server communications

remote_control/puzzlebox_brainstorms_network_server_thinkgear.py

  • adjustment to debug output for clarity
  • some configuration settings moved to configuration module

remote_control/puzzlebox_brainstorms_network_server.py:

  • adjustment to debug output for clarity
  • Property svn:executable set to *
File size: 9.7 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3#
4# Puzzlebox - Brainstorms - Remote Control
5#
6# Copyright Puzzlebox Productions, LLC (2010)
7#
8# This code is released under the GNU Pulic License (GPL) version 2
9# For more information please refer to http://www.gnu.org/copyleft/gpl.html
10#
11# Last Update: 2010.07.06
12#
13#####################################################################
14
15import sys, time
16import serial
17
18import jaraco.nxt
19import jaraco.nxt.messages
20
21import puzzlebox_brainstorms_configuration as configuration
22
23#####################################################################
24# Globals
25#####################################################################
26
27DEBUG = 2
28
29DISCRETE_CONTROL_COMMANDS = configuration.BRAINSTORMS_DISCRETE_CONTROL_COMMANDS
30
31DEFAULT_NXT_POWER_LEVEL = configuration.DEFAULT_NXT_POWER_LEVEL
32
33BLUETOOTH_DEVICE = configuration.NXT_BLUETOOTH_DEVICE
34
35MOTORS_MOUNTED_BACKWARDS = configuration.NXT_MOTORS_MOUNTED_BACKWARDS
36MOTOR_PORT_RIGHT = configuration.NXT_MOTOR_PORT_RIGHT
37MOTOR_PORT_LEFT = configuration.NXT_MOTOR_PORT_LEFT
38DEFAULT_RC_COMMAND = configuration.NXT_DEFAULT_RC_COMMAND
39
40#####################################################################
41# Classes
42#####################################################################
43
44class puzzlebox_brainstorms_remote_control:
45       
46        def __init__(self, \
47                     device=BLUETOOTH_DEVICE, \
48                     command=DEFAULT_RC_COMMAND, \
49                     DEBUG=DEBUG):
50               
51                self.DEBUG = DEBUG
52               
53                self.device = device
54                self.command = command
55               
56                self.connection = None
57               
58                try:
59                        self.connection = self.connect_to_nxt(self.device)
60                except Exception, e:
61                        if self.DEBUG:
62                                print "<-- [RC] Connection failed to NXT device [%s]" % self.device
63                                print "ERROR [RC]:",
64                                print e
65       
66       
67        ##################################################################
68       
69        def connect_to_nxt(self, device):
70               
71                connection = jaraco.nxt.Connection(self.device)
72               
73                if self.DEBUG:
74                        battery_voltage = self.get_battery_voltage(connection)
75                        print "--> [RC] Battery voltage:",
76                        print battery_voltage
77               
78               
79                return(connection)
80       
81       
82        ##################################################################
83       
84        def connect_to_port(self, device_port):
85       
86                if isinstance(device_port, basestring):
87                        port = getattr(jaraco.nxt.messages.OutputPort, device_port)
88               
89                assert port in jaraco.nxt.messages.OutputPort.values()
90               
91                return(port)
92       
93       
94        ##################################################################
95       
96        def get_battery_voltage(self, connection):
97               
98                cmd = jaraco.nxt.messages.GetBatteryLevel()
99                connection.send(cmd)
100               
101                response = connection.receive()
102                voltage = response.get_voltage()
103               
104                return(voltage)
105       
106       
107        ##################################################################
108       
109        def cycle_motor(self, connection, motor_port='a'):
110               
111                "Turn the motor one direction, then the other, then stop it"
112               
113                port = self.connect_to_port(motor_port)
114                cmd = jaraco.nxt.messages.SetOutputState(port, \
115                                                         motor_on=True, \
116                                                         set_power=60, \
117                                   run_state=jaraco.nxt.messages.RunState.running)
118                connection.send(cmd)
119               
120                time.sleep(2)
121               
122                cmd = jaraco.nxt.messages.SetOutputState(port, \
123                                                         motor_on=True, \
124                                                         set_power=-60, \
125                                   run_state=jaraco.nxt.messages.RunState.running)
126                connection.send(cmd)
127               
128                time.sleep(2)
129               
130                cmd = jaraco.nxt.messages.SetOutputState(port)
131                connection.send(cmd)
132       
133       
134        ##################################################################
135       
136        def drive(self, connection, left_power, right_power, duration):
137               
138                "Operate both motors, each at certain power, for a certain duration"
139               
140                left_motor = self.connect_to_port(MOTOR_PORT_LEFT)
141                right_motor = self.connect_to_port(MOTOR_PORT_RIGHT)
142               
143               
144                # If motors are mounted on the robot in reverse then all
145                # power settings need to be reversed
146                if MOTORS_MOUNTED_BACKWARDS:
147                        left_power = -left_power
148                        right_power = -right_power
149               
150                # Issue operation settings to both motors
151                cmd = jaraco.nxt.messages.SetOutputState(left_motor, \
152                                                                                                                          motor_on=True, \
153                                                                                                                          set_power=left_power, \
154                                                                 run_state=jaraco.nxt.messages.RunState.running)
155                connection.send(cmd)
156               
157                cmd = jaraco.nxt.messages.SetOutputState(right_motor, \
158                                                                                                                          motor_on=True, \
159                                                                                                                          set_power=right_power, \
160                                                                 run_state=jaraco.nxt.messages.RunState.running)
161                connection.send(cmd)
162               
163                # Continue operating motors while control program pauses
164                if DISCRETE_CONTROL_COMMANDS:
165                        time.sleep(duration)
166                       
167                        self.stop_motors(connection)
168       
169       
170        ##################################################################
171       
172        def stop_motors(self, connection):
173               
174                "Stop both motors"
175               
176                left_motor = self.connect_to_port(MOTOR_PORT_LEFT)
177                right_motor = self.connect_to_port(MOTOR_PORT_RIGHT)
178               
179                # Issue command to stop both motors
180                cmd = jaraco.nxt.messages.SetOutputState(left_motor)
181                connection.send(cmd)
182                cmd = jaraco.nxt.messages.SetOutputState(right_motor)
183                connection.send(cmd)
184       
185       
186        ##################################################################
187       
188        def drive_forward(self, connection, power=DEFAULT_NXT_POWER_LEVEL, duration=2):
189               
190                "Drive the robot forward at a certain speed for a certain duration"
191               
192                self.drive(connection, power, power, duration)
193       
194       
195        ##################################################################
196       
197        def drive_reverse(self, connection, power=DEFAULT_NXT_POWER_LEVEL, duration=2):
198               
199                "Drive the robot reverse at a certain speed for a certain duration"
200               
201                power = -power
202               
203                self.drive(connection, power, power, duration)
204       
205       
206        ##################################################################
207       
208        def turn_left_in_reverse(self, connection, power=DEFAULT_NXT_POWER_LEVEL, duration=3):
209               
210                "Turn the robot counter-clockwise while backing up at a"
211                " certain speed for a certain duration"
212               
213                left_power = -(power/3)
214                right_power = -power
215               
216                self.drive(connection, left_power, right_power, duration)
217       
218       
219        ##################################################################
220       
221        def turn_right_in_reverse(self, connection, power=DEFAULT_NXT_POWER_LEVEL, duration=3):
222               
223                "Turn the robot clockwise while backing up at a"
224                " certain speed for a certain duration"
225               
226                left_power = -power
227                right_power = -(power/3)
228               
229                self.drive(connection, left_power, right_power, duration)
230       
231       
232        ##################################################################
233       
234        def turn_left(self, connection, power=DEFAULT_NXT_POWER_LEVEL, duration=2):
235               
236                "Turn the robot counter-clockwise at a"
237                " certain speed for a certain duration"
238               
239                left_power = -(power/2)
240                right_power = power
241               
242                self.drive(connection, left_power, right_power, duration)
243       
244       
245        ##################################################################
246       
247        def turn_right(self, connection, power=DEFAULT_NXT_POWER_LEVEL, duration=2):
248               
249                "Turn the robot counter-clockwise at a"
250                " certain speed for a certain duration"
251               
252                left_power = power
253                right_power = -(power/2)
254               
255                self.drive(connection, left_power, right_power, duration)
256       
257       
258        ##################################################################
259       
260        def test_drive(self, connection):
261               
262                #self.cycle_motor(self.connection, motor_port='a')
263               
264                self.drive_forward(self.connection, power=100, duration=3)
265               
266                # half turn in reverse
267                self.turn_right_in_reverse(self.connection, power=100, duration=2)
268               
269                self.drive_forward(self.connection, power=80, duration=2)
270               
271                # quarter turn left
272                self.turn_left(self.connection, power=80, duration=2)
273               
274                self.drive_forward(self.connection, power=80, duration=1)
275               
276                # half turn right
277                self.turn_right(self.connection, power=80, duration=2)
278               
279                self.drive_forward(self.connection, power=80, duration=1)
280               
281                self.drive_reverse(self.connection, power=80, duration=1)
282       
283       
284        ##################################################################
285       
286        def run(self, command, power=DEFAULT_NXT_POWER_LEVEL):
287               
288                # If the LEGO Mindstorms NXT is instructed to drive with
289                # power less than 50% performance is so poor that we'd be
290                # better off simply stopping the motors.
291                if power < 50:
292                        command = 'stop_motors'
293               
294                if (command == 'drive_forward'):
295                        self.drive_forward(self.connection, power=power, duration=3)
296               
297                elif (command == 'drive_reverse'):
298                        self.drive_reverse(self.connection, power=power)
299               
300                elif (command == 'turn_left'):
301                        self.turn_left(self.connection, power=power)
302               
303                elif (command == 'turn_right'):
304                        self.turn_right(self.connection, power=power)
305               
306                elif (command == 'turn_left_in_reverse'):
307                        self.turn_left_in_reverse(self.connection, power=power)
308               
309                elif (command == 'turn_right_in_reverse'):
310                        self.turn_right_in_reverse(self.connection, power=power)
311               
312                elif (command == 'stop_motors'):
313                        self.stop_motors(self.connection)
314               
315                elif (command == 'test_drive'):
316                        self.test_drive(self.connection)
317       
318       
319        ##################################################################
320       
321        def stop(self):
322               
323                self.connection.close()
324
325
326#####################################################################
327# Functions
328#####################################################################
329
330#####################################################################
331# Main
332#####################################################################
333
334if __name__ == '__main__':
335       
336        # Collect default settings and command line parameters
337        device = BLUETOOTH_DEVICE
338        command = DEFAULT_RC_COMMAND
339       
340        for each in sys.argv:
341               
342                if each.startswith("--device="):
343                        device = each[ len("--device="): ]
344                elif each.startswith("--command="):
345                        command = each[ len("--command="): ]
346       
347       
348        rc = puzzlebox_brainstorms_remote_control(device=device, command=command, DEBUG=DEBUG)
349       
350        if rc.connection == None:
351                sys.exit()
352       
353        rc.run(rc.command)
354        rc.stop()
355
Note: See TracBrowser for help on using the repository browser.