Skip to content

Commit 10ac358

Browse files
committed
Set to home at startup and tidied up code a bit
1 parent 3132dfc commit 10ac358

File tree

1 file changed

+40
-61
lines changed

1 file changed

+40
-61
lines changed

microscope/stages/ludl.py

Lines changed: 40 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,7 @@
3636
# so far very basic support for stages
3737
# no support for filter, shutters, or slide loader as I dont have hardware
3838

39-
# Issues to fix
40-
# very slow in mosaic
41-
# No limit support
42-
# what is scaling?
43-
44-
45-
# commands
46-
# Where X - A: 12000
47-
# Where X Y - :A -2000 1000
48-
# Where X Y - :A -2000 N-2 # Y axis no installed N-2 is error -2
49-
39+
# Note:
5040
# commands end in a '\r' but replies return ending in '\n'!
5141

5242
# errors
@@ -65,23 +55,22 @@
6555
# end limit, etc….)
6656
# -17 Initialization erro
6757

68-
# MOVE X=2000 - A: positive reply? need to check movement is finished.
69-
# VMOVE X=1 y=2 -
70-
# MOVREL
71-
# REMRES - reset controller.
72-
73-
#suggested startup routine for stage which will explore the extremes
74-
#and then move stage to center and set that as 0,0
75-
#"CENTER X=100000 Y=100000"
76-
#"HERE X=0 Y=0"
77-
#
58+
#On startup the stage move to extremes to find limits and then sets
59+
# the -ve limit on each axis to 0.
7860

7961
LUDL_ERRORS = { -1: 'Unknown command',
80-
-2: 'Illegal point type or axis, or module not installed',
81-
-3: 'Not enough parameters (e.g. move r=)',
82-
-4: 'Parameter out of range',
83-
-21: 'Process aborted by HALT command',
84-
}
62+
-2: 'Illegal point type or axis, or module not installed',
63+
-3: 'Not enough parameters (e.g. move r=)',
64+
-4: 'Parameter out of range',
65+
-21: 'Process aborted by HALT command',
66+
# Slide Loader:
67+
#-4:, (parameter out of range) used for cassette or slot range errors
68+
-10: 'No slides selected',
69+
-11: 'End of list reached',
70+
-12: 'Slide error',
71+
-16: 'Motor move error (move not completed successfully due to stall, end limit, etc.',
72+
-17: 'Initialization error',
73+
}
8574

8675
AXIS_MAPPER = { 1: 'X' ,
8776
2: 'Y' ,
@@ -118,6 +107,7 @@ def __init__(self, port: str, baudrate: int, timeout: float) -> None:
118107
dsrdtr=False,
119108
)
120109
self._lock = threading.RLock()
110+
self.homed = False
121111

122112
with self._lock:
123113
# We do not use the general get_description() here because
@@ -138,42 +128,17 @@ def __init__(self, port: str, baudrate: int, timeout: float) -> None:
138128
# dev address,label,id,description, type
139129
self._devlist[devinfo[0]]=devinfo[1:]
140130

131+
# print(answer)
141132

142-
# ['EMOT', 'X', 'X axis stage', 'MCMSE']
143-
# >>> devinfo[0]
144-
# '1'
145-
# >>> answer[3]
146-
# b''
147-
# >>> answer[4]
148-
# b'1 EMOT X X axis stage MCMSE'
149-
# >>> answer[5]
150-
# b'2 EMOT Y Y axis stage MCMSE'
151-
# >>> answer[6]
152-
# b'3 EMOT B B aux motor MCMSE'
153-
# >>> answer[7]
154-
# b'7 HSMOT T T rotation robot MCMSE **** Should be T rot'
155-
156-
# for dev in self._devlist:
157-
158-
159-
print(answer)
160-
# if answer != b"PROSCAN INFORMATION\r":
161-
# self.read_until_timeout()
162-
# raise RuntimeError(
163-
# "Not a ProScanIII device: '?' returned '%s'"
164-
# % answer.decode()
165-
# )
166-
# # A description ends with END on its own line.
167-
# line = self._serial.read_until(b"\rEND\r")
168-
# if not line.endswith(b"\rEND\r"):
169-
# raise RuntimeError("Failed to clear description")
170133

171134
def is_busy(self):
172135
pass
173136

137+
def been_homed(self):
138+
return self.homed
139+
174140
def get_number_axes(self):
175141
return 2
176-
177142

178143
def command(self, command: bytes) -> None:
179144
"""Send command to device."""
@@ -193,8 +158,12 @@ def read_multiline(self):
193158
output.append(line.strip())
194159
if line==b'N' or line[0:2] == b':A' :
195160
#thins means an end of command strings doesn require an
196-
#addition timeout before it returns
161+
#additional timeout before it returns
197162
return (output)
163+
elif line[0] == b'N':
164+
#this is an error string
165+
error=line[2:].strip()
166+
raise('Ludl controller error: %s,%s' % (error,LUDL_ERRORS[error]))
198167
return(output)
199168

200169
def read_until_timeout(self) -> None:
@@ -310,8 +279,9 @@ def __init__(self, dev_conn: _LudlController, axis: str) -> None:
310279
# not a good solution as min/max are used to build the stage map in
311280
# mosaic etc... Maybe we just need to know it!
312281
self.min_limit = 0.0
313-
self.max_limit = 0.0
282+
self.max_limit = 100000.0
314283
self.set_speed(100000)
284+
self.home()
315285

316286
def move_by(self, delta: float) -> None:
317287
self._dev_conn.move_by_relative_position(self._axis, int(delta))
@@ -330,11 +300,16 @@ def position(self) -> float:
330300
def limits(self) -> microscope.AxisLimits:
331301
return microscope.AxisLimits(lower=self.min_limit, upper=self.max_limit)
332302

303+
# def speed(self) -> int:
304+
# return self.speed
305+
306+
333307
def home(self) -> None:
334308
self.find_limits()
335309
self.move_to(self.max_limit/2)
336310

337311
def set_speed(self, speed: int) -> None:
312+
self.speed = speed
338313
self._dev_conn.set_speed(self._axis, speed)
339314

340315
def find_limits(self,speed = 100000):
@@ -347,6 +322,7 @@ def find_limits(self,speed = 100000):
347322
print(self.position)
348323
self._dev_conn.reset_position(self._axis)
349324
self.min_limit=0.0
325+
self._dev_conn.homed = True
350326
# move to positive limit
351327
self._dev_conn.move_to_limit(self._axis,speed)
352328
self._dev_conn.wait_for_motor_stop(self._axis)
@@ -373,8 +349,8 @@ def _do_enable(self) -> bool:
373349
# Before a device can moved, it first needs to establish a
374350
# reference to the home position. We won't be able to move
375351
# unless we home it first.
376-
# if not self._dev_conn.been_homed():
377-
# self._dev_conn.home()
352+
if not self._dev_conn.been_homed():
353+
self.home()
378354
return True
379355

380356
@property
@@ -398,8 +374,11 @@ def move_to(self, position: typing.Mapping[str, float]) -> None:
398374
)
399375
self._dev_conn.wait_until_idle()
400376

401-
402-
377+
def home(self,axes = None):
378+
if axes == None:
379+
axes=self.axes
380+
for axis in axes:
381+
self.axes[axis].home()
403382

404383
# def assert_filterwheel_number(self, number: int) -> None:
405384
# assert number > 0 and number < 4

0 commit comments

Comments
 (0)