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
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
def doPoll(self, n, maxage): # also poll sub-AutoDevices we created for dev in devIter(self.__dict__, baseclass=AutoDevice): dev.poll(n, maxage)
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
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