Package motors :: Package tests :: Module test_qik2s9v1
[hide private]
[frames] | no frames]

Source Code for Module motors.tests.test_qik2s9v1

  1  #!/usr/bin/env python 
  2  # 
  3  # motors/pololu/test_qik2s9v1.py 
  4  # 
  5   
  6  import os 
  7  import unittest 
  8  import time 
  9  import logging 
 10   
 11  from motors import Qik2s9v1 
 12   
 13   
 14  BASE_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), 
 15                                           '..', '..', 'logs')) 
16 17 -def setupLogger(fullpath=None, level=logging.DEBUG):
18 FORMAT = ("%(asctime)s %(levelname)s %(module)s %(funcName)s " 19 "[line:%(lineno)d] %(message)s") 20 logging.basicConfig(filename=fullpath, format=FORMAT, level=level) 21 return logging.getLogger()
22
23 24 -class TestQik2s9v1(unittest.TestCase):
25 """ 26 Unit tests for the Qik 2s9v1 motor controller. 27 28 Most tests have a for loop which first tests the pololu protocol then tests 29 the compact protocol. 30 """ 31 _DEFAULT_TTY = '/dev/ttyUSB0' 32 _PROTOCOL_MAP = {0: "Pololu Protocol", 1: "Compact Protocol"} 33
34 - def __init__(self, name):
35 super(TestQik2s9v1, self).__init__(name) 36 # Timeouts [(0.0, 0), (0.262, 1), ...] 37 logFilePath = os.path.join(BASE_PATH, 'pololu_qik2s9v1.log') 38 self._log = setupLogger(fullpath=logFilePath)
39
40 - def setUp(self):
41 self._log.debug("Processing") 42 self._qik = Qik2s9v1(self._DEFAULT_TTY, readTimeout=5, log=self._log)
43
44 - def tearDown(self):
45 self._log.debug("Processing") 46 47 if self._qik.isOpen(): 48 dConfig = self._qik._deviceConfig.copy() 49 50 for d in dConfig: 51 self._qik.setDeviceID(self._qik.DEFAULT_DEVICE_ID, device=d) 52 53 self._qik.getError() 54 self._qik.setPWMFrequency(31500) 55 self._qik.setMotorShutdown(True) 56 self._qik.setSerialTimeout(0.0) 57 self._qik.setM0Speed(0) 58 self._qik.setM0Coast() 59 self._qik.setM1Speed(0) 60 self._qik.setM1Coast() 61 self._qik.close() 62 self._qik = None
63
64 - def test_getConfigForDevice(self):
65 self._log.debug("Processing") 66 67 for device in self._qik._deviceConfig: 68 config = self._qik.getConfigForDevice(device) 69 self.assertTrue(config['version'] in (1, 2)) 70 self.assertTrue(config['pwm'] == 0) 71 self.assertTrue(config['shutdown'] == 1) 72 self.assertTrue(config['timeout'] == 0)
73
74 - def test_close(self):
75 self._log.debug("Processing") 76 self.assertTrue(self._qik.isOpen() == True) 77 self._qik.close() 78 self.assertTrue(self._qik.isOpen() == False)
79
80 - def test_setCompactProtocol(self):
81 """ 82 The compact protocol is not the default. 83 """ 84 self._log.debug("Processing") 85 self.assertTrue(self._qik.isCompactProtocol() == False) 86 self._qik.setCompactProtocol() 87 self.assertTrue(self._qik.isCompactProtocol() == True)
88
89 - def test_setPololuProtocol(self):
90 """ 91 The pololu portocol is the default. 92 """ 93 self._log.debug("Processing") 94 self.assertTrue(self._qik.isPololuProtocol() == True) 95 self._qik.setCompactProtocol() 96 self.assertTrue(self._qik.isPololuProtocol() == False)
97
98 - def test_getFirmwareVersion(self):
99 self._log.debug("Processing") 100 self.assertTrue(self._qik.getFirmwareVersion() in (1, 2)) 101 self._qik.setCompactProtocol() 102 self.assertTrue(self._qik.getFirmwareVersion() in (1, 2))
103 104 @unittest.skip("Temporarily skipped")
106 self._log.debug("Processing")
107 108 @unittest.skip("Temporarily skipped")
109 - def test_getError_FrameError(self):
110 self._log.debug("Processing")
111 112 @unittest.skip("Temporarily skipped")
113 - def test_getError_CRCError(self):
114 self._log.debug("Processing")
115
117 self._log.debug("Processing") 118 command = 0x70 # Bad command breaks in both protocols 119 num = 64 120 error = self._qik._ERRORS.get(num) 121 122 for i in range(2): 123 protocol = self._PROTOCOL_MAP.get(i) 124 self._qik._writeData(command, self._qik.DEFAULT_DEVICE_ID) 125 result = self._qik.getError(message=False) 126 msg = "{}: Invalid error '{}' should be '{}'.".format( 127 protocol, result, [num]) 128 self.assertTrue(num in result and len(result) == 1, msg=msg) 129 self._qik._writeData(command, self._qik.DEFAULT_DEVICE_ID) 130 result = self._qik.getError() 131 msg = "{}: Invalid error '{}' should be '{}'.".format( 132 protocol, result, [error]) 133 self.assertTrue(error in result and len(result) == 1, msg=msg) 134 self._qik.setCompactProtocol()
135
137 self._log.debug("Processing") 138 timeout = 0.262 139 num = 128 140 error = self._qik._ERRORS.get(num) 141 142 for i in range(2): 143 protocol = self._PROTOCOL_MAP.get(i) 144 self._qik.setSerialTimeout(timeout) 145 time.sleep(0.275) 146 result = self._qik.getError(message=False) 147 msg = "{}: Invalid error '{}' should be '{}'.".format( 148 protocol, result, [num]) 149 self.assertTrue(num in result and len(result) == 1, msg=msg) 150 self._qik.setSerialTimeout(timeout) 151 time.sleep(0.275) 152 result = self._qik.getError() 153 msg = "{}: Invalid error '{}' should be '{}'.".format( 154 protocol, result, [error]) 155 self.assertTrue(error in result and len(result) == 1, msg=msg) 156 self._qik.setCompactProtocol()
157
158 - def test_getDeviceID(self):
159 """ 160 Only test Pololu protocol, it's the only protocol that uses the device 161 ID. 162 """ 163 protocol = self._PROTOCOL_MAP.get(0) 164 self._log.debug("Processing") 165 devices = (self._qik.DEFAULT_DEVICE_ID, 127) 166 # Default device 167 result = self._qik.getDeviceID(device=devices[0]) 168 msg = "Invalid device '{}' should be '{}'.".format( 169 protocol, result, devices[0]) 170 self.assertTrue(result == devices[0], msg=msg) 171 # Change device 172 self._qik.setDeviceID(devices[1], device=devices[0]) 173 result = self._qik.getDeviceID(device=devices[1]) 174 msg = "{}: Invalid device '{}' should be '{}'.".format( 175 protocol, result, devices[1]) 176 self.assertTrue(result == devices[1], msg=msg)
177
178 - def test_getPWMFrequency(self):
179 self._log.debug("Processing") 180 181 for i in range(2): 182 protocol = self._PROTOCOL_MAP.get(i) 183 result = self._qik.getPWMFrequency() 184 msg = "{}: Invalid PWM frequency '{}' should be '{}'.".format( 185 protocol, result, self._qik._CONFIG_PWM.get(0)[1]) 186 self.assertTrue(result == self._qik._CONFIG_PWM.get(0)[1], msg=msg) 187 result = self._qik.getPWMFrequency(message=False) 188 msg = "{}: Invalid PWM frequency '{}' should be '{}'.".format( 189 protocol, result, self._qik._CONFIG_PWM.get(0)[0]) 190 self.assertTrue(result == self._qik._CONFIG_PWM.get(0)[0], msg=msg) 191 self._qik.setCompactProtocol()
192
193 - def test_getMotorShutdown(self):
194 self._log.debug("Processing") 195 196 for i in range(2): 197 protocol = self._PROTOCOL_MAP.get(i) 198 tf = self._qik.getMotorShutdown() 199 msg = ("{}: Invalid motor shutdown value '{}' should be '{}'." 200 ).format(protocol, tf, True) 201 self.assertTrue(tf == True, msg=msg) 202 self._qik.setCompactProtocol()
203
204 - def test_getSerialTimeout(self):
205 self._log.debug("Processing") 206 207 for i in range(2): 208 protocol = self._PROTOCOL_MAP.get(i) 209 result = self._qik.getSerialTimeout() 210 timeout = self._qik._valueToTimeout.get(0) 211 msg = ("{}: Invalid serial timeout value '{}' should be '{}'." 212 ).format(protocol, result, timeout) 213 self.assertTrue(result == timeout, msg=msg) 214 self._qik.setSerialTimeout(200.0) 215 result = self._qik.getSerialTimeout() 216 timeout = self._qik._valueToTimeout.get(108) 217 msg = ("{}: Invalid serial timeout value '{}' should be '{}'." 218 ).format(protocol, result, timeout) 219 self.assertTrue(result == timeout, msg=msg) 220 self._qik.setCompactProtocol() 221 self._qik.setSerialTimeout(0.0)
222
223 - def test_setDeviceID(self):
224 self._log.debug("Processing") 225 devices = (self._qik.DEFAULT_DEVICE_ID, 127) 226 227 for i in range(2): 228 protocol = self._PROTOCOL_MAP.get(i) 229 result = self._qik.setDeviceID(devices[1], devices[0]) 230 msg = ("{}: Invalid device ID '{}' should be '{}'.").format( 231 protocol, result, 'OK') 232 self.assertTrue(result == 'OK', msg=msg) 233 result = self._qik.setDeviceID(devices[0], devices[1], 234 message=False) 235 msg = ("{}: Invalid device ID '{}' should be '{}'.").format( 236 protocol, result, devices[0]) 237 self.assertTrue(result == 0, msg=msg) 238 # Test that device has been properly changes in the stored config. 239 msg = ("{}: Set device '{}' is not in stored device config " 240 ).format(protocol, result) 241 self.assertTrue(devices[0] in self._qik._deviceConfig, msg=msg) 242 self._qik.setCompactProtocol()
243
244 - def test_setPWMFrequency(self):
245 self._log.debug("Processing") 246 pwms = [v[0] for v in self._qik._CONFIG_PWM.values()] 247 nums = dict([(v[0], k) for k, v in self._qik._CONFIG_PWM.items()]) 248 249 for i in range(2): 250 protocol = self._PROTOCOL_MAP.get(i) 251 252 for pwm in pwms: 253 result = self._qik.setPWMFrequency(pwm) 254 rtn = self._qik._CONFIG_RETURN.get(0) 255 msg = ("{}: Invalid PM return text '{}' for PWM '{}', " 256 "should be '{}'.").format(protocol, result, pwm, rtn) 257 self.assertTrue(result == rtn, msg=msg) 258 num = self._qik.setPWMFrequency(pwm, message=False) 259 msg = ("{}: Invalid PWM number '{}' for PWM '{}', " 260 "should be '{}'.").format(protocol, num, pwm, 0) 261 self.assertTrue(num == 0, msg=msg) 262 # Test the stored device config 263 freq = self._qik.getPWMFrequency(message=False) 264 num = self._qik._CONFIG_PWM_TO_VALUE.get(freq) 265 config = self._qik.getConfigForDevice( 266 self._qik.DEFAULT_DEVICE_ID) 267 cnum = config.get('pwm') 268 msg = ("{}: Invalid PWM number '{}' for PWM '{}', " 269 "in stored config, should be '{}'").format( 270 protocol, num, pwm, cnum) 271 self.assertTrue(num == cnum, msg=msg) 272 273 self._qik.setCompactProtocol()
274
275 - def test_setMotorShutdown(self):
276 self._log.debug("Processing") 277 command = 0x70 # Bad command breaks in both protocols 278 error = self._qik._ERRORS.get(64) # Format error 279 rtn = self._qik._CONFIG_RETURN.get(0) 280 281 for i in range(2): 282 protocol = self._PROTOCOL_MAP.get(i) 283 # Start with default motor stop on errors 284 # Start up motor M0 285 self._qik.setM0Speed(50) 286 tf = self._qik.getMotorShutdown() 287 msg = ("{}: Invalid motor shutdown value '{}' should be '{}'." 288 ).format(protocol, tf, True) 289 self.assertTrue(tf == True, msg=msg) 290 time.sleep(0.5) 291 # Create an error condition that will stop the motors. 292 self._qik._writeData(command, self._qik.DEFAULT_DEVICE_ID) 293 result = self._qik.getError() 294 msg = ("{}: Invalid response error text '{}' should be '{}'." 295 ).format(protocol, result, [error]) 296 self.assertTrue(error in result and len(result) == 1, msg=msg) 297 298 # Switch to non-stopping motors 299 text = self._qik.setMotorShutdown(False) 300 msg = "{}: Invalid response '{}' should be '{}'.".format( 301 protocol, text, rtn) 302 self.assertTrue(text == rtn, msg=msg) 303 tf = self._qik.getMotorShutdown() 304 msg = ("{}: Invalid motor shutdown value '{}' should be '{}'." 305 ).format(protocol, text, False) 306 self.assertTrue(text == rtn, msg=msg) 307 308 # Test the stored device config 309 config = self._qik.getConfigForDevice(self._qik.DEFAULT_DEVICE_ID) 310 shutdown = config.get('shutdown') 311 msg = ("{}: Invalid motor shutdown value '{}' in stored config, " 312 "should be '{}'.").format(protocol, tf, bool(shutdown)) 313 self.assertTrue(tf == bool(shutdown), msg=msg) 314 315 # Start up motor M0, If change motor shutdown, need to come to 316 # full stop. HAVING TO DO THIS MAY BE BECAUSE OF A BUG SOMEWHERE. 317 self._qik.setM0Speed(0) 318 self._qik.setM0Speed(-50) 319 tf = self._qik.getMotorShutdown() 320 msg = ("{}: Invalid motor shutdown value '{}' should be '{}'." 321 ).format(protocol, tf, False) 322 self.assertTrue(tf == False, msg=msg) 323 time.sleep(0.5) 324 # Create an error condition that will not stop the motors. 325 self._qik._writeData(command, self._qik.DEFAULT_DEVICE_ID) 326 result = self._qik.getError() 327 msg = ("{}: Invalid response error text '{}' should be '{}'." 328 ).format(protocol, result, [error]) 329 self.assertTrue(error in result and len(result) == 1, msg=msg) 330 self._qik.setM0Speed(0) 331 self._qik.setM0Coast() 332 333 # Test the stored device config 334 config = self._qik.getConfigForDevice(self._qik.DEFAULT_DEVICE_ID) 335 shutdown = config.get('shutdown') 336 msg = ("{}: Invalid motor shutdown value '{}' in stored config, " 337 "should be '{}'.").format(protocol, bool(shutdown), tf) 338 self.assertTrue(tf == bool(shutdown), msg=msg) 339 340 # Switch back to stopping motor. 341 result = self._qik.setMotorShutdown(True) 342 msg = "{}: Invalid response '{}' should be '{}'.".format( 343 protocol, result, rtn) 344 self.assertTrue(result == rtn, msg=msg) 345 self._qik.setCompactProtocol()
346
347 - def test_setSerialTimeout(self):
348 self._log.debug("Processing") 349 rtn = self._qik._CONFIG_RETURN.get(0) 350 shortDelay = self._qik._valueToTimeout.get(1) 351 longDelay = self._qik._valueToTimeout.get(127) 352 353 for i in range(2): 354 protocol = self._PROTOCOL_MAP.get(i) 355 # Test short timeout, will be 0.262 on the Qik 356 result = self._qik.setSerialTimeout(0.3) 357 msg = ("{}: Invalid serial timeout '{}' should be '{}'." 358 ).format(protocol, result, rtn) 359 self.assertTrue(result == rtn, msg=msg) 360 result = self._qik.getSerialTimeout() 361 msg = ("{}: Invalid serial timeout value '{}' should be '{}'." 362 ).format(protocol, result, shortDelay) 363 self.assertTrue(result == shortDelay, msg=msg) 364 365 # Test the stored device config 366 config = self._qik.getConfigForDevice(self._qik.DEFAULT_DEVICE_ID) 367 timeout = config.get('timeout') 368 msg = ("{}: Invalid motor timeout value '{}' in stored config, " 369 "should be '{}'.").format(protocol, result, timeout) 370 self.assertTrue(result == timeout, msg=msg) 371 372 # Test long timeout, will be 503.04 on the Qik 373 result = self._qik.setSerialTimeout(500.0) 374 msg = ("{}: Invalid serial timeout '{}' should be '{}'." 375 ).format(protocol, result, rtn) 376 self.assertTrue(result == rtn, msg=msg) 377 result = self._qik.getSerialTimeout() 378 msg = ("{}: Invalid serial timeout value '{}' should be '{}'." 379 ).format(protocol, result, longDelay) 380 self.assertTrue(result == longDelay, msg=msg) 381 382 # Test the stored device config 383 config = self._qik.getConfigForDevice(self._qik.DEFAULT_DEVICE_ID) 384 timeout = config.get('timeout') 385 msg = ("{}: Invalid motor timeout value '{}' in stored config, " 386 "should be '{}'.").format(protocol, result, timeout) 387 self.assertTrue(result == timeout, msg=msg) 388 389 self._qik.setCompactProtocol()
390 391 @unittest.skip("Skipped, no return values.")
392 - def test_setM0Coast(self):
393 self._log.debug("Processing") 394 395 for i in range(2): 396 self._qik.setM0Speed(50) 397 time.sleep(0.5) 398 self._qik.setM0Coast()
399 400 @unittest.skip("Skipped, no return values.")
401 - def test_setM1Coast(self):
402 self._log.debug("Processing") 403 404 for i in range(2): 405 self._qik.setM1Speed(50) 406 time.sleep(0.5) 407 self._qik.setM1Coast()
408 409 @unittest.skip("Skipped, no return values and no get speed command.")
410 - def test_setM0Speed(self):
411 self._log.debug("Processing") 412 413 for i in range(2): 414 self._qik.setM0Speed(50) 415 time.sleep(0.5)
416 417 @unittest.skip("Skipped, no return values and no get speed command.")
418 - def test_setM1Speed(self):
419 self._log.debug("Processing") 420 421 for i in range(2): 422 self._qik.setM1Speed(50) 423 time.sleep(0.5)
424 425 426 if __name__ == '__main__': 427 unittest.main() 428