-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathsimple_manipulator.py
148 lines (120 loc) · 4.2 KB
/
simple_manipulator.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
'''
Simple manipulator GUI.
A simple program with no camera.
* Microscope: positions
* Manipulators: Go, calibrate (secondary)
optionally: change pipette (but maybe not: just home, move up in z, back in X)
* No saving of configuration
Calibration is done in a separate program.
TODO:
* Safe movements: first on focal plane, then along X axis
* Configuration data should include device information.
* Error catching
* Refactoring: move virtualxyzunit into xyz unit
'''
from Tkinter import *
from devices import *
from geometry import *
import pickle
from serial import SerialException
from numpy import array
from os.path import expanduser
home = expanduser("~")
config_filename = home+'/config_manipulator.cfg'
__all__ = ['MicroscopeFrame', 'ManipulatorFrame', 'ManipulatorApplication']
class MicroscopeFrame(Frame):
'''
A frame for the stage positions.
'''
def __init__(self, master = None, unit = None, nmemories = 5, cnf = {}, **kw):
'''
Parameters
----------
master : parent window
unit : XYZ unit
'''
Frame.__init__(self, master, cnf, **kw)
self.master = master
self.unit = unit # XYZ unit
Button(self, text='Move to plane', command=self.move_to_plane).pack()
def move_to_plane(self):
'''
Moves the focus to the plane of interest.
'''
self.unit.absolute_move(self.plane.project(self.unit.position(), array([0.,0.,1.])))
class ManipulatorFrame(LabelFrame):
'''
A frame for a manipulator, showing virtual coordinates.
'''
def __init__(self, master = None, unit = None, cnf = {}, dev = None, **kw):
LabelFrame.__init__(self, master, cnf, **kw)
self.master = master
self.unit = unit # XYZ unit
Button(self, text="Go", command=self.go).pack()
Button(self, text="Calibrate", command=self.calibrate).pack()
def go(self):
self.unit.go()
def calibrate(self):
self.unit.secondary_calibration() # unless in calibration
class ManipulatorApplication(Frame):
'''
The main application.
'''
def __init__(self, master, stage, units, names):
'''
Parameters
----------
master : parent window
stage : the stage/microscope unit
units : a list of XYZ virtual units (manipulators)
names : names of the units
'''
Frame.__init__(self, master)
self.frame_microscope = MicroscopeFrame(self, unit=stage)
self.frame_microscope.grid(row=0, column=0, padx=5, pady=5, sticky=N)
self.frame_manipulator = []
i = 0
for name, unit in zip(names, units):
frame = ManipulatorFrame(self, text=name, unit=unit)
frame.grid(row=0, column=i + 1, padx=5, pady=5)
self.frame_manipulator.append(frame)
i += 1
self.load_configuration()
def load_configuration(self):
'''
Load calibration
'''
cfg_all = pickle.load(open(config_filename, "rb"))
for frame, cfg in zip(self.frame_manipulator, cfg_all['manipulator']):
frame.unit.M = cfg['M']
frame.unit.Minv = cfg['Minv']
frame.unit.x0 = cfg['x0']
self.frame_microscope.plane = cfg_all['microscope'].get('plane', None)
if __name__ == '__main__':
root = Tk()
root.title('Manipulator')
SM5 = False
try:
if SM5:
dev = LuigsNeumann_SM5('COM3')
else:
dev = LuigsNeumann_SM10()
except SerialException:
print "L&N not found. Falling back on fake device."
dev = FakeDevice()
if SM5:
microscope_Z = Leica('COM1')
microscope = XYMicUnit(dev, microscope_Z, [7, 8])
unit = [XYZUnit(dev, [4, 5, 6]),
XYZUnit(dev, [1, 2, 3])]
else:
microscope = XYZUnit(dev, [7, 8, 9])
unit = [XYZUnit(dev, [1, 2, 3]),
XYZUnit(dev, [4, 5, 6])]
virtual_unit = [VirtualXYZUnit(unit[i], microscope) for i in range(len(unit))]
print "Device initialized"
app = ManipulatorApplication(root, microscope, virtual_unit, ['Left','Right']).pack(side="top", fill="both", expand=True)
try:
root.mainloop()
except SerialException:
del(dev)