def startCmd(self, cmdStr, userCmd=None, callFunc=None, timeLim=0.):
     log.info("%s.startCmd(cmdStr=%s, userCmd=%s, callFunc=%s)"%(self, cmdStr, str(userCmd), str(callFunc)))
     # print("%s.startCmd(cmdStr=%s, userCmd=%s, callFunc=%s)"%(self, cmdStr, str(userCmd), str(callFunc)))
     # if not self.isConnected:
     #     userCmd.setState(userCmd.Failed, "filter wheel device not connected")
     # else:
     return ActorDevice.startCmd(self, cmdStr=cmdStr, userCmd=userCmd, callFunc=callFunc, timeLim=timeLim)
Esempio n. 2
0
    def handleReply(self, replyStr):
        """Handle a line of output from the device.

        @param[in] replyStr   the reply, minus any terminating \n
        """
        log.info("%s.handleReply(replyStr=%s)" % (self, replyStr))
        replyStr = replyStr.strip()
        # print(replyStr, self.currExeDevCmd.cmdStr)
        if not replyStr:
            return
        if self.currExeDevCmd.isDone:
            # ignore unsolicited output?
            log.info("%s usolicited reply: %s for done command %s" % (self, replyStr, str(self.currExeDevCmd)))
            self.writeToUsers("i", "%s usolicited reply: %s for done command %s" % (self, replyStr, str(self.currExeDevCmd)))
            return

        if "error 15" in replyStr.lower():
            self.writeToUsers("w", "Mitutoyo Error 15, not in counting state (was it power cycled?). Homing necessary.")
            self.encPos = [None]*6

        elif "error" in replyStr.lower():
            # some other error?
            self.writeToUsers("w", "Mitutoyo EV counter Error output: " + replyStr)

        if self.currExeDevCmd.cmdStr == READ_ENC:
            # all encoders values have been read
            # set command done
            self.setEncValue(replyStr)
            # was this the 6th value read? if so we are done
            if replyStr.startswith(ENCVAL_PREFIX+"%i"%6):
                self.currExeDevCmd.setState(self.currExeDevCmd.Done)
        if self.currExeDevCmd.cmdStr in [COUNTING_STATE, ZERO_SET, DISPLAY_CURR]:
            if replyStr == SUCESS:
                # successful set into counting state
                self.currExeDevCmd.setState(self.currExeDevCmd.Done)
Esempio n. 3
0
    def target(self, ra, dec, doHA, userCmd=None):
        """Set coordinates for a slew.

        @param[in] ra: right ascension decimal degrees
        @param[in] dec: declination decimal degrees
        @param[in] doHA: if True, use degrees in hour angle rather than ra.
        @param[in] userCmd: a twistedActor BaseCommand.
        """
        log.info("%s.slew(userCmd=%s, ra=%.2f, dec=%.2f)" % (self, userCmd, ra, dec))
        userCmd = expandUserCmd(userCmd)
        if not self.conn.isConnected:
            userCmd.setState(userCmd.Failed, "Not Connected to TCS")
            return userCmd
        if doHA:
            enterRa = "HAD %.8f"%ra
        else:
            enterRa = "RAD %.8f"%ra
        enterDec = "DECD %.8f"%dec
        enterEpoch = "MP %.2f"%2000 # LCO: HACK should coords always be 2000?
        devCmdList = [DevCmd(cmdStr=cmdStr) for cmdStr in [enterRa, enterDec, enterEpoch]]#, cmdSlew]]
        # set userCmd done only when each device command finishes
        # AND the pending slew is also done.
        # when the last dev cmd is done (the slew), set axis cmd statue to slewing

        LinkCommands(userCmd, devCmdList) #LCO: HACK don't wait for a slew to finish + [self.waitSlewCmd])
        for devCmd in devCmdList:
            self.queueDevCmd(devCmd)

        statusStr = self.status.getStatusStr()
        if statusStr:
            self.writeToUsers("i", statusStr, userCmd)
        return userCmd
Esempio n. 4
0
    def handleReply(self, replyStr):
        """Handle a line of output from the device. Called whenever the device outputs a new line of data.

        @param[in] replyStr   the reply, minus any terminating \n

        Tasks include:
        - Parse the reply
        - Manage the pending commands
        - Parse status to update the model parameters
        """
        log.info("%s read %r, currCmdStr: %s" % (self, replyStr, self.currDevCmdStr))
        # print("%s read %r, currCmdStr: %s" % (self, replyStr, self.currDevCmdStr))
        replyStr = replyStr.strip()
        if not replyStr:
            return
        if self.currExeDevCmd.isDone:
            # ignore unsolicited ouput
            return
        if "error" in replyStr.lower():
            # error
            self.writeToUsers("w", "Error in M2 reply: %s, current cmd: %s"%(replyStr, self.currExeDevCmd.cmdStr))
        # if this was a speed command, set it
        if self.currDevCmdStr.lower() == "speed":
            self.status.speed = float(replyStr)
        elif self.currDevCmdStr.lower() == "status":
            self.processStatus(replyStr)
        # only one line is ever returned after a request
        # so if we got one, then the request is done
        self.currExeDevCmd.setState(self.currExeDevCmd.Done)
