class PanoduinoShutter(AbstractHardwarePlugin, ShutterPlugin): def _init(self): Logger().trace("PanoduinoShutter._init()") AbstractHardwarePlugin._init(self) ShutterPlugin._init(self) self._hardware = PololuMicroMaestroHardware() def _defineConfig(self): AbstractHardwarePlugin._defineConfig(self) ShutterPlugin._defineConfig(self) self._addConfigKey('_channel', 'CHANNEL', default=DEFAULT_CHANNEL[self.capacity]) self._addConfigKey('_shutterOn', 'SHUTTER_ON', default=DEFAULT_SHUTTER_ON) self._addConfigKey('_shutterOff', 'SHUTTER_OFF', default=DEFAULT_SHUTTER_OFF) def _triggerOnShutter(self): """ Set the shutter on. """ self._driver.acquireBus() try: self._hardware.setTarget(self._config['SHUTTER_ON']) finally: self._driver.releaseBus() def _triggerOffShutter(self): """ Set the shutter off. """ self._driver.acquireBus() try: self._hardware.setTarget(self._config['SHUTTER_OFF']) finally: self._driver.releaseBus() #def activate(self): #Logger().trace("PanoduinoShutter.activate()") def init(self): Logger().trace("PanoduinoShutter.init()") self._hardware.setAxis(self._config['CHANNEL']), AbstractHardwarePlugin.init(self) def shutdown(self): Logger().trace("PanoduinoShutter.shutdown()") self._triggerOffShutter() self._hardware.shutdown() AbstractHardwarePlugin.shutdown(self) ShutterPlugin.shutdown(self)
class PanoduinoAxis(AbstractHardwarePlugin, AbstractAxisPlugin): def _init(self): Logger().trace("PanoduinoAxis._init()") AbstractHardwarePlugin._init(self) AbstractAxisPlugin._init(self) self._hardware = PololuMicroMaestroHardware() def _defineConfig(self): AbstractAxisPlugin._defineConfig(self) AbstractHardwarePlugin._defineConfig(self) self._addConfigKey('_speed', 'SPEED', default=DEFAULT_SPEED[self.capacity]) self._addConfigKey('_acceleration', 'ACCEL', default=DEFAULT_ACCEL[self.capacity]) self._addConfigKey('_channel', 'CHANNEL', default=DEFAULT_CHANNEL[self.capacity]) self._addConfigKey('_direction', 'DIRECTION', default=DEFAULT_DIRECTION[self.capacity]) self._addConfigKey('_angle1ms', 'ANGLE_1MS', default=DEFAULT_ANGLE_1MS[self.capacity]) self._addConfigKey('_neutralPos', 'NEUTRAL_POSITION', default=DEFAULT_NEUTRAL_POSITION[self.capacity]) self._addConfigKey('_additionalDelay', 'ADDITIONAL_DELAY', default=DEFAULT_ADDITIONAL_DELAY) def _checkLimits(self, position): """ Check if the position can be reached. First check if the position in degres is in the user limits (done in parent class), then check if the servo can mechanically reach the position. """ AbstractAxisPlugin._checkLimits(self, position) value = self.__angleToServo(position) if not VALUE_MIN <= value <= VALUE_MAX: raise HardwareError("Servo limit reached: %.2f not in [%d-%d]" % (value, VALUE_MIN, VALUE_MAX)) def init(self): Logger().trace("PanoduinoAxis.init()") AbstractHardwarePlugin.init(self) self.configure() self._hardware.setTarget(self._config['NEUTRAL_POSITION']) def shutdown(self): Logger().trace("PanoduinoAxis.shutdown()") self.stop() self._hardware.shutdown() AbstractHardwarePlugin.shutdown(self) AbstractAxisPlugin.shutdown(self) def configure(self): Logger().trace("PanoduinoAxis.configure()") AbstractAxisPlugin.configure(self) self._hardware.setAxis(self._config['CHANNEL']) self._hardware.configure(self._config['SPEED'], self._config['ACCEL']) def __angleToServo(self, position): """ Compute controller servo value from position. @param position: position, in ° @type position: float @return: value to send to servo controller @rtype: int """ direction = DIRECTION_TABLE[self._config['DIRECTION']] dir_ = DIRECTION_INDEX[direction] servoValue = int( round(self._config['NEUTRAL_POSITION'] + dir_ * position * 1000. / self._config['ANGLE_1MS'])) return servoValue def __servoToAngle(self, value): """ Compute position from controller servo value. @param value: servo value @type value: int @return: position, in ° @rtype: float """ direction = DIRECTION_TABLE[self._config['DIRECTION']] dir_ = DIRECTION_INDEX[direction] position = (value - self._config['NEUTRAL_POSITION'] ) * self._config['ANGLE_1MS'] / dir_ / 1000. return position def read(self): position = self.__servoToAngle(self._hardware.getPosition()) return position - self._offset def drive(self, position, useOffset=True, wait=True): Logger().debug("PanoduinoAxis.drive(): '%s' drive to %.1f" % (self.capacity, position)) self._checkLimits(position) if useOffset: position += self._offset value = self.__angleToServo(position) self._hardware.setTarget(value) if wait: self.waitEndOfDrive() def waitEndOfDrive(self): while self.isMoving(): time.sleep(0.2) time.sleep( self._config['ADDITIONAL_DELAY']) # internal servo decelaration self.waitStop() def startJog(self, dir_): Logger().debug("PanoduinoAxis.startJog(): dir_=%s" % repr(dir_)) currentPos = self.read() position = currentPos #+ self._offset ??? if dir_ == '+': position += MANUAL_SPEED_TABLE[self._manualSpeed] else: position -= MANUAL_SPEED_TABLE[self._manualSpeed] self._checkLimits(position) position += self._offset value = self.__angleToServo(position) self._hardware.setTarget(value) def stop(self): self.waitStop() def waitStop(self): pass def isMoving(self): return self._hardware.getMovingState()
class PanoduinoAxis(AbstractHardwarePlugin, AbstractAxisPlugin): def _init(self): Logger().trace("PanoduinoAxis._init()") AbstractHardwarePlugin._init(self) AbstractAxisPlugin._init(self) self._hardware = PololuMicroMaestroHardware() def _defineConfig(self): AbstractAxisPlugin._defineConfig(self) AbstractHardwarePlugin._defineConfig(self) self._addConfigKey('_speed', 'SPEED', default=DEFAULT_SPEED[self.capacity]) self._addConfigKey('_acceleration', 'ACCEL', default=DEFAULT_ACCEL[self.capacity]) self._addConfigKey('_channel', 'CHANNEL', default=DEFAULT_CHANNEL[self.capacity]) self._addConfigKey('_direction', 'DIRECTION', default=DEFAULT_DIRECTION[self.capacity]) self._addConfigKey('_angle1ms', 'ANGLE_1MS', default=DEFAULT_ANGLE_1MS[self.capacity]) self._addConfigKey('_neutralPos', 'NEUTRAL_POSITION', default=DEFAULT_NEUTRAL_POSITION[self.capacity]) self._addConfigKey('_additionalDelay', 'ADDITIONAL_DELAY', default=DEFAULT_ADDITIONAL_DELAY) def _checkLimits(self, position): """ Check if the position can be reached. First check if the position in degres is in the user limits (done in parent class), then check if the servo can mechanically reach the position. """ AbstractAxisPlugin._checkLimits(self, position) value = self.__angleToServo(position) if not VALUE_MIN <= value <= VALUE_MAX: raise HardwareError("Servo limit reached: %.2f not in [%d-%d]" % (value, VALUE_MIN, VALUE_MAX)) def init(self): Logger().trace("PanoduinoAxis.init()") AbstractHardwarePlugin.init(self) self.configure() self._hardware.setTarget(self._config['NEUTRAL_POSITION']) def shutdown(self): Logger().trace("PanoduinoAxis.shutdown()") self.stop() self._hardware.shutdown() AbstractHardwarePlugin.shutdown(self) AbstractAxisPlugin.shutdown(self) def configure(self): Logger().trace("PanoduinoAxis.configure()") AbstractAxisPlugin.configure(self) self._hardware.setAxis(self._config['CHANNEL']) self._hardware.configure(self._config['SPEED'], self._config['ACCEL']) def __angleToServo(self, position): """ Compute controller servo value from position. @param position: position, in ° @type position: float @return: value to send to servo controller @rtype: int """ direction = DIRECTION_TABLE[self._config['DIRECTION']] dir_ = DIRECTION_INDEX[direction] servoValue = int(round(self._config['NEUTRAL_POSITION'] + dir_ * position * 1000. / self._config['ANGLE_1MS'])) return servoValue def __servoToAngle(self, value): """ Compute position from controller servo value. @param value: servo value @type value: int @return: position, in ° @rtype: float """ direction = DIRECTION_TABLE[self._config['DIRECTION']] dir_ = DIRECTION_INDEX[direction] position = (value - self._config['NEUTRAL_POSITION']) * self._config['ANGLE_1MS'] / dir_ / 1000. return position def read(self): position = self.__servoToAngle(self._hardware.getPosition()) return position - self._offset def drive(self, position, useOffset=True, wait=True): Logger().debug("PanoduinoAxis.drive(): '%s' drive to %.1f" % (self.capacity, position)) self._checkLimits(position) if useOffset: position += self._offset value = self.__angleToServo(position) self._hardware.setTarget(value) if wait: self.waitEndOfDrive() def waitEndOfDrive(self): while self.isMoving(): time.sleep(0.2) time.sleep(self._config['ADDITIONAL_DELAY']) # internal servo decelaration self.waitStop() def startJog(self, dir_): Logger().debug("PanoduinoAxis.startJog(): dir_=%s" % repr(dir_)) currentPos = self.read() position = currentPos #+ self._offset ??? if dir_ == '+': position += MANUAL_SPEED_TABLE[self._manualSpeed] else: position -= MANUAL_SPEED_TABLE[self._manualSpeed] self._checkLimits(position) position += self._offset value = self.__angleToServo(position) self._hardware.setTarget(value) def stop(self): self.waitStop() def waitStop(self): pass def isMoving(self): return self._hardware.getMovingState()