0
0
mirror of https://github.com/bec-project/bec_widgets.git synced 2025-07-13 19:21:50 +02:00

feat: new GUI

This commit is contained in:
wyzula-jan
2023-08-25 11:36:49 +02:00
parent 3c0e5955d4
commit 0226188079
2 changed files with 498 additions and 288 deletions

View File

@ -6,288 +6,268 @@
<rect>
<x>0</x>
<y>0</y>
<width>1289</width>
<height>596</height>
<width>1115</width>
<height>506</height>
</rect>
</property>
<property name="windowTitle">
<string>Motor Controller</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<layout class="QHBoxLayout" name="horizontalLayout" stretch="7,1,7">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="pushButton_2">
<property name="text">
<string>Go</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_3">
<property name="text">
<string>Save</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="GraphicsLayoutWidget" name="glw">
<property name="enabled">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
<widget class="GraphicsLayoutWidget" name="glw">
<property name="enabled">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4" stretch="1,10,10">
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>General</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Decimal precision</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="spinBox"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Speed</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_speed"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="motorControl">
<property name="title">
<string>Motor Controls</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QCheckBox" name="checkBox_enableArrows">
<property name="text">
<string>Move with arrow keys</string>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<widget class="QToolButton" name="toolButton_up">
<property name="text">
<string>...</string>
</property>
<property name="arrowType">
<enum>Qt::UpArrow</enum>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QToolButton" name="toolButton_left">
<property name="text">
<string>...</string>
</property>
<property name="arrowType">
<enum>Qt::LeftArrow</enum>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="spinBox_step">
<property name="value">
<number>5</number>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QToolButton" name="toolButton_right">
<property name="text">
<string>...</string>
</property>
<property name="arrowType">
<enum>Qt::RightArrow</enum>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QToolButton" name="toolButton_down">
<property name="text">
<string>...</string>
</property>
<property name="arrowType">
<enum>Qt::DownArrow</enum>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="1">
<widget class="QLabel" name="label_6">
<property name="text">
<string>X</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Y</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="pushButton_go_absolute">
<property name="text">
<string>Go</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="spinBox_absolute_x"/>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="spinBox_absolute_y"/>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="pushButton_stop">
<property name="text">
<string>Stop Movement</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="title">
<string>Motor Limits</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="3" column="1">
<widget class="QSpinBox" name="spinBox_x_min">
<property name="minimum">
<number>-1000</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="value">
<number>-100</number>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QSpinBox" name="spinBox_y_max">
<property name="minimum">
<number>-1000</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="value">
<number>100</number>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QLabel" name="label_2">
<property name="text">
<string>- samy</string>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QSpinBox" name="spinBox_x_max">
<property name="minimum">
<number>-1000</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="value">
<number>100</number>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="label">
<property name="text">
<string>+ samy</string>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QLabel" name="label_3">
<property name="text">
<string>+ samx</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_4">
<property name="text">
<string>- samx</string>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QSpinBox" name="spinBox_y_min">
<property name="minimum">
<number>-1000</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="value">
<number>-100</number>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QPushButton" name="pushButton_updateLimits">
<property name="text">
<string>Update</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
<widget class="QFrame" name="Controls">
<property name="minimumSize">
<size>
<width>221</width>
<height>471</height>
</size>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QGroupBox" name="motorSelection">
<property name="title">
<string>Motor Selection</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="2" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Motor Y</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Motor X</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="comboBox"/>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="comboBox_2"/>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>18</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QGroupBox" name="motorControl">
<property name="title">
<string>Motor Relative</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QCheckBox" name="checkBox_enableArrows">
<property name="text">
<string>Move with arrow keys</string>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<item row="1" column="2" alignment="Qt::AlignHCenter|Qt::AlignVCenter">
<widget class="QToolButton" name="toolButton_up">
<property name="text">
<string>...</string>
</property>
<property name="arrowType">
<enum>Qt::UpArrow</enum>
</property>
</widget>
</item>
<item row="2" column="4">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="2" alignment="Qt::AlignHCenter|Qt::AlignVCenter">
<widget class="QSpinBox" name="spinBox_step">
<property name="value">
<number>5</number>
</property>
</widget>
</item>
<item row="3" column="2" alignment="Qt::AlignHCenter|Qt::AlignVCenter">
<widget class="QToolButton" name="toolButton_down">
<property name="text">
<string>...</string>
</property>
<property name="arrowType">
<enum>Qt::DownArrow</enum>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QToolButton" name="toolButton_left">
<property name="text">
<string>...</string>
</property>
<property name="arrowType">
<enum>Qt::LeftArrow</enum>
</property>
</widget>
</item>
<item row="0" column="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="3">
<widget class="QToolButton" name="toolButton_right">
<property name="text">
<string>...</string>
</property>
<property name="arrowType">
<enum>Qt::RightArrow</enum>
</property>
</widget>
</item>
<item row="2" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="2">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>13</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Move Absolute</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="1">
<widget class="QLabel" name="label_6">
<property name="text">
<string>X</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Y</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="pushButton_go_absolute">
<property name="text">
<string>Go</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="spinBox_absolute_x"/>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="spinBox_absolute_y"/>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="pushButton_stop">
<property name="text">
<string>Stop Movement</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QTabWidget" name="tabWidget">
<widget class="QTabWidget" name="tabWidget_tables">
<property name="enabled">
<bool>true</bool>
</property>
<property name="currentIndex">
<number>0</number>
</property>
@ -327,6 +307,209 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_3">
<attribute name="title">
<string>Settings</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QGroupBox" name="motorConfig">
<property name="title">
<string>Motor Limits</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="3" column="1">
<widget class="QSpinBox" name="spinBox_y_min">
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="minimum">
<number>-1000</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="value">
<number>-100</number>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QPushButton" name="pushButton_updateLimits">
<property name="text">
<string>Update</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QSpinBox" name="spinBox_x_max">
<property name="minimum">
<number>-1000</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="value">
<number>100</number>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_Y_max">
<property name="text">
<string>+ Y</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="spinBox_y_max">
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="minimum">
<number>-1000</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="value">
<number>100</number>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QSpinBox" name="spinBox_x_min">
<property name="minimum">
<number>-1000</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="value">
<number>-100</number>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="label_Y_min">
<property name="text">
<string>- Y</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_X_min">
<property name="text">
<string>- X</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="label_X_max">
<property name="text">
<string>+ X</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Motor config</string>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<item row="4" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox"/>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="spinBox"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Tolerance</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Update Frequency</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="spinBox_2"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Decimal Precision</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="spinBox_3"/>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_9">
<property name="text">
<string>X</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Speed</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Y</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="checkBox">
<property name="text">
<string>X = Y</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="spinBox_4"/>
</item>
<item row="2" column="2">
<widget class="QSpinBox" name="spinBox_5"/>
</item>
<item row="3" column="2">
<widget class="QSpinBox" name="spinBox_6"/>
</item>
<item row="4" column="2">
<widget class="QDoubleSpinBox" name="doubleSpinBox_2"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Queue</string>
@ -334,6 +517,9 @@
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QPushButton" name="pushButton_5">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Reset Queue</string>
</property>
@ -341,6 +527,9 @@
</item>
<item>
<widget class="QTableWidget" name="tableWidget_2">
<property name="enabled">
<bool>false</bool>
</property>
<column>
<property name="text">
<string>queueID</string>