Esempio n. 5
0
    def handleReply(self, replyStr):
        """Handle a line of output from the device. Called whenever the device outputs a new line of data.

        @param[in] replyStr   the reply, minus any terminating \n

        Tasks include:
        - Parse the reply
        - Manage the pending commands
        - Output data to users
        - Parse status to update the model parameters
        - If a command has finished, call the appropriate command callback
        """
        log.info("%s read %r, currCmdStr: %s" % (self, replyStr, self.currDevCmdStr))
        replyStr = replyStr.strip()
        if replyStr == "-1":
            # error
            errorStr = "handleReply failed for %s with -1"%self.currDevCmdStr
            if self.waitOffsetCmd.isActive:
                self.waitOffsetCmd.setState(self.waitOffsetCmd.Failed, errorStr)
            if self.waitRotCmd.isActive:
                # note the clamp should still execute!!!!
                self.waitRotCmd.setState(self.waitRotCmd.Failed, errorStr)
            self.currExeDevCmd.setState(self.currExeDevCmd.Failed, errorStr)
            return
        statusField = self.status.statusFieldDict.get(self.currDevCmdStr, None)
        if statusField:
            # a piece of status was requested, parse it
            # how to check for error condition? parsing -1 as a float will still work.
            statusField.setValue(replyStr)
            self.currExeDevCmd.setState(self.currExeDevCmd.Done)
        elif replyStr == "0":
            # this was a command, a "0" is expected
            self.currExeDevCmd.setState(self.currExeDevCmd.Done)
        else:
            log.info("unexpected reply" % replyStr)
Esempio n. 6
0
    def focus(self, focusValue, offset=False, userCmd=None):
        """Command an offset or absolute focus move

        @param[in] focusValue: float, focus value in microns
        @param[in] offset, if true this is offset, else absolute
        @param[in] userCmd: a twistedActor BaseCommand

        WARNING!!!
        At APO increasing focus corresponds to decreasing M1-M2 dist.
        The mirror controller at LCO convention is the opposite.
        """
        log.info("%s.focus(userCmd=%s, focusValue=%.2f, offset=%s)" % (self, userCmd, focusValue, str(bool(offset))))
        # if this focus value is < 50 microns
        userCmd = expandUserCmd(userCmd)
        if offset:
            deltaFocus = focusValue
        else:
            deltaFocus = self.status.secFocus - focusValue


        if abs(deltaFocus) < MIN_FOCUS_MOVE:
            # should focus be cancelled or just set to done?
            self.writeToUsers("w", "Focus offset below threshold of < %.2f, moving anyways."%MIN_FOCUS_MOVE, userCmd)
            # userCmd.setState(userCmd.Done)
            # return userCmd

        # focusDir = 1 # use M2's natural coordinates
        # focusDir = -1 # use convention at APO
        return self.move(valueList=[focusValue], offset=offset, userCmd=userCmd)
Esempio n. 7
0
    def queueDevCmd(self, devCmdStr, userCmd):
        def queueFunc(userCmd):
            self.startDevCmd(devCmdStr)

        self.cmdQueue.addCmd(userCmd, queueFunc)
        log.info("%s.runCommand(userCmd=%r, devCmdStr=%r, cmdQueue: %r" %
                 (self, userCmd, devCmdStr, self.cmdQueue))
Esempio n. 8
0
    def move(self, position, userCmd=None):
        """!Move to a position

        @param[in] postion: a float, position to move to (mm)
        @param[in] userCmd: a twistedActor BaseCommand
        """
        log.info("%s.move(postion=%.6f, userCmd=%s)" % (self, position, userCmd))
        userCmd=expandUserCmd(userCmd)
        if self.isMoving:
            userCmd.setState(userCmd.Failed, "Cannot move, device is busy moving")
            return userCmd
        # verify position is in range
        minPos, maxPos = self.status.moveRange
        if not minPos<=position<=maxPos:
            userCmd.setState(userCmd.Failed, "Move %.6f not in range [%.4f, %.4f]"%(position, minPos, maxPos))
            return userCmd
        self.iter = 1
        self.targetPos = position
        self.moveUserCmd = userCmd
        print("moving threadring to: ", self.targetPos)
        if not self.moveUserCmd.isActive:
            self.moveUserCmd.setState(self.moveUserCmd.Running)
        self.writeToUsers("i", "DesThreadRingPos=%.4f"%self.targetPos)
        moveDevCmd = self.queueDevCmd(self.getMoveCmdStr(), self.moveUserCmd)
        moveDevCmd.addCallback(self._moveCallback)
        return userCmd
 def cmd_move(self, userCmd):
     desPos = int(userCmd.parsedCommand.parsedPositionalArgs[0])
     log.info("%s.cmd_move(userCmd=%s) desPos: %i" %
              (self, userCmd, desPos))
     # print("%s.cmd_move(userCmd=%s) desPos: %i"%(self, userCmd, desPos))
     if desPos not in self.MoveRange:
         # raise ParseError("desPos must be one of %s for move command"%(str(self.MoveRange),))
         userCmd.setState(
             userCmd.Failed, "desPos must be one of %s for move command" %
             (str(self.MoveRange), ))
     elif not self.status.isHomed:
         userCmd.setState(userCmd.Failed,
                          "cannot command move, home filter wheel first.")
     elif not self.fwMoveCmd.isDone:
         userCmd.setState(userCmd.Failed, "filter wheel is moving")
     elif desPos == self.status.currentPos:
         userCmd.setState(userCmd.Done, "Filter currently in position")
     else:
         # get a fresh status
         self.getStatus()
         self.fwMoveCmd = userCmd
         if not self.fwMoveCmd.isActive:
             self.fwMoveCmd.setState(self.fwMoveCmd.Running)
         moveToFilter(desPos)
         self.getStatus()
         self.writeToUsers("i", self.status.moveStr, cmd=userCmd)
     return True
