Changeset 461
- Timestamp:
- 03/15/09 01:43:19 (3 years ago)
- Location:
- trunk/software/rb
- Files:
-
- 11 modified
-
controller.py (modified) (1 diff)
-
drive.py (modified) (5 diffs)
-
gps.py (modified) (2 diffs)
-
gui/analog.py (modified) (2 diffs)
-
gui/compass.py (modified) (1 diff)
-
gui/gui.py (modified) (11 diffs)
-
gui/speedgraph.py (modified) (1 diff)
-
kalman.py (modified) (2 diffs)
-
microstrain.py (modified) (5 diffs)
-
shell.py (modified) (2 diffs)
-
wiimote.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/software/rb/controller.py
r458 r461 1 # Copyright (C) 2009 Thomas W. Most 2 # Copyright (C) 2008 Andy Spencer 3 # 4 # This program is free software: you can redistribute it and/or modify 5 # it under the terms of the GNU General Public License as published by 6 # the Free Software Foundation, either version 3 of the License, or 7 # (at your option) any later version. 8 # 9 # This program is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 # GNU General Public License for more details. 13 # 14 # You should have received a copy of the GNU General Public License 15 # along with this program. If not, see <http://www.gnu.org/licenses/>. 16 1 17 import gobject 2 18 -
trunk/software/rb/drive.py
r459 r461 1 1 # Copyright (C) 2008 Thomas W. Most 2 # Copyright (C) 2009 Andy Spencer 2 3 # 3 4 # This program is free software: you can redistribute it and/or modify … … 74 75 ''' 75 76 76 def __init__(self, ldev, rdev): 77 self.left = Motor(ldev) 78 self.right = Motor(rdev) 79 #self.setspeed(0.0, 0.0) 80 81 def _get_running(self): 82 return self.left.running 83 84 def _set_running(self, value): 85 self.left.running = value 86 self.right.running = value 87 88 running = property(_get_running, _set_running) 77 def __init__(self, controller, ldev, rdev): 78 self.controller = controller 79 self.running = True 80 self.left = Motor(self, ldev) 81 self.right = Motor(self, rdev) 82 start_new_thread(self._main, ()) 83 84 def _main(self): 85 while self.running: 86 lcur, rcur = self._split('getspeed', (), ()) 87 if lcur is not None: 88 self.left.current = (lcur*50*60 / 256.0) / MAX 89 else: 90 print "Drive._main: timeout getting left speed" 91 if rcur is not None: 92 self.right.current = (rcur*50*60 / 256.0) / MAX 93 else: 94 print "Drive._main: timeout getting right speed" 95 if lcur is not None and rcur is not None: 96 self.controller.send('drive_speeds', self.getspeed()) 97 time.sleep(.05) 89 98 90 99 def _split(self, type, lt_data, rt_data): … … 116 125 self.left.target = clip(left, -1.0, 1.0) * MAX 117 126 self.right.target = clip(right, -1.0, 1.0) * MAX 127 self.controller.send('drive_targets', self.gettarget()) 118 128 119 129 def gettarget(self): … … 138 148 ''' 139 149 140 def __init__(self, port): 141 self._port_name = port 142 self.running = True 150 def __init__(self, drive, port): 151 self.drive = drive 143 152 self.target = 0 # Speed the motor controllers should be at 144 153 self.current = 0 # Latest reported speed of the motors 154 self._port_name = port 155 self._port_lock = Lock() 145 156 self._port = Serial(port, 19200, timeout=.5) 146 157 time.sleep(1) 147 self._port_lock = Lock()148 158 start_new_thread(self._main, ()) 149 159 150 160 def _main(self): 151 161 print "Motor._main: starting" 152 while self.running: 153 #print "Motor._main: stepping" 154 cur = self._send("getspeed") 155 if cur is not None: 156 #print "updating speed, cur=%d target=%d" % (cur, self.target) 157 #inc = min(0.05*MAX, abs(self.target - cur)) 158 #if cur < self.target: 159 # self._send("setspeed", cur + inc) 160 #elif cur > self.target: 161 # self._send("setspeed", cur - inc) 162 #else: 163 self.current = (cur*50*60 / 256.0) / MAX 164 self._send("setspeed", self.target) # Ping! 165 else: 166 print "Motor._main: timeout getting speed" 162 while self.drive.running: 163 self._send("setspeed", self.target) # Ping! 167 164 time.sleep(.05) 168 165 print "Motor._main: exiting" … … 257 254 print "FakeMotor sending %s - %s" % (type, repr(t_data)) 258 255 259 current = property(lambda s: s.target )256 current = property(lambda s: s.target, lambda s: None) -
trunk/software/rb/gps.py
r363 r461 81 81 ''' 82 82 83 def __init__(self, dev):83 def __init__(self, controller, dev): 84 84 ''' 85 85 Create a new `GPS` object. `dev` is the device to start gpsd 86 86 listening on. 87 87 ''' 88 self. latest_coords = None88 self.controller = controller 89 89 self.dev = dev 90 90 self.running = True 91 self.latest_coords = None 91 92 self.gpsd = None 92 93 self.gps = None 93 super(GPS, self).__init__()94 94 95 thread.start_new_thread(self._run_gpsd, ()) 95 96 thread.start_new_thread(self._main, ()) … … 164 165 log_debug("GPS: got update") 165 166 self.latest_coords = GPSCoord(*data) 167 self.controller.send('gps_fix', self.latest_coords) 166 168 last_data = data 167 169 168 169 def main():170 '''171 Print constant updates from the GPS.172 '''173 logging.log_level = logging.DEBUG174 gps = GPS(sys.argv[1])175 last_data = None176 try:177 while True:178 data = gps.latest_coords179 if data is not last_data:180 last_data = data181 print data.pformat()182 except KeyboardInterrupt:183 print "Shutting down, just a sec"184 gps.running = False185 186 if __name__ == '__main__':187 main() -
trunk/software/rb/gui/analog.py
r458 r461 1 # Copyright (C) 2008-2009 Andy Spencer 2 # Copyright (C) 2008-2009 Thomas W. Most 3 # 4 # This program is free software: you can redistribute it and/or modify 5 # it under the terms of the GNU General Public License as published by 6 # the Free Software Foundation, either version 3 of the License, or 7 # (at your option) any later version. 8 # 9 # This program is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 # GNU General Public License for more details. 13 # 14 # You should have received a copy of the GNU General Public License 15 # along with this program. If not, see <http://www.gnu.org/licenses/>. 16 1 17 from math import pi 2 18 import gtk … … 77 93 l = x+y 78 94 r = y-x 79 80 #log_debug("\tgui: x=%f, y=%f, l=%f, r=%f" % (x,y,l,r)) 81 self.controller.set_speed(l, r) 95 self.controller.drive.setspeed(l, r) -
trunk/software/rb/gui/compass.py
r445 r461 1 1 #!/usr/bin/env python 2 2 3 # Copyright (C) 2008 Nathan T. Mendel, Ching-Chen Ma, Thomas W. Most 3 # Copyright (C) 2008 Nathan T. Mendel 4 # Copyright (C) 2008 Ching-Chen Ma 5 # Copyright (C) 2009 Thomas W. Most 4 6 # 5 7 # This program is free software: you can redistribute it and/or modify -
trunk/software/rb/gui/gui.py
r459 r461 1 # Copyright (C) 2008-2009 Andy Spencer 2 # Copyright (C) 2008-2009 Thomas W. Most 3 # 4 # This program is free software: you can redistribute it and/or modify 5 # it under the terms of the GNU General Public License as published by 6 # the Free Software Foundation, either version 3 of the License, or 7 # (at your option) any later version. 8 # 9 # This program is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 # GNU General Public License for more details. 13 # 14 # You should have received a copy of the GNU General Public License 15 # along with this program. If not, see <http://www.gnu.org/licenses/>. 16 17 from __future__ import division 18 1 19 import gobject 2 20 import pygtk; pygtk.require("2.0") … … 4 22 5 23 import os.path 24 from math import pi 6 25 from thread import start_new_thread 7 26 … … 27 46 } 28 47 48 # Blue color for indicating the robot's orientation 49 RAW_ORIENT_BLUE = (85/255, 107/255, 160/255) # Raw MicroStrain data 50 ORIENT_BLUE = (6/255, 67/255, 213/255) # Kalman filter estimation 51 29 52 30 53 class GUI(Controller): … … 55 78 self.builder.add_from_file(GTKBUILDER_FILE) 56 79 self.builder.connect_signals(self) 57 self.window = self.builder.get_object('window')80 self.window = self.builder.get_object('window') 58 81 59 82 # Glade-3 -> GtkBuilder fix … … 65 88 self.analog = AnalogWidget(self) 66 89 self.compass = CompassWidget() 90 self.raw_orient_dir = self.compass.new_direction(RAW_ORIENT_BLUE, pi / 2) 67 91 self.speed_graph = SpeedGraph(self.drive) 68 92 self.builder.get_object("analog_body").add(self.analog) … … 79 103 Shell(self).cmdloop() 80 104 gobject.idle_add(gtk.main_quit) 105 106 def update_compass_raw_orient(self, state_accel): 107 self.raw_orient_dir.update(state_accel.orient[2]) 81 108 82 109 def process(self, type, data): … … 86 113 elif type == 'drive_speeds': 87 114 self.analog.queue_draw() 115 elif type == 'microstrain': 116 self.update_compass_orient(data) 88 117 89 118 def set_navigator(self, nav): … … 105 134 if nav == 'stop': 106 135 print "Switching to 'stop' navigator" 107 self. set_speed(0, 0)136 self.drive.setspeed(0, 0) 108 137 elif nav == 'analog': 109 138 print "Switching to analog navigator" … … 141 170 # E-Stop 142 171 if event.keyval in (gtk.keysyms.Escape, gtk.keysyms.space): 143 self.set_ mode('stop')172 self.set_navigator('stop') 144 173 145 174 # Switch tabs … … 150 179 elif event.keyval in self.arrow_keys_map: 151 180 lo, ro = self.arrow_keys_map[event.keyval] 152 self. set_speed(self.drive.left.target+lo,153 self.drive.right.target+ro)181 self.drive.setspeed(self.drive.left.target+lo, 182 self.drive.right.target+ro) 154 183 155 184 # Key not found … … 205 234 self.drive.eewrite() 206 235 207 # utilities208 def set_speed(self, lspeed, rspeed):209 # Constrain l and r210 self.drive.setspeed(lspeed, rspeed)211 self.analog.redraw(None)212 213 236 # GTK Callbacks 214 237 def on_window_destroy(self, widget, data=None): -
trunk/software/rb/gui/speedgraph.py
r460 r461 1 # Copyright (C) 200 8Thomas W. Most1 # Copyright (C) 2009 Thomas W. Most 2 2 # 3 3 # This program is free software: you can redistribute it and/or modify -
trunk/software/rb/kalman.py
r458 r461 1 # Copyright (C) 2009 Thomas W. Most 2 # 3 # This program is free software: you can redistribute it and/or modify 4 # it under the terms of the GNU General Public License as published by 5 # the Free Software Foundation, either version 3 of the License, or 6 # (at your option) any later version. 7 # 8 # This program is distributed in the hope that it will be useful, 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 # GNU General Public License for more details. 12 # 13 # You should have received a copy of the GNU General Public License 14 # along with this program. If not, see <http://www.gnu.org/licenses/>. 15 1 16 2 17 from thread import start_new_thread 18 19 from rb.utils import meter_offset 3 20 4 21 … … 46 63 # Use the robot's initial location as zero 47 64 self.gps_zero = coords.lat_lon 65 x, y = meter_offset(self.gps_zero, coords.lat_lon) 48 66 49 # Convert GPS coordinates to meters 50 # FIXME! 67 self._x_y = (x, y) 51 68 52 69 def update_drive_speed(self, (lspeed, rspeed)): -
trunk/software/rb/microstrain.py
r360 r461 1 # Copyright (C) 2008 Thomas W. Most1 # Copyright (C) 2008-2009 Thomas W. Most 2 2 # Copyright (C) 2008 Andy Spencer 3 3 # … … 90 90 ''' 91 91 92 def __init__(self, dev):92 def __init__(self, controller, dev): 93 93 ''' 94 94 Create a new `MicroStrain` object. `dev` is the serial device 95 95 on which the MicroStrain is present. 96 96 ''' 97 97 self.controller = controller 98 98 self.running = True 99 99 self.dev = dev … … 129 129 elif isinstance(result, StateAccel): 130 130 self.latest_state = result 131 self. smoothed_state = self.calc_smoothed(result)131 self.controller.send('microstrain', result) 132 132 133 133 port.write("\x10\x00\x00") # Stop continuous mode … … 135 135 log_error("MicroStrain: disconnetion: %s" % e) 136 136 time.sleep(1) # The cable was probably pulled. Wait for it. 137 138 def calc_smoothed(self, new_state): 139 self._window.append(new_state) 140 if len(self._window) > WINDOW_SIZE: 141 self._window = self._window[len(self._window) - WINDOW_SIZE:WINDOW_SIZE] 142 num = len(self._window) 143 return StateAccel( 144 _smooth_triple(self._window, 'orient', num), 145 _smooth_triple(self._window, 'ang_vel', num), 146 _smooth_triple(self._window, 'accel', num) 147 ) 148 149 150 def _smooth_triple(window, attr, num): 151 ''' 152 Return a three-tuple of the average of each dataset 153 `attr` in `window`, a list of StateAccel objects. 154 ''' 155 # TODO: Probably should do a weighted average 156 # and/or more filtering. 157 triples = [getattr(sa, attr) for sa in window] 158 return ( 159 sum(t[0] for t in triples) / num, 160 sum(t[1] for t in triples) / num, 161 sum(t[2] for t in triples) / num 162 ) 137 138 163 139 164 140 def handle_packet(port): … … 268 244 0x25: (11, None), 269 245 } 270 271 272 def main():273 '''274 Print MicroStrain data to the screen.275 '''276 logging.log_level = logging.DEBUG277 ms = MicroStrain(sys.argv[1])278 last_state = None279 try:280 while True:281 state = ms.smoothed_state282 if state is not last_state:283 print state.pformat()284 last_state = state285 time.sleep(.01)286 except KeyboardInterrupt:287 ms.running = False288 289 if __name__ == '__main__':290 main() -
trunk/software/rb/shell.py
r459 r461 1 # Copyright (C) 2008 Thomas W. Most 1 # Copyright (C) 2008-2009 Thomas W. Most 2 # Copyright (C) 2009 Michael Auchter 3 # Copyright (C) 2009 Andy Spencer 2 4 # 3 5 # This program is free software: you can redistribute it and/or modify … … 160 162 161 163 def do_stop(self, cmd): 162 self.controller.drive.set _speeds(0.0, 0.0)164 self.controller.drive.setspeed(0.0, 0.0) 163 165 164 166 def help_stop(self): -
trunk/software/rb/wiimote.py
r449 r461 113 113 rspeed = y / 127.0 if (abs(y) > 5) else 0 114 114 115 self.controller. set_speed(lspeed, rspeed)115 self.controller.drive.setspeed(lspeed, rspeed) 116 116 117 117 def handle_mesg(self, messages):

