Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
58d048b
Import InertialMotor
adeshazer123 Dec 11, 2024
1438661
Create KIM101
adeshazer123 Dec 11, 2024
c7ad612
Finish Kinesis
adeshazer123 Dec 11, 2024
7c84717
Update import
adeshazer123 Dec 11, 2024
de2cdab
Add close method
adeshazer123 Dec 11, 2024
2c4df5b
Update daq_move
adeshazer123 Dec 12, 2024
6dfbadd
Add channel
adeshazer123 Dec 12, 2024
f52827e
Fix self._channel
adeshazer123 Dec 12, 2024
68a02ef
Update channel daq_move
adeshazer123 Dec 12, 2024
9eb3904
Merge branch 'dev/kim101' of https://github.com/adeshazer123/pymodaq_…
nano713 Dec 12, 2024
b3cabc0
Correct typo.
nano713 Dec 12, 2024
054a8ea
Add suggestion in move_rel, channel, and others.
nano713 Dec 12, 2024
a8de663
default_units
nano713 Dec 12, 2024
020a194
Fix params, fix serialnumbers
adeshazer123 Dec 12, 2024
1124119
pass move_rel
adeshazer123 Dec 12, 2024
3e76ecb
Update axis
adeshazer123 Dec 12, 2024
d0c0336
test and debug
nano713 Dec 12, 2024
b09c809
Correct unit. Add suggestion
nano713 Dec 13, 2024
f2150fd
add self.axis
adeshazer123 Dec 13, 2024
ebc88ad
Update channel
adeshazer123 Dec 13, 2024
35232e7
Add int() for channel
adeshazer123 Dec 13, 2024
b299c54
Update move_abs, home. Test and debug.
nano713 Dec 13, 2024
858926a
Remove decimal
adeshazer123 Dec 13, 2024
bfea912
Merge branch 'dev/kim101' of https://github.com/nano713/pymodaq_plugi…
adeshazer123 Dec 13, 2024
58b8b51
Add channel and pass move_rel
adeshazer123 Dec 13, 2024
41f7989
Update info
adeshazer123 Dec 13, 2024
2097b0f
Update move_rel method.
nano713 Dec 14, 2024
61af638
pass commit_settings
adeshazer123 Dec 18, 2024
51b5b33
Delete comments
adeshazer123 Jan 14, 2025
e9fb634
Merge branch 'main' of https://github.com/PyMoDAQ/pymodaq_plugins_tho…
adeshazer123 Jan 14, 2025
fe36ecc
Update actuators
adeshazer123 Jan 14, 2025
fbb46bc
Rename KIM101
adeshazer123 Jan 14, 2025
19ff78a
delete comments
adeshazer123 Jan 14, 2025
cf1d262
Refractor comments
adeshazer123 Jan 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Actuators
* **PRM1Z8_pylablib**: DC servo motorized 360° rotation mount (Thorlabs PRM1Z8) using the pylablib control module. The Thorlabs APT software should be installed: https://www.thorlabs.com/newgrouppage9.cfm?objectgroup_id=9019.
* **BrushlessDCMotor**: Kinesis control of DC Brushless Motor (tested with the BBD201 controller)
* **Kinesis_KPZ101**: Piezo Electric Stage Kinesis series (KPZ101)
* **Kinesis_KIM101**: Four Channel Piezo Inertia Motion Kinesis series (KIM101)


Viewer0D
Expand Down
127 changes: 127 additions & 0 deletions src/pymodaq_plugins_thorlabs/daq_move_plugins/daq_move_KIM101.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
from pymodaq.control_modules.move_utility_classes import (
DAQ_Move_base, comon_parameters_fun, main, DataActuatorType, DataActuator)
from pymodaq.utils.daq_utils import ThreadCommand
from pymodaq.utils.parameter import Parameter
from pymodaq_plugins_thorlabs.hardware.kinesis import serialnumbers_inertial_motor, KIM101
from pymodaq.utils.logger import set_logger, get_module_name