Esempio n. 10
0
    def queueDevCmd(self, devCmdStr, userCmd):
        """Add a device command to the device command queue

        @param[in] devCmdStr: a command string to send to the device.
        @param[in] userCmd: a UserCmd associated with this device (probably but
                                not necessarily linked.  Used here for writeToUsers
                                reference.
        """
        log.info("%s.queueDevCmd(devCmdStr=%r, cmdQueue: %r"%(self, devCmdStr, self.devCmdQueue))
        # append a cmdVerb for the command queue (otherwise all get the same cmdVerb and cancel eachother)
        # could change the default behavior in CommandQueue?
        cmdVerb = devCmdStr.split()[0]
        assert cmdVerb in self.validCmdVerbs
        devCmd = DevCmd(cmdStr=devCmdStr)
        devCmd.cmdVerb = cmdVerb
        devCmd.userCmd = userCmd
        def queueFunc(devCmd):
            # when the command is ready run this
            # everything besides a move should return quickly
            devCmd.setTimeLimit(SEC_TIMEOUT)
            devCmd.setState(devCmd.Running)
            if cmdVerb == "status":
                # wipe status, to ensure we've
                # gotten a full status when done.
                self.status.flushStatus()
            self.startDevCmd(devCmd.cmdStr)
        self.devCmdQueue.addCmd(devCmd, queueFunc)
        return devCmd
 def cmd_ping(self, userCmd):
     """! Implement the ping command
     @param[in]  userCmd  a twistedActor command with a parsedCommand attribute
     """
     log.info("%s.cmd_ping(userCmd=%s)" % (self, str(userCmd)))
     # print("%s.cmd_ping(userCmd=%s)"%(self, str(userCmd)))
     userCmd.setState(userCmd.Done, textMsg="alive")
     return True
 def cmd_init(self, userCmd):
     """! Implement the init command
     @param[in]  userCmd  a twistedActor command with a parsedCommand attribute
     """
     log.info("%s.cmd_init(userCmd=%s)" % (self, str(userCmd)))
     # print("%s.cmd_init(userCmd=%s)"%(self, str(userCmd)))
     self.init(userCmd, getStatus=True)
     # userCmd.setState(userCmd.Done)
     return True
Esempio n. 13
0
    def init(self, userCmd=None, timeLim=3, getStatus=True):
        """Called automatically on startup after the connection is established.
        Only thing to do is query for status or connect if not connected

        getStatus ignored?
        """
        log.info("%s.init(userCmd=%s, timeLim=%s, getStatus=%s)" % (self, userCmd, timeLim, getStatus))
        userCmd = expandUserCmd(userCmd)
        self.getStatus(userCmd) # status links the userCmd
        return userCmd
 def cmd_stopWheel(self, userCmd):
     log.info("%s.cmd_stop(userCmd=%s)" % (self, str(userCmd)))
     # print("%s.cmd_stop(userCmd=%s)"%(self, str(userCmd)))
     if not self.fwMoveCmd.isDone:
         self.fwMoveCmd.setState(self.fwMoveCmd.Failed, "stop commanded")
     if not self.fwHomeCmd.isDone:
         self.fwHomeCmd.setState(self.fwHomeCmd.Failed, "stop commanded")
     stop()
     userCmd.setState(userCmd.Done)
     return True
 def cmd_status(self, userCmd=None, setDone=True):
     """! Implement the status command
     @param[in]  userCmd  a twistedActor command with a parsedCommand attribute
     """
     log.info("%s.cmd_status(userCmd=%s)" % (self, str(userCmd)))
     userCmd = expandUserCmd(userCmd)
     self.getStatus()
     self.writeToUsers("i", self.status.statusStr, cmd=userCmd)
     if setDone:
         userCmd.setState(userCmd.Done)
     return True
 def cmd_home(self, userCmd):
     log.info("%s.cmd_home(userCmd=%s)" % (self, str(userCmd)))
     # print("%s.cmd_home(userCmd=%s)"%(self, str(userCmd)))
     if False in [self.fwMoveCmd.isDone, self.fwHomeCmd]:
         userCmd.setState(userCmd.Failed, "filter wheel is moving")
     else:
         self.fwHomeCmd = userCmd
         if not self.fwHomeCmd.isActive:
             self.fwHomeCmd.setState(self.fwHomeCmd.Running)
         home()
         self.cmd_status(userCmd, setDone=False)
         return True
    def cmd_diffuIn(self, userCmd):
        """Move the diffuser into the beam
        """
        log.info("%s.cmd_diffuIn(userCmd=%s)" % (self, userCmd))
        if self.status.diffuCover == 0:
            setDiffuserIn()
            time.sleep(3)
            self.getStatus()
            self.writeToUsers("i", self.status.statusStr, cmd=userCmd)
            userCmd.setState(userCmd.Done)

        return True
Esempio n. 18
0
 def startCmd(self, cmdStr, userCmd=None, callFunc=None, timeLim=0.):
     log.info("%s.startCmd(cmdStr=%s, userCmd=%s, callFunc=%s)" %
              (self, cmdStr, str(userCmd), str(callFunc)))
     # print("%s.startCmd(cmdStr=%s, userCmd=%s, callFunc=%s)"%(self, cmdStr, str(userCmd), str(callFunc)))
     # if not self.isConnected:
     #     userCmd.setState(userCmd.Failed, "filter wheel device not connected")
     # else:
     return ActorDevice.startCmd(self,
                                 cmdStr=cmdStr,
                                 userCmd=userCmd,
                                 callFunc=callFunc,
                                 timeLim=timeLim)
