Beispiel #1
0
    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))
Beispiel #3
0
    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))
Beispiel #6
0
    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  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Beispiel #7
0
    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))
Beispiel #8
0
 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)
Beispiel #9
0
 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
Beispiel #11
0
    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
Beispiel #12
0
    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
Beispiel #13
0
    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
Beispiel #14
0
    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()
Beispiel #15
0
    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
Beispiel #18
0
    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'