def __shutdown( ): #not sure if already set or should be in Plugin!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! cmd = "AMVP ABS, 0, 0" #send axis 0 home self._driver.empty() self._driver.write("%s\r" % cmd) c = '' c = self._driver.read(100) (header, errorCode, replyValue) = c.split(' ') #splits incoming string if errorCode != '100': raise HardwareError( "Axis did not go home" ) #check !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! cmd = "AMVP ABS, 1, 0" #send axis 1 home self._driver.empty() self._driver.write("%s\r" % cmd) c = '' c = self._driver.read(100) (header, errorCode, replyValue) = c.split(' ') #splits incoming string if errorCode != '100': raise HardwareError( "Axis did not go home" ) #check !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! cmd = "ABIN" #return module to binary input self._driver.empty() self._driver.write("%s\r" % cmd)
def init(self): #self.__localCwd = None # Needed? self.__gphotoShell = GphotoShell(self._config['PROGRAM_PATH']) # List up root directory of the camera dirs, files = self.__gphotoShell.ls() if dirs is None or files is None: raise HardwareError("Unable to access camera file system") # List config configs = self.__gphotoShell.listConfig() if configs is None or len(configs) == 0: raise HardwareError( "Unable to retrieve config list from the camera") for config in configs: if config.endswith("/shutterspeed") or config.endswith("/exptime"): self.__speedConfig = config # Detected a 'Your Camera Model here' message ???!!!??? #Logger().debug("GphotoBracketShutter.init(): gphoto2.stderr=\"%s\"" % self.__gphotoShell.popen.stderr.readline().rstrip()) # Get config props, choices = self.__gphotoShell.getConfig(self.__speedConfig) if props is None or choices is None: raise HardwareError("Unable to read shutter speed") # Load all available speeds and the current speed self.__availableSpeeds = choices self.__baseSpeed = props['Current'] for index, choice in enumerate(choices): if choice == self.__baseSpeed: self.__baseSpeedIndex = index if float(self.__availableSpeeds[1]) > float(self.__availableSpeeds[2]): self.__speedOrder = 1 # Slower speed first else: self.__speedOrder = -1 # Faster speed first # Guess EV step (1/2, or 1/3) if float(self.__availableSpeeds[1]) / float( self.__availableSpeeds[3]) < 1.9: self.__evSteps = 3 else: self.__evSteps = 2 Logger().debug("GphotoBracketShutter.init(): basespeed=%s config=%s order=%+d steps=1/%d" % \ (self.__baseSpeed, self.__speedConfig, self.__speedOrder, self.__evSteps))
def establishConnection(self): # Move to hardware? """ Establish the connection. The SIN-11 device used to control the Pixorb axis needs to be initialised before any command can be sent to the axis controllers. """ AbstractHardwarePlugin.establishConnection(self) Logger().trace("AbstractPixOrbHardware.establishConnection()") if not AbstractPixOrbHardware.__initSIN11: try: answer = "" self._driver.empty() # Ask the SIN-11 to scan online controllers self._driver.write('&') # Add '\n' if ethernet driver? self._driver.setTimeout(SIN11_INIT_TIMEOUT) # Sin-11 takes several seconds to answer c = '' while c != '\r': c = self._driver.read(1) if c in ('#', '?'): self._driver.read(2) # Read last CRLF Logger().debug("AbstractPixOrbHardware.establishConnection(): SIN-11 '&' answer=%s" % answer) raise HardwareError("Can't init SIN-11") else: answer += c answer = answer.strip() # Remove final CRLF Logger().debug("AbstractPixOrbHardware.establishConnection(): SIN-11 '&' answer=%s" % answer) AbstractPixOrbHardware.__initSIN11 = True self._driver.setTimeout(ConfigManager().getFloat('Plugins/HARDWARE_COM_TIMEOUT')) except: self._connected = False raise
def __sendCmd(self, cmd, param=""): """ Send a command to the axis. @param cmd: command to send @type cmd: str @return: answer @rtype: str """ cmd = "%s%d%s" % (cmd, self._axis, param) #Logger().debug("GigaPanBotHardware.__sendCmd(): axis %d cmd=%s" % (self._axis, repr(cmd))) for nbTry in xrange(self._nbRetry): try: self._driver.empty() self._driver.write(":%s\r" % cmd) answer = "" while True: c = self._driver.read(1) #Logger().debug("GigaPanBotHardware.__sendCmd(): c=%s" % repr(c)) if c == '=': continue elif c == '!': c = self._driver.read(1) # Get error code # Do we need to read an additional '\r', here? raise HardwareError("Error in command %s (err=%s)" % (repr(cmd), repr(c))) elif c == '\r': break else: answer += c except (IOError, HardwareError): Logger().exception("GigaPanBotHardware.__sendCmd") Logger().warning( "GigaPanBotHardware.__sendCmd(): axis %d can't sent command %s. Retrying..." % (self._axis, repr(cmd))) else: break else: raise HardwareError("Axis %d can't send command %s" % (self._axis, repr(cmd))) #Logger().debug("GigaPanBotHardware.__sendCmd(): axis %d ans=%s" % (self._axis, repr(answer))) return answer
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 __zeroAxisValue(self): #added for zeroing axis home position cmd = "ASAP 1,", self._axis, ", 0" #zero axis position self._driver.empty() self._driver.write("%s\r" % cmd) c = '' c = self._driver.read(100) (header, errorCode, replyValue) = c.split(' ') #splits incoming string if errorCode != '100': raise HardwareError( "Axis did not set home" ) #check !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
def create(self, type_): """ create a hardware driver object. @param type_: type of hardware object @type type_: str @raise HardwareError: unknown type """ try: # Bluetooth driver # Nous on utilise aujourd'hui que celui la. if type_ == 'bluetooth': if self.__drivers['bluetooth'] is None: from bluetoothDriver import BluetoothDriver mutex = QtCore.QMutex(QtCore.QMutex.Recursive) self.__drivers['bluetooth'] = BluetoothDriver(mutex) return self.__drivers['bluetooth'] # Serial driver elif type_ == 'serial': if self.__drivers['serial'] is None: from serialDriver import SerialDriver mutex = QtCore.QMutex(QtCore.QMutex.Recursive) self.__drivers['serial'] = SerialDriver(mutex) return self.__drivers['serial'] # Ethernet driver elif type_ == 'ethernet': if self.__drivers['ethernet'] is None: from ethernetDriver import EthernetDriver mutex = QtCore.QMutex(QtCore.QMutex.Recursive) self.__drivers['ethernet'] = EthernetDriver(mutex) return self.__drivers['ethernet'] else: raise HardwareError("Unknown '%s' driver type" % type_) except Exception, msg: Logger().exception("DriverFactory.create()") raise HardwareError(unicode(msg))
def _init(self): host = ConfigManager().get('Plugins/HARDWARE_ETHERNET_HOST') port = ConfigManager().getInt('Plugins/HARDWARE_ETHERNET_PORT') Logger().debug("EthernetDriver._init(): trying to connect to %s:%d..." % (host, port)) try: #import time #time.sleep(3) self.setDeviceHostPort(host, port) self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self._sock.connect((self.__host, self.__port)) self._sock.settimeout(ConfigManager().getFloat('Plugins/HARDWARE_COM_TIMEOUT')) self.empty() except Exception, msg: Logger().exception("EthernetDriver._init()") raise HardwareError(msg)
def _init(self): Logger().trace("BluetoothDriver._init()") address = ConfigManager().get('Plugins/HARDWARE_BLUETOOTH_DEVICE_ADDRESS') Logger().debug("BluetoothDriver._init(): trying to connect to %s..." % address) try: self._sock = BluetoothSocket(RFCOMM) self._sock.connect((address, 1)) try: self._sock.settimeout(ConfigManager().getFloat('Plugins/HARDWARE_COM_TIMEOUT')) except NotImplementedError: Logger().warning("BluetoothDriver._init(): bluetooth stack does not implment settimeout()") except BluetoothError, error: Logger().exception("BluetoothDriver._init()") err, msg = eval(error.message) raise HardwareError(msg)
def __sendCmd(self, cmd, param=""): """ Send a command to the axis. @param cmd: command to send @type cmd: str @return: answer @rtype: str """ cmd = ":%s%d%s\r" % (cmd, self._axis, param) #Logger().debug("MerlinOrionHardware.__sendCmd(): axis %d cmd=%s" % (self._axis, repr(cmd))) for nbTry in xrange(self._nbRetry): try: answer = "" self._driver.empty() self._driver.write(cmd) c = '' while c not in ('=', '!'): c = self._driver.read(1) #Logger().debug("MerlinOrionHardware.__sendCmd(): c=%s" % repr(c)) if c == '!': c = self._driver.read(1) # Get error code raise IOError("Error in command %s (err=%s)" % (repr(cmd), c)) answer = "" while True: c = self._driver.read(1) #Logger().debug("MerlinOrionHardware.__sendCmd(): c=%s" % repr(c)) if c == '\r': break answer += c except IOError: Logger().exception("MerlinOrionHardware.__sendCmd") Logger().warning( "MerlinOrionHardware.__sendCmd(): axis %d can't sent command %s. Retrying..." % (self._axis, repr(cmd))) else: break else: raise HardwareError("axis %d can't send command %s" % (self._axis, repr(cmd))) #Logger().debug("MerlinOrionHardware.__sendCmd(): axis %d ans=%s" % (self._axis, repr(answer))) return answer
def __sendCmd(self, cmd): """ Send a command to the axis. @param cmd: command to send @type cmd: str @return: answer @rtype: str """ Logger().debug("OwlHardware.__sendCmd(): cmd=%s" % (repr(cmd))) for nbTry in xrange(self._nbRetry): try: answer = "" self._driver.empty() self._driver.write("%s\r" % cmd) c = '' '''c = self._driver.read(100) (header, errorCode, replyValue) = c.split(' ') if errorCode != '100': raise IOError("Error in command %s (err=%s)" % (repr(cmd), c))''' answer = "" while True: c = self._driver.read(1) if c == '\r': break answer += c (header, errorCode, replyValue) = answer.split(" ") answer = (replyValue) if errorCode == '100': return answer #will this work except IOError: Logger().exception("OwlHardware.__sendCmd") Logger().warning( "OwlHardware.__sendCmd(): axis %d can't sent command %s. Retrying..." % (self._axis, repr(cmd))) else: break else: raise HardwareError("axis %d can't send command %s" % (self._axis, repr(cmd))) #Logger().debug("OwlHardware.__sendCmd(): axis %d ans=%s" % (self._axis, repr(answer))) return answer
def __sendCmd(self, cmd, axis): """ Send a command to the axis. @param cmd: command to send @type cmd: str @param axis: name of the axis @type axis: str @return: answer @rtype: str """ cmd = "%s%s" % (axis, cmd) #Logger().debug("PixOrbHardware.__sendCmd(): axis %s cmd=%s" % (axis, repr(cmd))) for nbTry in xrange(self._nbRetry): try: answer = "" self._driver.empty() self._driver.write("%s\n" % cmd) c = '' while c != '\r': c = self._driver.read(1) if c in ('#', '!', '$'): self._driver.read(2) # Read last CRLF raise IOError("Error on command '%s' (answer=%s)" % (cmd, answer)) else: answer += c except IOError: Logger().exception("PixOrbHardware.__sendCmd") Logger().warning( "PixOrbHardware.__sendCmd(): axis %s failed to send command '%s'. Retrying..." % (axis, cmd)) else: answer = answer.strip() # Remove final CRLF break else: raise HardwareError("Axis %s can't send command %s (answer=%s)" % (axis, repr(cmd), repr(answer))) #Logger().debug("PixOrbHardware.__sendCmd(): axis %s, ans=%s" % (axis, repr(answer))) return answer
def init(self): """ Init the Owl hardware. Done only once. """ if self._axis == 0: self._driver.acquireBus() try: self.__encoderFullCircle = 1152000 cmd = '\x01\x8B\x00\x00\x00\x00\x00\x00\x8C' #set module to ascii self._driver.empty() self._driver.write("%s\r" % cmd) cmd = 'ASGP 67, 0, 33' #echo cancel self._driver.empty() self._driver.write("%s\r" % cmd) c = '' answer = "" while True: c = self._driver.read(1) if c == '\r': break answer += c (header, errorCode, replyValue) = answer.split(" ") #Logger().debug("int(): answer=%s header=%s errorCode=%s replyValue=%s" % (answer, header, errorCode, replyValue)) value = int(replyValue) if errorCode != '100': raise HardwareError("Module did not initialize properly") Logger().debug( "OwlHardware.init(): encoder full circle=%s" % self.__encoderFullCircle) finally: self._driver.releaseBus() return
def init(self): #self._driver.setTimeout(0.1) # Only initialize if we have yaw or pitch, not shutter class if self._axis != 0: self._driver.acquireBus() try: # Rodeon head also had a transceiver to initialize. Do it before anything. # When done, don't initialize twice... if self._axis == 1: # Reset transceiver twice value = self.__sendCmd("R", 0) # Is transceiver answering to reset order? if len(value) == 0: raise HardwareError("No answer at all. Check baudrate (must be 19200, not 9600). Stopping...") elif value == 'R': # Good answer Logger().debug("ClaussHardware.init(): Transceiver answer successfully to reset order") else: # No, probably bad serial or hardware raise HardwareError("Is it a Clauss hardware? I can't talk with it. Stopping...") # Get brand value = self.__sendCmd("m", 0, 2, "") if value != "CLAUSS": # Retry... Logger().debug("ClaussHardware.init(): BRAND ERROR. Retrying...") value = self.__sendCmd("m", 0, 2, "") if value != "CLAUSS": raise HardwareError("'%s' is not a Clauss head. Stopping..." % value) Logger().debug("ClaussHardware.init(): Transceiver brand=%s" % value) value = self.__sendCmd("w", 0, 2, "") Logger().debug("ClaussHardware.init(): Transceiver reference number=%s" % value) value = self.__sendCmd("v", 0, 2, "") Logger().debug("ClaussHardware.init(): Transceiver firmware version=%s" % value) # Reset motor self.__sendCmd("R", self._axis) # Go to factory position 0° self.__sendCmd("Y", self._axis) # Get reference number transceiver value = self.__sendCmd("w", self._axis, 2, "") Logger().debug("ClaussHardware.init(): axis=%d, motor reference number=%s" % (self._axis, value)) # Get brand value = self.__sendCmd("m", self._axis, 2, "") if value != "CLAUSS": raise HardwareError("ClaussHardware.init(): '%s' is not a Clauss head, stopping..." % value) Logger().debug("ClaussHardware.init(): axis=%d, motor brand=%s" % (self._axis, value)) # Get firmware version value = self.__sendCmd("v", self._axis, 2, "") Logger().debug("ClaussHardware.init(): axis=%d, motor firmware version=%s" % (self._axis, value)) # Get number of steps self.__encoderFullCircle = int(self.__sendCmd("u", self._axis, 2, "")) Logger().debug("ClaussHardware.init(): axis=%d, number of steps=%d accuracy=%s°" % (self._axis, self.__encoderFullCircle, 360./self.__encoderFullCircle)) # Get max speed self.__maxSpeed = int(self.__sendCmd("f", self._axis, 2)) Logger().debug("ClaussHardware.init(): axis=%d, motor max speed=%s" % (self._axis, self.__maxSpeed)) # Unknow command self.__sendCmd("a", self._axis, 2, "") # Wait motor to reach 0° position (issued by command Y) while self.isMoving(): time.sleep(1) Logger().debug("ClaussHardware.init(): axis=%d, motor is still moving. Waiting..." % self._axis) # Reset position to 0° self.__sendCmd("N", self._axis) # Acheive initialisation with this unknow commands for transceiver... # Do it after anything. if self._axis == 2: Logger().debug("ClaussHardware.init(): axis=%d, finalizing transceiver init" % self._axis) self.__sendCmd("L", 0, 1, "00") self.__sendCmd("L", 0, 1, "10") self.__sendCmd("L", 0, 1, "20") self.__sendCmd("L", 0, 1, "30") self.__sendCmd("L", 0, 1, "40") self.__sendCmd("L", 0, 1, "50") self.__sendCmd("L", 0, 1, "60") self.__sendCmd("L", 0, 1, "70") self.__sendCmd("L", 0, 1, "80") self.__sendCmd("L", 0, 1, "90") Logger().debug("ClaussHardware.init(): axis=%d, init done" % self._axis) if self.isOnBattery(): Logger().debug("ClaussHardware.init(): Clauss head is on battery (%d)" % self.checkBattery()) else: Logger().debug("ClaussHardware.init(): Clauss head is on AC power") finally: self._driver.releaseBus()
def __sendCmd(self, cmd, element=0, cr=1, param=""): """ Send a command to the axis. @param cmd: command to send @type cmd: str @param element: element ID (0 for transceiver, 1 for motor H, 2 for motor V) @type element: int @param cr: number of CR normally returned. @type cr: int @param param: additionnal parameter @type param: str @return: answer @rtype: str """ # Append 'c' and element number to a single hexa value hexQuery = "0x%c%d" % ('c', element) hexPredictedAnswer = "0x%c%d" % ('a', element) # Create command, ended by CR. hexcmd = "%c%c%s%c" % (int(hexQuery, 16), cmd, param, '\r') for nbTry in xrange(self._nbRetry): try: self._driver.empty() self._driver.write(hexcmd) answer = "" crCount = 1 begin = False magic = False while True: c = self._driver.read(1) # Valid answer, processing if ord(c) == int(hexPredictedAnswer, 16) and not begin: magic = True begin = True continue # Valid answer, processing elif ord(c) == int(hexPredictedAnswer, 16) and begin: magic = True continue # Invalid value, waiting answer pattern elif ord(c) != int(hexPredictedAnswer, 16) and not begin: continue # Ignore some Bluetooth answers (b0/b9) elif c == 'b' and cmd != 'R' and magic: crCount -= 1 continue # Verifying validity of answer elif c == cmd and magic: magic = False # For short command with 1 CR, just return an ack. if cr == 1: answer += c continue # Correct number of CR: end of processing elif c == '\r' and crCount == cr: break # CR elif c == '\r': crCount += 1 # Usefull char for answer elif crCount == cr: answer += c except (IOError, HardwareError): Logger().exception("ClaussHardware.__sendCmd()") Logger().warning("ClaussHardware.__sendCmd(): Can't sent command %s to element %d. Retrying..." % (repr(cmd), element)) else: break else: raise HardwareError("Can't send command %s to element %d" % (repr(cmd), element)) #Logger().debug("ClaussHardware.__sendCmd(): element=%d, ans=%s" % (element, repr(answer))) # empty ignored part of actual answer #self._driver.empty() return answer
def handleCmd(self, cmdStr): """ Handle a command. @param cmdStr: command to simulate @type cmdStr: str @return: response @rtype: str raise HardwareError: wrong command """ Logger().debug("GigaPanBotBaseHandler.handleCmd(): cmdStr=%s" % cmdStr) if not cmdStr.startswith(':'): raise HardwareError("Invalid command format (%s)" % repr(cmdStr)) # Split cmdStr cmd = cmdStr[1] numAxis = int(cmdStr[2]) if numAxis not in (1, 2): raise HardwareError("Invalid axis number (%d)" % numAxis) param = cmdStr[3:-1] Logger().debug( "GigaPanBotBaseHandler.handleCmd(): cmdStr=%s, cmd=%s, numAxis=%d, param=%s" % (repr(cmdStr), cmd, numAxis, param)) # Compute command response response = "" # Stop command if cmd == 'L': Logger().debug("GigaPanBotBaseHandler.handleCmd(): stop") self._axis[numAxis].stop() # Get encoder full circle command elif cmd == 'a': Logger().debug( "GigaPanBotBaseHandler.handleCmd(): get encoder full circle") response = self._encodeAxisValue(self._angleToEncoder(0xE62D3)) # Get firmeware version command elif cmd == 'e': Logger().debug( "GigaPanBotBaseHandler.handleCmd(): get firmware version?") response = "Vx.x" # Read command elif cmd == 'j': Logger().debug("GigaPanBotBaseHandler.handleCmd(): read") pos = self._axis[numAxis].read() response = self._encodeAxisValue(self._angleToEncoder(pos)) # Status command elif cmd == 'f': Logger().debug("GigaPanBotBaseHandler.handleCmd(): status") if self._axis[numAxis].isMoving(): response = "1" else: response = "0" # Connect/disconnect command elif cmd == 'F': Logger().debug( "GigaPanBotBaseHandler.handleCmd(): connect/disconnect") # Start jog command elif cmd == 'G': Logger().debug("GigaPanBotBaseHandler.handleCmd(): start jog") #self._axisCmd[numAxis] = 'jog' if param == '0': dir_ = '+' elif param == '1': dir_ = '-' else: raise HardwareError("Invalid param") self._axis[numAxis].startJog(dir_) Logger().debug( "GigaPanBotBaseHandler.handleCmd(): axis %d direction=%s" % (numAxis, dir_)) # Goto command elif cmd == 'S': Logger().debug("GigaPanBotBaseHandler.handleCmd(): goto") self._axis[numAxis].drive(self._encoderToAngle( self._decodeAxisValue(param)), wait=False) # Speed command elif cmd == 'I': Logger().debug("GigaPanBotBaseHandler.handleCmd(): speed") speed = int(param) Logger().debug( "GigaPanBotBaseHandler.handleCmd(): axis %s speed=%d" % (numAxis, speed)) # Output command elif cmd == 'O': Logger().debug("GigaPanBotBaseHandler.handleCmd(): output") # Invalid command else: raise HardwareError("Invalid command") return "=%s\r" % response
def handleCmd(self, cmdStr): """ Handle a command. @param cmdStr: command to simulate @type cmdStr: str @return: response @rtype: str raise HardwareError: wrong command """ Logger().debug("MerlinOrionBaseHandler.handleCmd(): cmdStr=%s" % cmdStr) if not cmdStr.startswith(':'): raise HardwareError("Invalid command format (%s)" % repr(cmdStr)) # Split cmdStr cmd = cmdStr[1] numAxis = int(cmdStr[2]) if numAxis not in (1, 2): raise HardwareError("Invalid axis number (%d)" % numAxis) param = cmdStr[3:-1] Logger().debug( "MerlinOrionBaseHandler.handleCmd(): cmdStr=%s, cmd=%s, numAxis=%d, param=%s" % (repr(cmdStr), cmd, numAxis, param)) # Compute command response response = "" # Stop command if cmd == 'L': Logger().debug("MerlinOrionBaseHandler.handleCmd(): stop") self._axis[numAxis].stop() response = "" # Check motor command elif cmd == 'F': Logger().trace("MerlinOrionBaseHandler.handleCmd(): ???") # Get encoder full circle command elif cmd == 'a': Logger().debug("MerlinOrionBaseHandler.handleCmd(): ???") response = self._encodeAxisValue(ENCODER_FULL_CIRCLE) # Get sidereal rate command elif cmd == 'D': Logger().debug("MerlinOrionBaseHandler.handleCmd(): ???") response = self._encodeAxisValue(SIDEREAL_RATE) # Get firmeware version command elif cmd == 'e': Logger().debug("MerlinOrionBaseHandler.handleCmd(): ???") response = "xxxxxx" # Read command elif cmd == 'j': Logger().debug("MerlinOrionBaseHandler.handleCmd(): read") pos = self._axis[numAxis].read() response = self._encodeAxisValue(self._angleToEncoder(pos)) # Status command elif cmd == 'f': Logger().debug("MerlinOrionBaseHandler.handleCmd(): status") if self._axis[numAxis].isMoving(): response = "-1-" else: response = "-0-" # Set action command elif cmd == 'G': Logger().debug("MerlinOrionBaseHandler.handleCmd(): set action") if param[0] == '0': self._axisCmd[numAxis] = 'drive' elif param[0] == '3': self._axisCmd[numAxis] = 'jog' if param[1] == '0': self._axisDir[numAxis] = '+' elif param[1] == '1': self._axisDir[numAxis] = '-' else: raise HardwareError("Invalid param") Logger().debug( "MerlinOrionBaseHandler.handleCmd(): axis %d direction=%s" % (numAxis, self._axisDir[numAxis])) else: raise NotImplementedError # Speed command elif cmd == 'I': Logger().debug("MerlinOrionBaseHandler.handleCmd(): speed") try: speed = self._decodeAxisValue(param) Logger().debug( "MerlinOrionBaseHandler.handleCmd(): axis %d speed=%d" % (numAxis, speed)) self._axisSpeed[numAxis] = speed except KeyError: raise HardwareError("No direction has been set") # Position command elif cmd == 'S': Logger().debug("MerlinOrionBaseHandler.handleCmd(): position") self._axisPos[numAxis] = self._encoderToAngle( self._decodeAxisValue(param)) # Run command elif cmd == 'J': Logger().debug("MerlinOrionBaseHandler.handleCmd(): run") try: if self._axisCmd[numAxis] == 'jog': dir_ = self._axisDir[numAxis] speed = self._axisSpeed[numAxis] self._axis[numAxis].startJog(dir_) elif self._axisCmd[numAxis] == 'drive': pos = self._axisPos[numAxis] self._axis[numAxis].drive(pos, wait=False) except KeyError: raise HardwareError( "Missing one axis cmd/direction/speed value") # Shutter command elif cmd == 'O': Logger().debug("MerlinOrionBaseHandler.handleCmd(): shutter") # Invalid command else: raise HardwareError("Invalid command") return "=%s\r" % response
def start(self): """ Start pano shooting. """ def checkPause(): """ Check if pause requested. """ if self.__pause: Logger().info("Pause shooting") self.__pauseTime = time.time() self.__paused = True self.paused() while self.__pause: time.sleep(0.1) self.__paused = False self.resumed() self.__totalPausedTime += time.time() - self.__pauseTime Logger().info("Resume shooting") def checkStop(): """ Check if stop requested. """ if self.__stop: Logger().info("Stop shooting") raise StopIteration Logger().trace("Shooting.start()") self.__startTime = time.time() self.__totalPausedTime = 0. self.__stop = False self.__pause = False self.__paused = False self.__shooting = True self.started() self.progress(0., 0.) if self.cameraOrientation == 'portrait': roll = 90. elif self.cameraOrientation == 'landscape': roll = 0. elif self.cameraOrientation == 'custom': roll = self.cameraRoll else: raise ValueError("cameraOrientation must be in ('portrait', 'landscape', 'custom'") focal = self.camera.lens.focal if self.camera.lens.type_ == 'rectilinear': focal *= self.camera.lens.opticalMultiplier values = {'title' : ConfigManager().get('Configuration/DATA_TITLE'), 'gps': ConfigManager().get('Configuration/DATA_GPS'), 'comment': ConfigManager().get('Configuration/DATA_COMMENT') % {'version': config.VERSION}, 'headOrientation': "up", 'cameraOrientation': "%s" % self.cameraOrientation, 'roll': "%.1f" % roll, 'stabilizationDelay': "%.1f" % self.stabilizationDelay, 'counter': "%03d" % self.shootingCounter, 'timeValue': "%.1f" % self.shutter.timeValue, 'bracketingNbPicts': "%d" % self.shutter.bracketingNbPicts, 'sensorCoef': "%.1f" % self.camera.sensorCoef, 'sensorRatio': "%s" % self.camera.sensorRatio, 'lensType': "%s" % self.camera.lens.type_, 'focal': "%.1f" % focal } Logger().info("Start shooting process...") try: # Timer after if self.timerAfterEnable: initialTime = time.time() remainingTime = self.timerAfter - (time.time() - initialTime) while remainingTime > 0: Logger().debug("Shooting.start(): start in %s" % sToHmsAsStr(remainingTime)) self.waiting(remainingTime) time.sleep(1) # Check only stop checkStop() remainingTime = self.timerAfter - (time.time() - initialTime) # Timer repeat if self.timerRepeatEnable: numRepeat = self.timerRepeat else: numRepeat = 1 for repeat in xrange(1, numRepeat + 1): # Create data object (use a factory) if self.mode == 'mosaic': Logger().debug("Shooting.start(): create mosaic data object") data = MosaicData() values.update({'yawNbPicts': "%d" % self.mosaic.yawNbPicts, 'pitchNbPicts': "%d" % self.mosaic.pitchNbPicts, 'overlap': "%.2f" % self.mosaic.overlap, 'yawRealOverlap': "%.2f" % self.mosaic.yawRealOverlap, 'pitchRealOverlap': "%.2f" % self.mosaic.pitchRealOverlap}) else: Logger().debug("Shooting.start(): create preset data object") data = PresetData() values.update({'name': "%s" % self.preset.name}) # Create header data.createHeader(values) # Increase shooting counter self.shootingCounter += 1 if self.shootingCounter > config.SHOOTING_COUNTER_MAX: self.shootingCounter = 1 ConfigManager().save() startTime = time.time() Logger().debug("Shooting.start(): repeat %d/%d" % (repeat, numRepeat)) self.repeat(repeat) self.progress(0.) # Loop over all positions self.scan.index = 1 while True: try: index, (yaw, pitch) = self.scan.getCurrentPosition() if isinstance(index, tuple): index_, yawIndex, pitchIndex = index else: index_ = index Logger().debug("Shooting.start(): pict #%d of %d, index=%s, yaw=%.1f, pitch=%.1f" % (index_, self.scan.totalNbPicts, str(index), yaw, pitch)) self.update(index, yaw, pitch, next=True) self.__forceNewPosition = False Logger().info("Moving") self.sequence('moving') self.head.gotoPosition(yaw, pitch) # Test step-by-step flag (use a function) if self.__stepByStep and not self.__stop: self.__pause = True Logger().info("Wait for manual shooting trigger...") # 'Pause every' feature if self.pauseEveryEnable and self.scan.index > 1 and not self.scan.index % self.pauseEvery - 1: self.__pause = True Logger().info("Automatic pausing...") checkPause() checkStop() # If a new shooting position has been requested (rewind/forward), # we start over if self.__forceNewPosition: continue # Take pictures for bracket in xrange(1, self.shutter.bracketingNbPicts + 1): # Mirror lockup sequence # TODO: move call to plugin! if self.shutter.mirrorLockup: Logger().info("Mirror lockup") self.sequence('mirror') retCode = self.shutter.lockupMirror() if retCode: raise HardwareError(self.tr("Shutter failed while mirror locking up")) self.__LastShootTime = time.time() Logger().info("Stabilization") self.sequence('stabilization') time.sleep(self.stabilizationDelay) # Take pictures Logger().info("Shutter cycle") Logger().debug("Shooting.start(): bracket #%d of %d" % (bracket, self.shutter.bracketingNbPicts)) self.sequence('shutter', bracket) retCode = self.shutter.shoot(bracket) if retCode: raise HardwareError(self.tr("Shutter failed while shooting")) # Add image to the xml data file realYaw, realPitch = self.head.readPosition() data.addPicture(bracket, realYaw, realPitch, roll) checkStop() except OutOfLimitsError, msg: self.head.stopAxis() Logger().warning("Shooting.start(): %s" % unicode(msg)) state = 'invalid' except HardwareError, msg: self.head.stopAxis() Logger().exception("Shooting.start()") #Logger().warning("Shooting.start(): position index=%s, yaw=%.1f, pitch=%.1f out of limits" % (index_, yaw, pitch)) state = 'error'