Esempio n. 19
0
 def init(self, userCmd=None, timeLim=None, getStatus=False):
     """Called automatically on startup after the connection is established.
     Only thing to do is query for status or connect if not connected
     """
     log.info("%s.init(userCmd=%s, timeLim=%s, getStatus=%s)" % (self, userCmd, timeLim, getStatus))
     userCmd = expandUserCmd(userCmd)
     # stop, set speed, then status?
     stopCmd = self.queueDevCmd("stop", userCmd)
     speedCmd = self.queueDevCmd("speed %.4f"%self.nomSpeed, userCmd)
     statusCmd = self.queueDevCmd("status", userCmd)
     LinkCommands(userCmd, [stopCmd, speedCmd, statusCmd])
     return userCmd
Esempio n. 20
0
 def init(self, userCmd=None, timeLim=None, getStatus=True):
     """Called automatically on startup after the connection is established.
     Only thing to do is query for status or connect if not connected
     """
     log.info("%s.init(userCmd=%s, timeLim=%s, getStatus=%s)" % (self, userCmd, timeLim, getStatus))
     # print("%s.init(userCmd=%s, timeLim=%s, getStatus=%s)" % (self, userCmd, timeLim, getStatus))
     userCmd = expandUserCmd(userCmd)
     # if not self.isConnected:
     #     return self.connect(userCmd=userCmd)
     # get the speed on startup
     # ignore getStatus flag, just do it always
     self.queueDevCmd("speed")
     return self.getStatus(userCmd=userCmd)
 def init(self, userCmd=None, getStatus=True, timeLim=DefaultTimeLim):
     """! Initialize all devices, and get status if wanted
     @param[in]  userCmd  a UserCmd or None
     @param[in]  getStatus if true, query all devices for status
     @param[in]  timeLim
     """
     userCmd = expandUserCmd(userCmd)
     log.info("%s.init(userCmd=%s, timeLim=%s, getStatus=%s)" %
              (self, userCmd, timeLim, getStatus))
     if getStatus:
         self.cmd_status(userCmd)  # sets done
     else:
         userCmd.setState(userCmd.Done)
     return userCmd
Esempio n. 22
0
 def startDevCmd(self, devCmdStr):
     """
     @param[in] devCmdStr a line of text to send to the device
     """
     devCmdStr = devCmdStr.lower()
     log.info("%s.startDevCmd(%r)" % (self, devCmdStr))
     try:
         if self.conn.isConnected:
             log.info("%s writing %r" % (self, devCmdStr))
             self.conn.writeLine(devCmdStr)
         else:
             self.currExeDevCmd.setState(self.currExeDevCmd.Failed, "Not connected")
     except Exception as e:
         self.currExeDevCmd.setState(self.currExeDevCmd.Failed, textMsg=strFromException(e))
Esempio n. 23
0
 def init(self, userCmd=None, timeLim=None, getStatus=True):
     """Called automatically on startup after the connection is established.
     Only thing to do is query for status or connect if not connected
     """
     log.info("%s.init(userCmd=%s, timeLim=%s, getStatus=%s)" % (self, userCmd, timeLim, getStatus))
     # print("%s.init(userCmd=%s, timeLim=%s, getStatus=%s)" % (self, userCmd, timeLim, getStatus))
     userCmd = expandUserCmd(userCmd)
     # if not self.isConnected:
     #     # time lim handled by lco.deviceCmd
     #     return self.connect(userCmd=userCmd)
     if getStatus:
         return self.getStatus(userCmd=userCmd)
     else:
         userCmd.setState(userCmd.Done)
         return userCmd
Esempio n. 24
0
 def startDevCmd(self, devCmd):
     """
     @param[in] devCmd a dev command
     """
     log.info("%s.startDevCmd(%r)" % (self, devCmd.cmdStr))
     #print("%s.startDevCmd(%r)" % (self, devCmd.cmdStr))
     try:
         if self.conn.isConnected:
             log.info("%s writing %r" % (self, devCmd.cmdStr))
             devCmd.setState(devCmd.Running)
             self.conn.writeLine(devCmd.cmdStr)
         else:
             self.currExeDevCmd.setState(self.currExeDevCmd.Failed, "Not connected")
     except Exception as e:
         self.currExeDevCmd.setState(self.currExeDevCmd.Failed, textMsg=strFromException(e))
Esempio n. 25
0
    def queueDevCmd(self, devCmd):
        """Add a device command to the device command queue

        @param[in] devCmd: a twistedActor DevCmd.
        """
        log.info("%s.queueDevCmd(devCmd=%r, devCmdStr=%r, cmdQueue: %r"%(self, devCmd, devCmd.cmdStr, self.devCmdQueue))
        # append a cmdVerb for the command queue (other wise all get the same cmdVerb and cancel eachother)
        # could change the default behavior in CommandQueue?
        devCmd.cmdVerb = devCmd.cmdStr
        def queueFunc(devCmd):
            # all tcs commands return immediately so set a short timeout
            devCmd.setTimeLimit(SEC_TIMEOUT)
            devCmd.setState(devCmd.Running)
            self.startDevCmd(devCmd.cmdStr)
        self.devCmdQueue.addCmd(devCmd, queueFunc)
Esempio n. 26
0
 def startDevCmd(self, devCmdStr):
     """
     @param[in] devCmdStr a line of text to send to the device
     """
     log.info("%s.startDevCmd(%r)" % (self, devCmdStr))
     try:
         if self.conn.isConnected:
             log.info("%s writing %r" % (self, devCmdStr))
             self.conn.writeLine(devCmdStr)
             if devCmdStr == "init":
                 self.waitingForInitEcho = True
             self.currDevCmdStr = devCmdStr
         else:
             self.currExeCmd.setState(self.currExeCmd.Failed, "Not connected")
     except Exception as e:
         self.currExeCmd.setState(self.currExeCmd.Failed, textMsg=strFromException(e))