View File

@ -11,6 +11,18 @@ from pyqtgraph.Qt import QtWidgets, uic
from bec_lib.core import MessageEndpoints, BECMessage
# TODO - General features
# - setting motor speed and frequency
# - setting motor acceleration
# - updating motor precision
# - put motor selection dropdown or listwidget
# - put motor status (moving, stopped, etc)
# - remove all hardcoded references to samx and samy
# - add spinBox for motor scatter size
# - add mouse interactions with the plot -> click to select coordinates, double click to move?
# - adjust right click actions
class MotorApp(QWidget):
coordinates_updated = pyqtSignal(float, float)
@ -23,9 +35,8 @@ class MotorApp(QWidget):
# Coordinates tracking
self.motor_positions = np.array([])
self.max_points = 50 # Maximum number of points to keep
self.max_points = 5000 # Maximum number of points to keep
self.num_dim_points = 15 # Number of points to dim gradually
self.precision = 2 # Define the decimal precision
# QThread for motor movement + signals
self.motor_thread = MotorControl()
@ -40,9 +51,6 @@ class MotorApp(QWidget):
print(f"Init limits: samx:{self.limit_x}, samy:{self.limit_y}")
# self.background_map_scale = 10
# self.visited_coordinates = {}
# Initialize the image map
self.init_motor_map()
@ -103,6 +111,14 @@ class MotorApp(QWidget):
size=2, pen=pg.mkPen(None), brush=pg.mkBrush(255, 255, 255, 255)
)
self.plot_map.addItem(self.motor_map)
self.plot_map.showGrid(x=True, y=True)
##########################
# Motor General setting
##########################
# TODO make function to update precision
self.precision = 2 # self.spinBox_precision.value() # Define the decimal precision
##########################
# Motor movements signals
@ -132,6 +148,9 @@ class MotorApp(QWidget):
)
)
self.pushButton_go_absolute.clicked.connect(self.save_absolute_coordinates)
self.pushButton_go_absolute.setShortcut("Ctrl+G")
self.pushButton_go_absolute.setToolTip("Ctrl+G")
self.motor_thread.move_finished.connect(lambda: self.enable_motor_controls(True))
# Stop Button
@ -158,7 +177,7 @@ class MotorApp(QWidget):
# TODO map with floats as well -> or decide system for higher precision
self.motor_thread.coordinates_updated.connect(
lambda x, y: self.update_image_map(round(x, 2), round(y, 2))
lambda x, y: self.update_image_map(round(x, self.precision), round(y, self.precision))
)
# Coordinates table
@ -294,19 +313,23 @@ class MotorControl(QThread):
move_finished = pyqtSignal() # Signal to emit when the move is finished
# progress_updated = pyqtSignal(int) #TODO Signal to emit progress percentage
def __init__(self, parent=None):
def __init__(
self,
active_devices=["samx", "samy"],
parent=None,
):
super().__init__(parent)
self.target_coordinates = None
self.running = False
self.active_devices = active_devices
# Initialize current coordinates with the provided initial coordinates
(
self.current_x,
self.current_y,
) = self.get_coordinates() # TODO maybe not needed, coordinates always stored in redis
self.active_devices = ["samx", "samy"]
self.motors_consumer = client.connector.consumer(
topics=[
MessageEndpoints.device_readback(self.active_devices[0]),
@ -319,13 +342,9 @@ class MotorControl(QThread):
self.motors_consumer.start()
def get_coordinates(self) -> tuple:
# TODO decide if the get_coordinates and retrieve coordinates makes sense
# TODO or move also to signal/slot as in the case of limits
# TODO or move just to redis CB function
"""Get current motor position"""
dev.samx.read(cached=True) # TODO to get last message ['value'] -> last position
x = dev.samx.position()
y = dev.samy.position()
x = dev.samx.read(cached=True)["value"] # TODO remove hardcoded samx and samy
y = dev.samx.read(cached=True)["value"]
return x, y
def retrieve_coordinates(self) -> tuple:
@ -360,7 +379,9 @@ class MotorControl(QThread):
if current_position[0] < x_limit[0] or current_position[0] > x_limit[1]:
raise ValueError("Current motor position is outside the new limits (X)")
else:
self.update_motor_limits(dev.samx, low_limit=x_limit[0], high_limit=x_limit[1])
self.update_motor_limits(
dev.samx, low_limit=x_limit[0], high_limit=x_limit[1]
) # TODO Remove hardcoded samx and samy
if y_limit is not None:
if current_position[1] < y_limit[0] or current_position[1] > y_limit[1]: