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

feat: setting map according to motor limits

This commit is contained in:
wyzula-jan
2023-08-18 17:06:37 +02:00
parent e6952a6d13
commit 512e698e26
2 changed files with 297 additions and 46 deletions

View File

@ -6,33 +6,74 @@
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>266</height>
<width>1289</width>
<height>596</height>
</rect>
</property>
<property name="windowTitle">
<string>Motor Controller</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_status">
<property name="text">
<string>Motor Position</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,1,1">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_status">
<property name="text">
<string>Motor Position</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<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>false</bool>
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</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="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Decimal precision</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinBox"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="motorControl">
<property name="title">
@ -92,7 +133,7 @@
<item>
<widget class="QGroupBox" name="groupBox">
<property name="enabled">
<bool>false</bool>
<bool>true</bool>
</property>
<property name="title">
<string>Motor Limits</string>
@ -120,13 +161,34 @@
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="spinBox_samxN"/>
<widget class="QSpinBox" name="spinBox_x_min">
<property name="minimum">
<number>-1000</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="spinBox_samyP"/>
<widget class="QSpinBox" name="spinBox_y_max">
<property name="minimum">
<number>-1000</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QSpinBox" name="spinBox_samxP"/>
<widget class="QSpinBox" name="spinBox_x_max">
<property name="minimum">
<number>-1000</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLabel" name="label_3">
@ -136,12 +198,12 @@
</widget>
</item>
<item row="3" column="2">
<widget class="QSpinBox" name="spinBox_samyN"/>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Update</string>
<widget class="QSpinBox" name="spinBox_y_min">
<property name="minimum">
<number>-1000</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
@ -150,6 +212,94 @@
</item>
</layout>
</item>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Saved</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QPushButton" name="pushButton_4">
<property name="text">
<string>Go to selected</string>
</property>
</widget>
</item>
<item>
<widget class="QTableWidget" name="tableWidget">
<column>
<property name="text">
<string>Show</string>
</property>
</column>
<column>
<property name="text">
<string>X</string>
</property>
</column>
<column>
<property name="text">
<string>Y</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Queue</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QPushButton" name="pushButton_5">
<property name="text">
<string>Reset Queue</string>
</property>
</widget>
</item>
<item>
<widget class="QTableWidget" name="tableWidget_2">
<column>
<property name="text">
<string>queueID</string>
</property>
</column>
<column>
<property name="text">
<string>scanID</string>
</property>
</column>
<column>
<property name="text">
<string>is_scan</string>
</property>
</column>
<column>
<property name="text">
<string>type</string>
</property>
</column>
<column>
<property name="text">
<string>scan_number</string>
</property>
</column>
<column>
<property name="text">
<string>IQ status</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<customwidgets>

View File