Esempio n. 27
0
 def getStatus(self, userCmd=None):
     """Return current telescope status. Continuously poll.
     """
     log.info("%s.getStatus(userCmd=%s)" % (self, userCmd)) # logging this will flood the log
     # print("%s.getStatus(userCmd=%s)" % (self, userCmd))
     userCmd = expandUserCmd(userCmd)
     if not self.conn.isConnected:
         userCmd.setState(userCmd.Failed, "Not Connected to M2")
         return userCmd
     self._statusTimer.cancel() # incase a status is pending
     userCmd = expandUserCmd(userCmd)
     # userCmd.addCallback(self._statusCallback)
     # gather list of status elements to get
     statusCmd = self.queueDevCmd("status", userCmd)
     LinkCommands(userCmd, [statusCmd])
     return userCmd
Esempio n. 28
0
    def queueDevCmd(self, devCmdStr, userCmd):
        """Add a device command to the device command queue

        @param[in] devCmdStr: a command string to send to the device.
        @param[in] userCmd: a UserCmd associated with this device (probably but
                                not necessarily linked.  Used here for writeToUsers
                                reference.
        """
        log.info("%s.queueDevCmd(devCmdStr=%r, cmdQueue: %r"%(self, devCmdStr, self.devCmdQueue))
        #print("%s.queueDevCmd(devCmdStr=%r, cmdQueue: %r"%(self, devCmdStr, self.devCmdQueue))
        # append a cmdVerb for the command queue (otherwise all get the same cmdVerb and cancel eachother)
        # could change the default behavior in CommandQueue?
        devCmd = DevCmd(cmdStr=devCmdStr)
        devCmd.userCmd = userCmd
        devCmd.cmdVerb = devCmdStr
        self.devCmdQueue.addCmd(devCmd, self.startDevCmd)
        return devCmd
Esempio n. 29
0
    def parseAndDispatchCmd(self, cmd):
        """Dispatch the user command, parse the cmd string and append the result as a parsedCommand attribute
        on cmd

        @param[in] cmd  user command (a twistedActor.UserCmd)
        """
        log.info("%s.parseAndDispatchCmd cmdBody=%r"%(self, cmd.cmdBody))
        if not cmd.cmdBody:
            # echo to show alive
            self.writeToOneUser(":", "", cmd=cmd)
            return

        parsedCommand = arcticCommandSet.parse(cmd.cmdBody)

        # append the parsedCommand to the cmd object, and send along
        cmd.parsedCommand = parsedCommand
        return Actor.parseAndDispatchCmd(self, cmd)
Esempio n. 30
0
    def queueDevCmd(self, cmdStr, userCmd=None):
        """Add a device command to the device command queue

        @param[in] cmdStr, string to send to the device.
        """
        log.info("%s.queueDevCmd(cmdStr=%r, cmdQueue: %r"%(self, cmdStr, self.devCmdQueue))
        # print("%s.queueDevCmd(devCmd=%r, devCmdStr=%r, cmdQueue: %r"%(self, devCmd, devCmd.cmdStr, self.devCmdQueue))
        # append a cmdVerb for the command queue (other wise all get the same cmdVerb and cancel eachother)
        # could change the default behavior in CommandQueue?
        userCmd = expandUserCmd(userCmd)
        devCmd = DevCmd(cmdStr)
        devCmd.cmdVerb = cmdStr.split()[0]
        devCmd.userCmd = userCmd
        def queueFunc(devCmd):
            self.startDevCmd(devCmd)
        self.devCmdQueue.addCmd(devCmd, queueFunc)
        return devCmd
Esempio n. 31
0
    def move(self, valueList, offset=False, userCmd=None):
        """Command an offset or absolute orientation move

        @param[in] valueList: list of 1 to 5 values specifying pistion(um), tiltx("), tilty("), transx(um), transy(um)
        @param[in] offset, if true this is offset, else absolute
        @param[in] userCmd: a twistedActor BaseCommand

        Note: increasing distance eg pistion means increasing spacing between primary and
        secondary mirrors.
        """
        log.info("%s.move(userCmd=%s, valueList=%s, offset=%s)" % (self, userCmd, str(valueList), str(bool(offset))))
        userCmd = expandUserCmd(userCmd)
        if not self.waitMoveCmd.isDone:
            userCmd.setState(userCmd.Failed, "Mirror currently moving")
            return userCmd
        if not 1<=len(valueList)<=5:
            userCmd.setState(userCmd.Failed, "Must specify 1 to 5 numbers for a move")
            return userCmd
        self.waitMoveCmd = UserCmd()
        self.waitMoveCmd.userCmd = userCmd # for write to users
        self.status.desOrientation = self.status.orientation[:]
        if offset:
            # if offset is specified, offset from current value
            for ii, value in enumerate(valueList):
                self.status.desOrientation[ii] += value
        else:
            # if absolute is wanted, overwrite all those
            # specified
            for ii, value in enumerate(valueList):
                self.status.desOrientation[ii] = value
        cmdType = "offset" if offset else "move"
        strValList = " ".join(["%.2f"%val for val in valueList])
        cmdStr = "%s %s"%(cmdType, strValList)
        moveCmd = self.queueDevCmd(cmdStr, userCmd)
        statusCmd = self.queueDevCmd("status", userCmd)
        # status immediately to see moving state
        # determine total time for move
        # just use focus distance as proxy (ignore)
        galilOverHead = 2 # galil take roughly 2 secs to boot up.
        extraOverHead = 2 #
        self.status._moveTimeTotal = self.getTimeForMove()
        timeout = self.status._moveTimeTotal+galilOverHead+extraOverHead
        userCmd.setTimeLimit(timeout)
        LinkCommands(userCmd, [moveCmd, statusCmd, self.waitMoveCmd])
        return userCmd
