Skip to content

Commit

Permalink
added the instrument class to control the rook
Browse files Browse the repository at this point in the history
  • Loading branch information
seb5g committed Mar 3, 2025
1 parent 2fd4d70 commit ca2def5
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from pymodaq.control_modules.move_utility_classes import (DAQ_Move_base, comon_parameters_fun,
main, DataActuatorType, DataActuator)

from pymodaq_utils.utils import ThreadCommand # object used to send info back to the main thread
from pymodaq_utils.utils import ThreadCommand
from pymodaq_utils.logger import set_logger, get_module_name

from pymodaq_data import Q_
Expand Down
119 changes: 48 additions & 71 deletions src/pymodaq_plugins_montana/daq_move_plugins/daq_move_Rook.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,53 +3,48 @@
from pymodaq.control_modules.move_utility_classes import (DAQ_Move_base, comon_parameters_fun,
main, DataActuatorType, DataActuator)

from pymodaq_utils.logger import set_logger, get_module_name
from pymodaq_utils.utils import ThreadCommand # object used to send info back to the main thread

from pymodaq_data import Q_

from pymodaq_gui.parameter import Parameter

from pymodaq_plugins_montana.hardware.rook import Rook
from pymodaq_plugins_montana.utils import Config as PluginConfig


plugin_config = PluginConfig()
logger = set_logger(get_module_name(__file__))


class DAQ_Move_Rook(DAQ_Move_base):
""" Instrument plugin class for an actuator.
This object inherits all functionalities to communicate with PyMoDAQ’s DAQ_Move module through inheritance via
DAQ_Move_base. It makes a bridge between the DAQ_Move module and the Python wrapper of a particular instrument.
TODO Complete the docstring of your plugin with:
* The set of controllers and actuators that should be compatible with this instrument plugin.
* With which instrument and controller it has been tested.
* The version of PyMoDAQ during the test.
* The version of the operating system.
* Installation instructions: what manufacturer’s drivers should be installed to make it run?
Attributes:
-----------
controller: object
The particular object that allow the communication with the hardware, in general a python wrapper around the
hardware library.
# TODO add your particular attributes here if any
"""
is_multiaxes = False # TODO for your plugin set to True if this plugin is controlled for a multiaxis controller
_axis_names: Union[List[str], Dict[str, int]] = ['Axis1', 'Axis2'] # TODO for your plugin: complete the list
_controller_units: Union[str, List[str]] = 'mm' # TODO for your plugin: put the correct unit here, it could be
# TODO a single str (the same one is applied to all axes) or a list of str (as much as the number of axes)
_epsilon: Union[float, List[float]] = 0.1 # TODO replace this by a value that is correct depending on your controller
# TODO it could be a single float of a list of float (as much as the number of axes)
data_actuator_type = DataActuatorType.DataActuator # wether you use the new data style for actuator otherwise set this
# as DataActuatorType.float (or entirely remove the line)

