33
44import os
55import time
6- import copy
76import collections
87
9- import numpy as np
10-
11- from ctypes import *
12-
138import attune
9+ import yaqc
1410
1511import project
1612import project .classes as pc
1713import project .project_globals as g
1814from project .ini_handler import Ini
1915from hardware .opas .opas import Driver as BaseDriver
2016from hardware .opas .opas import GUI as BaseGUI
21- from hardware .opas .TOPAS .TOPAS_API import TOPAS_API
2217
2318# --- define --------------------------------------------------------------------------------------
2419
@@ -36,13 +31,29 @@ def __init__(self, *args, **kwargs):
3631 self .curve_paths = collections .OrderedDict ()
3732 self .ini = project .ini_handler .Ini (os .path .join (main_dir , 'hardware' , 'opas' , 'TOPAS' , 'TOPAS.ini' ))
3833 self .has_shutter = kwargs ['has_shutter' ]
34+ self .yaq_port = kwargs ['yaq_port' ]
3935 if self .has_shutter :
4036 self .shutter_position = pc .Bool (name = 'Shutter' , display = True , set_method = 'set_shutter' )
4137 BaseDriver .__init__ (self , * args , ** kwargs )
38+ self .serial_number = self .ini .read ('OPA' + str (self .index ), 'serial number' )
39+ # load api
40+ self .api = yaqc .Client (self .yaq_port )
41+ if self .has_shutter :
42+ self .api .set_shutter (False )
43+
44+ # motor positions
45+ for motor_name in self .motor_names :
46+ min_position , max_position = self .api .get_motor_range (motor_name )
47+ limits = pc .NumberLimits (min_position , max_position )
48+ number = pc .Number (initial_value = 0 , limits = limits , display = True , decimals = 6 )
49+ self .motor_positions [motor_name ] = number
50+ self .recorded ['w%d_' % self .index + motor_name ] = [number , None , 1. , motor_name ]
51+ # finish
52+
4253 if self .has_shutter :
4354 self .exposed += [self .shutter_position ]
4455 # tuning curves
45- self .serial_number = self .ini .read (' OPA' + str ( self .index ) , 'serial number' )
56+ self .serial_number = self .ini .read (f" OPA{ self .index } " , 'serial number' )
4657 self .TOPAS_ini_filepath = os .path .join (g .main_dir .read (), 'hardware' , 'opas' , 'TOPAS' , 'configuration' , str (self .serial_number ) + '.ini' )
4758 self .TOPAS_ini = Ini (self .TOPAS_ini_filepath )
4859 self .TOPAS_ini .return_raw = True
@@ -66,6 +77,7 @@ def __init__(self, *args, **kwargs):
6677 self .interaction_string_combo .updated .connect (self .load_curve )
6778 g .queue_control .disable_when_true (self .interaction_string_combo )
6879 self .load_curve (update = False )
80+ self .homeable = {m : True for m in self .motor_names }
6981
7082 def _get_motor_index (self , name ):
7183 c = self .curve
@@ -76,98 +88,9 @@ def _get_motor_index(self, name):
7688 raise KeyError (name )
7789
7890 def _home_motors (self , motor_names ):
79- motor_indexes = []
80- c = self .curve
81- while len (motor_names ):
82- for m in motor_names :
83- if m in c .dependents :
84- motor_indexes .append (c [m ].index )
85- motor_names .pop (name )
86- c = c .subcurve
87-
88- section = 'OPA' + str (self .index )
89- # close shutter
90- if self .has_shutter :
91- original_shutter = self .shutter_position .read ()
92- self .set_shutter ([False ])
93- # record current positions
94- original_positions = []
95- for motor_index in motor_indexes :
96- error , position = self .api .get_motor_position (motor_index )
97- original_positions .append (position )
98- # send motors to left reference switch ----------------------------------------------------
99- # set all max, current positions to spoof values
100- overflow = 8388607
101- for motor_index in motor_indexes :
102- self .api .set_motor_positions_range (motor_index , 0 , overflow )
103- self .api .set_motor_position (motor_index , overflow )
104- # send motors towards zero
105- for motor_index in motor_indexes :
106- self .api .start_motor_motion (motor_index , 0 )
107- # wait for motors to hit left reference switch
108- motor_indexes_not_homed = copy .copy (motor_indexes )
109- while len (motor_indexes_not_homed ) > 0 :
110- for motor_index in motor_indexes_not_homed :
111- time .sleep (0.1 )
112- error , left , right = self .api .get_reference_switch_status (motor_index )
113- if left :
114- motor_indexes_not_homed .remove (motor_index )
115- # set counter to zero
116- self .api .set_motor_position (motor_index , 0 )
117- # send motors to 400 steps ----------------------------------------------------------------
118- for motor_index in motor_indexes :
119- self .api .start_motor_motion (motor_index , 400 )
91+ for m in motor_names :
92+ self .api .home_motor (m )
12093 self .wait_until_still ()
121- # send motors left reference switch slowly ------------------------------------------------
122- # set motor speed
123- for motor_index in motor_indexes :
124- min_velocity = self .ini .read (section , 'motor {} min velocity (us/s)' .format (motor_index ))
125- max_velocity = self .ini .read (section , 'motor {} max velocity (us/s)' .format (motor_index ))
126- acceleration = self .ini .read (section , 'motor {} acceleration (us/s^2)' .format (motor_index ))
127- error = self .api .set_speed_parameters (motor_index , min_velocity , int (max_velocity / 2 ), acceleration )
128- # set all max, current positions to spoof values
129- for motor_index in motor_indexes :
130- self .api .set_motor_positions_range (motor_index , 0 , overflow )
131- self .api .set_motor_position (motor_index , overflow )
132- # send motors towards zero
133- for motor_index in motor_indexes :
134- self .api .start_motor_motion (motor_index , 0 )
135- # wait for motors to hit left reference switch
136- motor_indexes_not_homed = copy .copy (motor_indexes )
137- while len (motor_indexes_not_homed ) > 0 :
138- for motor_index in motor_indexes_not_homed :
139- time .sleep (0.1 )
140- error , left , right = self .api .get_reference_switch_status (motor_index )
141- if left :
142- motor_indexes_not_homed .remove (motor_index )
143- # set counter to zero
144- self .api .set_motor_position (motor_index , 0 )
145- # send motors to 400 steps (which is now true zero) ---------------------------------------
146- for motor_index in motor_indexes :
147- self .api .start_motor_motion (motor_index , 400 )
148- self .wait_until_still ()
149- for motor_index in motor_indexes :
150- self .api .set_motor_position (motor_index , 0 )
151- # finish ----------------------------------------------------------------------------------
152- # set speed back to real values
153- for motor_index in motor_indexes :
154- min_velocity = self .ini .read (section , 'motor {} min velocity (us/s)' .format (motor_index ))
155- max_velocity = self .ini .read (section , 'motor {} max velocity (us/s)' .format (motor_index ))
156- acceleration = self .ini .read (section , 'motor {} acceleration (us/s^2)' .format (motor_index ))
157- error = self .api .set_speed_parameters (motor_index , min_velocity , max_velocity , acceleration )
158- # set range back to real values
159- for motor_index in motor_indexes :
160- min_position = self .ini .read (section , 'motor {} min position (us)' .format (motor_index ))
161- max_position = self .ini .read (section , 'motor {} max position (us)' .format (motor_index ))
162- error = self .api .set_motor_positions_range (motor_index , min_position , max_position )
163- # launch return motion
164- for motor_index , position in zip (motor_indexes , original_positions ):
165- self .api .start_motor_motion (motor_index , position )
166- # wait for motors to finish moving
167- self .wait_until_still ()
168- # return shutter
169- if self .has_shutter :
170- self .set_shutter ([original_shutter ])
17194
17295 def _load_curve (self , interaction ):
17396 interaction = self .interaction_string_combo .read ()
@@ -176,27 +99,31 @@ def _load_curve(self, interaction):
17699 del curve_paths_copy ['Poynting' ]
177100 crv_paths = [m .read () for m in curve_paths_copy .values ()]
178101 all_curves = attune .TopasCurve .read_all (crv_paths )
102+ for curve in all_curves .values ():
103+ for dependent in curve .dependent_names :
104+ if dependent not in self .motor_names :
105+ try :
106+ curve .rename_dependent (dependent , self .motor_names [int (dependent )])
107+ except :
108+ pass
179109 self .interaction_string_combo .set_allowed_values (list (all_curves .keys ()))
180110 self .curve = all_curves [interaction ]
181111 return self .curve
182112
183113 def _set_motors (self , motor_destinations ):
184114 for motor_name , destination in motor_destinations .items ():
185- motor_index = self ._get_motor_index (motor_name )
186- error , destination_steps = self .api .convert_position_to_steps (motor_index , destination )
187- self .api .start_motor_motion (motor_index , destination_steps )
115+ destination = float (destination )
116+ self .api .set_motor_position (motor_name , destination )
188117
189118 def _update_api (self , interaction ):
190119 # write to TOPAS ini
191- self .api .close ()
192120 for curve_type , curve_path_mutex in self .curve_paths .items ():
193121 if curve_type == 'Poynting' :
194122 continue
195123 curve_path = curve_path_mutex .read ()
196124 section = 'Optical Device'
197125 option = 'Curve ' + str (self .curve_indices [curve_type ])
198126 self .TOPAS_ini .write (section , option , curve_path )
199- self .api = TOPAS_API (self .TOPAS_ini_filepath )
200127 # save current interaction string
201128 self .ini .write ('OPA%i' % self .index , 'current interaction string' , interaction )
202129
@@ -210,59 +137,21 @@ def close(self):
210137 self .api .close ()
211138
212139 def get_motor_positions (self ):
213- for i in range (6 ):
214- motor_mutex = list (self .motor_positions .values ())[i ]
215- error , position_steps = self .api .get_motor_position (i )
216- error , position = self .api .convert_position_to_units (i , position_steps )
140+ for m , motor_mutex in self .motor_positions .items ():
141+ position = self .api .get_motor_position (m )
217142 motor_mutex .write (position )
218143 if self .poynting_correction :
219144 self .poynting_correction .get_motor_positions ()
220145
221- def get_speed_parameters (self , inputs ):
222- motor_index = inputs [0 ]
223- error , min_speed , max_speed , acceleration = self .api ._get_speed_parameters (motor_index )
224- return [error , min_speed , max_speed , acceleration ]
225-
226- def initialize (self ):
227- self .serial_number = self .ini .read ('OPA' + str (self .index ), 'serial number' )
228- # load api
229- self .api = TOPAS_API (self .TOPAS_ini_filepath )
230- if self .has_shutter :
231- self .api .set_shutter (False )
232-
233- # motor positions
234- for motor_index , motor_name in enumerate (self .motor_names ):
235- error , min_position_steps , max_position_steps = self .api .get_motor_positions_range (motor_index )
236- valid_position_steps = np .arange (min_position_steps , max_position_steps + 1 )
237- valid_positions_units = [self .api .convert_position_to_units (motor_index , s )[1 ] for s in valid_position_steps ]
238- min_position = min (valid_positions_units )
239- max_position = max (valid_positions_units )
240- limits = pc .NumberLimits (min_position , max_position )
241- number = pc .Number (initial_value = 0 , limits = limits , display = True , decimals = 6 )
242- self .motor_positions [motor_name ] = number
243- self .recorded ['w%d_' % self .index + motor_name ] = [number , None , 1. , motor_name ]
244- # finish
245- BaseDriver .initialize (self )
246-
247146 def is_busy (self ):
248- if self .api .open :
249- error , still = self .api .are_all_motors_still ()
250- print ('TOPAS is busy' , error , still )
251- return not still
252- else :
253- return False # for shutdown
147+ return any (self .api .is_motor_busy (m ) for m in self .motor_names )
254148
255149 def set_shutter (self , inputs ):
256150 shutter_state = inputs [0 ]
257151 error = self .api .set_shutter (shutter_state )
258152 self .shutter_position .write (shutter_state )
259153 return error
260154
261- def set_speed_parameters (self , inputs ):
262- motor_index , min_speed , max_speed , accelleration = inputs
263- error = self .api ._set_speed_parameters (motor_index , min_speed , max_speed , acceleration )
264- return error
265-
266155
267156# --- gui -----------------------------------------------------------------------------------------
268157
0 commit comments