Esempio n. 32
0
    def doExpose(self, userCmd, expType, expTime, basename=None, comment=None):
        """!Begin a camera exposure

        @param[in] userCmd: a twistedActor UserCmd instance
        @param[in] expType: string, one of object, flat, dark, bias
        @param[in] expTime: float, exposure time.
        """

        if not self.exposeCmd.isDone:
            userCmd.setState(userCmd.Failed, "cannot start new exposure, self.exposeCmd not done")
            return
        if self.pollTimer.isActive:
            userCmd.setState(userCmd.Failed, "cannot start new exposure, self.pollTimer is active - bug")
            return
        self.exposeCmd = userCmd
        expTypeEnum = ExpTypeDict.get(expType)
        if basename:
            # save location was specified
            expName = basename
        else:
            # wasn't specified choose a default place/name
            if not os.path.exists(self.imageDir):
                os.makedirs(self.imageDir)
            expName = os.path.abspath("%s_%d.fits" % (expType, self.expNum))
            expName = "%s_%d.fits" % (expType, self.expNum)
            expName = os.path.join(self.imageDir, expName)
        # print "startExposure(%r, %r, %r)" % (expTime, expTypeEnum, expName)
        self.expStartTime = datetime.datetime.now()
        log.info("startExposure(%r, %r, %r)" % (expTime, expTypeEnum, expName))
        self.expName = expName
        self.comment = comment
        self.expType = expType
        self.expTime = expTime
        self.readingFlag = False
        try:
            self.camera.startExposure(expTime, expTypeEnum, expName)
            self.writeToUsers("i", self.exposureStateKW, self.exposeCmd)
            if expType.lower() in ["object", "flat"]:
                self.writeToUsers("i", "shutter=open") # fake shutter
            self.expNum += 1
            self.pollCamera()
        except RuntimeError as e:
            self.exposeCmd.setState(self.exposeCmd.Failed, str(e))
            # note, check what state the exposure kw is in after a runtime error here?
            self.exposeCleanup()
Esempio n. 33
0
 def startDevCmd(self, devCmdStr):
     """
     @param[in] devCmdStr a line of text to send to the device
     """
     log.info("%s.startDevCmd(%r)" % (self, devCmdStr))
     try:
         if self.conn.isConnected:
             log.info("%s writing %r" % (self, devCmdStr))
             self.conn.writeLine(devCmdStr)
             if devCmdStr == "init":
                 self.waitingForInitEcho = True
             self.currDevCmdStr = devCmdStr
         else:
             self.currExeCmd.setState(self.currExeCmd.Failed,
                                      "Not connected")
     except Exception as e:
         self.currExeCmd.setState(self.currExeCmd.Failed,
                                  textMsg=strFromException(e))
Esempio n. 34
0
 def startDevCmd(self, devCmdStr):
     """
     @param[in] devCmdStr a line of text to send to the device
     """
     devCmdStr = devCmdStr.upper() # lco uses all upper case
     log.info("%s.startDevCmd(%r)" % (self, devCmdStr))
     try:
         if self.conn.isConnected:
             log.info("%s writing %r" % (self, devCmdStr))
             if CMDOFF.upper() == devCmdStr:
                 self.waitOffsetCmd.setState(self.waitOffsetCmd.Running)
             elif "CIR" in devCmdStr:
                 self.waitRotCmd.setState(self.waitRotCmd.Running)
             self.conn.writeLine(devCmdStr)
         else:
             self.currExeDevCmd.setState(self.currExeDevCmd.Failed, "Not connected to TCS")
     except Exception as e:
         self.currExeDevCmd.setState(self.currExeDevCmd.Failed, textMsg=strFromException(e))
Esempio n. 35
0
    def slewOffset(self, ra, dec, userCmd=None):
        """Offset telescope in right ascension and declination.

        @param[in] ra: right ascension in decimal degrees
        @param[in] dec: declination in decimal degrees
        @param[in] userCmd a twistedActor BaseCommand

        @todo, consolidate similar code with self.target?
        """
        log.info("%s.slewOffset(userCmd=%s, ra=%.6f, dec=%.6f)" % (self, userCmd, ra, dec))
        userCmd = expandUserCmd(userCmd)
        # zero the delta computation so the offset isn't marked done immediately
        self.status.previousDec = ForceSlew
        self.status.previousRA = ForceSlew
        if not self.conn.isConnected:
            userCmd.setState(userCmd.Failed, "Not Connected to TCS")
            return userCmd
        if not self.waitOffsetCmd.isDone:
            self.waitOffsetCmd.setState(self.waitOffsetCmd.Cancelled, "Superseded by new offset")
        waitOffsetCmd = UserCmd()
        self.waitOffsetCmd = waitOffsetCmd
        enterRa = "OFRA %.8f"%(ra*ArcSecPerDeg)
        enterDec = "OFDC %.8f"%(dec*ArcSecPerDeg) #lcohack
        devCmdList = [DevCmd(cmdStr=cmdStr) for cmdStr in [enterRa, enterDec, CMDOFF]]
        # set userCmd done only when each device command finishes
        # AND the pending slew is also done.
        # set an offset done after 6 seconds no matter what
        def setWaitOffsetCmdDone(aWaitingOffsetCmd):
            print("wait offset command state", aWaitingOffsetCmd.state)
            if not aWaitingOffsetCmd.isDone:
                print("Wait offset timed out!!!!")
                self.writeToUsers("w", "Text=OFFSET SET DONE ON TIMER.")
                aWaitingOffsetCmd.setState(aWaitingOffsetCmd.Done, "offset set done on a timer")
        self.waitOffsetTimer.start(8, setWaitOffsetCmdDone, waitOffsetCmd)
        # self.waitOffsetCmd.setTimeLimit(6)
        LinkCommands(userCmd, devCmdList + [self.waitOffsetCmd])
        for devCmd in devCmdList:
            self.queueDevCmd(devCmd)
        statusStr = self.status.getStatusStr()
        if statusStr:
            self.writeToUsers("i", statusStr, userCmd)
        return userCmd
