diff --git a/artiq/devices/thorlabs_tcube/__init__.py b/artiq/devices/thorlabs_tcube/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/artiq/devices/thorlabs_tcube/driver.py b/artiq/devices/thorlabs_tcube/driver.py deleted file mode 100644 index 51ac2643b..000000000 --- a/artiq/devices/thorlabs_tcube/driver.py +++ /dev/null @@ -1,1486 +0,0 @@ -from enum import Enum -import logging -import struct as st -import asyncio - -import asyncserial - - -logger = logging.getLogger(__name__) - - -class MGMSG(Enum): - HW_DISCONNECT = 0x0002 - HW_REQ_INFO = 0x0005 - HW_GET_INFO = 0x0006 - HW_START_UPDATEMSGS = 0x0011 - HW_STOP_UPDATEMSGS = 0x0012 - HUB_REQ_BAYUSED = 0x0065 - HUB_GET_BAYUSED = 0x0066 - HW_RESPONSE = 0x0080 - HW_RICHRESPONSE = 0x0081 - MOD_SET_CHANENABLESTATE = 0x0210 - MOD_REQ_CHANENABLESTATE = 0x0211 - MOD_GET_CHANENABLESTATE = 0x0212 - MOD_IDENTIFY = 0x0223 - MOT_SET_ENCCOUNTER = 0x0409 - MOT_REQ_ENCCOUNTER = 0x040A - MOT_GET_ENCCOUNTER = 0x040B - MOT_SET_POSCOUNTER = 0x0410 - MOT_REQ_POSCOUNTER = 0x0411 - MOT_GET_POSCOUNTER = 0x0412 - MOT_SET_VELPARAMS = 0x0413 - MOT_REQ_VELPARAMS = 0x0414 - MOT_GET_VELPARAMS = 0x0415 - MOT_SET_JOGPARAMS = 0x0416 - MOT_REQ_JOGPARAMS = 0x0417 - MOT_GET_JOGPARAMS = 0x0418 - MOT_SET_LIMSWITCHPARAMS = 0x0423 - MOT_REQ_LIMSWITCHPARAMS = 0x0424 - MOT_GET_LIMSWITCHPARAMS = 0x0425 - MOT_REQ_STATUSBITS = 0x0429 - MOT_GET_STATUSBITS = 0x042A - MOT_SET_GENMOVEPARAMS = 0x043A - MOT_REQ_GENMOVEPARAMS = 0x043B - MOT_GET_GENMOVEPARAMS = 0x043C - MOT_SET_HOMEPARAMS = 0x0440 - MOT_REQ_HOMEPARAMS = 0x0441 - MOT_GET_HOMEPARAMS = 0x0442 - MOT_MOVE_HOME = 0x0443 - MOT_MOVE_HOMED = 0x0444 - MOT_SET_MOVERELPARAMS = 0x0445 - MOT_REQ_MOVERELPARAMS = 0x0446 - MOT_GET_MOVERELPARAMS = 0x0447 - MOT_MOVE_RELATIVE = 0x0448 - MOT_SET_MOVEABSPARAMS = 0x0450 - MOT_REQ_MOVEABSPARAMS = 0x0451 - MOT_GET_MOVEABSPARAMS = 0x0452 - MOT_MOVE_ABSOLUTE = 0x0453 - MOT_MOVE_VELOCITY = 0x0457 - MOT_MOVE_COMPLETED = 0x0464 - MOT_MOVE_STOP = 0x0465 - MOT_MOVE_STOPPED = 0x0466 - MOT_MOVE_JOG = 0x046A - MOT_SUSPEND_ENDOFMOVEMSGS = 0x046B - MOT_RESUME_ENDOFMOVEMSGS = 0x046C - MOT_REQ_DCSTATUSUPDATE = 0x0490 - MOT_GET_DCSTATUSUPDATE = 0x0491 - MOT_ACK_DCSTATUSUPDATE = 0x0492 - MOT_SET_DCPIDPARAMS = 0x04A0 - MOT_REQ_DCPIDPARAMS = 0x04A1 - MOT_GET_DCPIDPARAMS = 0x04A2 - MOT_SET_POTPARAMS = 0x04B0 - MOT_REQ_POTPARAMS = 0x04B1 - MOT_GET_POTPARAMS = 0x04B2 - MOT_SET_AVMODES = 0x04B3 - MOT_REQ_AVMODES = 0x04B4 - MOT_GET_AVMODES = 0x04B5 - MOT_SET_BUTTONPARAMS = 0x04B6 - MOT_REQ_BUTTONPARAMS = 0x04B7 - MOT_GET_BUTTONPARAMS = 0x04B8 - MOT_SET_EEPROMPARAMS = 0x04B9 - PZ_SET_POSCONTROLMODE = 0x0640 - PZ_REQ_POSCONTROLMODE = 0x0641 - PZ_GET_POSCONTROLMODE = 0x0642 - PZ_SET_OUTPUTVOLTS = 0x0643 - PZ_REQ_OUTPUTVOLTS = 0x0644 - PZ_GET_OUTPUTVOLTS = 0x0645 - PZ_SET_OUTPUTPOS = 0x0646 - PZ_REQ_OUTPUTPOS = 0x0647 - PZ_GET_OUTPUTPOS = 0x0648 - PZ_SET_INPUTVOLTSSRC = 0x0652 - PZ_REQ_INPUTVOLTSSRC = 0x0653 - PZ_GET_INPUTVOLTSSRC = 0x0654 - PZ_SET_PICONSTS = 0x0655 - PZ_REQ_PICONSTS = 0x0656 - PZ_GET_PICONSTS = 0x0657 - PZ_GET_PZSTATUSUPDATE = 0x0661 - PZ_SET_OUTPUTLUT = 0x0700 - PZ_REQ_OUTPUTLUT = 0x0701 - PZ_GET_OUTPUTLUT = 0x0702 - PZ_SET_OUTPUTLUTPARAMS = 0x0703 - PZ_REQ_OUTPUTLUTPARAMS = 0x0704 - PZ_GET_OUTPUTLUTPARAMS = 0x0705 - PZ_START_LUTOUTPUT = 0x0706 - PZ_STOP_LUTOUTPUT = 0x0707 - PZ_SET_EEPROMPARAMS = 0x07D0 - PZ_SET_TPZ_DISPSETTINGS = 0x07D1 - PZ_REQ_TPZ_DISPSETTINGS = 0x07D2 - PZ_GET_TPZ_DISPSETTINGS = 0x07D3 - PZ_SET_TPZ_IOSETTINGS = 0x07D4 - PZ_REQ_TPZ_IOSETTINGS = 0x07D5 - PZ_GET_TPZ_IOSETTINGS = 0x07D6 - - -class Direction: - def __init__(self, direction): - if direction not in (1, 2): - raise ValueError("Direction must be either 1 or 2") - self.direction = direction - - def __str__(self): - if self.direction == 1: - return "forward" - else: - return "backward" - - -class MsgError(Exception): - pass - - -class Message: - def __init__(self, id, param1=0, param2=0, dest=0x50, src=0x01, - data=None): - if data is not None: - dest |= 0x80 - self.id = id - self.param1 = param1 - self.param2 = param2 - self.dest = dest - self.src = src - self.data = data - - def __str__(self): - return ("".format( - self.id, self.param1, self.param2, - self.dest, self.src)) - - @staticmethod - def unpack(data): - id, param1, param2, dest, src = st.unpack("` - or :py:meth:`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 = None - - async def handle_message(self, msg): - msg_id = msg.id - data = msg.data - - if msg_id == MGMSG.HW_DISCONNECT: - raise MsgError("Error: Please disconnect the TPZ001") - elif msg_id == MGMSG.HW_RESPONSE: - raise MsgError("Hardware error, please disconnect " - "and reconnect the TPZ001") - elif msg_id == MGMSG.HW_RICHRESPONSE: - (code, ) = st.unpack("` - 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;{}]" - .format(self.voltage_limit)) - volt = int(voltage*32767/self.voltage_limit) - payload = st.pack("` method. - - 0x01 External Signal: Unit sums the differential signal on the rear - panel EXT IN(+) and EXT IN(-) connectors with the voltage set - using the set_outputvolts method. - - 0x02 Potentiometer: The HV amp output is controlled by a - potentiometer input (either on the control panel, or connected - to the rear panel User I/O D-type connector) summed with the - voltage set using the set_outputvolts method. - - The values can be bitwise or'ed to sum the software source with - either or both of the other source options. - """ - payload = st.pack("` - method docstring for meaning of bits. - :rtype: int - """ - get_msg = await self.send_request(MGMSG.PZ_REQ_INPUTVOLTSSRC, - [MGMSG.PZ_GET_INPUTVOLTSSRC], 1) - return st.unpack("` - 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 - bandwidth of 7 KHz, e.g. 500 LUT values will take approximately 71 ms - to be clocked out. - - :param lut_index: The position in the array of the value to be set (0 - 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` - method. - """ - volt = round(output*32767/self.voltage_limit) - payload = st.pack("` for - the meaning of those parameters. - :rtype: a 2 elements tuple (int, int) - """ - get_msg = await self.send_request(MGMSG.PZ_REQ_TPZ_IOSETTINGS, - [MGMSG.PZ_GET_TPZ_IOSETTINGS], 1) - voltage_limit, hub_analog_input = st.unpack("` for a - description of each tuple element meaning. - :rtype: An 8 int tuple - """ - get_msg = await self.send_request(MGMSG.MOT_REQ_POTPARAMS, - [MGMSG.MOT_GET_POTPARAMS], 1) - return st.unpack("` - method. - :rtype: A 2 int tuple. - """ - get_msg = await self.send_request(MGMSG.MOT_REQ_LIMSWITCHPARAMS, - [MGMSG.MOT_GET_LIMSWITCHPARAMS], 1) - return st.unpack("` - command. - """ - await self.send_request(MGMSG.MOT_MOVE_RELATIVE, - [MGMSG.MOT_MOVE_COMPLETED, - MGMSG.MOT_MOVE_STOPPED], - 1) - - async def move_relative(self, relative_distance): - """Start a relative move - - :param relative_distance: The distance to move in position encoder - counts. - """ - payload = st.pack("` - command. - """ - await self.send_request(MGMSG.MOT_MOVE_ABSOLUTE, - [MGMSG.MOT_MOVE_COMPLETED, - MGMSG.MOT_MOVE_STOPPED], - param1=1) - - async def move_absolute(self, absolute_distance): - """Start an absolute move. - - :param absolute_distance: The distance to move. This is a signed - integer that specifies the absolute distance in position encoder - counts. - """ - payload = st.pack("` - command until a :py:meth:`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)) - - async def move_stop(self, stop_mode): - """Stop any type of motor move. - - Stops any of those motor move: relative, absolute, homing or move at - velocity. - - :param stop_mode: The stop mode defines either an immediate (abrupt) - or profiled stop. Set this byte to 1 to stop immediately, or to 2 - to stop in a controlled (profiled) manner. - """ - if await self.is_moving(): - await self.send_request(MGMSG.MOT_MOVE_STOP, - [MGMSG.MOT_MOVE_STOPPED, - MGMSG.MOT_MOVE_COMPLETED], - 1, stop_mode) - - async def set_dc_pid_parameters(self, proportional, integral, differential, - integral_limit, filter_control=0x0F): - """Set the position control loop parameters. - - :param proportional: The proportional gain, values in range [0; 32767]. - :param integral: The integral gain, values in range [0; 32767]. - :param differential: The differential gain, values in range [0; 32767]. - :param integral_limit: The integral limit parameter is used to cap the - value of the integrator to prevent runaway of the integral sum at - the output. Values are in range [0; 32767]. If set to 0, then - integration term in the PID loop is ignored. - :param filter_control: Identifies which of the above are applied by - setting the corresponding bit to 1. By default, all parameters are - applied, and this parameter is set to 0x0F (1111). - """ - payload = st.pack("` - for precise description. - :rtype: A 5 int tuple. - """ - get_msg = await self.send_request(MGMSG.MOT_REQ_DCPIDPARAMS, - [MGMSG.MOT_GET_DCPIDPARAMS], 1) - return st.unpack("` - 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 - will move when the bottom button is pressed. - """ - payload = st.pack("` - for description. - :rtype: A 3 int tuple - """ - get_msg = await self.send_request(MGMSG.MOT_REQ_BUTTONPARAMS, - [MGMSG.MOT_GET_BUTTONPARAMS], 1) - return st.unpack(" 512: - raise ValueError("LUT index should be in range [0;512] and not {}" - .format(lut_index)) - self.lut[lut_index] = output - - def get_output_lut(self): - return 0, 0 # FIXME: the API description here doesn't make any sense - - def set_output_lut_parameters(self, mode, cycle_length, num_cycles, - delay_time, precycle_rest, postcycle_rest): - self.mode = mode - self.cycle_length = cycle_length - self.num_cycles = num_cycles - self.delay_time = delay_time - self.precycle_rest = precycle_rest - self.postcycle_rest = postcycle_rest - - def get_output_lut_parameters(self): - return (self.mode, self.cycle_length, self.num_cycles, - self.delay_time, self.precycle_rest, self.postcycle_rest) - - def start_lut_output(self): - pass - - def stop_lut_output(self): - pass - - def set_eeprom_parameters(self, msg_id): - pass - - def set_tpz_display_settings(self, intensity): - self.intensity = intensity - - def get_tpz_display_settings(self): - return self.intensity - - def set_tpz_io_settings(self, voltage_limit, hub_analog_input): - if voltage_limit not in [75, 100, 150]: - raise ValueError("voltage_limit must be 75 V, 100 V or 150 V") - self.voltage_limit = voltage_limit - self.hub_analog_input = hub_analog_input - - def get_tpz_io_settings(self): - return self.voltage_limit, self.hub_analog_input - - -class TdcSim: - def close(self): - pass - - def module_identify(self): - pass - - def set_pot_parameters(self, zero_wnd, vel1, wnd1, vel2, wnd2, vel3, - wnd3, vel4): - self.zero_wnd = zero_wnd - self.vel1 = vel1 - self.wnd1 = wnd1 - self.vel2 = vel2 - self.wnd2 = wnd2 - self.vel3 = vel3 - self.wnd3 = wnd3 - self.vel4 = vel4 - - def get_pot_parameters(self): - return (self.zero_wnd, self.vel1, self.wnd1, self.vel2, self.wnd2, - self.vel3, self.wnd3, self.vel4) - - def hub_get_bay_used(self): - return False - - def set_position_counter(self, position): - self.position = position - - def get_position_counter(self): - return self.position - - def set_encoder_counter(self, encoder_count): - self.encoder_count = encoder_count - - def get_encoder_counter(self): - return self.encoder_count - - def set_velocity_parameters(self, acceleration, max_velocity): - self.acceleration = acceleration - self.max_velocity = max_velocity - - def get_velocity_parameters(self): - return self.acceleration, self.max_velocity - - def set_jog_parameters(self, mode, step_size, acceleration, - max_velocity, stop_mode): - self.jog_mode = mode - self.step_size = step_size - self.acceleration = acceleration - self.max_velocity = max_velocity - self.stop_mode = stop_mode - - def get_jog_parameters(self): - return (self.jog_mode, self.step_size, self.acceleration, - self.max_velocity, self.stop_mode) - - def set_gen_move_parameters(self, backlash_distance): - self.backlash_distance = backlash_distance - - def get_gen_move_parameters(self): - return self.backlash_distance - - def set_move_relative_parameters(self, relative_distance): - self.relative_distance = relative_distance - - def get_move_relative_parameters(self): - return self.relative_distance - - def set_move_absolute_parameters(self, absolute_position): - self.absolute_position = absolute_position - - def get_move_absolute_parameters(self): - return self.absolute_position - - def set_home_parameters(self, home_velocity): - self.home_velocity = home_velocity - - def get_home_parameters(self): - return self.home_velocity - - def move_home(self): - pass - - def set_limit_switch_parameters(self, cw_hw_limit, ccw_hw_limit): - self.cw_hw_limit = cw_hw_limit - self.ccw_hw_limit = ccw_hw_limit - - def get_limit_switch_parameters(self): - return self.cw_hw_limit, self.ccw_hw_limit - - def move_relative_memory(self): - pass - - def move_relative(self, relative_distance): - pass - - def move_absolute_memory(self): - pass - - def move_absolute(self, absolute_distance): - pass - - def move_jog(self, direction): - pass - - def move_velocity(self, direction): - pass - - def move_stop(self, stop_mode): - pass - - def set_dc_pid_parameters(self, proportional, integral, differential, - integral_limit, filter_control=0x0F): - self.proportional = proportional - self.integral = integral - self.differential = differential - self.integral_limit = integral_limit - self.filter_control = filter_control - - def get_dc_pid_parameters(self): - return (self.proportional, self.integral, self.differential, - self.integral_limit, self.filter_control) - - def set_av_modes(self, mode_bits): - self.mode_bits = mode_bits - - def get_av_modes(self): - return self.mode_bits - - def set_button_parameters(self, mode, position1, position2): - self.mode = mode - self.position1 = position1 - self.position2 = position2 - - def get_button_parameters(self): - return self.mode, self.position1, self.position2 - - def set_eeprom_parameters(self, msg_id): - pass - - def get_dc_status_update(self): - return 0, 0, 0x80000400 # FIXME: not implemented yet for simulation - - def get_status_bits(self): - return 0x80000400 # FIXME: not implemented yet for simulation - - def suspend_end_of_move_messages(self): - pass - - def resume_end_of_move_messages(self): - pass diff --git a/artiq/frontend/aqctl_thorlabs_tcube.py b/artiq/frontend/aqctl_thorlabs_tcube.py deleted file mode 100755 index dea1a0d65..000000000 --- a/artiq/frontend/aqctl_thorlabs_tcube.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env python3 - -import argparse -import sys -import os -import asyncio - -from artiq.devices.thorlabs_tcube.driver import Tdc, Tpz, TdcSim, TpzSim -from artiq.protocols.pc_rpc import simple_server_loop -from artiq.tools import * - - -def get_argparser(): - parser = argparse.ArgumentParser() - parser.add_argument("-P", "--product", required=True, - help="type of the Thorlabs T-Cube device to control: " - "tdc001/tpz001") - parser.add_argument("-d", "--device", default=None, - help="serial device. See documentation for how to " - "specify a USB Serial Number.") - parser.add_argument("--simulation", action="store_true", - help="Put the driver in simulation mode, even if " - "--device is used.") - simple_network_args(parser, 3255) - add_common_args(parser) - return parser - - -def main(): - args = get_argparser().parse_args() - init_logger(args) - - if os.name == "nt": - asyncio.set_event_loop(asyncio.ProactorEventLoop()) - - if not args.simulation and args.device is None: - print("You need to specify either --simulation or -d/--device " - "argument. Use --help for more information.") - sys.exit(1) - - product = args.product.lower() - if args.simulation: - if product == "tdc001": - dev = TdcSim() - elif product == "tpz001": - dev = TpzSim() - else: - print("Invalid product string (-P/--product), " - "choose from tdc001 or tpz001") - sys.exit(1) - else: - if product == "tdc001": - 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") - sys.exit(1) - - try: - simple_server_loop({product: dev}, - bind_address_from_args(args), args.port) - finally: - dev.close() - -if __name__ == "__main__": - main() diff --git a/artiq/test/test_frontends.py b/artiq/test/test_frontends.py index 10db9eea0..c80228294 100644 --- a/artiq/test/test_frontends.py +++ b/artiq/test/test_frontends.py @@ -10,7 +10,7 @@ class TestFrontends(unittest.TestCase): # Skip tests for GUI programs on headless CI environments. commands = { "aqctl": [ - "corelog", "thorlabs_tcube" + "corelog" ], "artiq": [ "client", "compile", "coreanalyzer", "coremgmt", "ctlmgr", diff --git a/artiq/test/test_thorlabs_tcube.py b/artiq/test/test_thorlabs_tcube.py deleted file mode 100644 index b1adf6208..000000000 --- a/artiq/test/test_thorlabs_tcube.py +++ /dev/null @@ -1,183 +0,0 @@ -import time -import sys -import unittest - -from artiq.language.units import V -from artiq.test.hardware_testbench import ControllerCase, GenericControllerCase - - -class GenericTdcTest: - def test_pot_parameters(self): - test_vector = 1, 2, 3, 4, 5, 6, 7, 8 - self.cont.set_pot_parameters(*test_vector) - self.assertEqual(test_vector, self.cont.get_pot_parameters()) - - def test_position_counter(self): - test_vector = 42 - self.cont.set_position_counter(test_vector) - self.assertEqual(test_vector, self.cont.get_position_counter()) - - def test_encoder_counter(self): - test_vector = 43 - self.cont.set_encoder_counter(test_vector) - self.assertEqual(test_vector, self.cont.get_encoder_counter()) - - def test_velocity_parameters(self): - test_vector = 44, 45 - self.cont.set_velocity_parameters(*test_vector) - self.assertEqual(test_vector, self.cont.get_velocity_parameters()) - - def test_jog_parameters(self): - test_vector = 46, 47, 48, 49, 50 - self.cont.set_jog_parameters(*test_vector) - self.assertEqual(test_vector, self.cont.get_jog_parameters()) - - def test_gen_move_parameters(self): - test_vector = 51 - self.cont.set_gen_move_parameters(test_vector) - self.assertEqual(test_vector, self.cont.get_gen_move_parameters()) - - def test_moverelparams(self): - test_vector = 52 - self.cont.set_move_relative_parameters(test_vector) - self.assertEqual(test_vector, self.cont.get_move_relative_parameters()) - - def test_move_absolute_parameters(self): - test_vector = 53 - self.cont.set_move_absolute_parameters(test_vector) - self.assertEqual(test_vector, self.cont.get_move_absolute_parameters()) - - def test_home_parameters(self): - test_vector = 54 - self.cont.set_home_parameters(test_vector) - self.assertEqual(test_vector, self.cont.get_home_parameters()) - - def test_limit_switch_parameters(self): - test_vector = 2, 1 - self.cont.set_limit_switch_parameters(*test_vector) - self.assertEqual(test_vector, self.cont.get_limit_switch_parameters()) - - def test_dc_pid_parameters(self): - test_vector = 57, 58, 59, 60, 0x0f - self.cont.set_dc_pid_parameters(*test_vector) - self.assertEqual(test_vector, self.cont.get_dc_pid_parameters()) - - def test_av_modes(self): - for i in range(1): - for j in range(1): - for k in range(1): - with self.subTest(i=i): - with self.subTest(j=j): - with self.subTest(k=k): - test_vector = i << 2 + j << 1 + k - self.cont.set_av_modes(test_vector) - self.assertEqual(test_vector, - self.cont.get_av_modes()) - - def test_button_parameters(self): - test_vector = 2, 3, 4 - self.cont.set_button_parameters(*test_vector) - self.assertEqual(test_vector, self.cont.get_button_parameters()) - - -class GenericTpzTest: - def test_position_control_mode(self): - test_vector = 1 - self.cont.set_position_control_mode(test_vector) - self.assertEqual(test_vector, self.cont.get_position_control_mode()) - - def test_ouput_volts(self): - for voltage in 5*V, 10*V, 15*V, \ - round(self.cont.get_tpz_io_settings()[0])*V: - with self.subTest(voltage=voltage): - test_vector = voltage - self.cont.set_output_volts(test_vector) - time.sleep(1) # Wait for the output voltage to converge - self.assertAlmostEqual(test_vector, - self.cont.get_output_volts(), - delta=0.03*V) - - def test_output_position(self): - test_vector = 31000 - self.cont.set_output_position(test_vector) - self.assertEqual(test_vector, self.cont.get_output_position()) - - def test_input_volts_source(self): - for i in range(3): - test_vector = i - self.cont.set_input_volts_source(i) - with self.subTest(i=i): - self.assertEqual(test_vector, - self.cont.get_input_volts_source()) - - def test_pi_constants(self): - test_vector = 42, 43 - self.cont.set_pi_constants(*test_vector) - self.assertEqual(test_vector, self.cont.get_pi_constants()) - - def test_tpz_display_settings(self): - for intensity in 0, 10, 30, 50, 100, 150, 254: - with self.subTest(intensity=intensity): - test_vector = intensity - self.cont.set_tpz_display_settings(test_vector) - self.assertEqual(test_vector, - self.cont.get_tpz_display_settings()) - - def test_tpz_io_settings(self): - for v in 75*V, 100*V, 150*V: - with self.subTest(v=v): - test_vector = v, 1 - self.cont.set_tpz_io_settings(*test_vector) - self.assertEqual(test_vector, self.cont.get_tpz_io_settings()) - - -class TestTdc(ControllerCase, GenericTdcTest): - def setUp(self): - ControllerCase.setUp(self) - self.start_controller("tdc") - self.cont = self.device_mgr.get("tdc") - - -class TestTdcSim(GenericControllerCase, GenericTdcTest): - def get_device_db(self): - return { - "tdc": { - "type": "controller", - "host": "::1", - "port": 3255, - "command": (sys.executable.replace("\\", "\\\\") - + " -m artiq.frontend.aqctl_thorlabs_tcube " - + "-p {port} -P tdc001 --simulation") - } - } - - def setUp(self): - GenericControllerCase.setUp(self) - self.start_controller("tdc") - self.cont = self.device_mgr.get("tdc") - - -class TestTpz(ControllerCase, GenericTpzTest): - def setUp(self): - ControllerCase.setUp(self) - self.start_controller("tpz") - self.cont = self.device_mgr.get("tpz") - - -class TestTpzSim(GenericControllerCase, GenericTpzTest): - def get_device_db(self): - return { - "tpz": { - "type": "controller", - "host": "::1", - "port": 3255, - "command": (sys.executable.replace("\\", "\\\\") - + " -m artiq.frontend.aqctl_thorlabs_tcube " - + "-p {port} -P tpz001 --simulation") - } - } - - def setUp(self): - GenericControllerCase.setUp(self) - self.start_controller("tpz") - self.cont = self.device_mgr.get("tpz") diff --git a/doc/manual/faq.rst b/doc/manual/faq.rst index a550392a8..817b64130 100644 --- a/doc/manual/faq.rst +++ b/doc/manual/faq.rst @@ -88,7 +88,13 @@ The preferred way to specify a serial device is to make use of the ``hwgrep://`` URL: it allows to select the serial device by its USB vendor ID, product ID and/or serial number. Those never change, unlike the device file name. -See the :ref:`TDC001 documentation ` for an example of ``hwgrep://`` usage. +For instance, if you want to specify the Vendor/Product ID and the USB Serial Number, you can do: + +``-d "hwgrep://: SNR="``. +for example: + +``-d "hwgrep://0403:faf0 SNR=83852734"`` + run unit tests? --------------- diff --git a/doc/manual/ndsp_reference.rst b/doc/manual/ndsp_reference.rst index 7a266394e..2a8f2b26e 100644 --- a/doc/manual/ndsp_reference.rst +++ b/doc/manual/ndsp_reference.rst @@ -7,90 +7,3 @@ Core device logging controller .. argparse:: :ref: artiq.frontend.aqctl_corelog.get_argparser :prog: aqctl_corelog - - -Thorlabs T-Cube ---------------- - -.. note:: - When power is applied before the USB connection, some devices will enter a state where they fail to report the completion of commands. When using the ARTIQ controller, this cause certain function calls to never return and freeze the controller. To prevent this, connect USB first and then power up the device. When a device has entered the problematic state, power-cycling it while keeping the USB connection active also resolves the problem. - -TDC001 Driver -+++++++++++++ - -.. autoclass:: artiq.devices.thorlabs_tcube.driver.Tdc - :members: - -TPZ001 Driver -+++++++++++++ - -.. autoclass:: artiq.devices.thorlabs_tcube.driver.Tpz - :members: - -Controller -++++++++++ - -.. argparse:: - :ref: artiq.frontend.aqctl_thorlabs_tcube.get_argparser - :prog: aqctl_thorlabs - -.. _tdc001-controller-usage-example: - -TDC001 controller usage example -+++++++++++++++++++++++++++++++ - -First, run the TDC001 controller:: - - $ aqctl_thorlabs_tcube -P TDC001 -d /dev/ttyUSBx - -.. note:: - On Windows the serial port (the ``-d`` argument) will be of the form ``COMx``. - -.. note:: - Anything compatible with `serial_for_url `_ - can be given as a device in ``-d`` argument. - - For instance, if you want to specify the Vendor/Product ID and the USB Serial Number, you can do: - - ``-d "hwgrep://: SNR="``. - for instance: - - ``-d "hwgrep://0403:faf0 SNR=83852734"`` - - The hwgrep URL works on both Linux and Windows. - -Then, send commands to it via the ``artiq_rpctool`` utility:: - - $ artiq_rpctool ::1 3255 list-targets - Target(s): tdc001 - $ artiq_rpctool ::1 3255 call move_relative 10000 # will move forward - $ artiq_rpctool ::1 3255 call move_relative -10000 # will move backward - $ artiq_rpctool ::1 3255 call move_absolute 20000 # absolute move to 20000 - $ artiq_rpctool ::1 3255 call move_home # will go back to home position - $ artiq_rpctool ::1 3255 call close # close the device - -TPZ001 controller usage example -+++++++++++++++++++++++++++++++ - -First, run the TPZ001 controller:: - - $ aqctl_thorlabs_tcube -P TPZ001 -d /dev/ttyUSBx - -.. note:: - On Windows the serial port (the ``-d`` argument) will be of the form ``COMx``. - -.. note:: - See the :ref:`TDC001 documentation ` for - how to specify the USB Serial Number of the device instead of the - /dev/ttyUSBx (or the COMx name). - -Then, send commands to it via the ``artiq_rpctool`` utility:: - - $ artiq_rpctool ::1 3255 list-targets - Target(s): tpz001 - $ artiq_rpctool ::1 3255 call set_output_volts 15 # set output voltage to 15 V - $ artiq_rpctool ::1 3255 call get_output_volts # read back output voltage - 15 - $ artiq_rpctool ::1 3255 call set_tpz_io_settings 150 1 # set maximum output voltage to 150 V - $ artiq_rpctool ::1 3255 call set_output_volts 150 # set output voltage to 150 V - $ artiq_rpctool ::1 3255 call close # close the device diff --git a/setup.py b/setup.py index 82be9483b..f57925539 100755 --- a/setup.py +++ b/setup.py @@ -37,7 +37,6 @@ console_scripts = [ "artiq_flash = artiq.frontend.artiq_flash:main", "aqctl_corelog = artiq.frontend.aqctl_corelog:main", - "aqctl_thorlabs_tcube = artiq.frontend.aqctl_thorlabs_tcube:main", ] gui_scripts = [