3. ASI Stage Handler - aasmaa11/microscope GitHub Wiki
Following the installation of Microscope-Cockpit, we've added the ASI Stage handler in the file './microscope/stages/asi.py'.
ASI stage handler
Inspired from https://github.com/amsikking/asi_MS_2000_500_CP. As shown in the figure below, the ASI stage handler needs three classes: the ASIStage class, the ASIStageAxis class and the SerialConnection class. The ASIStage is a subclass of the abstract base class Stage and ASIStageAxis ASIStage is a subclass of the abstract base class StageAxis. These inheritances link the ASI stage handler to Microscope.
The handler is able to control the stage through Python code by sending formatted strings to the serial connection. For instance, by sending the string "M X=100", the handler moves the X-axis to 100 (um???). The ASI backup manual details all the strings that can be used to control the stage.
ASIStage class
Init function
This functions takes as input:
- which_port: the port of the serial connection
- axes: tuple of axis names; ex: ('X','Y')
- piezo_z: a boolean for the Z-axis
- True when the Z-axis is controlled by a piezo-motor
- False when the Z-axis is controlled by a linear screw motion
- lead_screws: tuple with names of lead screw associated with each axis; ex: ('UC', 'SC')
- See 'Note about screw types' below to understand how the choice of lead screw affects the axis
- axes_min_mm: tuple with minimum position in mm associated with each axis
- axes_max_mm: tuple with maximum position associated with each axis
- encoder_counts_per_um: tuple with the encoder counts per um associated with each axis
- This value is used to convert counts to position in um (in ASIStageAxis _get_position function)
- use_pwm: a boolean for the LED's PWM output
- name: the name of the stage
- verbose and very_verbose: booleans used for debugging purposes to print statements when running the ASIStage class.
- index
Inside the initialization function, the class instantiate a serial connection with the input port to be able to send formatted serial commands to the stage (see SerialConnection section below). It also instantiate an ASIStageAxis object (see ASIStageAxis section below) for each axis name passed as input.
Note about lead screw types
The lead screw of a given axis defines its pitch, resolution and speed. The speed is in fact the maximum velocity (in mm/s) of the axis. Here is the list of lead screw types with their associated pitch, resolution and speed.
| Lead Screw Name | Pitch (mm) | Resolution (nm) | Speed (mm/s) |
|---|---|---|---|
| UC | 25.40 | 88.0 | 28.0 |
| SC | 12.70 | 44.0 | 14.0 |
| S | 6.350 | 22.0 | 7.00 |
| F | 1.590 | 5.50 | 1.75 |
| XF | 0.653 | 2.20 | 0.70 |
Note: When testing different screw lead type, only the 'F' type was moving the axes.
List of functions
- _do_disable: Should perform any device-specific work on disable. For now, it only return true.
- _do_enable: Should perform any device-specific work on enable. For now, it only return true.
- _do_shutdown: Sets the PWM state to OFF and closes the serial connection.
- get_pwm_intensity: Retrieves the PWM intensity of the X-axis's LED and returns it. This function should be placed in ASIStageAxis.
- string sent to the serial connection: 'LED X?'
- set_pwm_intensity: Sets the PWM intensity of the X-axis's LED to the input intensity. This function should be placed in ASIStageAxis.
- string sent to the serial connection: 'LED X=%d :NA'%intensity
- set_pwm_state: Sets the TTL in and out mode based on the input PWM state and updates the state of the stage. This function should be renamed set_state.
- move_by: Moves each axis to the relative position taken as input
- move_to: Moves each axis to the absolute position taken as input
List of properties
- axes: Returns a dictionary that maps axis name to the corresponding instance of ASIStageAxis
- position: Returns a dictionary that maps axis name to their current position
- limits: Returns a dictionary that maps axis name to their limits
ASIStageAxis
Init function
This function takes as input:
- name: the name of the axis (X for the X-axis, Y for the Y-axis, Z for the linear or piezo Z-axis)
- real_name: the real name of the axis (X for the X-axis, Y for the Y-axis, Z for the linear Z-axis and F for the piezo Z-axis) used to send commands to the serial connection.
- upper_limit: Maximum position the axis can go to.
- lower_limit: Minimum position the axis can go to.
- serial_connection: The instance of SerialConnection to which the ASIStage is linked.
- max_velocity_mmps: Maximum velocity in mm/s which depends on the lead screw (see 'Note about lead screw types' above)
- min_acceleration_ms: Minimum acceleration of the axis.
- max_acceleration_ms: Maximum acceleration of the axis.
- max_settle_time_ms: Minimum settle-time of the axis.
- tol_settle_time_ms: Settle-time tolerance of the axis.
- min_precision_um: Minimum precision of the axis.
- max_precision_um: Minimum precision of the axis.
- encoder_counts_per_um: Number of counts per um.
List of functions
- _set_velocity: Sets the velocity to the input value velocity_mmps (expressed in mm/s)
- string sent to the serial connection: 'V%s=%0.6f '%(self.real_name, velocity_mmps)
- _get_velocity: Retrieves the velocity and returns it as a float
- string sent to the serial connection: 'S '+'? '.join(self.real_name)+'?'
- _set_acceleration: Sets the acceleration to the input value acceleration_ms
- string sent to the serial connection: 'AC%s=%0.6f '%(self.real_name, acceleration_ms)
- _get_acceleration: Retrieves the acceleration and returns it as a float
- string sent to the serial connection: 'AC '+'? '.join(self.real_name)+'?'
- _set_settle_time: Sets the settle-time to the input value settle_time_ms
- string sent to the serial connection: 'WT%s=%0.6f '%(self.real_name, settle_time_ms)
- _get_settle_time: Retrieves the settle-time and returns it as a float
- string sent to the serial connection: 'WT '+'? '.join(self.real_name)+'?'
- _set_precision: Sets the precision to the input value precision_um (expressed in um)
- string sent to the serial connection: 'PC%s=%0.6f '%(self.real_name, 1e-6 * precision_um)
- _get_precision: Retrieves the precision, converts it and rounds it to um and returns it as a float
- string sent to the serial connection: 'PC '+'? '.join(self.real_name)+'?'
- _counts2position: Converts an input count value to a position in um
- _position2counts: Converts an input position value in um to a count rounded to the nearest int
- _get_position: Retrieves the current count, converts it to the current position in um and returns it
- string sent to the serial connection: 'W '+' '.join(self.real_name)
- _finish_moving: Concludes the axis move and checks that it moved to the correct position, throws an assert if not
- string sent to the serial connection to check if the axis is still moving: '/'
- if the axis stops moving, the serial connection returns this string: 'N'
- move_um: Moves the axis to/by the input position
- string sent to the serial connection: 'M %s=%0.6f '%(self.real_name, self._position2counts(move_um)
- move_by: Moves the axis by the input delta (calls move_um with relative=True)
- move_to: Moves the axis by the input position (calls move_um with relative=False)
List of properties
- position: Returns the current position as a float by calling _get_position
- name: Returns the axis name.
- limits: Returns the axis's limits as Microscope.AxisLimits
SerialConnection
List of functions
- init: Constructs a serial connection using Python's serial module
- _send: Encodes the input command (see ASIStageAxis for examples of formatted commands), writes it to the serial connection and returns the decoded response
Following functions need to be modified or maybe moved to the ASIStage class because they refer to the axes
- _set_ttl_in_mode: Sets the TTL mode of the x-axis to the mode passed as input
- _get_ttl_in_mode: Getter for the TTL mode of the x-axis
- _set_ttl_out_mode: Sets the TTL mode of the y-axis to the mode passed as input
- _get_ttl_out_mode: Getter for the TTL mode of the y-axis