Esempio n. 36
0
    def home(self, userCmd=None):
        log.info("%s.home(userCmd=%s)" % (self, userCmd))
        setCountCmd = self.measScaleDev.setCountState()

        def finishHome(_statusCmd):
            if _statusCmd.didFail:
                userCmd.setState(userCmd.Failed, "status failed.")
            elif _statusCmd.isDone:
                # assert that the encoders are really reading
                # zeros
                if not numpy.all(numpy.abs(self.measScaleDev.encPos) < 0.001):
                    userCmd.setState(userCmd.Failed, "zeros failed to set: %s"%str(self.measScaleDev.encPos))
                else:
                    userCmd.setState(userCmd.Done)

        def getStatus(_zeroEncCmd):
            if _zeroEncCmd.didFail:
                userCmd.setState(userCmd.Failed, "Encoder zero failed.")
            elif _zeroEncCmd.isDone:
                statusCmd = self.getStatus()
                statusCmd.addCallback(finishHome)

        def zeroEncoders(_moveCmd):
            if _moveCmd.didFail:
                userCmd.setState(userCmd.Failed, "Failed to move scaling ring to home position")
            elif _moveCmd.isDone:
                # zero the encoders in 1 second (give the ring a chance to stop)
                def zeroEm():
                    zeroEncCmd = self.measScaleDev.setZero()
                    zeroEncCmd.addCallback(getStatus)
                reactor.callLater(1., zeroEm)

        def moveThreadRing(_setCountCmd):
            if _setCountCmd.didFail:
                userCmd.setState(userCmd.Failed, "Failed to set Mitutoyo EV counter into counting state")
            elif _setCountCmd.isDone:
                moveCmd = self.queueDevCmd("move %.6f"%self.measScaleDev.zeroPoint, userCmd)
                moveCmd.addCallback(zeroEncoders)
        setCountCmd.addCallback(moveThreadRing)
Esempio n. 37
0
 def startDevCmd(self, devCmd):
     """
     @param[in] devCmdStr a line of text to send to the device
     """
     devCmdStr = devCmd.cmdStr.lower() # m2 uses all lower case
     log.info("%s.startDevCmd(%r)" % (self, devCmdStr))
     try:
         if self.conn.isConnected:
             log.info("%s writing %r" % (self, devCmdStr))
             # set move command to running now. Bug if set earlier race condition
             # with status
             if "move" in devCmdStr.lower() or "offset" in devCmdStr.lower():
                 self.waitMoveCmd.setState(self.waitMoveCmd.Running)
                 self.status.state = Moving
                 self.writeToUsers("i", self.status.secStateStr(), devCmd.userCmd)
             # if "galil" in devCmdStr.lower():
             #     self.waitGalilCmd.setState(self.waitGalilCmd.Running)
             self.conn.writeLine(devCmdStr)
         else:
             self.currExeDevCmd.setState(self.currExeDevCmd.Failed, "Not connected to M2")
     except Exception as e:
         self.currExeDevCmd.setState(self.currExeDevCmd.Failed, textMsg=strFromException(e))
Esempio n. 38
0
    def handleReply(self, replyStr):
        """Handle a line of output from the device. Called whenever the device outputs a new line of data.

        @param[in] replyStr   the reply, minus any terminating \n

        Tasks include:
        - Parse the reply
        - Manage the pending commands
        - Output data to users
        - Parse status to update the model parameters
        - If a command has finished, call the appropriate command callback
        """
        log.info("%s read %r, currExeCmd: %r" %
                 (self, replyStr, self.currExeCmd))
        # print("%s read %r, currExeCmd: %r, currDevCmdStr: %s" % (self, replyStr, self.currExeCmd, self.currDevCmdStr))
        if self.currExeCmd.isDone:
            log.info("Ignoring unsolicited output from Galil: %s " % replyStr)
            return
        gotOK = False
        if replyStr == "OK":
            replyStr = ""
            gotOK = True
        elif replyStr.endswith(" OK"):
            gotOK = True
            replyStr = replyStr[:-3]
        # handle things specially for init
        if self.waitingForInitEcho:
            if replyStr != "init":
                return
            else:
                # saw init echo
                self.waitingForInitEcho = False
                replyStr = ""
        if replyStr and replyStr != self.currDevCmdStr:
            # must be status parse and set accordingly
            self.parseStatusLine(replyStr)
        if gotOK:
            self.currExeCmd.setState(self.currExeCmd.Done)
