Skip to content

Commit

Permalink
Tpz fixes (#1178)
Browse files Browse the repository at this point in the history
*   flake8
*   fix TPZ constructor after move to asyncio
*   Tcube fix docummentation in set_channel_enable_state
  • Loading branch information
pathfinder49 authored and sbourdeauducq committed Oct 20, 2018
1 parent a84c6c6 commit 029f9d9
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 47 deletions.
104 changes: 57 additions & 47 deletions artiq/devices/thorlabs_tcube/driver.py
Expand Up @@ -207,7 +207,8 @@ async def handle_message(self, msg):
# derived classes must implement this
raise NotImplementedError

async def send_request(self, msgreq_id, wait_for_msgs, param1=0, param2=0, data=None):
async def send_request(self, msgreq_id, wait_for_msgs, param1=0, param2=0,
data=None):
await self.send(Message(msgreq_id, param1, param2, data=data))
msg = None
while msg is None or msg.id not in wait_for_msgs:
Expand All @@ -218,7 +219,7 @@ async def send_request(self, msgreq_id, wait_for_msgs, param1=0, param2=0, data=
async def set_channel_enable_state(self, activated):
"""Enable or Disable channel 1.
:param activated: 1 to enable channel, 2 to disable it.
:param activated: 1 to enable channel, 0 to disable it.
"""

if activated:
Expand Down Expand Up @@ -283,9 +284,13 @@ async def ping(self):


class Tpz(_Tcube):
"""Either :py:meth:`set_tpz_io_settings()<Tpz.set_tpz_io_settings>`
or :py:meth:`get_tpz_io_settings()<Tpz.get_tpz_io_settings>` must
be completed to finish initialising the driver.
"""
def __init__(self, serial_dev):
_Tcube.__init__(self, serial_dev)
self.voltage_limit = self.get_tpz_io_settings()[0]
self.voltage_limit = None

async def handle_message(self, msg):
msg_id = msg.id
Expand Down Expand Up @@ -336,7 +341,7 @@ async def get_position_control_mode(self):
:rtype: int
"""
get_msg = await self.send_request(MGMSG.PZ_REQ_POSCONTROLMODE,
[MGMSG.PZ_GET_POSCONTROLMODE], 1)
[MGMSG.PZ_GET_POSCONTROLMODE], 1)
return get_msg.param2

async def set_output_volts(self, voltage):
Expand All @@ -348,9 +353,8 @@ async def set_output_volts(self, voltage):
:param voltage: The output voltage applied to the piezo when operating
in open loop mode. The voltage value must be in range
[0; voltage_limit]. Voltage_limit being set by the
:py:meth:`set_tpz_io_settings()
<artiq.devices.thorlabs_tcube.driver.Tpz.set_tpz_io_settings>` method
between the three values 75 V, 100 V and 150 V.
:py:meth:`set_tpz_io_settings()<Tpz.set_tpz_io_settings>`
method between the three values 75 V, 100 V and 150 V.
"""
if voltage < 0 or voltage > self.voltage_limit:
raise ValueError("Voltage must be in range [0;{}]"
Expand All @@ -366,7 +370,7 @@ async def get_output_volts(self):
:rtype: float
"""
get_msg = await self.send_request(MGMSG.PZ_REQ_OUTPUTVOLTS,
[MGMSG.PZ_GET_OUTPUTVOLTS], 1)
[MGMSG.PZ_GET_OUTPUTVOLTS], 1)
return st.unpack("<H", get_msg.data[2:])[0]*self.voltage_limit/32767

async def set_output_position(self, position_sw):
Expand Down Expand Up @@ -404,7 +408,7 @@ async def set_input_volts_source(self, volt_src):
0x00 Software Only: Unit responds only to software inputs and the
HV amp output is that set using the :py:meth:`set_output_volts()
<artiq.devices.thorlabs_tcube.driver.Tpz.set_output_volts>` method.
<Tpz.set_output_volts>` method.
0x01 External Signal: Unit sums the differential signal on the rear
panel EXT IN(+) and EXT IN(-) connectors with the voltage set
Expand All @@ -426,13 +430,12 @@ async def get_input_volts_source(self):
amplifier circuit.
:return: Value which selects the various analog sources, cf.
:py:meth:`set_input_volts_source()
<artiq.devices.thorlabs_tcube.driver.Tpz.set_input_volts_source>` method
docstring for meaning of bits.
:py:meth:`set_input_volts_source()<Tpz.set_input_volts_source>`
method docstring for meaning of bits.
:rtype: int
"""
get_msg = await self.send_request(MGMSG.PZ_REQ_INPUTVOLTSSRC,
[MGMSG.PZ_GET_INPUTVOLTSSRC], 1)
[MGMSG.PZ_GET_INPUTVOLTSSRC], 1)
return st.unpack("<H", get_msg.data[2:])[0]

async def set_pi_constants(self, prop_const, int_const):
Expand All @@ -459,7 +462,7 @@ async def get_pi_constants(self):
:rtype: a 2 int elements tuple : (int, int)
"""
get_msg = await self.send_request(MGMSG.PZ_REQ_PICONSTS,
[MGMSG.PZ_GET_PICONSTS], 1)
[MGMSG.PZ_GET_PICONSTS], 1)
return st.unpack("<HH", get_msg.data[2:])

async def set_output_lut(self, lut_index, output):
Expand Down Expand Up @@ -488,7 +491,7 @@ async def set_output_lut(self, lut_index, output):
applicable channel is specified by the Chan Ident parameter If only a
sub set of the array is being used (as specified by the cyclelength
parameter of the :py:meth:`set_output_lut_parameters()
<artiq.devices.thorlabs_tcube.driver.Tpz.set_output_lut_parameters>`
<Tpz.set_output_lut_parameters>`
function), then only the first cyclelength values need to be set. In
this manner, any arbitrary voltage waveform can be programmed into the
LUT. Note. The LUT values are output by the system at a maximum
Expand All @@ -499,8 +502,8 @@ async def set_output_lut(self, lut_index, output):
to 512 for TPZ).
:param output: The voltage value to be set. Values are in the range
[0; voltage_limit]. Voltage_limit being set with the
:py:meth:`set_tpz_io_settings
<artiq.devices.thorlabs_tcube.driver.Tpz.set_tpz_io_settings>` method.
:py:meth:`set_tpz_io_settings<Tpz.set_tpz_io_settings>`
method.
"""
volt = round(output*32767/self.voltage_limit)
payload = st.pack("<HHH", 1, lut_index, volt)
Expand All @@ -519,7 +522,8 @@ async def get_output_lut(self):
return index, output*self.voltage_limit/32767

async def set_output_lut_parameters(self, mode, cycle_length, num_cycles,
delay_time, precycle_rest, postcycle_rest):
delay_time, precycle_rest,
postcycle_rest):
"""Set Waveform Generator Mode parameters.
It is possible to use the controller in an arbitrary Waveform
Expand Down Expand Up @@ -680,8 +684,8 @@ async def get_tpz_io_settings(self):
:return: Returns a tuple whose elements are the voltage limit and the
Hub analog input. Refer to :py:meth:`set_tpz_io_settings()
<artiq.devices.thorlabs_tcube.driver.Tpz.set_tpz_io_settings>` for the
meaning of those parameters.
<Tpz.set_tpz_io_settings>` for
the meaning of those parameters.
:rtype: a 2 elements tuple (int, int)
"""
get_msg = await self.send_request(MGMSG.PZ_REQ_TPZ_IOSETTINGS,
Expand Down Expand Up @@ -760,8 +764,7 @@ async def get_pot_parameters(self):
:return: An 8 int tuple containing the following values: zero_wnd,
vel1, wnd1, vel2, wnd2, vel3, wnd3, vel4. See
:py:meth:`set_pot_parameters()
<artiq.devices.thorlabs_tcube.driver.Tdc.set_pot_parameters>` for a
:py:meth:`set_pot_parameters()<Tdc.set_pot_parameters>` for a
description of each tuple element meaning.
:rtype: An 8 int tuple
"""
Expand Down Expand Up @@ -839,7 +842,7 @@ async def get_velocity_parameters(self):
return st.unpack("<LL", get_msg.data[6:])

async def set_jog_parameters(self, mode, step_size, acceleration,
max_velocity, stop_mode):
max_velocity, stop_mode):
"""Set the velocity jog parameters.
:param mode: 1 for continuous jogging, 2 for single step jogging.
Expand Down Expand Up @@ -883,7 +886,7 @@ async def get_gen_move_parameters(self):
:rtype: int
"""
get_msg = await self.send_request(MGMSG.MOT_REQ_GENMOVEPARAMS,
[MGMSG.MOT_GET_GENMOVEPARAMS], 1)
[MGMSG.MOT_GET_GENMOVEPARAMS], 1)
return st.unpack("<l", get_msg.data[2:])[0]

async def set_move_relative_parameters(self, relative_distance):
Expand Down Expand Up @@ -950,7 +953,8 @@ async def move_home(self):
This call is blocking until device is homed or move is stopped.
"""
await self.send_request(MGMSG.MOT_MOVE_HOME,
[MGMSG.MOT_MOVE_HOMED, MGMSG.MOT_MOVE_STOPPED], 1)
[MGMSG.MOT_MOVE_HOMED, MGMSG.MOT_MOVE_STOPPED],
1)

async def set_limit_switch_parameters(self, cw_hw_limit, ccw_hw_limit):
"""Set the limit switch parameters.
Expand Down Expand Up @@ -988,7 +992,7 @@ async def get_limit_switch_parameters(self):
:return: A 2 int tuple containing the following in order: cw_hw_limit,
ccw_hw_limit. Cf. description in
:py:meth:`set_limit_switch_parameters()
<artiq.devices.thorlabs_tcube.driver.Tdc.set_limit_switch_parameters>`
<Tdc.set_limit_switch_parameters>`
method.
:rtype: A 2 int tuple.
"""
Expand All @@ -1001,11 +1005,13 @@ async def move_relative_memory(self):
The relative distance parameter used for the move will be the parameter
sent previously by a :py:meth:`set_move_relative_parameters()
<artiq.devices.thorlabs_tcube.driver.Tdc.set_move_relative_parameters>`
<Tdc.set_move_relative_parameters>`
command.
"""
await self.send_request(MGMSG.MOT_MOVE_RELATIVE,
[MGMSG.MOT_MOVE_COMPLETED, MGMSG.MOT_MOVE_STOPPED], 1)
[MGMSG.MOT_MOVE_COMPLETED,
MGMSG.MOT_MOVE_STOPPED],
1)

async def move_relative(self, relative_distance):
"""Start a relative move
Expand All @@ -1015,19 +1021,21 @@ async def move_relative(self, relative_distance):
"""
payload = st.pack("<Hl", 1, relative_distance)
await self.send_request(MGMSG.MOT_MOVE_RELATIVE,
[MGMSG.MOT_MOVE_COMPLETED, MGMSG.MOT_MOVE_STOPPED],
[MGMSG.MOT_MOVE_COMPLETED,
MGMSG.MOT_MOVE_STOPPED],
data=payload)

async def move_absolute_memory(self):
"""Start an absolute move of distance in the controller's memory.
The absolute move position parameter used for the move will be the
parameter sent previously by a :py:meth:`set_move_absolute_parameters()
<artiq.devices.thorlabs_tcube.driver.Tdc.set_move_absolute_parameters>`
<Tdc.set_move_absolute_parameters>`
command.
"""
await self.send_request(MGMSG.MOT_MOVE_ABSOLUTE,
[MGMSG.MOT_MOVE_COMPLETED, MGMSG.MOT_MOVE_STOPPED],
[MGMSG.MOT_MOVE_COMPLETED,
MGMSG.MOT_MOVE_STOPPED],
param1=1)

async def move_absolute(self, absolute_distance):
Expand All @@ -1039,7 +1047,8 @@ async def move_absolute(self, absolute_distance):
"""
payload = st.pack("<Hl", 1, absolute_distance)
await self.send_request(MGMSG.MOT_MOVE_ABSOLUTE,
[MGMSG.MOT_MOVE_COMPLETED, MGMSG.MOT_MOVE_STOPPED],
[MGMSG.MOT_MOVE_COMPLETED,
MGMSG.MOT_MOVE_STOPPED],
data=payload)

async def move_jog(self, direction):
Expand All @@ -1048,7 +1057,8 @@ async def move_jog(self, direction):
:param direction: The direction to jog. 1 is forward, 2 is backward.
"""
await self.send_request(MGMSG.MOT_MOVE_JOG,
[MGMSG.MOT_MOVE_COMPLETED, MGMSG.MOT_MOVE_STOPPED],
[MGMSG.MOT_MOVE_COMPLETED,
MGMSG.MOT_MOVE_STOPPED],
param1=1, param2=direction)

async def move_velocity(self, direction):
Expand All @@ -1057,15 +1067,15 @@ async def move_velocity(self, direction):
When this method is called, the motor will move continuously in the
specified direction using the velocity parameter set by the
:py:meth:`set_move_relative_parameters()
<artiq.devices.thorlabs_tcube.driver.Tdc.set_move_relative_parameters>`
command until a :py:meth:`move_stop()
<artiq.devices.thorlabs_tcube.driver.Tdc.move_stop>` command (either
<Tdc.set_move_relative_parameters>`
command until a :py:meth:`move_stop()<Tdc.move_stop>` command (either
StopImmediate or StopProfiled) is called, or a limit switch is reached.
:param direction: The direction to jog: 1 to move forward, 2 to move
backward.
"""
await self.send(Message(MGMSG.MOT_MOVE_VELOCITY, param1=1, param2=direction))
await self.send(Message(MGMSG.MOT_MOVE_VELOCITY, param1=1,
param2=direction))

async def move_stop(self, stop_mode):
"""Stop any type of motor move.
Expand All @@ -1080,11 +1090,11 @@ async def move_stop(self, stop_mode):
if await self.is_moving():
await self.send_request(MGMSG.MOT_MOVE_STOP,
[MGMSG.MOT_MOVE_STOPPED,
MGMSG.MOT_MOVE_COMPLETED],
MGMSG.MOT_MOVE_COMPLETED],
1, stop_mode)

async def set_dc_pid_parameters(self, proportional, integral, differential,
integral_limit, filter_control=0x0F):
integral_limit, filter_control=0x0F):
"""Set the position control loop parameters.
:param proportional: The proportional gain, values in range [0; 32767].
Expand All @@ -1108,8 +1118,8 @@ async def get_dc_pid_parameters(self):
:return: A 5 int tuple containing in this order:
proportional gain, integral gain, differential gain, integral limit
and filter control. Cf. :py:meth:`set_dc_pid_parameters()
<artiq.devices.thorlabs_tcube.driver.Tdc.set_dc_pid_parameters>` for
precise description.
<Tdc.set_dc_pid_parameters>`
for precise description.
:rtype: A 5 int tuple.
"""
get_msg = await self.send_request(MGMSG.MOT_REQ_DCPIDPARAMS,
Expand Down Expand Up @@ -1151,10 +1161,10 @@ async def set_button_parameters(self, mode, position1, position2):
:param mode: If set to 1, the buttons are used to jog the motor. Once
set to this mode, the move parameters for the buttons are taken
from the arguments of the :py:meth:`set_jog_parameters()
<artiq.devices.thorlabs_tcube.driver.Tdc.set_jog_parameters>` method.
If set to 2, each button can be programmed with a differente
position value such that the controller will move the motor to that
position when the specific button is pressed.
<Tdc.set_jog_parameters>`
method. If set to 2, each button can be programmed with a
differente position value such that the controller will move the
motor to that position when the specific button is pressed.
:param position1: The position (in encoder counts) to which the motor
will move when the top button is pressed.
:param position2: The position (in encoder counts) to which the motor
Expand All @@ -1169,8 +1179,8 @@ async def get_button_parameters(self):
:return: A 3 int tuple containing in this order: button mode,
position1 and position2. Cf. :py:meth:`set_button_parameters()
<artiq.devices.thorlabs_tcube.driver.Tdc.set_button_parameters>` for
description.
<Tdc.set_button_parameters>`
for description.
:rtype: A 3 int tuple
"""
get_msg = await self.send_request(MGMSG.MOT_REQ_BUTTONPARAMS,
Expand Down
2 changes: 2 additions & 0 deletions artiq/frontend/aqctl_thorlabs_tcube.py
Expand Up @@ -53,6 +53,8 @@ def main():
dev = Tdc(args.device)
elif product == "tpz001":
dev = Tpz(args.device)
loop = asyncio.get_event_loop()
loop.run_until_complete(dev.get_tpz_io_settings())
else:
print("Invalid product string (-P/--product), "
"choose from tdc001 or tpz001")
Expand Down

0 comments on commit 029f9d9

Please sign in to comment.