params = [ # TODO for your custom plugin: elements to be added here as dicts in order to control your custom stage
is_multiaxes = True
_axis_names: Union[List[str], Dict[str, int]] = {'Xaxis': 1, 'Yaxis': 2, 'Zaxis':3}
_controller_units: Union[str, List[str]] = 'm'
_epsilon: Union[float, List[float]] = 1e-7
data_actuator_type = DataActuatorType.DataActuator
params = [
{'title': 'Server IP:', 'name': 'ipaddress', 'type': 'str', 'value': plugin_config('ip_address')},
{'title': 'Cryo. Port:', 'name': 'cryo_port', 'type': 'int', 'value': plugin_config('rook_port')},
] + comon_parameters_fun(is_multiaxes, axis_names=_axis_names, epsilon=_epsilon)
# _epsilon is the initial default value for the epsilon parameter allowing pymodaq to know if the controller reached
# the target value. It is the developer responsibility to put here a meaningful value

def ini_attributes(self):
# TODO declare the type of the wrapper (and assign it to self.controller) you're going to use for easy
# autocompletion
self.controller: PythonWrapperOfYourInstrument = None

#TODO declare here attributes you want/need to init with a default value
pass
self.controller: Rook = None
self.stack_num = 1

def get_actuator_value(self):
"""Get the current value from the hardware with scaling conversion.
Expand All @@ -58,9 +53,9 @@ def get_actuator_value(self):
-------
float: The position obtained after scaling conversion.
"""
## TODO for your custom plugin
raise NotImplemented # when writing your own plugin remove this line
pos = DataActuator(data=self.controller.your_method_to_get_the_actuator_value()) # when writing your own plugin replace this line

pos = DataActuator(data=self.controller.get_axis_encoder_position(self.stack_num, self.axis_value),
units=self.axis_unit)
pos = self.get_position_with_scaling(pos)
return pos

Expand All @@ -72,17 +67,11 @@ def user_condition_to_reach_target(self) -> bool:
-------
bool: if True, PyMoDAQ considers the target value has been reached
"""
# TODO either delete this method if the usual polling is fine with you, but if need you can
# add here some other condition to be fullfilled either a completely new one or
# using or/and operations between the epsilon_bool and some other custom booleans
# for a usage example see DAQ_Move_brushlessMotor from the Thorlabs plugin
return True
return not self.controller.get_axis_moving(self.stack_num, self.axis_value)

def close(self):
"""Terminate the communication protocol"""
## TODO for your custom plugin
raise NotImplemented # when writing your own plugin remove this line
# self.controller.your_method_to_terminate_the_communication() # when writing your own plugin replace this line
self.controller.close()

def commit_settings(self, param: Parameter):
"""Apply the consequences of a change of value in the detector settings
Expand All @@ -92,17 +81,7 @@ def commit_settings(self, param: Parameter):
param: Parameter
A given parameter (within detector_settings) whose value has been changed by the user
"""
## TODO for your custom plugin
if param.name() == 'axis':
self.axis_unit = self.controller.your_method_to_get_correct_axis_unit()
# do this only if you can and if the units are not known beforehand, for instance
# if the motors connected to the controller are of different type (mm, µm, nm, , etc...)
# see BrushlessDCMotor from the thorlabs plugin for an exemple

elif param.name() == "a_parameter_you've_added_in_self.params":
self.controller.your_method_to_apply_this_param_change()
else:
pass
pass

def ini_stage(self, controller=None):
"""Actuator communication initialization
Expand All @@ -118,16 +97,26 @@ def ini_stage(self, controller=None):
initialized: bool
False if initialization failed otherwise True
"""
raise NotImplemented # TODO when writing your own plugin remove this line and modify the ones below
self.ini_stage_init(slave_controller=controller) # will be useful when controller is slave

if self.is_master: # is needed when controller is master
self.controller = PythonWrapperOfYourInstrument(arg1, arg2, ...) # arguments for instantiation!)
# todo: enter here whatever is needed for your controller initialization and eventual
# opening of the communication channel
self.controller = Rook(ip=self.settings['ipaddress'], port=self.settings['cryo_port'])
else:
self.controller = controller

self.emit_status(ThreadCommand('update_ui', attribute='set_abs_value_red',
args=[Q_(0, 'um')]))

self.emit_status(ThreadCommand('update_ui', attribute='set_abs_value_green',
args=[Q_(100, 'um')]))

self.emit_status(ThreadCommand('update_ui', attribute='set_abs_value',
args=[Q_(100, 'um')]))

self.emit_status(ThreadCommand('update_ui', attribute='set_rel_value',
args=[Q_(100, 'um')]))

info = "Whatever info you want to log"
initialized = self.controller.a_method_or_atttribute_to_check_if_init() # todo
info = "Rook is connected"
initialized = True
return info, initialized

def move_abs(self, value: DataActuator):
Expand All @@ -141,10 +130,7 @@ def move_abs(self, value: DataActuator):
value = self.check_bound(value) #if user checked bounds, the defined bounds are applied here
self.target_value = value
value = self.set_position_with_scaling(value) # apply scaling if the user specified one
## TODO for your custom plugin
raise NotImplemented # when writing your own plugin remove this line
self.controller.your_method_to_set_an_absolute_value(value.value()) # when writing your own plugin replace this line
self.emit_status(ThreadCommand('Update_Status', ['Some info you want to log']))
self.controller.move_axis_absolute_position(self.stack_num, self.axis_value, value.value())

def move_rel(self, value: DataActuator):
""" Move the actuator to the relative target actuator value defined by value
Expand All @@ -157,26 +143,17 @@ def move_rel(self, value: DataActuator):
self.target_value = value + self.current_position
value = self.set_position_relative_with_scaling(value)

## TODO for your custom plugin
raise NotImplemented # when writing your own plugin remove this line
self.controller.your_method_to_set_a_relative_value(value.value()) # when writing your own plugin replace this line
self.emit_status(ThreadCommand('Update_Status', ['Some info you want to log']))
self.move_abs(self.target_value)

def move_home(self):
"""Call the reference method of the controller"""

## TODO for your custom plugin
raise NotImplemented # when writing your own plugin remove this line
self.controller.your_method_to_get_to_a_known_reference() # when writing your own plugin replace this line
self.emit_status(ThreadCommand('Update_Status', ['Some info you want to log']))
self.controller.move_axis_to_negative_limit(self.stack_num, self.axis_value, wait=True)

def stop_motion(self):
"""Stop the actuator and emits move_done signal"""

## TODO for your custom plugin
raise NotImplemented # when writing your own plugin remove this line
self.controller.your_method_to_stop_positioning() # when writing your own plugin replace this line
self.emit_status(ThreadCommand('Update_Status', ['Some info you want to log']))
self.controller.stop_axis(self.stack_num, self.axis_value)


if __name__ == '__main__':
Expand Down
9 changes: 5 additions & 4 deletions src/pymodaq_plugins_montana/hardware/rook.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@

import sys
import os
from . import instrument
from pymodaq_plugins_montana.hardware import instrument
import time
import datetime


class Rook(instrument.Instrument):
def __init__(self, ip, version='v1', verbose=False, tunnel=False):
def __init__(self, ip, version='v1', verbose=False, tunnel=False, port=instrument.Rest_Ports.lynx_hlm):
super().__init__(ip=ip,
port=instrument.Rest_Ports.lynx_hlm,
port=port,
version=version,
verbose=verbose,
tunnel=tunnel)
Expand Down Expand Up @@ -137,7 +138,7 @@ def set_axis_hard_stop_sensitivity(self, stack_num, axis_num, sensitivity):

if __name__ == "__main__":

rook = Rook('192.168.45.120', verbose=False)
rook = Rook('10.35.3.38', verbose=False)

stack_num = 1
axis_num = 1
Expand Down
1 change: 1 addition & 0 deletions src/pymodaq_plugins_montana/resources/config_template.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ title = 'this is the configuration file of the plugin Montana'
ip_address = '10.35.3.38'

cryo_port = 47101
rook_port = 47171

temp_stability = 0.05 # K

Expand Down

0 comments on commit ca2def5

Please sign in to comment.