"""
A class for access to a particular unit managed by a device.
It is essentially a subset of a Manipulator
"""
from __future__ import absolute_import
from numpy import ones, arange
from .manipulator import Manipulator
__all__ = ['ManipulatorUnit']
[docs]class ManipulatorUnit(Manipulator):
def __init__(self, dev, axes):
'''
Parameters
----------
dev : underlying device
axes : list of 3 axis indexes
'''
Manipulator.__init__(self)
self.dev = dev
self.axes = axes
# Motor ranges in um; by default +- one meter
self.min = -ones(len(axes))*1e6
self.max = ones(len(axes))*1e6
[docs] def position(self, axis = None):
'''
Current position along an axis.
Parameters
----------
axis : axis number starting at 0; if None, all XYZ axes
Returns
-------
The current position of the device axis in um.
'''
if axis is None: # all positions in a vector
#return array([self.dev.position(self.axes[axis]) for axis in range(len(self.axes))])
return self.dev.position_group(self.axes)
else:
return self.dev.position(self.axes[axis])
[docs] def absolute_move(self, x, axis = None):
'''
Moves the device axis to position x in um.
Parameters
----------
axis : axis number starting at 0; if None, all XYZ axes
x : target position in um.
'''
if axis is None:
# then we move all axes
#for i, axis in enumerate(self.axes):
# self.dev.absolute_move(x[i], axis)
self.dev.absolute_move_group(x, self.axes)
else:
self.dev.absolute_move(x, self.axes[axis])
self.sleep(.05)
[docs] def absolute_move_group(self, x, axes):
self.dev.absolute_move_group(x, self.axes[axes])
self.sleep(.05)
[docs] def relative_move(self, x, axis = None):
'''
Moves the device axis by relative amount x in um.
Parameters
----------
axis : axis number starting at 0; if None, all XYZ axes
x : position shift in um.
'''
if axis is None:
self.dev.relative_move_group(x, self.axes)
else:
self.dev.relative_move(x, self.axes[axis])
self.sleep(.05)
[docs] def stop(self, axis = None):
"""
Stop current movements.
"""
if axis is None:
# then we stop all axes
for i, axis in enumerate(self.axes):
self.dev.stop(axis)
else:
self.dev.stop(self.axes[axis])
[docs] def motor_ranges(self):
"""
Runs the motors to calculate ranges of the motors.
DOESN'T WORK! DO NOT USE!
"""
return
dx = ones(len(self.axes)) * 1000000. # (1 meter; should more than any platform)
self.relative_move(-dx)
self.wait_until_still()
self.min = self.position()
self.relative_move(dx)
self.wait_until_still()
self.max = self.position()
[docs] def is_accessible(self, x, axis = None):
"""
Checks whether position x is accessible.
THIS METHOD IS INCORRECT.
"""
if axis is None:
return all([self.is_accessible(x[i]) for i in range(self.axes)])
else:
return (x>=min) and (x<=max) # This is clearly wrong!
[docs] def wait_until_still(self, axes = None):
"""
Waits for the motors to stop.
"""
if axes is None: # all axes
axes = arange(len(self.axes))
if hasattr(axes, '__len__'): # is that useful?
for i in axes:
self.wait_until_still(i)
else:
self.dev.wait_until_still([self.axes[axes]])
self.sleep(.05)
[docs] def wait_until_reached(self, position, axes=None, precision=0.5, timeout=10):
"""
Waits until position is reached within precision, and raises an error if the
target is not reached after the time out, unless the manipulator is still moving.
Parameters
----------
position : target position in micrometer
axes : axis number of list of axis numbers
precision : precision in micrometer
timeout : time out in second
"""
self.dev.wait_until_reached(position, axes, precision, timeout)