Skip to content

Commit 156ebf0

Browse files
authored
v1.0.4
version 1.0.4
2 parents f31ae99 + a02c07c commit 156ebf0

File tree

3 files changed

+121
-92
lines changed

3 files changed

+121
-92
lines changed

pyobs_zaber/zaberdriver.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
from contextlib import contextmanager
2+
from typing import Any
3+
4+
from zaber_motion import Units
5+
from zaber_motion.ascii import Connection, Axis, Device
6+
7+
8+
@contextmanager
9+
async def zaber_device(port) -> Device:
10+
async with Connection.open_serial_port_async(port) as connection:
11+
await connection.enable_alerts_async()
12+
devices = await connection.detect_devices_async()
13+
yield devices[0]
14+
15+
16+
@contextmanager
17+
async def zaber_axis(port) -> Axis:
18+
async with zaber_device(port) as device:
19+
yield device.get_axis(1)
20+
21+
22+
class ZaberDriver:
23+
"""Wrapper for zaber_motion."""
24+
25+
__module__ = "pyobs_zaber.ZaberDriver"
26+
27+
def __init__(
28+
self,
29+
port: str = "/dev/ttyUSB0",
30+
speed: float = 2000,
31+
acceleration: float = 200,
32+
length_unit=Units.ANGLE_DEGREES,
33+
speed_unit=Units.ANGULAR_VELOCITY_DEGREES_PER_SECOND,
34+
acceleration_unit=Units.ANGULAR_ACCELERATION_DEGREES_PER_SECOND_SQUARED,
35+
system_led: bool = False,
36+
**kwargs: Any,
37+
):
38+
"""Creates a new ZaberDriver.
39+
Args:
40+
port: USB port of the motor, usually "/dev/ttyUSB0"
41+
speed: velocity of the selector movement
42+
length_unit: unit of the length, must be from zaber-motion.Units
43+
speed_unit: unit of the velocity, must be from zaber-motion.Units
44+
system_led: whether the motor LED is active or not
45+
"""
46+
self.port = port
47+
self.speed = speed
48+
self.acceleration = acceleration
49+
self.length_unit = length_unit
50+
self.speed_unit = speed_unit
51+
self.acceleration_unit = acceleration_unit
52+
self.enable_led(system_led)
53+
54+
async def home(self) -> None:
55+
async with zaber_axis(self.port) as axis:
56+
await axis.home_async()
57+
58+
async def move_by(self, length, speed=None) -> None:
59+
"""
60+
Move Zaber motor by a given value.
61+
Args:
62+
length: value by which the motor moves
63+
speed: velocity at which the motor moves
64+
"""
65+
if speed is None:
66+
speed = self.speed
67+
68+
# move
69+
async with zaber_axis(self.port) as axis:
70+
await axis.move_relative_async(
71+
length,
72+
self.length_unit,
73+
velocity=speed,
74+
velocity_unit=self.speed_unit,
75+
acceleration=self.acceleration,
76+
acceleration_unit=self.acceleration_unit,
77+
)
78+
79+
async def get_position(self) -> float:
80+
"""
81+
Get the current position of the Zaber motor.
82+
"""
83+
async with zaber_axis(self.port) as axis:
84+
return await axis.get_position_async(unit=self.length_unit)
85+
86+
async def move_to(self, position) -> None:
87+
"""
88+
Move Zaber motor to a given position.
89+
Args:
90+
position: value to which the motor moves
91+
"""
92+
async with zaber_axis(self.port) as axis:
93+
await axis.move_absolute_async(
94+
position,
95+
self.length_unit,
96+
velocity=self.speed,
97+
velocity_unit=self.speed_unit,
98+
acceleration=self.acceleration,
99+
acceleration_unit=self.acceleration_unit,
100+
)
101+
102+
async def enable_led(self, status: bool) -> None:
103+
"""
104+
Turn on the motor's status LED.
105+
Args:
106+
status: True -> LED on, False -> LED off
107+
"""
108+
async with zaber_device(self.port) as device:
109+
device.settings.set("system.led.enable", float(status))
110+
111+
async def stop(self):
112+
"""Stop motion."""
113+
async with zaber_axis(self.port) as axis:
114+
await axis.stop_async()

pyobs_zaber/zabermodeselector.py

Lines changed: 6 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66
from pyobs.modules import Module
77
from pyobs.utils.enums import MotionStatus
88

9-
from zaber_motion import Units
10-
from zaber_motion.ascii import Connection
9+
from pyobs_zaber.zaberdriver import ZaberDriver
1110

1211

1312
class ZaberModeSelector(Module, IMode, IMotion):
@@ -18,92 +17,20 @@ class ZaberModeSelector(Module, IMode, IMotion):
1817
def __init__(
1918
self,
2019
modes: dict,
21-
port: str = "/dev/ttyUSB0",
22-
speed: float = 2000,
23-
acceleration: float = 200,
24-
length_unit=Units.ANGLE_DEGREES,
25-
speed_unit=Units.ANGULAR_VELOCITY_DEGREES_PER_SECOND,
26-
acceleration_unit=Units.ANGULAR_ACCELERATION_DEGREES_PER_SECOND_SQUARED,
27-
system_led: bool = False,
2820
**kwargs: Any,
2921
):
3022
"""Creates a new ZaberModeSelector.
3123
Args:
3224
modes: dictionary of available modes in the form {name: position}
33-
port: USB port of the motor, usually "/dev/ttyUSB0"
34-
speed: velocity of the selector movement
35-
length_unit: unit of the length, must be from zaber-motion.Units
36-
speed_unit: unit of the velocity, must be from zaber-motion.Units
37-
system_led: whether the motor LED is active or not
3825
"""
3926
Module.__init__(self, **kwargs)
4027

