Changeset 420
- Timestamp:
- 02/20/09 17:44:27 (3 years ago)
- Location:
- trunk/software/rb
- Files:
-
- 3 modified
Legend:
- Unmodified
- Added
- Removed
-
trunk/software/rb/controller.py
r412 r420 4 4 class Controller(): 5 5 def __init__(self): 6 self.drive = False 7 self.drive = rb.drive.FakeDrive(rbconfig.left_motor_port, 8 rbconfig.right_motor_port) 9 #self.drive = rb.drive.Drive(rbconfig.left_motor_port, 10 # rbconfig.right_motor_port) 6 #self.drive = rb.drive.FakeDrive(rbconfig.left_motor_port, 7 # rbconfig.right_motor_port) 8 self.drive = rb.drive.Drive(rbconfig.left_motor_port, 9 rbconfig.right_motor_port) -
trunk/software/rb/drive.py
r419 r420 14 14 # along with this program. If not, see <http://www.gnu.org/licenses/>. 15 15 16 from __future__ import division , with_statement16 from __future__ import division 17 17 18 18 ''' … … 26 26 from serial import Serial 27 27 from thread import start_new_thread 28 from threading import RLock28 from threading import Lock 29 29 from time import sleep 30 30 … … 45 45 46 46 Ok, Err = range(2) 47 (Tdisable, Rdisable, 48 Tenable, Renable, 49 Tsetdc, Rsetdc, 50 Tgetdc, Rgetdc, 51 Tsetgain, Rsetgain, 52 Tgetgain, Rgetgain, 53 Tsetspeed, Rsetspeed, 54 Tgetspeed, Rgetspeed, 55 Tgetstat, Rgetstat, 56 Teewrite, Reewrite) = range(20) 57 47 48 messages = { 49 'disable' : [{'op':0 , 'fmt':'' }, {'op':1 , 'fmt':'' }], # (nil) 50 'enable' : [{'op':2 , 'fmt':'' }, {'op':3 , 'fmt':'' }], # (nil) 51 'setdc' : [{'op':4 , 'fmt':'>h' }, {'op':5 , 'fmt':'' }], # (int16_t dc) 52 'getdc' : [{'op':6 , 'fmt':'' }, {'op':7 , 'fmt':'>h' }], # (int16_t dc) 53 'setgain' : [{'op':8 , 'fmt':'>hhh'}, {'op':9 , 'fmt':'' }], # (int16_t Kp, int16_t Ki, int16_t Kd) 54 'getgain' : [{'op':10, 'fmt':'' }, {'op':11, 'fmt':'>hhh'}], # (int16_t Kp, int16_t Ki, int16_t Kd) 55 'setspeed': [{'op':12, 'fmt':'>h' }, {'op':13, 'fmt':'' }], # (int16_t rpm) 56 'getspeed': [{'op':14, 'fmt':'' }, {'op':15, 'fmt':'>h' }], # (int16_t speed) 57 'getstat' : [{'op':16, 'fmt':'' }, {'op':17, 'fmt':'>hhh'}], # (int16_t p, int16_t i, int16_t d) 58 'eewrite' : [{'op':18, 'fmt':'' }, {'op':19, 'fmt':'' }], # (nil) 59 } 58 60 59 61 … … 73 75 self.left = Motor(ldev) 74 76 self.right = Motor(rdev) 75 self.set _speeds(0.0, 0.0)77 self.setspeed(0.0, 0.0) 76 78 77 79 def _get_running(self): … … 83 85 84 86 running = property(_get_running, _set_running) 85 86 def set_speeds(self, left, right): 87 88 def _split(self, type, lt_data, rt_data): 89 ''' 90 Call _send on the left and right motor passing in type and the 91 corresponding data. If data is None, it will not be set 92 ''' 93 if lt_data == None: 94 l = None 95 else: 96 l = self.left._send(type, *lt_data) 97 if rt_data == None: 98 r = None 99 else: 100 r = self.right._send(type, *rt_data) 101 return (l, r) 102 103 def setspeed(self, left, right): 87 104 ''' 88 105 Set the motor speeds directly. `left` and `right` are floats … … 94 111 for each, respectively. 95 112 ''' 96 #print "Drive.set_speeds: %f, %f" % (left, right) 97 self.left.target = clip(left, -1.0, 1.0) 98 self.right.target = clip(right, -1.0, 1.0) 113 print "Drive.setspeed: %f, %f" % (left, right) 114 self.left.target = clip(left, -1.0, 1.0)*MAX 115 self.right.target = clip(right, -1.0, 1.0)*MAX 116 117 def getspeed(self): 118 return (float(self.left._send( "getspeed")) / MAX, 119 float(self.right._send("getspeed")) / MAX) 120 121 def disable(self): return self._split("disable", (), ()) 122 def enable (self): return self._split("enable" , (), ()) 123 def setdc (self,l,r): return self._split("setdc" , l, r ) 124 def getdc (self): return self._split("getdc" , (), ()) 125 def setgain(self,l,r): return self._split("setgain", l, r ) 126 def getgain(self): return self._split("getgain", (), ()) 127 def getstat(self): return self._split("getstat", (), ()) 128 def eewrite(self): return self._split("eewrite", (), ()) 99 129 100 130 … … 105 135 106 136 def __init__(self, port): 107 self.target = 0 108 self.running = True 109 self.current = 0 # Current value reported by the motors 110 self._current_set = 0 # Current value the motors have been set to 111 self._port = Serial(port, 19200, timeout=.5) 112 self.lock = RLock() 137 self.running = True 138 self.target = 0 # Speed the motor coltrollers should be at 139 self._port = Serial(port, 19200, timeout=.5) 140 #self._port = open("/tmp/fake", "w+") 141 self._port_lock = Lock() 113 142 start_new_thread(self._main, ()) 114 143 115 144 def _main(self): 116 #print "Motor._main: starting"117 self.running = True118 145 while self.running: 119 #print "Motor._main: stepping" 120 try: 121 self.step() 122 except Exception, e: 123 log_error('Motor: Exception in step() %r' % e) 146 cur = self._send("getspeed") 147 if cur: 148 inc = min(0.05*MAX, abs(self.target - cur)) 149 if cur < self.target: 150 self._send("setspeed", cur + inc) 151 elif cur > self.target: 152 self._send("setspeed", cur - inc) 153 else: 154 self._send("setspeed", cur) # Ping! 124 155 sleep(.1) 125 self._set_speed(0) 126 #print "Motor._main: exiting" 127 128 def step(self): 129 with self.lock: 130 inc = min(0.05, abs(self.target - self._current_set)) 131 if self._current_set < self.target: 132 self._current_set += inc 133 elif self._current_set > self.target: 134 self._current_set -= inc 135 136 self._set_speed(self._current_set) 137 #~ self.current = (self._get_speed() / MAX) 138 139 def _send(self, type, msg): 140 #print 'Motor._send: start' 141 self._port.write(chr(type)) 142 self._port.write(chr(len(msg))) 143 self._port.write(msg) 144 #print 'Motor._send: end' 145 146 def _receive(self): 147 type = self._port.read(1) 148 length = self._port.read(1) 149 150 if len(type) != 1: 151 print "Timeout reading `type' from motor controller" 152 if len(length) != 1: 153 print "Timeout reading `length' from motor controller" 154 155 if ord(length) == 0: 156 return ord(type), '' 157 else: 158 return ord(type), self._port.read(ord(length)) 159 160 def _set_speed(self, fspeed): 161 with self.lock: 162 speed = int(fspeed * MAX) 163 #print 'Motor._set_speed: %d' % speed 164 self._send(Tsetspeed, struct.pack('>h', speed)) 165 type, res = self._receive() 166 if type != Rsetspeed or ord(res) != Ok: 167 log_error('motor: Error setting speed') 168 169 def _set_gain(self, kp, ki, kd): 170 with self.lock: 171 self._send(Tsetgain, struct.pack('>hhh', kp, ki, kd)) 172 type, res = self._receive() 173 if type != Rsetgain or ord(res) != Ok: 174 log_error('motor: Error setting gain') 175 176 def _write_eeprom(self): 177 with self.lock: 178 self._send(Teewrite, '') 179 type, res = self._receive() 180 if type != Reewrite or ord(res) != Ok: 181 log_error('motor: Error writing settings to eeprom') 182 183 def _get_speed(self): 184 with self.lock: 185 self._send(Tgetspeed, '') 186 type, s = self._receive() 187 if type != Rgetspeed: 188 log_error('motor: Tag mismatch') 189 (speed,) = struct.unpack('>h', s) 190 # speed returned is unscaled, this assumes 50Hz loop 191 return speed * 60.0 * 50 / 256.0 156 self._send("setspeed", 0) 157 158 def _send(self, type, *t_data): 159 self._port_lock.acquire() 160 161 t, r = messages[type] 162 163 # Transmit query 164 t_st = struct.pack(t['fmt'], *t_data) 165 self._port.write(chr(t['op'])) 166 self._port.write(chr(len(t_st))) 167 self._port.write(t_st) 168 169 # Recieve response 170 r_op = self._port.read(1) 171 if len(r_op) != 1: 172 print "Motor._send: Timeout reading `r_type' from motor controller" 173 elif r_op != chr(r['op']): 174 print "Motor._send: Recieved incorrect `r_type' from motor controller" 175 176 r_length = self._port.read(1) 177 if len(r_length) != 1: 178 print "Motor._send: Timeout reading `r_length' from motor controller" 179 return 180 r_length = ord(r_length) 181 if r_length != struct.calcsize(r['fmt']): 182 print "Motor._send: Recieved incorrect `r_length' from motor controller" 183 184 if r_length == 0: 185 # No need to recieve/unpack structure 186 return 187 188 r_st = self._port.read(r_length) 189 if len(r_st) != r_length: 190 print "Motor._send: Timeout reading `r_data' from motor controller" 191 r_data = struct.unpack(r['fmt'], r_st) 192 193 if (len(r_data) == 1): 194 # struct's return format is annoying 195 return r_data(0) 196 197 self._port_lock.release() 198 return r_data 192 199 193 200 … … 202 209 self.right = FakeMotor() 203 210 204 def set _speeds(self, left, right):211 def setspeed(self, left, right): 205 212 log_debug("MockDrive: left motor speed % 3.03f" % left) 206 213 log_debug("MockDrive: right motor speed % 3.03f" % right) … … 212 219 def __init__(self, *args, **kwargs): 213 220 self.target = 0 214 215 current = property(lambda s: s.target)221 def _send(type, *t_data): 222 print "sending %s - %s" % (type, repr(t_data)) -
trunk/software/rb/shell.py
r413 r420 114 114 115 115 # Motor control 116 def do_setspeed(self, cmd): 117 try: 118 lspeed, rspeed = unpack(cmd, (0.0, float), (0.0, float)) 119 self.drive.setspeed(lspeed, rspeed) 120 except ValueError: 121 print "Invalid parameters" 122 123 def do_getspeed(self, cmd): 124 self.drive.getspeed() 125 116 126 def do_setgain(self, cmd): 117 127 try: 118 128 kp, ki, kd, m = unpack(cmd, (0, int), (0, int), (0, int), ('b', str)) 119 if m in ('l', 'b'): 120 self.drive.left._set_gain(kp, ki, kd) 121 if m in ('r', 'b'): 122 self.drive.right._set_gain(kp, ki, kd) 129 if m == 'l': 130 self.drive.setgain((kp,ki,kd),None) 131 elif m == 'r': 132 self.drive.setgain(None,(kp,ki,kd)) 133 else: 134 self.drive.setgain((kp,ki,kd),(kp,ki,kd)) 123 135 except ValueError: 124 136 print "Invalid Parameters" 125 137 126 138 def do_getspeed(self, cmd): 127 try: 128 (m,) = unpack(cmd, ('b', str)) 129 print 'm = %r' % m 130 if m in ('l', 'b'): 131 speed = self.drive.left._get_speed() 132 print 'l: %d\n' % speed 133 if m in ('r', 'b'): 134 speed = self.drive.right._get_speed() 135 print 'r: %d\n' % speed 136 137 except ValueError: 138 print "Invalid Parameters" 139 140 141 def do_speeds(self, cmd): 142 try: 143 lspeed, rspeed = unpack(cmd, (0.0, float), (0.0, float)) 144 self.drive.set_speeds(lspeed, rspeed) 145 except ValueError: 146 print "Invalid parameters" 139 print self.drive.getspeed() 140 141 def do_setdc(self, cmd): 142 ldc, rdc = unpack(cmd, (0, int), (0, int)) 143 print self.drive.setdc(ldc, rdc) 144 145 def do_disable(self, cmd): 146 print self.drive.disable() 147 148 def do_enable(self, cmd): 149 print self.drive.enable() 150 151 def do_getdc(self, cmd): 152 print self.drive.getdc() 153 154 def do_getgain(self, cmd): 155 print self.drive.getgain() 156 157 def do_getstat(self, cmd): 158 print self.drive.getstat() 159 160 def do_eewrite(self, cmd): 161 print self.drive.eewrite() 147 162 148 163 def do_stop(self, cmd):

