-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #7 from UW-Quantum-Defect-Lab/003-adding-qdlmove
#3 adding qdlmove
- Loading branch information
Showing
8 changed files
with
1,162 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
src/qt3utils/applications/qdlmove/application_controller.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import logging | ||
import time | ||
|
||
import numpy as np | ||
|
||
logger = logging.getLogger(__name__) | ||
logging.basicConfig(level=logging.INFO) | ||
|
||
|
||
class MovementController: | ||
''' | ||
This is a basic application controller backend for the `qdlmove` application. | ||
In its current implementation, it manages calls to move or step the various | ||
hardware by reference to their name as stored in the `self.positioners` dict. | ||
In the future, if more features are desired of the `qdlmove` application, | ||
for example recording/saving of positions, plotting points, etc. the developer | ||
should add these features into this class and update the GUI/main application | ||
to trigger methods or store data in this class. | ||
''' | ||
def __init__(self, positioners: dict = {}): | ||
self.positioners = positioners # dictionary of the controller instantiations | ||
|
||
|
||
def move_axis(self, axis_controller_name: str, position: float): | ||
# Move the axis specified by the axis_controller_name | ||
self.positioners[axis_controller_name].go_to_position(position) | ||
|
||
def step_axis(self, axis_controller_name: str, dx: float): | ||
# Step the axis specified by the axis_controller_name | ||
self.positioners[axis_controller_name].step_position(dx) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
import tkinter as tk | ||
|
||
class PositionControllerApplicationView(): | ||
''' | ||
Main Application GUI which houses the individual controller GUIs. | ||
''' | ||
|
||
def __init__(self, main_window: tk.Tk): | ||
# Get the frame to pack the GUI | ||
frame = tk.Frame(main_window) | ||
frame.pack(side=tk.TOP, fill=tk.BOTH, expand=True, padx=16, pady=16) | ||
|
||
# =============================================================================== | ||
# Edit here to add more controllers | ||
# =============================================================================== | ||
# 2. ADD APPLICATION CONTROLLER GUIs HERE | ||
# Edit here to add more movement control | ||
# This creates a GUI element for the specified axes with the provided names. | ||
# You must make a controller of the right type and with correct associations | ||
# in order for the GUI to work properly. | ||
self.micros_view = TwoAxisApplicationView(root_frame=frame, | ||
title='Micros', | ||
axis_1_label='X axis', | ||
axis_2_label='Y axis') | ||
self.piezos_view = ThreeAxisApplicationView(root_frame=frame, | ||
title='Piezos', | ||
axis_1_label='X axis', | ||
axis_2_label='Y axis', | ||
axis_3_label='Z axis') | ||
|
||
|
||
# =============================================================================== | ||
# No edits below here! | ||
# =============================================================================== | ||
|
||
|
||
class TwoAxisApplicationView(): | ||
''' | ||
Application control for two-axis movement | ||
''' | ||
def __init__(self, root_frame: tk.Frame, title: str, axis_1_label: str, axis_2_label: str): | ||
|
||
# Frame to house this subwindow | ||
self.base_frame = tk.Frame(root_frame) | ||
self.base_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=True, padx=4, pady=8) | ||
|
||
|
||
row = 0 | ||
tk.Label(self.base_frame, text=title, font='Helvetica 14').grid(row=row, column=0, pady=[0,5], columnspan=5) | ||
|
||
row += 1 | ||
# Enable/disable the stepper | ||
self.stepping_active = tk.IntVar() | ||
self.stepping_laser_toggle = tk.Checkbutton ( self.base_frame, var=self.stepping_active, text='Enable stepping') | ||
self.stepping_laser_toggle.grid(row=row, column=0, pady=[0,0], columnspan=2) | ||
tk.Label(self.base_frame, text='Set value', font='Helvetica 10', width=10).grid(row=row, column=2, pady=[0,0], columnspan=1) | ||
tk.Label(self.base_frame, text='Step', font='Helvetica 10', width=10).grid(row=row, column=3, pady=[0,0], columnspan=1) | ||
tk.Label(self.base_frame, text='Current', font='Helvetica 10', width=10).grid(row=row, column=4, pady=[0,0], columnspan=1) | ||
|
||
row += 1 | ||
tk.Label(self.base_frame, text=axis_1_label, font='Helvetica 10', width=10).grid(row=row, column=0, pady=[0,0], columnspan=1) | ||
self.axis_1_set_button = tk.Button(self.base_frame, text='Set position', width=10) | ||
self.axis_1_set_button.grid(row=row, column=1, columnspan=1, padx=0) | ||
self.axis_1_set_entry = tk.Entry(self.base_frame, width=10) | ||
self.axis_1_set_entry.insert(0, 0) | ||
self.axis_1_set_entry.grid(row=row, column=2) | ||
self.axis_1_step_entry = tk.Entry(self.base_frame, width=10) | ||
self.axis_1_step_entry.insert(0, 0) | ||
self.axis_1_step_entry.grid(row=row, column=3) | ||
self.axis_1_readout_entry = tk.Entry(self.base_frame, width=10) | ||
self.axis_1_readout_entry.insert(0, 0) | ||
self.axis_1_readout_entry.config(state='readonly') | ||
self.axis_1_readout_entry.grid(row=row, column=4) | ||
|
||
row += 1 | ||
tk.Label(self.base_frame, text=axis_2_label, font='Helvetica 10', width=10).grid(row=row, column=0, pady=[0,0], columnspan=1) | ||
self.axis_2_set_button = tk.Button(self.base_frame, text='Set position', width=10) | ||
self.axis_2_set_button.grid(row=row, column=1, columnspan=1, padx=0) | ||
self.axis_2_set_entry = tk.Entry(self.base_frame, width=10) | ||
self.axis_2_set_entry.insert(0, 0) | ||
self.axis_2_set_entry.grid(row=row, column=2) | ||
self.axis_2_step_entry = tk.Entry(self.base_frame, width=10) | ||
self.axis_2_step_entry.insert(0, 0) | ||
self.axis_2_step_entry.grid(row=row, column=3) | ||
self.axis_2_readout_entry = tk.Entry(self.base_frame, width=10) | ||
self.axis_2_readout_entry.insert(0, 0) | ||
self.axis_2_readout_entry.config(state='readonly') | ||
self.axis_2_readout_entry.grid(row=row, column=4) | ||
|
||
|
||
class ThreeAxisApplicationView(): | ||
''' | ||
Application control for two-axis movement | ||
''' | ||
def __init__(self, root_frame: tk.Frame, title: str, axis_1_label: str, axis_2_label: str, axis_3_label: str): | ||
|
||
# Frame to house this subwindow | ||
self.base_frame = tk.Frame(root_frame) | ||
self.base_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=True, padx=4, pady=8) | ||
|
||
|
||
row = 0 | ||
tk.Label(self.base_frame, text=title, font='Helvetica 14').grid(row=row, column=0, pady=[0,5], columnspan=5) | ||
|
||
row += 1 | ||
# Enable/disable the stepper | ||
self.stepping_active = tk.IntVar() | ||
self.stepping_laser_toggle = tk.Checkbutton ( self.base_frame, var=self.stepping_active, text='Enable stepping') | ||
self.stepping_laser_toggle.grid(row=row, column=0, pady=[0,0], columnspan=2) | ||
tk.Label(self.base_frame, text='Set value', font='Helvetica 10', width=10).grid(row=row, column=2, pady=[0,0], columnspan=1) | ||
tk.Label(self.base_frame, text='Step', font='Helvetica 10', width=10).grid(row=row, column=3, pady=[0,0], columnspan=1) | ||
tk.Label(self.base_frame, text='Current', font='Helvetica 10', width=10).grid(row=row, column=4, pady=[0,0], columnspan=1) | ||
|
||
row += 1 | ||
tk.Label(self.base_frame, text=axis_1_label, font='Helvetica 10', width=10).grid(row=row, column=0, pady=[0,0], columnspan=1) | ||
self.axis_1_set_button = tk.Button(self.base_frame, text='Set position', width=10) | ||
self.axis_1_set_button.grid(row=row, column=1, columnspan=1, padx=0) | ||
self.axis_1_set_entry = tk.Entry(self.base_frame, width=10) | ||
self.axis_1_set_entry.insert(0, 0) | ||
self.axis_1_set_entry.grid(row=row, column=2) | ||
self.axis_1_step_entry = tk.Entry(self.base_frame, width=10) | ||
self.axis_1_step_entry.insert(0, 0) | ||
self.axis_1_step_entry.grid(row=row, column=3) | ||
self.axis_1_readout_entry = tk.Entry(self.base_frame, width=10) | ||
self.axis_1_readout_entry.insert(0, 0) | ||
self.axis_1_readout_entry.config(state='readonly') | ||
self.axis_1_readout_entry.grid(row=row, column=4) | ||
|
||
row += 1 | ||
tk.Label(self.base_frame, text=axis_2_label, font='Helvetica 10', width=10).grid(row=row, column=0, pady=[0,0], columnspan=1) | ||
self.axis_2_set_button = tk.Button(self.base_frame, text='Set position', width=10) | ||
self.axis_2_set_button.grid(row=row, column=1, columnspan=1, padx=0) | ||
self.axis_2_set_entry = tk.Entry(self.base_frame, width=10) | ||
self.axis_2_set_entry.insert(0, 0) | ||
self.axis_2_set_entry.grid(row=row, column=2) | ||
self.axis_2_step_entry = tk.Entry(self.base_frame, width=10) | ||
self.axis_2_step_entry.insert(0, 0) | ||
self.axis_2_step_entry.grid(row=row, column=3) | ||
self.axis_2_readout_entry = tk.Entry(self.base_frame, width=10) | ||
self.axis_2_readout_entry.insert(0, 0) | ||
self.axis_2_readout_entry.config(state='readonly') | ||
self.axis_2_readout_entry.grid(row=row, column=4) | ||
|
||
row += 1 | ||
tk.Label(self.base_frame, text=axis_3_label, font='Helvetica 10', width=10).grid(row=row, column=0, pady=[0,0], columnspan=1) | ||
self.axis_3_set_button = tk.Button(self.base_frame, text='Set position', width=10) | ||
self.axis_3_set_button.grid(row=row, column=1, columnspan=1, padx=0) | ||
self.axis_3_set_entry = tk.Entry(self.base_frame, width=10) | ||
self.axis_3_set_entry.insert(0, 0) | ||
self.axis_3_set_entry.grid(row=row, column=2) | ||
self.axis_3_step_entry = tk.Entry(self.base_frame, width=10) | ||
self.axis_3_step_entry.insert(0, 0) | ||
self.axis_3_step_entry.grid(row=row, column=3) | ||
self.axis_3_readout_entry = tk.Entry(self.base_frame, width=10) | ||
self.axis_3_readout_entry.insert(0, 0) | ||
self.axis_3_readout_entry.config(state='readonly') | ||
self.axis_3_readout_entry.grid(row=row, column=4) |
Empty file.
67 changes: 67 additions & 0 deletions
67
src/qt3utils/applications/qdlmove/config_files/qdlmove_micros_and_piezos.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
QDLMOVE: | ||
Positioners: # Add positioner configs defiend below; edit the GUI/application accordingly. | ||
- MicroX | ||
- MicroY | ||
- PiezoX | ||
- PiezoY | ||
- PiezoZ | ||
|
||
MicroX: | ||
import_path : qt3utils.applications.qdlmove.newportmicrometer | ||
class_name : NewportMicrometer | ||
configure : | ||
port: COM4 # Serial port name | ||
min: 0.0 # Minimum position in microns | ||
max: 25000.0 # Maximum position in microns | ||
timeout: 10 # Time in seconds before timing out on movement | ||
|
||
MicroY: | ||
import_path : qt3utils.applications.qdlmove.newportmicrometer | ||
class_name : NewportMicrometer | ||
configure : | ||
port: COM5 # Serial port name | ||
min: 0.0 # Minimum position in microns | ||
max: 25000.0 # Maximum position in microns | ||
timeout: 10 # Time in seconds before timing out on movement | ||
|
||
PiezoX: | ||
import_path : qt3utils.applications.qdlmove.nidaqpiezo | ||
class_name : NiDaqPiezoController | ||
configure: | ||
device_name: Dev1 | ||
write_channel: ao0 | ||
read_channel: | ||
move_settle_time: 0.0 # Time in seconds to wait after movement | ||
scale_microns_per_volt: 8 # Number of microns moved per volt | ||
zero_microns_volt_offset: 5 # Value of voltage at position 0 microns | ||
min_position: -40.0 # Minimum position in microns | ||
max_position: 40.0 # Maximum position in microns | ||
invert_axis: True # If True, modifies scale and offset internally to invert axis | ||
|
||
PiezoY: | ||
import_path : qt3utils.applications.qdlmove.nidaqpiezo | ||
class_name : NiDaqPiezoController | ||
configure: | ||
device_name: Dev1 | ||
write_channel: ao1 | ||
read_channel: | ||
move_settle_time: 0.0 | ||
scale_microns_per_volt: 8 | ||
zero_microns_volt_offset: 5 | ||
min_position: -40.0 | ||
max_position: 40.0 | ||
invert_axis: True | ||
|
||
PiezoZ: | ||
import_path : qt3utils.applications.qdlmove.nidaqpiezo | ||
class_name : NiDaqPiezoController | ||
configure: | ||
device_name: Dev1 | ||
write_channel: ao2 | ||
read_channel: | ||
move_settle_time: 0.0 | ||
scale_microns_per_volt: 8 | ||
zero_microns_volt_offset: 5 | ||
min_position: -40.0 | ||
max_position: 40.0 | ||
invert_axis: True |
Oops, something went wrong.