4128
# check
4229
if self.comm is None:
4330
logging.warning("No comm module given!")
4431

32+
self.driver = ZaberDriver(**kwargs)
4533
self.modes = modes
46-
self.port = port
47-
self.speed = speed
48-
self.acceleration = acceleration
49-
self.length_unit = length_unit
50-
self.speed_unit = speed_unit
51-
self.acceleration_unit = acceleration_unit
52-
self.enable_led(system_led)
53-
54-
async def move_by(self, length, speed=None) -> None:
55-
"""
56-
Move Zaber motor by a given value.
57-
Args:
58-
length: value by which the motor moves
59-
speed: velocity at which the motor moves
60-
"""
61-
if speed is None:
62-
speed = self.speed
63-
64-
# move
65-
async with Connection.open_serial_port_async(self.port) as connection:
66-
await connection.enable_alerts_async()
67-
device = (await connection.detect_devices_async())[0]
68-
# TODO: raise xxx if len(device_list) is not 1 (0 -> no device found, >1 -> try to find correct one)
69-
axis = device.get_axis(1)
70-
await axis.move_relative_async(
71-
length,
72-
self.length_unit,
73-
velocity=speed,
74-
velocity_unit=self.speed_unit,
75-
acceleration=self.acceleration,
76-
acceleration_unit=self.acceleration_unit,
77-
)
78-
79-
async def check_position(self) -> float:
80-
"""
81-
Get the current position of the Zaber motor.
82-
"""
83-
async with Connection.open_serial_port_async(self.port) as connection:
84-
await connection.enable_alerts_async()
85-
device = (await connection.detect_devices_async())[0]
86-
axis = device.get_axis(1)
87-
return await axis.get_position_async(unit=self.length_unit)
88-
89-
async def move_to(self, position) -> None:
90-
"""
91-
Move Zaber motor to a given position.
92-
Args:
93-
position: value to which the motor moves
94-
"""
95-
async with Connection.open_serial_port_async(self.port) as connection:
96-
await connection.enable_alerts_async()
97-
device = (await connection.detect_devices_async())[0]
98-
axis = device.get_axis(1)
99-
await axis.move_absolute_async(
100-
position,
101-
self.length_unit,
102-
velocity=self.speed,
103-
velocity_unit=self.speed_unit,
104-
acceleration=self.acceleration,
105-
acceleration_unit=self.acceleration_unit,
106-
)
10734

10835
async def list_modes(self, **kwargs: Any) -> List[str]:
10936
"""List available modes.
@@ -129,7 +56,7 @@ async def set_mode(self, mode: str, **kwargs) -> None:
12956
logging.info("Mode %s already selected.", mode)
13057
else:
13158
logging.info("Moving mode selector ...")
132-
await self.move_to(self.modes[mode])
59+
await self.driver.move_to(self.modes[mode])
13360
logging.info("Mode %s ready.", mode)
13461
else:
13562
logging.warning("Unknown mode %s. Available modes are: %s", mode, available_modes)
@@ -140,7 +67,7 @@ async def get_mode(self, **kwargs: Any) -> str:
14067
Returns:
14168
Name of currently set mode.
14269
"""
143-
pos_current = await self.check_position()
70+
pos_current = await self.driver.get_position()
14471
for mode, mode_pos in self.modes.items():
14572
if round(pos_current) == mode_pos:
14673
return mode
@@ -154,15 +81,15 @@ async def init(self, **kwargs: Any) -> None:
15481
Raises:
15582
InitError: If device could not be initialized.
15683
"""
157-
logging.error("Not implemented")
84+
await self.driver.home()
15885

15986
async def park(self, **kwargs: Any) -> None:
16087
"""Park device.
16188
16289
Raises:
16390
ParkError: If device could not be parked.
16491
"""
165-
logging.error("Not implemented")
92+
await self.driver.home()
16693

16794
async def get_motion_status(self, device: Optional[str] = None, **kwargs: Any) -> MotionStatus:
16895
"""Returns current motion status.
@@ -190,16 +117,4 @@ async def is_ready(self, **kwargs: Any) -> bool:
190117
Returns:
191118
Whether device is ready
192119
"""
193-
logging.error("Not implemented")
194120
return True
195-
196-
def enable_led(self, status: bool) -> None:
197-
"""
198-
Turn on the motor's status LED.
199-
Args:
200-
status: True -> LED on, False -> LED off
201-
"""
202-
with Connection.open_serial_port(self.port) as connection:
203-
connection.enable_alerts()
204-
device = connection.detect_devices()[0]
205-
device.settings.set("system.led.enable", float(status))

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "pyobs-zaber"
3-
version = "1.0.3"
3+
version = "1.0.4"
44
description = "pyobs model for Zaber motors"
55
authors = ["Leon Meerwart <[email protected]>"]
66
license = "MIT"

0 commit comments

Comments
 (0)