-
Notifications
You must be signed in to change notification settings - Fork 11
Modified for running in Linux and New stage driver #1045
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
62e86e6
6d8ef3d
81f27a8
49607a6
1b6cefa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -511,8 +511,18 @@ def load_stages( | |
exception=TLFTDICommunicationError, | ||
) | ||
) | ||
|
||
elif stage_type == "KST101": | ||
elif stage_type == "KINESIS" and platform.system() == "Linux": | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is now obsolete with the latest PR. |
||
from navigate.model.devices.stages.tl_kinesis_steppermotor import ( | ||
build_KINESIS_Stage_connection | ||
) | ||
stage_devices.append( | ||
auto_redial( | ||
build_KINESIS_Stage_connection, | ||
(stage_config["serial_number"],), | ||
exception=Exception | ||
) | ||
) | ||
elif stage_type == "KST101" and platform.system=="Windows": | ||
from navigate.model.devices.stages.tl_kcube_steppermotor import ( | ||
build_TLKSTStage_connection, | ||
) | ||
|
@@ -562,12 +572,8 @@ def load_stages( | |
) | ||
) | ||
|
||
elif stage_type == "MS2000" and platform.system() == "Windows": | ||
"""Filter wheel can be controlled from the same Controller. If | ||
so, then we will load this as a shared device. If not, we will create the | ||
connection to the Controller. | ||
|
||
TODO: Evaluate whether MS2000 should be able to operate as a shared device. | ||
elif stage_type == "MS2000": | ||
"""Stage and filter wheel are independent and should not be a shared device | ||
""" | ||
|
||
from navigate.model.devices.stages.asi_MSTwoThousand import ( | ||
|
@@ -705,7 +711,10 @@ def start_stage( | |
from navigate.model.devices.stages.tl_kcube_inertial import TLKIMStage | ||
|
||
return TLKIMStage(microscope_name, device_connection, configuration, id) | ||
|
||
elif device_type == "KINESIS": | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This device should also be added to the configuration wizard. |
||
from navigate.model.devices.stages.tl_kinesis_steppermotor import TLKINStage | ||
|
||
return TLKINStage(microscope_name, device_connection, configuration, id) | ||
elif device_type == "KST101": | ||
from navigate.model.devices.stages.tl_kcube_steppermotor import TLKSTStage | ||
|
||
|
@@ -1265,7 +1274,6 @@ def start_lasers( | |
modulation = "analog" | ||
elif digital == "NI": | ||
modulation = "digital" | ||
|
||
return LaserNI( | ||
microscope_name=microscope_name, | ||
device_connection=device_connection, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
""" | ||
API for connection to Thorlabs.MotionControl.KCube.StepperMotor.dll. | ||
See Thorlabs.MotionControl.KCube.StepperMotor.h for more functions to implement. | ||
""" | ||
|
||
""" | ||
2024/10/23 Sheppard: Initialized to control Kinesis Stepper motor in Linux | ||
""" | ||
from pylablib.devices import Thorlabs | ||
import logging | ||
# Local Imports | ||
|
||
# Logger Setup | ||
p = __name__.split(".")[1] | ||
logger = logging.getLogger(p) | ||
|
||
class KinesisStage(): | ||
def __init__(self, dev_path: str, verbose: bool): | ||
"""_summary_ | ||
|
||
Args: | ||
connection (_type_): _description_ | ||
""" | ||
connection = {"port":dev_path,"baudrate":115200,"rtscts":True} | ||
self.verbose = verbose | ||
self.dev_path = dev_path | ||
self.defualt_axes = ["f"] | ||
|
||
self.move_params = {"min_velocity":None, | ||
"max_velocity":None, | ||
"acceleration":None} | ||
|
||
self.open(connection) | ||
|
||
|
||
def __str__(self) -> str: | ||
"""Returns the string representation of the MS2000 Controller class""" | ||
return "KinesisController" | ||
|
||
def open(self, connection): | ||
""" | ||
Open the device for communications. | ||
|
||
Parmeters | ||
--------- | ||
serial_number : str | ||
Serial number of Thorlabs Kinesis Stepper Motor (KST) device. | ||
|
||
Returns | ||
------- | ||
int | ||
The error code or 0 if successful. | ||
""" | ||
try: | ||
self.stage = Thorlabs.KinesisMotor(("serial", connection), scale="step") | ||
success = True | ||
except Exception as e: | ||
success = False | ||
raise ConnectionError(f"KST101 stage connection failed! \nError: {e}") | ||
|
||
def close(self): | ||
""" | ||
Disconnect and close the device. | ||
|
||
Parmeters | ||
--------- | ||
serial_number : str | ||
Serial number of Thorlabs Kinesis Stepper Motor (KST) device. | ||
|
||
Returns | ||
------- | ||
None | ||
""" | ||
self.stage.stop() | ||
self.stage.close() | ||
|
||
def move_to_position(self, position, steps_per_um, wait_till_done): | ||
"""Move to position (um) | ||
""" | ||
self.stage.get_position(channel=1, scale=False) | ||
cur_pos = self.stage.get_position(channel=1, scale=False) | ||
position_um = cur_pos / steps_per_um | ||
# calculate the distance needed to move | ||
distance = position - position_um | ||
# convert total distance to steps | ||
steps = steps_per_um * distance | ||
self.stage.move_by(steps, channel=1, scale=False) | ||
if wait_till_done: | ||
self.stage.wait_move(channel=1) | ||
return 0 | ||
|
||
def get_current_position(self, steps_per_um): | ||
"""Get the current position | ||
|
||
Parmeters | ||
--------- | ||
serial_number : str | ||
Serial number of Thorlabs Kinesis Stepper Motor (KST) device. | ||
|
||
Returns | ||
------- | ||
int | ||
Current position. | ||
""" | ||
self.stage.get_position(channel=1, scale=False) | ||
position = self.stage.get_position(channel=1, scale="False") | ||
position_um = position / steps_per_um | ||
return round(position_um, 2) | ||
|
||
def stop(self): | ||
""" | ||
Halt motion | ||
|
||
Parmeters | ||
--------- | ||
serial_number : str | ||
Serial number of Thorlabs Kinesis Stepper Motor (KST) device. | ||
channel : int | ||
The device channel. One of SCC_Channels. | ||
|
||
Returns | ||
------- | ||
int | ||
The error code or 0 if successful. | ||
""" | ||
self.stage.stop() | ||
return 0 | ||
|
||
def home_stage(self): | ||
"""Home Device | ||
""" | ||
self.stage.home() | ||
return 0 | ||
|
||
def set_velocity_params(self, | ||
min_velocity, | ||
max_velocity, | ||
acceleration, | ||
steps_per_um): | ||
"""Set velocity profile required for move | ||
""" | ||
min_velocity *= steps_per_um | ||
max_velocity *= steps_per_um | ||
acceleration *= steps_per_um | ||
self.stage.set_move_params(min_velocity, max_velocity, acceleration) | ||
self.move_params = {"min_velocity":min_velocity, | ||
"max_velocity":max_velocity, | ||
"acceleration":acceleration} | ||
return 0 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -66,8 +66,8 @@ def build_photometrics_connection(camera_connection): | |
""" | ||
try: | ||
pvc.init_pvcam() | ||
# camera_names = Camera.get_available_camera_names() | ||
camera_to_open = Camera.select_camera(camera_connection) | ||
camera_names = Camera.get_available_camera_names() | ||
camera_to_open = Camera.select_camera(camera_names[0]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this assume only one camera? |
||
camera_to_open.open() | ||
return camera_to_open | ||
except Exception as e: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -172,12 +172,14 @@ def set_external_trigger(self, external_trigger=None) -> None: | |
self.analog_output_tasks[ | ||
board_name | ||
].triggers.start_trigger.cfg_dig_edge_start_trig(trigger_source) | ||
try: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If it was throwing an error, but handled with a try/except statement, why did you have to remove it? |
||
self.analog_output_tasks[board_name].register_done_event(None) | ||
except Exception: | ||
logger.debug( | ||
f"Error Registering Done Event: {traceback.format_exc()}" | ||
) | ||
# NOTE: this was causing an error for me using PCIe-6343 in Linux. Not sure if it was board or OS related. | ||
# try: | ||
# # print(board_name) | ||
# # self.analog_output_tasks[board_name].register_done_event(None) | ||
# except Exception: | ||
# logger.debug( | ||
# f"Error Registering Done Event: {traceback.format_exc()}" | ||
# ) | ||
else: | ||
# close master trigger task | ||
if self.master_trigger_task: | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should discuss this. I'm hesitant to make the change immediately, but we can consider a better way to communicate the origin.