Esempio n. 39
0
 def getStatus(self, userCmd=None):
     """Return current telescope status. Continuously poll.
     """
     log.info("%s.getStatus(userCmd=%s)" % (self, userCmd)) # logging this will flood the log
     userCmd = expandUserCmd(userCmd)
     if not self.conn.isConnected:
         userCmd.setState(userCmd.Failed, "Not Connected to TCS")
         return userCmd
     self._statusTimer.cancel() # incase a status is pending
     userCmd = expandUserCmd(userCmd)
     userCmd.addCallback(self._statusCallback)
     # record the present RA, DEC (for determining when offsets are done)
     # self.status.previousRA = self.status.statusFieldDict["ra"].value
     # self.status.previousDec = self.status.statusFieldDict["dec"].value
     if self.status.statusFieldDict["mpos"].value is None:
         self.status.previousRA, self.status.previousDec = None, None
     else:
         self.status.previousRA = self.status.statusFieldDict["mpos"].value[0]
         self.status.previousDec = self.status.statusFieldDict["mpos"].value[1]
     # gather list of status elements to get
     devCmdList = [DevCmd(cmdStr=cmdVerb) for cmdVerb in self.status.statusFieldDict.keys()]
     LinkCommands(userCmd, devCmdList)
     for devCmd in devCmdList:
         self.queueDevCmd(devCmd)
     if not self.status.isClamped or self.rotDelay:
         # rotator is moving, get status frequently
         pollTime = PollTimeRot
     elif self.isSlewing:
         # slewing, get status kinda frequently
         pollTime = PollTimeSlew
     elif self.isTracking:
         # tracking, get status less frequently
         pollTime = PollTimeTrack
     else:
         # idle, get status infrequently (as things shouldn't be changing fast)
         pollTime = PollTimeIdle
     self._statusTimer.start(pollTime, self.getStatus)
     return userCmd
Esempio n. 40
0
 def pollCamera(self):
     """Begin continuously polling the camera for exposure status, write the image when ready.
     """
     expState = self.camera.getExposureState()
     if expState.state == arctic.Reading and not self.readingFlag:
         self.readingFlag = True
         self.writeToUsers("i", "shutter=closed") # fake shutter
         # self.startReadTime = time.time()
         self.writeToUsers("i", self.exposureStateKW, self.exposeCmd)
     if expState.state == arctic.ImageRead:
         log.info("saving image: exposure %s"%self.expName)
         self.camera.saveImage() # saveImage sets camera exp state to idle
         # write headers
         self.writeHeaders()
         # clean up
         log.info("exposure %s complete"%self.expName)
         self.exposeCleanup()
     elif expState.state == arctic.Idle:
         log.warn("pollCamera() called but exposure state is idle.  Should be harmless, but why did it happen?")
         self.exposeCleanup()
     else:
         # if the camera is not idle continue polling
         self.pollTimer.start(0.05, self.pollCamera)
Esempio n. 41
0
    def handleReply(self, replyStr):
        """Handle a line of output from the device. Called whenever the device outputs a new line of data.

        @param[in] replyStr   the reply, minus any terminating \n

        Tasks include:
        - Parse the reply
        - Manage the pending commands
        - Output data to users
        - Parse status to update the model parameters
        - If a command has finished, call the appropriate command callback
        """
        log.info("%s read %r, currExeCmd: %r" % (self, replyStr, self.currExeCmd))
        # print("%s read %r, currExeCmd: %r, currDevCmdStr: %s" % (self, replyStr, self.currExeCmd, self.currDevCmdStr))
        if self.currExeCmd.isDone:
            log.info("Ignoring unsolicited output from Galil: %s " % replyStr)
            return
        gotOK = False
        if replyStr == "OK":
            replyStr = ""
            gotOK = True
        elif replyStr.endswith(" OK"):
            gotOK = True
            replyStr = replyStr[:-3]
        # handle things specially for init
        if self.waitingForInitEcho:
            if replyStr != "init":
                return
            else:
                # saw init echo
                self.waitingForInitEcho = False
                replyStr = ""
        if replyStr and replyStr != self.currDevCmdStr:
            # must be status parse and set accordingly
            self.parseStatusLine(replyStr)
        if gotOK:
            self.currExeCmd.setState(self.currExeCmd.Done)
Esempio n. 42
0
    def init(self, userCmd=None, getStatus=True, timeLim=DefaultTimeLim):
        """! Initialize all devices, and get status if wanted
        @param[in]  userCmd  a UserCmd or None
        @param[in]  getStatus if true, query all devices for status
        @param[in]  timeLim
        """
        userCmd = expandUserCmd(userCmd)
        log.info("%s.init(userCmd=%s, timeLim=%s, getStatus=%s)" % (self, userCmd, timeLim, getStatus))
        # initialize camera
        self.setCamera()
        subCmdList = []
        # connect (if not connected) and initialize devices
        filterDevCmd = expandUserCmd(None)
        shutterDevCmd = expandUserCmd(None)
        subCmdList.append(filterDevCmd)
        subCmdList.append(shutterDevCmd)
        if not self.filterWheelDev.isConnected:
            self.filterWheelDev.connect(userCmd=filterDevCmd)
        else:
            self.filterWheelDev.init(userCmd=filterDevCmd)

        if not self.shutterDev.isConnected:
            self.shutterDev.connect(userCmd=shutterDevCmd)
        else:
            self.shutterDev.init(userCmd=shutterDevCmd)
        if getStatus:
            # get status only when the conn/initialization is done
            def getStatus(foo):
                if userCmd.isDone:
                    self.getStatus()
            userCmd.addCallback(getStatus)
        LinkCommands(mainCmd=userCmd, subCmdList=subCmdList)
        if not self.exposeCmd.isDone:
            self.exposeCmd.setState(self.exposeCmd.Failed, "currently running exposure killed via init")
            self.exposeCleanup()
        return userCmd
Esempio n. 43
0
 def testSimplestCase(self):
     logMsg = "I was just logged"
     log.info(logMsg)
     loggedInfo = self.getLogInfo(self.logFilePath)
     self.assertEqual(len(loggedInfo), 1) # only one line in log
     self.assertEqual(loggedInfo[0][1], logMsg)
Esempio n. 44
0
 def handleReply(self, reply):
     """!Called each time a reply comes through the line
     """
     # print "%s.handleReply(reply=%r)" % (self, reply)
     log.info("%s read %r" % (self, reply))