@ -1,6 +1,7 @@
import os
import numpy as np
from PyQt5 import QtGui
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import QApplication, QWidget
from pyqtgraph.Qt import QtCore, QtWidgets, uic
@ -17,7 +18,14 @@ class MotorApp(QWidget):
uic.loadUi(os.path.join(current_path, "motor_controller.ui"), self)
# UI
self.start_x, self.start_y = self.get_xy()
self.limit_x, self.limit_y = self.get_motor_limits(dev.samx), self.get_motor_limits(
dev.samy
)
self.label_status.setText(
f"Motor position: ({dev.samx.position():.2f}, {dev.samy.position():.2f})"
)
self.init_ui()
def init_ui(self):
@ -31,13 +39,17 @@ class MotorApp(QWidget):
self.image_map = pg.ImageItem()
self.plot_map.addItem(self.image_map)
self.image_map_data = np.zeros((100, 100), dtype=np.float32)
x, y = self.get_xy() # Assuming get_xy returns the motor position
self.update_image_map(x, y)
self.image_map.setImage(self.image_map_data.T) # Set the image
# self.image_map_data = np.zeros((100, 100), dtype=np.float32)
# x, y = self.get_xy() # Assuming get_xy returns the motor position
# self.update_image_map(x, y)
# self.image_map.setImage(self.image_map_data.T) # Set the image
# self.init_motor_map()
##########################
# Signals
##########################
# Buttons - Motor Movement
self.toolButton_right.clicked.connect(
lambda: self.move_motor(dev.samx, self.spinBox_step.value())
@ -52,6 +64,32 @@ class MotorApp(QWidget):
lambda: self.move_motor(dev.samy, -self.spinBox_step.value())
)
# SpinBoxes - Motor Limits #TODO make spinboxes own limits updated, currently is [-1000, 1000]
# manually set limits before readout #TODO will be removed when spinboxes have own limits
# dev.samx.low_limit = -100
# dev.samx.high_limit = 100
# dev.samy.low_limit = -100
# dev.samy.high_limit = 100
# display initial limits
self.spinBox_x_min.setValue(self.limit_x[0])
self.spinBox_x_max.setValue(self.limit_x[1])
self.spinBox_y_min.setValue(self.limit_y[0])
self.spinBox_y_max.setValue(self.limit_y[1])
# # change limits of motors for all motors and spinboxes
self.spinBox_x_min.valueChanged.connect(
lambda x: self.update_motor_limits(dev.samx, low_limit=x)
)
self.spinBox_x_max.valueChanged.connect(
lambda x: self.update_motor_limits(dev.samx, high_limit=x)
)
self.spinBox_y_min.valueChanged.connect(
lambda x: self.update_motor_limits(dev.samy, low_limit=x)
)
self.spinBox_y_max.valueChanged.connect(
lambda x: self.update_motor_limits(dev.samy, high_limit=x)
)
# Map
self.motor_position.connect(lambda x: self.update_image_map(*self.get_xy()))
@ -70,8 +108,87 @@ class MotorApp(QWidget):
)
)
self.init_motor_map()
def init_motor_map(self):
# Get motor limits
limit_x_min, limit_x_max = self.get_motor_limits(dev.samx)
limit_y_min, limit_y_max = self.get_motor_limits(dev.samy)
self.offset_x = limit_x_min
self.offset_y = limit_y_min
# Define the size of the image map based on the motor's limits
map_width = limit_x_max - limit_x_min + 1
map_height = limit_y_max - limit_y_min + 1
# Create an empty image map
self.background_value = 15
self.image_map_data = np.full(
(map_width, map_height), self.background_value, dtype=np.float32
)
# Set the initial position on the map
x, y = self.get_xy()
self.prev_x, self.prev_y = x, y
self.update_image_map(x, y)
# Translate and scale the image item to match the motor coordinates
self.tr = QtGui.QTransform()
self.tr.translate(limit_x_min, limit_y_min)
self.image_map.setTransform(self.tr)
self.image_map.dataTransform()
def update_image_map(self, x, y):
"""Update the image map with the new motor position"""
# Define the dimming factor
dimming_factor = 0.80
# Apply the dimming factor only to pixels above the background value
self.image_map_data[self.image_map_data > self.background_value] *= dimming_factor
# Mapping of motor coordinates to pixel coordinates
pixel_x = int(x - self.offset_x)
pixel_y = int(y - self.offset_y)
# Set the bright pixel at the new position
self.image_map_data[pixel_x, pixel_y] = 255
# Update the display
self.image_map.updateImage(self.image_map_data, levels=(0, 255))
def get_motor_limits(self, motor):
"""Get the limits of a motor"""
high_limit = motor.high_limit
low_limit = motor.low_limit
return low_limit, high_limit
def update_motor_limits(self, motor, low_limit=None, high_limit=None):
# Get current limits
current_low_limit, current_high_limit = motor.limits[0], motor.limits[1]
# Check if the low limit has changed and is not None
if low_limit is not None and low_limit != current_low_limit:
motor.low_limit = low_limit
# Check if the high limit has changed and is not None
if high_limit is not None and high_limit != current_high_limit:
motor.high_limit = high_limit
def move_motor(self, motor, value: float) -> None:
scans.mv(motor, value, relative=True)
try:
status = scans.mv(motor, value, relative=True)
while status.status not in ["COMPLETED", "STOPPED"]:
print(status.status)
# return status
except Exception as e:
print(e)
motor_position = motor.position()
self.motor_position.emit(motor_position)
@ -83,22 +200,6 @@ class MotorApp(QWidget):
y = dev.samy.position()
return x, y
def update_image_map(self, x, y):
"""Update the image map with the new motor position"""
# Reduce the brightness of all pixels by a fixed fraction (e.g., 5%)
self.image_map_data *= 0.8
# Modify this mapping as needed
pixel_x = int(x)
pixel_y = int(y)
# Set the bright pixel at the new position
self.image_map_data[pixel_x, pixel_y] = 255
# Update the display
self.image_map.setImage(self.image_map_data)
if __name__ == "__main__":
from bec_widgets.bec_dispatcher import bec_dispatcher