Пример #1
0
 def doStatus(self, maxage=0):
     """Return highest statusvalue."""
     stati = [dev.status(maxage)
              for dev in devIter(self._getWaiters(), Readable)] + \
             [self._seq_status]
     # sort inplace by first element, i.e. status code
     stati.sort(key=lambda st: st[0])
     # select highest (worst) status
     # if no status is 'worse' then _seq_status, this is _seq_status
     _status = stati[-1]
     if self._seq_is_running():
         return max(status.BUSY, _status[0]), _status[1]
     return _status
Пример #2
0
 def doStatus(self, maxage=0):
     """Return highest statusvalue."""
     stati = [self._seq_status]
     for dev in devIter(self._getWaiters(), Readable):
         stat = dev.status(maxage)
         # ignore busy status of attached tt and st devices since they
         # will used in each device and the state of this device should
         # not changed if no sequence is running
         if dev in [self._attached_tt, self._attached_st]:
             if stat[0] == status.BUSY:
                 continue
         stati.append(stat)
     # sort inplace by first element, i.e. status code
     stati.sort(key=lambda st: st[0])
     # select highest (worst) status
     # if no status is 'worse' then _seq_status, this is _seq_status
     _status = stati[-1]
     if self._seq_is_running():
         return max(status.BUSY, _status[0]), _status[1]
     return _status
Пример #3
0
 def doPoll(self, n, maxage):
     # also poll sub-AutoDevices we created
     for dev in devIter(self.__dict__, baseclass=AutoDevice):
         dev.poll(n, maxage)
Пример #4
0
    def doReference(self, gotopos=None):  # pylint: disable=W0221
        """references this axis by finding the reference switch and then
        setting current position to refpos.
        1) Finding the refswitch by going backwards until the refswitch
           (=negative limit switch) fires,
        2) then go forward a little until the switch is not active,
        3) then crawl SLOWLY backwards to hit it again.
        4) current position is set to self.refpos (e.g. the reference is
           stored, the referencing done)
        If an axis can't go reliably backwards (e.g. blocking) in step 1)
        then this fails!!!

        the refpos must be within motor.abslimits!
        """

        # Check initial conditions
        if self.refpos is None:
            self.log.error('Can\'t reference, no refpos specified!')
            return
        if self._mode not in [MASTER, MAINTENANCE]:
            if self._mode == SIMULATION:
                self.log.debug('would reference')
            else:
                self.log.error('Can\'t reference if not in master or '
                               'maintenance mode!')
            return

        try:
            # helper for DRY: check for ANY Refswitch
            def refsw(motor):
                return motor.doStatus()[1].lower().find('limit switch') > -1

            # helper: wait until the motor HW is no longer busy
            def wait_for_motor(m):
                while m.doStatus()[0] == status.BUSY:
                    session.delay(m._base_loop_delay)
                m.poll()

            self.stop()  # make sure the axis code does not interfere
            self._referencing = True
            m = self._attached_motor
            oldspeed = m.speed

            # figure out the final position (=current position or gotopos, if
            # gotopos is given)
            oldpos = self.doRead() if gotopos is None else gotopos

            # Step 1) Try to hit the refswitch by turning backwards in a fast
            # way
            self.log.info('Referencing: FAST Mode: find refswitch')
            try:
                # ignore Userlimits! -> use doStart
                m.doStart(m.abslimits[0])
            except NicosError:
                # if refswitch is already active, doStart gives an exception
                pass
            # wait until a) refswitch fires or b) movement finished
            wait_for_motor(m)
            if not refsw(m) and self._checkTargetPosition(
                    self.read(0), self.abslimits[0], error=False):
                self.log.error('Referencing: No refswitch found!!! Exiting')
                self.start(oldpos)
                return

            # Step 2) Try find a position without refswitch active, but close
            # to it.
            self.log.info('Referencing: FAST Mode: looking for inactive '
                          'refswitch')
            steps = [0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, 100, 200]
            for stepsize in steps:
                self.log.debug('trying %s', self.format(stepsize, unit=True))
                m.doStart(m.doRead() + stepsize)
                wait_for_motor(m)
                if not refsw(m):
                    break
            else:
                self.log.error(
                    'Referencing: RefSwitch still active after '
                    '%.1f %s, exiting!', sum(steps), self.unit)
                self.start(oldpos)
                return

            # Step 3) Now SLOWLY crawl onto the refswitch
            if self.refspeed:
                m.speed = self.refspeed
            tries = 7
            self.log.info('Referencing: SLOW Mode: find refswitch')
            while not (refsw(m)) and tries > 0:
                self.log.debug('Another %d slots left to try', tries)
                try:
                    m.doStart(m.doRead() - stepsize / 3.)  # pylint: disable=W0631
                except NicosError:
                    # if refswitch is already active, doStart gives an
                    # exception
                    pass
                wait_for_motor(m)
                tries -= 1
            m.stop()
            m.speed = oldspeed
            if tries == 0:
                self.log.error(
                    'Referencing: RefSwitch still not active after '
                    '%.1f %s, exiting!', self.wraparound, self.unit)
                self.start(oldpos)
                return

            # Step 4) We are _at_ refswitch, motor stopped
            # => we are at refpos, communicate this to the motor
            self.poll()
            self.log.info(
                'Found Refswitch at %.2f, should have been at %.2f, '
                'lost %.3f %s', m.doRead(), self.refpos,
                m.doRead() - self.refpos, self.unit)

            for d in devIter(self._adevs):
                if hasattr(d, 'setPosition'):
                    try:
                        d.setPosition(self.refpos)
                    except NicosError as e:
                        self.log.error(str(e))
            self.poll()

            self.log.info('Referenced, moving to position (%.2f)...', oldpos)
            self.start(oldpos)
            self._moves = 0
        finally:
            m.speed = oldspeed
            # if gotopos was given, do not wait...
            if gotopos is None:
                self.wait()
            self._referencing = False
