Package dics :: Module cortex
[hide private]
[frames] | no frames]

Source Code for Module dics.cortex

  1  import logging 
  2  import serial 
  3   
4 -class Error(Exception):
5 """Base class for exceptions in this module.""" 6 pass
7
8 -class CortexError(Error):
9 """Exception raised if the Cortex controller responds to a command 10 with 'E#/r/n', i.e. if it receives and illegal command. This should 11 of course never happen... 12 13 Attributes: command - the command string sent to the controller which 14 resulted in the error."""
15 - def __init__(self, command):
16 self.command = command
17
18 -class RangeError(Error):
19 """Exception raised if there is an attempt to set a Cortex parameter 20 with an value outside the allowed range. 21 22 Attributes: parameter - the parameter in question 23 value - the illegal value requested 24 range - the allowed range for the parameter"""
25 - def __init__(self, parameter, value, range):
26 self.parameter = parameter 27 self.value = value 28 self.range = range
29
30 -class TimeoutError(Error):
31 """Exception raised when there is no response from the Cortex 32 controller. This most likely means it's been disconnected, 33 switched off, or a command has been sent to a non-existant unit 34 in a daisy chain. 35 36 Attributes: command - the last command string sent to the controller"""
37 - def __init__(self, command):
38 self.commmand = command
39
40 -class ResponseError(Error):
41 """Exception raised when an unexpected response is received from the 42 Cortex controller. This should of course never happen... 43 44 Attributes: command - the command string sent to the controller 45 response - the response string received"""
46 - def __init__(self, command, response):
47 self.command = command 48 self.response = response
49
50 -class cortex:
51 """Basic class representing an interface to a Cortex controller 52 (or daisy chain of controllers). Presents functions corresponding 53 to each of the commands accepted by a Cortex controller. Performs 54 range checking on arguments and returns response from the 55 controller.""" 56
57 - def __init__(self, portname, units, name='cortex'):
58 """ 59 Arguments: 60 61 portname: device name of the serial port to use 62 units: number of cortex units in the chain 63 name: name to be used as a label in the logs 64 """ 65 self.portname = portname 66 self.units = int(units) 67 self.name = name 68 self.logger = logging.getLogger(name) 69 # Open the serial port. If it doesn't work there'll be 70 # a SerialException. 71 try: 72 self.__port = serial.Serial(portname, timeout=5) 73 except serial.SerialException: 74 # It's all gone horribly wrong 75 self.logger.critical('Failed to open serial port %s!' % portname) 76 return 77 self.logger.info('Connected to serial port %s' % portname) 78 # Tell the cortex controller (or the first in the chain) 79 # to terminate its lines properly (i.e. use newlines). 80 self.__port.write('\r\n') 81 self.__setNewline(True, cortex_num=1) 82 # To begin with disable outputs and set currents to zero. 83 for unit in range(1, self.units + 1): 84 self.setCurrent(0, unit) 85 self.setOutput(0, unit)
86
87 - def __basicCommand(self, command):
88 """Function used to send any command that expects the basic 89 '#\r\n' response, and parses the response received. If 90 the standard response is not received an appropriate 91 exception is raised. 92 93 Arguments: command - string containing the command to send.""" 94 self.__port.flushInput() 95 self.__port.write(command) 96 response = self.__port.readline() 97 if response == "#\r\n": 98 return 99 elif response == "E\r\n": 100 # raise CortexError(command) 101 self.logger.critical('Syntax error - sent ' + repr(command)) 102 elif not response: 103 # raise TimeoutError(command) 104 self.logger.critical('No response on port %s - sent ' \ 105 % self.portname + repr(command)) 106 else: 107 # raise ResponseError(command, response) 108 self.logger.critical('Unexpected response ' + repr(response) + \ 109 ' - sent ' + repr(command))
110
111 - def __intCommand(self, command):
112 """Function used to send any command that expects an integer 113 N in a 'N#\r\n' response, parses the response received, and returns 114 the integer. If the expected response is not received an appropriate 115 exception is raised. 116 117 Arguments: command - string containing the command to send.""" 118 self.__port.flushInput() 119 self.__port.write(command) 120 response = self.__port.readline() 121 if response[-3:] == "#\r\n": 122 return int(response[:-3]) 123 elif response == "E\r\n": 124 #raise CortexError(command) 125 self.logger.critical('Syntax error - sent "%s"' % command) 126 elif not response: 127 #raise TimeoutError(command) 128 self.logger.critical('No response on port %s - sent "%s"' \ 129 % (self.portname, command)) 130 else: 131 #raise ResponseError(command, response) 132 self.logger.critical('Unexpected response "%s" - sent "%s"' % 133 (response, command))
134
135 - def getInput(self, cortex_num=1):
136 """ 137 Gets the status of the 4-bit input of the Cortex Controller, 138 returning it as an integer in the range 0-15. 139 140 Arguments: cortex_num - which controller of a daisy chain to 141 query, default 1. 142 """ 143 if cortex_num > self.units or cortex_num < 1: 144 self.logger.warning('Illegal unit number in getInput(%i)'\ 145 % cortex_num) 146 else: 147 self.logger.debug('getInput(%i) called' % cortex_num) 148 return self.__intCommand("%iI\n" % cortex_num)
149
150 - def getLimitStatus(self, cortex_num=1):
151 """Queries the limit switch status, returns -1 if lower limit made, 152 +1 if upper limit made and 0 is neither is. Note, this command 153 ALWAYS stops the motors, use isActive() first to determine if the 154 motors are in motion. 155 156 Arguments: cortex_num - which controller of a daisy chain to 157 query, default 1.""" 158 if cortex_num > self.units or cortex_num < 1: 159 self.logger.warning('Illegal unit number in getLimitStatus(%i)'\ 160 % cortex_num) 161 else: 162 self.logger.debug('getLimitStatus(%i) called' % cortex_num) 163 return self.__intCommand("%iRL\n" % cortex_num)
164
165 - def getParams(self, cortex_num=1):
166 if cortex_num > self.units or cortex_num < 1: 167 self.logger.warning('Illegal unit number in getParams(%i)'\ 168 % cortex_num) 169 else: 170 self.logger.debug('getParams(%i) called' % cortex_num) 171 self.__port.flushInput() 172 self.__port.write("%i?\n" % cortex_num) 173 return self.__port.readline()
174
175 - def getPosition(self, cortex_num=1):
176 """Requests the current motor position from the controller, 177 in steps from the datum and returns it as an integer. 178 179 Arguments: cortex_num - which controller of a daisy chain to 180 query, default 1.""" 181 if cortex_num > self.units or cortex_num < 1: 182 self.logger.warning('Illegal unit number in getPosition(%i)'\ 183 % cortex_num) 184 else: 185 self.logger.debug('getPosition(%i) called' % cortex_num) 186 return self.__intCommand("%iW\n" % cortex_num)
187
188 - def getRemaining(self, cortex_num=1):
189 """Requests the number of steps left to go in the current move 190 from the controller and returns the reply as an integer. 191 192 Arguments: cortex_num - which controller of a daisy chain to 193 query, default 1.""" 194 if cortex_num > self.units or cortex_num < 1: 195 self.logger.warning('Illegal unit number in getRemaining(%i)'\ 196 % cortex_num) 197 else: 198 self.logger.debug('getRemaining(%i) called' % cortex_num) 199 return self.__intCommand("%iRS\n" % cortex_num)
200
201 - def isActive(self, cortex_num=1):
202 """Requests the motor status from the controller, returns True 203 if the motor is active, False otherwise. 204 205 Arguments: cortex_num - which controller of a daisy chain to 206 query, default 1.""" 207 if cortex_num > self.units or cortex_num < 1: 208 self.logger.warning('Illegal unit number in isActive(%i)'\ 209 % cortex_num) 210 else: 211 self.logger.debug('isActive(%i) called' % cortex_num) 212 return bool(self.__intCommand("%iA\n" % cortex_num))
213
214 - def saveParams(self, cortex_num=1):
215 """Writes all current controller parameters to EEPROM, if 216 fitted. 217 218 Arguments: cortex_num - which controller of a daisy chain to 219 command, default 1.""" 220 if cortex_num > self.units or cortex_num < 1: 221 self.logger.warning('Illegal unit number in saveParams(%i)'\ 222 % cortex_num) 223 else: 224 self.logger.debug('saveParams(%i) called' % cortex_num) 225 self.__basicCommand("%iQ\n" % cortex_nun)
226
227 - def setCurrent(self, current=160, cortex_num=1):
228 """Sets the motor current, in mA. Allowed range is 229 0-600mA, in steps of 40mA (intermediate values, if given, 230 are rounded down to the nearest multiple of 40). N.B. 231 Do not exceed 160mA in continous use unless a heatsink is 232 fitted. 233 234 Arguments: current - motor current, in mA, integer in range 235 0-600. 236 cortex_num - which controller of a daisy chain to 237 command, default 1.""" 238 if cortex_num > self.units or cortex_num < 1: 239 self.logger.warning('Illegal unit number in setCurrent(%i, %i)'\ 240 % (current, cortex_num)) 241 return 242 if current < 0 or current > 600: 243 # raise RangeError("Current", current, "0:600") 244 self.logger.warning('Illegal current in setCurrent(%i, &i)'\ 245 % (current, cortex_num)) 246 else: 247 self.logger.debug('setCurrent(%i, %i) called' \ 248 % (current, cortex_num)) 249 self.__basicCommand("%iE %i\n" % (cortex_num, current/40))
250
251 - def setDatum(self, position=0, cortex_num=1):
252 """Change the coordinate system so that the current position 253 is equal to the argument. 254 255 Arguments: position - value to assign to the current position, 256 default 0. 257 cortex_num - which controller of a daisy chain to 258 command, default 1.""" 259 if cortex_num > self.units or cortex_num < 1: 260 self.logger.warning('Illegal unit number in setDatum(%i, %i)'\ 261 % (position, cortex_num)) 262 else: 263 self.logger.debug('setDatum(%i, %i) called' \ 264 % (position, cortex_num)) 265 self.__basicCommand("%iD %i\n" % (cortex_num, position))
266
267 - def setDefaults(self, cortex_num=1):
268 """Return all parameters to their default values, with the 269 exception of the newline parameter on the first controller in 270 the chain (newlines are required for communication using 271 pySerial). The default values are given in the Cortex 272 controller doumentation. 273 274 Arguments: cotrex_num - which controller of a daisy chain to 275 reset to defaults, default 1.""" 276 277 if cortex_num > self.units or cortex_num < 1: 278 self.logger.warning('Illegal unit number in setDefaults(%i)'\ 279 % cortex_num) 280 return 281 self.logger.debug('setDefaults(%i) called' % cortex_num) 282 if cortex_num == 1: 283 command = "1F\n" 284 self.__port.flushInput() 285 self.__port.write(command) 286 response = self.__port.readline() 287 if response == "#\r": 288 self.__setNewline(True, cortex_num=1) 289 elif response == "E\r": 290 self.logger.critical('Syntax error - sent "%s"' % command) 291 #raise CortexError(command) 292 elif not response: 293 self.logger.critical('No response on port %s - sent "%s"' \ 294 % (self.portname, command)) 295 #raise TimeoutError(command) 296 else: 297 self.logger.critical('Unexpected response "%s" - sent "%s"' % 298 (response, command)) 299 #raise ResponseError(command, response) 300 else: 301 self.__basicCommand("%iF\n" % cortex_num)
302
303 - def setJoystick(self, jitter=4, deadband=20, slowband=10, sense=0, \ 304 cortex_num=1):
305 """Sets the joystick parameters. No sanity checking of 306 arguments implemented yet. 307 308 Arguments: jitter - allowable joystick noise, default 4 309 deadband - joystick deadband, default 20 310 slowband - slow motion band, default 10 311 sense - joystick not reversed, default 0 312 cortex_num - which controller in a daisy chain 313 to command, default 1.""" 314 if cortex_num > self.units or cortex_num < 1: 315 self.logger.warning(\ 316 'Illegal unit number in setJoystick(%i, %i, %i, $i, %i)'\ 317 % (jitter, deadband, slowband, sense, cortex_num)) 318 else: 319 self.logger.debug(\ 320 'setJoystick(%i, %i, %i, %i, %i) called'\ 321 % (jitter, deadband, slowband, sense, cortex_num)) 322 self.__basicCommand("%iJ %i %i %i %i\n" % \ 323 (cortex_num, jitter, deadband, slowband, \ 324 sense))
325
326 - def setLocalMode(self, yes=True, cortex_num=1):
327 """Toggles local/manual mode. If the first argument is 328 True sets local mode on, if False sets local mode off. 329 330 Arguments: yes - boolean, if True set local mode on, 331 and vice versa, default True 332 cortex_num - which controller in a daisy chain 333 to command, default 1.""" 334 if cortex_num > self.units or cortex_num < 1: 335 self.logger.warning('Illegal unit number in setLocalMode(%i, %i)'\ 336 % (yes, cortex_num)) 337 return 338 self.logger.debug('setLocalMode(%i, %i) called' % (yes, cortex_num)) 339 if yes: 340 self.__basicCommand("%iL 1\n" % cortex_num) 341 else: 342 self.__basicCommand("%iL 0\n" % cortex_num)
343
344 - def setMicrostepping(self, ratio, cortex_num=1):
345 """Set the microstepping ratio using the numeric codes 346 described in the Cortex controller documentation. The 347 argument ratio should be an integer in the range 0-63. 348 349 Arguments: ratio - microstepping ratio code, integer 350 in range 0-63. 351 cortex_num - which controller in a diasy chain 352 to set, default 1.""" 353 if cortex_num > self.units or cortex_num < 1: 354 self.logger.warning(\ 355 'Illegal unit number in setMicrostepping(%i, %i)' \ 356 % (ratio, cortex_num)) 357 return 358 if ratio < 0 or ratio > 63: 359 #raise RangeError("Microstepping", ratio, "0:63") 360 self.logger.warning(\ 361 'Illegal ratio in setMicrostepping(%i, %i)' \ 362 % (ratio, cortex_num)) 363 else: 364 self.logger.debug('setMicrostepping(%i, %i) called'\ 365 % (ratio, cortex_num)) 366 self.__basicCommand("%iR %i\n" % (cortex_num, ratio))
367
368 - def setMotorParams(self, baseSpeed = 1000, maxSpeed = 60000, \ 369 acceleration = 30000, deceleration = 120000, \ 370 cortex_num=1):
371 """Sets the motor motion parameters, base speed, maximum 372 speed, acceleration and deceleration. 373 374 Arguments: baseSpeed - starting speed for move, moveAbs 375 and moveLimit commands, default 376 1000. 377 maxSpeed - top speed, default 60000 378 acceleration - acceleration, default 30000 379 deceleration - deceleration, default 120000 380 cortex_num - which controller in a daisy chain 381 to set, default 1.""" 382 if cortex_num > self.units or cortex_num < 1: 383 self.logger.warning(\ 384 'Illegal unit number in setMotorParams(%i, %i, %i, %i, %i)'\ 385 % (baseSpeed, maxSpeed, acceleration, \ 386 deceleration, cortex_num)) 387 else: 388 self.logger.debug(\ 389 'setMotorParams(%i, %i, %i, %i, %i) called'\ 390 % (baseSpeed, maxSpeed, acceleration, \ 391 deceleration, cortex_num)) 392 self.__basicCommand("%iP%i %i %i %i\n" % \ 393 (cortex_num, baseSpeed, maxSpeed, \ 394 acceleration, deceleration))
395
396 - def __setNewline(self, yes=True, cortex_num=1):
397 """Toggles the addition of newlines to the replies from the 398 Cortex controller. If the first argument is True sets 399 newlines on, if False sets newlines off. In order for 400 proper communications with the first cortex controller 401 in the chain it must have newlines set to True. For 402 inter-controller communications to work all other 403 controllers (if present) should have newlines False. 404 405 Arguments: yes - boolean, if True set local mode on, 406 and vice versa, default True 407 cortex_num - which controller in a daisy chain 408 to command, default 1.""" 409 if cortex_num > self.units or cortex_num < 1: 410 self.logger.warning(\ 411 'Illegal unit number in __setNewline(%i, %i)' \ 412 % (yes, cortex_num)) 413 return 414 self.logger.debug('__setNewline(%i, %i) called' \ 415 % (yes, cortex_num)) 416 if yes: 417 self.__basicCommand("%iN 1\n" % cortex_num) 418 else: 419 self.__basicCommand("%iN 0\n" % cortex_num)
420
421 - def setOutput(self, output, cortex_num=1):
422 """Sets the state of the four bit optocoupler output 423 of the Cortex controller. 424 425 Arguments: output - integer in range 0-15 corresponding 426 to desired state of the 4 bit output. 427 cortex_num - which controller in a chain to 428 set, default 1.""" 429 if cortex_num > self.units or cortex_num < 1: 430 self.logger.warning(\ 431 'Illegal unit number in setOutput(%i, %i)' \ 432 % (output, cortex_num)) 433 return 434 if output < 0 or output > 15: 435 #raise RangeError("Output", output, "0:15") 436 self.logger.warning(\ 437 'Illegal output in setOutput(%i, %i)' \ 438 % (output, cortex_num)) 439 else: 440 self.logger.debug('setOutput(%i, %i) called' \ 441 % (output, cortex_num)) 442 self.__basicCommand("%iO %i\n" % (cortex_num, output))
443
444 - def setSpeed(self, speed=150, cortex_num=1):
445 """Sets the constant speed for moveConst, moveConstAbs 446 and moveConstLimit commands. 447 448 Arguments: speed - required speed in steps/sec, 449 integer in range 62-60000 450 cortex_num - which controller in a chain 451 to set, default 1.""" 452 if cortex_num > self.units or cortex_num < 1: 453 self.logger.warning(\ 454 'Illegal unit number in setSpeed(%i, %i)' \ 455 % (speed, cortex_num)) 456 return 457 if speed < 62 or speed > 60000: 458 #raise RangeError("Speed", speed, "62:60000") 459 self.logger.warning(\ 460 'Illegal speed in setSpeed(%i, %i)' \ 461 % (speed, cortex_num)) 462 else: 463 self.logger.debug('setSpeed(%i, %i) called' \ 464 % (speed, cortex_num)) 465 self.__basicCommand("%iC %i\n" % (cortex_num, speed))
466
467 - def halt(self, cortex_num=1):
468 """Smoothly halts the motor. For emergency stops use 469 the stop command. 470 471 Arguments: cortex_num - which controller in a chain 472 to halt, default 1.""" 473 if cortex_num > self.units or cortex_num < 1: 474 self.logger.warning(\ 475 'Illegal unit number in halt(%i)' % cortex_num) 476 else: 477 self.logger.debug('halt(%i) called' % cortex_num) 478 self.__basicCommand("%iH\n" % cortex_num)
479
480 - def move(self, steps, cortex_num=1):
481 """Move a given number of steps (<2000000000) with 482 acceleration (uses motion parameters defined by 483 setMotorParams). 484 485 Arguments: steps - number of steps to move, integer in 486 range -2000000000:+2000000000 487 cortex_num - which controller to instruct to 488 move, default 1.""" 489 if cortex_num > self.units or cortex_num < 1: 490 self.logger.warning('Illegal unit number in move(%i, %i)' \ 491 % (steps, cortex_num)) 492 return 493 if steps < -2000000000 or steps > 2000000000: 494 #raise RangeError("steps", steps, "-2000000000:+2000000000") 495 self.logger.warning('Illegal steps in move(%i, %i)' \ 496 % (steps, cortex_num)) 497 else: 498 self.logger.debug('move(%i, %i) called' \ 499 % (steps, cortex_num)) 500 self.__basicCommand("%iM %i\n" % (cortex_num, steps))
501
502 - def moveAbs(self, position, cortex_num=1):
503 """Move to a given position, with acceleration (uses motion 504 parameters defined by setMotorParams). 505 506 Arguments: position - position, measure in steps from the datum 507 to move to. 508 cortex_num - which controller to instruct to 509 move, default 1.""" 510 if cortex_num > self.units or cortex_num < 1: 511 self.logger.warning('Illegal unit number in moveAbs(%i, %i)' \ 512 % (position, cortex_num)) 513 else: 514 self.logger.debug('moveAbs(%i, %i) called' \ 515 % (position, cortex_num)) 516 self.__basicCommand("%iMA %i\n" % (cortex_num, position))
517
518 - def moveConst(self, steps, cortex_num=1):
519 """Move a given number of steps (<2000000000) at a 520 constant speed (uses speed set via setSpeed). 521 522 Arguments: steps - number of steps to move, integer in 523 range -2000000000:+2000000000 524 cortex_num - which controller to instruct to 525 move, default 1.""" 526 if cortex_num > self.units or cortex_num < 1: 527 self.logger.warning('Illegal unit number in moveConst(%i, %i)' \ 528 % (steps, cortex_num)) 529 return 530 if steps < -2000000000 or steps > 2000000000: 531 #raise RangeError("steps", steps, "-2000000000:+2000000000") 532 self.logger.warning('Illegal steps in moveConst(%i, %i)' \ 533 % (steps, cortex_num)) 534 else: 535 self.logger.debug('moveConst(%i, %i) called' \ 536 % (steps, cortex_num)) 537 self.__basicCommand("%iMC %i\n" % (cortex_num, steps))
538
539 - def moveConstAbs(self, position, cortex_num=1):
540 """Move to a given position at a constant speed (used 541 speed set via setSpeed). 542 543 Arguments: position - position, measure in steps from the datum 544 to move to. 545 cortex_num - which controller to instruct to 546 move, default 1.""" 547 if cortex_num > self.units or cortex_num < 1: 548 self.logger.warning('Illegal unit number in moveConstAbs(%i, %i)'\ 549 % (position, cortex_num)) 550 else: 551 self.logger.debug('moveConstAbs(%i, %i) called' \ 552 % (position, cortex_num)) 553 self.__basicCommand("%iMCA %i\n" % (cortex_num, position))
554
555 - def moveConstLimit(self, direction, cortex_num=1):
556 """Move to a given limit at a constant speed (uses speed 557 set via setSpeed). 558 559 Arguments: direction - the direction to move in, 1 for 560 towards the upper limit, -1 for 561 towards the lower limit, or 0 562 for, er, something else (Cortex 563 documentation doesn't explain this). 564 cortex_num - which controller to instruct to 565 move, default 1.""" 566 if cortex_num > self.units or cortex_num < 1: 567 self.logger.warning(\ 568 'Illegal unit number in moveConstLimit(%i, %i)'\ 569 % (direction, cortex_num)) 570 if direction < -1 or direction > 1: 571 #raise RangeError("direction", direction, "-1,0,+1") 572 self.logger.warning('Illegal direction in moveConstLimit(%i, %i)'\ 573 % (direction, cortex_num)) 574 else: 575 self.logger.debug('moveConstLimit(%i, %i) called' \ 576 % (direction, cortex_num)) 577 self.__basicCommand("%iMCL %i\n" & (cortex_num, direction))
578
579 - def moveLimit(self, direction, cortex_num=1):
580 """Move to a given limit with acceleration (uses motion 581 parameters defined with setMotorParams). 582 583 Arguments: direction - the direction to move in, 1 for 584 towards the upper limit, -1 for 585 towards the lower limit, or 0 586 for, er, something else (Cortex 587 documentation doesn't explain this). 588 cortex_num - which controller to instruct to 589 move, default 1.""" 590 if cortex_num > self.units or cortex_num < 1: 591 self.logger.warning(\ 592 'Illegal unit number in moveLimit(%i, %i)'\ 593 % (direction, cortex_num)) 594 if direction < -1 or direction > 1: 595 #raise RangeError("direction", direction, "-1,0,+1") 596 self.logger.warning('Illegal direction in moveLimit(%i, %i)'\ 597 % (direction, cortex_num)) 598 else: 599 self.logger.debug('moveLimit(%i, %i) called' \ 600 % (direction, cortex_num)) 601 self.__basicCommand("%iML %i\n" % (cortex_num, direction))
602
603 - def stop(self, cortex_num=1):
604 """Emergency stop. 605 606 Arguments: cortex_num - which controller in a chain to stop, 607 default 1.""" 608 if cortex_num > self.units or cortex_num < 1: 609 self.logger.warning('Illegal unit number in stop(%i)' % cortex_num) 610 else: 611 self.logger.debug('stop(%i) called' % cortex_num) 612 self.__basicCommand("%iS\n" % cortex_num)
613
614 - def trigger(self, input=-1, cortex_num=1):
615 """Delay move until given a given input goes high. If no 616 input is specified then moves occur as they are requested. 617 618 Arguments: input - the number of the input to trigger on, 619 integer in the range 0-3 (I think). If 620 omitted triggering is suspended. 621 cortex_num - which controller in a chain to set 622 triggering for, default 1.""" 623 if cortex_num > self.units or cortex_num < 1: 624 self.logger.warning('Illegal unit number in trigger(%i, %i)' \ 625 % (input, cortex_num)) 626 return 627 if input < -1 or input > 3: 628 #raise RangeError("trigger", input, "0:3") 629 self.logger.warning('Illegal input in trigger(%i, %i)' \ 630 % (input, cortex_num)) 631 elif input == -1: 632 self.__basicCommand("%iT\n" % cortex_num) 633 self.logger.debug('trigger(cortex_num=%i) called' % cortex_num) 634 else: 635 self.__basicCommand("%iT %i\n" % (cortex_num, input)) 636 self.logger.debug('trigger(%i, %i) called' % (trigger, cortex_num))
637