class DAQ_Move_KIM101(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.

Attributes:
-----------
controller: object
The particular object that allow the communication with the hardware, in general a python wrapper around the
hardware library.

"""
_controller_units = KIM101.default_units
is_multiaxes = True
_axes_names = {'1': 1, '2': 2, '3': 3, '4': 4}
_epsilon = 0.01
data_actuator_type = DataActuatorType.DataActuator
params = [
{'title': 'Serial Number:', 'name': 'serial_number', 'type': 'list',
'limits': serialnumbers_inertial_motor, 'value': serialnumbers_inertial_motor[0]},

] + comon_parameters_fun(is_multiaxes, axes_names=_axes_names, epsilon=_epsilon)

def ini_attributes(self):
self.controller: KIM101 = None

def get_actuator_value(self):
"""Get the current value from the hardware with scaling conversion.

Returns
-------
DataActuator: The position obtained after scaling conversion.
"""
pos = DataActuator(
data=self.controller.get_position(channel=self.axis_value),
units=self.controller.get_units()
)
pos = self.get_position_with_scaling(pos)
return pos

def close(self):
"""Terminate the communication protocol"""
if self.is_master:
self.controller.close()

def commit_settings(self, param: Parameter):
"""Apply the consequences of a change of value in the detector settings

Parameters
----------
param: Parameter
A given parameter (within detector_settings) whose value has been changed by the user
"""
pass

def ini_stage(self, controller=None):
"""Actuator communication initialization

Parameters
----------
controller: (object)
custom object of a PyMoDAQ plugin (Slave case). None if only one actuator by controller (Master case)

Returns
-------
info: str
initialized: bool
False if initialization failed otherwise True
"""

if self.is_master:
self.controller = KIM101()
self.controller.connect(self.settings['serial_number'])
else:
self.controller = controller

self.axis_unit = self._controller_units

info = "KIM101 Initialized"
initialized = True
return info, initialized

def move_abs(self, value: DataActuator):
""" Move the actuator to the absolute target defined by value

Parameters
----------
value: (DataActuator) value of the absolute target positioning
"""
value = self.check_bound(value)
self.target_value = value
value = self.set_position_with_scaling(value)
self.controller.move_abs(int(value.value()), self.axis_value)

def move_rel(self, value: DataActuator):
""" Move the actuator to the relative target actuator value defined by value

Parameters
----------
value: (float) value of the relative target positioning
"""
value = self.check_bound(self.current_position + value) - self.current_position
self.target_value = value + self.current_position
value = self.set_position_relative_with_scaling(value)

self.controller.move_rel(int(value.value()), self.axis_value)


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

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


if __name__ == '__main__':
main(__file__, init=False)
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def ini_stage(self, controller=None):

self.axis_unit = self._controller_units

info = f'{self.controller.name} - {self.controller.serial_number}'
info = "KIM101 Initialized"
initialized = True
return info, initialized

Expand All @@ -103,7 +103,7 @@ def move_abs(self, value: DataActuator):
value = self.check_bound(value)
self.target_value = value
value = self.set_position_with_scaling(value)
self.controller.move_abs(value.value())
self.controller.move_abs(value.value(), axis=self.axis)

def move_rel(self, value: DataActuator):
""" Move the actuator to the relative target actuator value defined by value
Expand All @@ -119,7 +119,7 @@ def move_rel(self, value: DataActuator):

def move_home(self):
"""Call the reference method of the controller"""
self.controller.home()
self.controller.home(axis=self.axis)

def stop_motion(self):
"""Stop the actuator and emits move_done signal"""
Expand Down
55 changes: 55 additions & 0 deletions src/pymodaq_plugins_thorlabs/hardware/kinesis.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from System import Action
from System import UInt64
from System import UInt32
import logging

kinesis_path = 'C:\\Program Files\\Thorlabs\\Kinesis'
sys.path.append(kinesis_path)
Expand All @@ -19,13 +20,15 @@
clr.AddReference("Thorlabs.MotionControl.FilterFlipperCLI")
clr.AddReference("Thorlabs.MotionControl.Benchtop.BrushlessMotorCLI")
clr.AddReference("Thorlabs.MotionControl.KCube.PiezoCLI")
clr.AddReference("Thorlabs.MotionControl.KCube.InertialMotorCLI")

import Thorlabs.MotionControl.FilterFlipperCLI as FilterFlipper
import Thorlabs.MotionControl.IntegratedStepperMotorsCLI as Integrated
import Thorlabs.MotionControl.DeviceManagerCLI as Device
import Thorlabs.MotionControl.GenericMotorCLI as Generic
import Thorlabs.MotionControl.Benchtop.BrushlessMotorCLI as BrushlessMotorCLI
import Thorlabs.MotionControl.KCube.PiezoCLI as KCubePiezo
import Thorlabs.MotionControl.KCube.InertialMotorCLI as InertialMotor

Device.DeviceManagerCLI.BuildDeviceList()
serialnumbers_integrated_stepper = [str(ser) for ser in
Expand All @@ -36,6 +39,8 @@
Device.DeviceManagerCLI.GetDeviceList(BrushlessMotorCLI.BenchtopBrushlessMotor.DevicePrefix)]
serialnumbers_piezo = [str(ser) for ser in Device.DeviceManagerCLI.GetDeviceList(KCubePiezo.KCubePiezo.DevicePrefix)]

serialnumbers_inertial_motor = [str(ser) for ser in Device.DeviceManagerCLI.GetDeviceList(InertialMotor.KCubeInertialMotor.DevicePrefix_KIM101)]


class Kinesis:
default_units = ''
Expand Down Expand Up @@ -323,6 +328,56 @@ def get_position(self) -> float:
def stop(self):
pass

class KIM101(Kinesis):
default_units = ' '

def __init__(self):
self._device: InertialMotor.KCubeInertialMotor = None
self._channel = []

def connect(self, serial: int):
if serial in serialnumbers_inertial_motor:
self._device = InertialMotor.KCubeInertialMotor.CreateKCubeInertialMotor(serial)
self._device.Connect(serial)
self._device.WaitForSettingsInitialized(5000)
self._device.StartPolling(250)
self._device.EnableDevice()
self._channel = [
InertialMotor.InertialMotorStatus.MotorChannels.Channel1,
InertialMotor.InertialMotorStatus.MotorChannels.Channel2,
InertialMotor.InertialMotorStatus.MotorChannels.Channel3,
InertialMotor.InertialMotorStatus.MotorChannels.Channel4
]

def move_abs(self, position: int, channel: int):
self._device.MoveTo(self._channel[channel-1], position, 6000)

def move_rel(self, increment: int, channel: int):
target_position = self.get_position(channel) + increment
while (increment != 0):
if (increment > 0):
step = min(increment, 1)
else:
step = max(increment, -1)
position_new = self.get_position(channel) + step
self.move_abs(position_new, channel)
increment = target_position - self.get_position(channel)


def get_position(self, channel: int):
return self._device.GetPosition(self._channel[channel-1])

def home(self, channel: int):
self._device.MoveTo(self._channel[channel-1], 0, 6000)

def stop(self):
pass

def close(self):
self._device.StopPolling()
self._device.Disconnect()


if __name__ == '__main__':
controller = BrushlessDCMotor()
controller.connect(serialnumbers_brushless[0])
Expand Down