Пример #5
0
    def doReference(self, gotopos=None):  # pylint: disable=W0221
        """references this axis by finding the reference switch and then
        setting current position to refpos.
        1) Finding the refswitch by going backwards until the refswitch
           (=negative limit switch) fires,
        2) then go forward a little until the switch is not active,
        3) then crawl SLOWLY backwards to hit it again.
        4) current position is set to self.refpos (e.g. the reference is
           stored, the referencing done)
        If an axis can't go reliably backwards (e.g. blocking) in step 1)
        then this fails!!!
        """

        # Check initial conditions
        if not (-self.wraparound <= self.refpos <= self.wraparound):
            raise ConfigurationError(
                self, 'Refpos needs to be a float within '
                '[-%.1f .. %.1f]' % (self.wraparound, self.wraparound))
        if self.refpos is None:
            self.log.error('Can\'t reference, no refpos specified!')
            return
        if self._mode not in [MASTER, MAINTENANCE]:
            if self._mode == SIMULATION:
                self.log.debug('would reference')
            else:
                self.log.error('Can\'t reference if not in master or '
                               'maintenance mode!')
            return

        # helper for DRY: check for ANY Refswitch
        def refsw(motor):
            st = motor.doStatus()[1].lower()
            return 'limit switch' in st

        try:
            self.stop()  # make sure the axis code does not interfere
            self._referencing = True
            m = self._attached_motor
            oldspeed = m.speed

            # figure out the final position (=current position or gotopos,
            # if gotopos is given)
            oldpos = self.doRead() if gotopos is None else gotopos

            # Step 1a) change logical position to below self.wraparound
            curpos = m.doRead(0)
            while curpos > 0:
                curpos -= self.wraparound
            m.setPosition(curpos)
            m.poll()

            if not refsw(m):
                # Step 1b) Try to hit the refswitch going active
                self.log.info('Referencing: FAST mode: find refswitch')
                tries = int(self.wraparound / 10 + 1)
                while not refsw(m) and tries > 0:
                    m.maw(m.doRead() + 10)
                    tries -= 1
                if tries == 0:
                    self.log.error(
                        'Referencing: switch not found after '
                        '%.1f %s, exiting!', self.wraparound, self.unit)
                    self.doStart(oldpos)
                    return

                # Step 2) Go quickly some distance.
                self.log.info('Referencing: FAST mode: skip some distance')
                self.maw(m.doRead() + self.switchspan)

            # Step 3) Now SLOWLY crawl off the refswitch
            if self.refspeed:
                m.speed = self.refspeed
            tries = int(360 / self.leaveswitchstep)
            self.log.info('Referencing: SLOW mode: find refswitch end')
            while refsw(m) and tries > 0:
                self.log.debug('at %f: another %d %f %s slots left to try',
                               m.doRead(), tries, self.leaveswitchstep,
                               self.unit)
                m.maw(m.doRead() + self.leaveswitchstep)
                tries -= 1
            m.stop()
            m.speed = oldspeed
            if tries == 0:
                self.log.error(
                    'Referencing: refswitch still active after '
                    '%.1f %s, exiting!', 360, self.unit)
                self.doStart(oldpos)
                return

            # Step 4) We are _at_ refswitch, motor stopped
            # => we are at refpos, communicate this to the motor
            self.poll()
            self.log.info(
                'Found refswitch at %.1f, should have been at %.1f, '
                'lost %.2f %s',
                m.doRead() % self.wraparound, self.refpos,
                abs(m.doRead() % self.wraparound - self.refpos), self.unit)
            for d in devIter(self._adevs):
                if hasattr(d, 'setPosition'):
                    try:
                        d.setPosition(self.refpos)
                    except NicosError as e:
                        self.log.error(str(e))
            self.poll()

            self.log.info('Referenced, moving to position (%.2f)...', oldpos)
            self.start(oldpos)
            self._moves = 0
        finally:
            m.speed = oldspeed
            # if gotopos was given, do not wait...
            if gotopos is None:
                self.wait()
            self._referencing = False