This commit is contained in:
flandre 2025-02-18 23:31:44 +08:00
parent b9e3947a25
commit b7164b7c78
15 changed files with 593 additions and 374 deletions

View File

@ -27,5 +27,5 @@ override-dependencies = [
[tool.uv.sources]
av = [
{ path = "./av-14.1.0-cp312-cp312-win_amd64.whl", marker = "sys_platform == 'win32'" },
{ path = "./av-14.1.0-cp312-cp312-linux_amd64.whl", marker = "sys_platform == 'linux'" },
{ path = "./av-14.1.0-cp312-cp312-linux_x86_64.whl", marker = "sys_platform == 'linux'" },
]

View File

@ -9,7 +9,7 @@ import zmq
from config import PLAYBACK_SOCKET, VIDEO_WIDTH, VIDEO_HEIGHT, LIVE_SOCKET
from nodes.Node import Node
from utils.Msg import BMMsg, ImageArgMsg, KillMsg, SeqMetaMsg, SetPlayMode, SetDeviceConfigMsg, SetRecordMsg, \
from utils.Msg import BMMsg, ImageArgMsg, KillMsg, SetSeqMetaMsg, SetPlayMode, SetDeviceConfigMsg, SetRecordMsg, \
RecordFrameMsg
from utils.RfFile import RfFrame, RfSequenceMeta
from utils.RfMat import RfMat
@ -19,7 +19,7 @@ logger = logging.getLogger(__name__)
class Beamformer(Node):
topics = [ImageArgMsg, SeqMetaMsg, SetPlayMode, SetDeviceConfigMsg, SetRecordMsg]
topics = [ImageArgMsg, SetSeqMetaMsg, SetPlayMode, SetDeviceConfigMsg, SetRecordMsg]
def __init__(self, level=logging.INFO):
super(Beamformer, self).__init__(level=level)
@ -89,7 +89,7 @@ class Beamformer(Node):
if isinstance(msg, KillMsg):
if msg.name == '':
return
if isinstance(msg, SeqMetaMsg):
if isinstance(msg, SetSeqMetaMsg):
match msg.target:
case 'live':
self.seq_meta_live = RfSequenceMeta.from_name(msg.name)

View File

@ -1,17 +1,22 @@
import logging
import cv2
import numpy as np
import zmq
from utils.Msg import BMMsg
from config import VIDEO_HEIGHT, VIDEO_WIDTH
from nodes.Node import Node
from utils.Msg import BMMsg, SetWindowVisibleMsg
logger = logging.getLogger(__name__)
class ImageCV(Node):
topics = [BMMsg]
topics = [BMMsg, SetWindowVisibleMsg]
def __init__(self):
super().__init__()
def __init__(self, level=logging.INFO):
super().__init__(level=level)
self.show = True
self.buffer = np.zeros((VIDEO_HEIGHT, VIDEO_WIDTH, 3), dtype=np.uint8) + 128
def loop(self):
@ -19,10 +24,23 @@ class ImageCV(Node):
while True:
socks = dict(self.c.poller.poll(0.001))
if self.c.sub in socks and socks[self.c.sub] == zmq.POLLIN:
r = self.recv()
if isinstance(r, BMMsg):
b = np.frombuffer(r.data, dtype=np.uint8)
msg = self.recv()
if isinstance(msg, BMMsg):
b = np.frombuffer(msg.data, dtype=np.uint8)
b = np.reshape(b, (VIDEO_HEIGHT, VIDEO_WIDTH, 4))
self.buffer = b
cv2.imshow('image', self.buffer)
cv2.waitKey(1)
elif isinstance(msg, SetWindowVisibleMsg):
if msg.name == 'bscan' and msg.sender != 'cv':
self.show = msg.value
if msg.value:
cv2.namedWindow('image', cv2.WINDOW_NORMAL)
else:
cv2.destroyWindow('image')
if self.show:
if cv2.getWindowProperty('image', cv2.WND_PROP_VISIBLE) < 1:
self.show = False
self.send(SetWindowVisibleMsg('cv', 'bscan', False))
cv2.destroyWindow('image')
continue
cv2.imshow('image', self.buffer)
cv2.waitKey(1)

View File

@ -7,14 +7,15 @@ import zmq
from config import PLAYBACK_SOCKET_PORT, SOFTWARE_CONFIG
from nodes.Node import Node
from utils.Msg import MoveAxisMsg, KillMsg, SelectSeqMsg, SeqMetaMsg, SeqIdMinMax, SetBaseMsg, SeqListMsg, SeqIdList
from utils.Msg import MoveAxisMsg, KillMsg, SelectSeqMsg, SetSeqMetaMsg, SeqIdMinMax, SetBaseMsg, SeqListMsg, SeqIdList, \
SetSidMsg
from utils.RfFile import RfSequence
logger = logging.getLogger(__name__)
class Loader(Node):
topics = [MoveAxisMsg, SelectSeqMsg, SetBaseMsg]
topics = [MoveAxisMsg, SelectSeqMsg, SetBaseMsg, SetSidMsg]
def loop(self):
playback_socket = self.context.socket(zmq.PUSH)
@ -29,16 +30,18 @@ class Loader(Node):
if isinstance(msg, MoveAxisMsg) and rff is not None:
logger.debug(f'Move axis: {msg}')
if msg.axis == 'S':
frame = rff.frames[msg.value]
buffer = io.BytesIO()
buffer.write(struct.pack('=iqi', 114514, frame.meta.sequence_id, frame.meta.encoder))
buffer.write(frame.bytes)
playback_socket.send(buffer.getvalue())
pass
elif isinstance(msg, SetSidMsg):
frame = rff.frames[msg.value]
buffer = io.BytesIO()
buffer.write(struct.pack('=iqi', 114514, frame.meta.sequence_id, frame.meta.encoder))
buffer.write(frame.bytes)
playback_socket.send(buffer.getvalue())
elif isinstance(msg, SelectSeqMsg):
if base is None:
continue
rff = RfSequence.from_folder(base / msg.value)
self.send(SeqMetaMsg('playback', rff.meta.name))
self.send(SetSeqMetaMsg('playback', rff.meta.name))
self.send(SeqIdMinMax(*rff.seq_id_minmax))
self.send(SeqIdList([f.meta.sequence_id for f in rff.frames]))
elif isinstance(msg, SetBaseMsg):

View File

@ -1,6 +1,7 @@
import logging
import platform
import sys
import traceback
from enum import Enum, auto
from pathlib import Path
@ -10,12 +11,12 @@ from PyQt6.QtWidgets import QMainWindow, QApplication, QFrame, QMessageBox, QFil
from Main import Ui_MainWindow
from ZMQReceiver import ZMQReceiver
from config import DS
from config import DS, SOFTWARE_CONFIG
from nodes.Node import Node
from utils.Msg import KillMsg, Msg, ImageArgMsg, SelectSeqMsg, SeqIdMinMax, MoveAxisMsg, SeqListMsg, SetBaseMsg, \
SeqMetaMsg, SetPlayMode, DeviceConnectedMsg, DeviceEnabledMsg, DeviceOnlineMsg, SetDeviceEnabledMsg, \
SetSeqMetaMsg, SetPlayMode, DeviceConnectedMsg, DeviceEnabledMsg, DeviceOnlineMsg, SetDeviceEnabledMsg, \
SetDeviceConnectedMsg, DeviceConfigListMsg, SetDeviceConfigMsg, SetRecordMsg, RobotRtsiMsg, RecordFrameMsg, \
SeqIdList
SeqIdList, SetWindowVisibleMsg, SetSidMsg
from utils.RfMeta import RfSequenceMeta
logger = logging.getLogger(__name__)
@ -60,7 +61,7 @@ class Adv(QMainWindow, Ui_MainWindow):
self.c_playback_seq_name.currentIndexChanged.connect(self.on_select_plyayback_seq_name)
self.s_sid.valueChanged.connect(self.c_sid)
self.arg = ImageArgMsg('ui', t_start=0, t_end=1499)
self.b_base.clicked.connect(self.on_base)
self.b_base.clicked.connect(self.on_base_open)
self.seq_meta: RfSequenceMeta | None = None
self.b_play_live.clicked.connect(self.on_play_live)
self.b_play_playback.clicked.connect(self.on_play_playback)
@ -70,8 +71,8 @@ class Adv(QMainWindow, Ui_MainWindow):
self.device_enabled = False
# self.b_device_enabled.clicked.connect(lambda: self.p.send(SetDeviceEnabledMsg(not self.device_enabled)))
# self.b_device_connected.clicked.connect(lambda: self.p.send(SetDeviceConnectedMsg(not self.device_connected)))
self.c_seq_meta.currentIndexChanged.connect(self.on_seq_meta)
self.l_base.setText(DS.__str__())
self.c_live_seq_name.currentIndexChanged.connect(self.on_seq_meta)
self.l_base.setText(SOFTWARE_CONFIG.base_dir.__str__())
self.b1, self.b2 = False, False
self.b3, self.b4 = False, False
@ -84,6 +85,10 @@ class Adv(QMainWindow, Ui_MainWindow):
self.b_select_base.clicked.connect(self.on_select_base)
self.cb_bscan.stateChanged.connect(self.on_cb_bscan)
# self.cb_bscan.checkStateChanged.connect(lambda e: print(e == 2, flush=True))
# self.cb_bscan.checkStateChanged.connect(lambda e: print(e.name, flush=True))
def on_select_base(self):
base = QFileDialog.getExistingDirectory(self, 'Select Base Folder', DS.__str__())
self.l_base.setText(Path(base).__str__())
@ -91,8 +96,8 @@ class Adv(QMainWindow, Ui_MainWindow):
def update_b_play_live_enabled(self):
self.b_play_live.setEnabled(all([self.b1, self.b2]))
def on_base(self):
if Path(self.l_base.text()).exists():
def on_base_open(self):
if Path(self.l_base.text()):
self.p.send(SetBaseMsg(self.l_base.text()))
self.b1 = True
self.update_b_play_live_enabled()
@ -101,7 +106,7 @@ class Adv(QMainWindow, Ui_MainWindow):
match status:
case LinkStatus.RED:
self.device_connected = False
self.c_seq_meta.setEnabled(False)
self.c_live_seq_name.setEnabled(False)
self.lb_device_connection.setText('Disconnected')
self.lb_device_connection.setStyleSheet('background-color: pink;')
case LinkStatus.YELLOW:
@ -109,7 +114,7 @@ class Adv(QMainWindow, Ui_MainWindow):
self.lb_device_connection.setStyleSheet('background-color: yellow;')
case LinkStatus.GREEN:
self.device_connected = True
self.c_seq_meta.setEnabled(True)
self.c_live_seq_name.setEnabled(True)
self.lb_device_connection.setText('Connected')
self.lb_device_connection.setStyleSheet('background-color: LightGreen;')
@ -131,21 +136,24 @@ class Adv(QMainWindow, Ui_MainWindow):
self.c_playback_seq_name.setEnabled(all([self.b3, self.b4]))
def on_play_live(self):
self.s_sid.setEnabled(False)
self.b_play_live.setStyleSheet('background-color: red;')
self.b_play_playback.setStyleSheet('')
self.b_record.setEnabled(True)
self.l_record_commit.setEnabled(True)
self.p.send(SeqMetaMsg('live', self.c_seq_meta.itemText(self.c_seq_meta.currentIndex())))
self.p.send(SetSeqMetaMsg('live', self.c_live_seq_name.itemText(self.c_live_seq_name.currentIndex())))
self.p.send(SetPlayMode('live'))
self.b3 = False
self.update_c_playback_seq_name_enable()
def on_play_playback(self):
self.s_sid.setEnabled(True)
self.b_play_live.setStyleSheet('')
self.b_play_playback.setStyleSheet('background-color: red;')
self.b_record.setEnabled(False)
self.l_record_commit.setEnabled(False)
self.p.send(SeqMetaMsg('playback', self.c_playback_seq_name.itemText(self.c_playback_seq_name.currentIndex())))
self.p.send(
SetSeqMetaMsg('playback', self.c_playback_seq_name.itemText(self.c_playback_seq_name.currentIndex())))
self.p.send(SetPlayMode('playback'))
logger.debug(f'set playmode playback')
self.b3 = True
@ -236,75 +244,92 @@ class Adv(QMainWindow, Ui_MainWindow):
QMessageBox.warning(None, 'hint', 'Commit is empty!!')
def on_zmq_event(self, msg: QByteArray):
msg = Msg.decode_msg(msg.data())
if isinstance(msg, KillMsg):
if msg.name == '':
self.close()
elif isinstance(msg, ImageArgMsg):
self.s_t_end.setValue(msg.t_start)
self.s_t_end.setValue(msg.t_end)
elif isinstance(msg, MoveAxisMsg):
match msg.axis:
case 'S':
self.s_sid.setValue(msg.value)
self.l_seq_current.setText(str(self.seq_id_list[msg.value]))
elif isinstance(msg, SeqIdList):
self.seq_id_list = msg.li
self.s_sid.setMaximum(msg.li.__len__() - 1)
self.sp_sid.setMaximum(msg.li.__len__() - 1)
self.l_seq_min.setText(str(min(msg.li)))
self.l_seq_max.setText(str(max(msg.li)))
elif isinstance(msg, SeqListMsg):
self.b4 = True
self.update_c_playback_seq_name_enable()
self.c_playback_seq_name.clear()
for name in msg.value:
self.c_playback_seq_name.addItem(name)
if msg.value.__len__() > 0:
self.p.send(SelectSeqMsg(self.c_playback_seq_name.itemText(self.c_playback_seq_name.currentIndex())))
self.b_play_playback.setEnabled(True)
elif isinstance(msg, SeqMetaMsg):
self.seq_meta = RfSequenceMeta.from_name(msg.name)
self.s_t_start.setMaximum(max(self.seq_meta.shape))
self.s_t_end.setMaximum(max(self.seq_meta.shape))
elif isinstance(msg, DeviceConnectedMsg):
if msg.value:
self.set_device_connection(LinkStatus.GREEN)
else:
self.set_device_connection(LinkStatus.RED)
self.update_device_buttons()
elif isinstance(msg, DeviceEnabledMsg):
if msg.value:
self.set_device_enable(LinkStatus.GREEN)
else:
self.set_device_enable(LinkStatus.RED)
self.update_device_buttons()
elif isinstance(msg, DeviceOnlineMsg):
if msg.value:
self.l_online.setStyleSheet("")
self.l_online.setText("Device Online")
else:
self.l_online.setStyleSheet("background-color: pink;")
self.l_online.setText("Device Offline")
elif isinstance(msg, DeviceConfigListMsg):
for name, txt in msg.arr:
self.c_seq_meta.addItem(name, txt)
elif isinstance(msg, RobotRtsiMsg):
self.l_robot_pos.setText(','.join([f'{v:.3f}' for v in msg.pos]))
self.l_robot_force.setText(','.join([f'{v:.3f}' for v in msg.force]))
elif isinstance(msg, RecordFrameMsg):
try:
msg = Msg.decode_msg(msg.data())
if isinstance(msg, KillMsg):
if msg.name == '':
self.close()
elif isinstance(msg, ImageArgMsg):
self.s_t_end.setValue(msg.t_start)
self.s_t_end.setValue(msg.t_end)
elif isinstance(msg, MoveAxisMsg):
match msg.axis:
case 'S':
pass
# self.s_sid.setValue(msg.value)
# self.l_seq_current.setText(str(self.seq_id_list[msg.value]))
elif isinstance(msg, SetSidMsg):
self.s_sid.setValue(msg.value)
self.l_seq_current.setText(str(self.seq_id_list[msg.value]))
elif isinstance(msg, SeqIdList):
self.seq_id_list = msg.li
self.s_sid.setMaximum(msg.li.__len__() - 1)
self.sp_sid.setMaximum(msg.li.__len__() - 1)
self.l_seq_min.setText(str(min(msg.li)))
self.l_seq_max.setText(str(max(msg.li)))
elif isinstance(msg, SeqListMsg):
self.b4 = True
self.update_c_playback_seq_name_enable()
self.c_playback_seq_name.clear()
for name in msg.value:
self.c_playback_seq_name.addItem(name)
if msg.value.__len__() > 0:
self.p.send(
SelectSeqMsg(self.c_playback_seq_name.itemText(self.c_playback_seq_name.currentIndex())))
self.b_play_playback.setEnabled(True)
elif isinstance(msg, SetSeqMetaMsg):
self.seq_meta = RfSequenceMeta.from_name(msg.name)
self.s_t_start.setMaximum(max(self.seq_meta.shape))
self.s_t_end.setMaximum(max(self.seq_meta.shape))
elif isinstance(msg, DeviceConnectedMsg):
if msg.value:
self.set_device_connection(LinkStatus.GREEN)
else:
self.set_device_connection(LinkStatus.RED)
self.update_device_buttons()
elif isinstance(msg, DeviceEnabledMsg):
if msg.value:
self.set_device_enable(LinkStatus.GREEN)
else:
self.set_device_enable(LinkStatus.RED)
self.update_device_buttons()
elif isinstance(msg, DeviceOnlineMsg):
if msg.value:
self.l_online.setStyleSheet("")
self.l_online.setText("Device Online")
else:
self.l_online.setStyleSheet("background-color: pink;")
self.l_online.setText("Device Offline")
elif isinstance(msg, DeviceConfigListMsg):
for name, txt in msg.arr:
self.c_live_seq_name.addItem(name, txt)
elif isinstance(msg, RobotRtsiMsg):
self.l_robot_pos.setText(','.join([f'{v:.3f}' for v in msg.pos]))
self.l_robot_force.setText(','.join([f'{v:.3f}' for v in msg.force]))
elif isinstance(msg, RecordFrameMsg):
self.record_frame_cnt += 1
self.record_size_cnt += msg.size
self.l_record_size.setText(humanbytes(self.record_size_cnt))
self.l_record_frames.setText(str(self.record_frame_cnt))
self.l_record_max_sid.setText(str(msg.current_sid))
self.record_frame_cnt += 1
self.record_size_cnt += msg.size
self.l_record_size.setText(humanbytes(self.record_size_cnt))
self.l_record_frames.setText(str(self.record_frame_cnt))
self.l_record_max_sid.setText(str(msg.current_sid))
elif isinstance(msg, SetWindowVisibleMsg):
if msg.name == 'bscan' and msg.sender != 'ui':
self.cb_bscan.setChecked(msg.value)
except Exception as e:
logger.error(e)
traceback.print_exception(e)
def closeEvent(self, event):
self.p.send(KillMsg(''))
# event.accept()
# event.ignore()
@QtCore.pyqtSlot(int)
def on_cb_bscan(self, v):
if self.cb_bscan.sender() is None:
self.p.send(SetWindowVisibleMsg('ui', 'bscan', v == 2))
@QtCore.pyqtSlot(int)
def on_t_start(self, v):
if self.s_t_end.sender() is None:
@ -326,21 +351,22 @@ class Adv(QMainWindow, Ui_MainWindow):
def c_sid(self, v):
if self.s_sid.sender() is None:
self.sp_sid.setValue(v)
self.p.send(MoveAxisMsg('ui', 'S', v))
self.p.send(SetSidMsg(v))
# self.p.send(MoveAxisMsg('ui', 'S', v))
@QtCore.pyqtSlot(int)
def on_seq_meta(self, v):
if self.c_seq_meta.sender() is None or isinstance(self.c_seq_meta.sender(), QFrame):
if self.c_seq_meta.itemText(v) != 'Empty':
if self.c_live_seq_name.sender() is None or isinstance(self.c_live_seq_name.sender(), QFrame):
if self.c_live_seq_name.itemText(v) != 'Empty':
self.b2 = True
self.update_b_play_live_enabled()
self.p.send(SetDeviceConfigMsg(self.c_seq_meta.itemData(v)))
self.p.send(SeqMetaMsg('live', self.c_seq_meta.itemText(v)))
self.p.send(SetDeviceConfigMsg(self.c_live_seq_name.itemData(v)))
self.p.send(SetSeqMetaMsg('live', self.c_live_seq_name.itemText(v)))
class MainUI(Node):
topics = [ImageArgMsg, SeqIdMinMax, MoveAxisMsg,
SeqListMsg, SeqMetaMsg, SeqIdList,
SeqListMsg, SetSeqMetaMsg, SeqIdList, SetWindowVisibleMsg, SetSidMsg,
DeviceConnectedMsg, DeviceEnabledMsg, DeviceOnlineMsg, DeviceConfigListMsg,
RobotRtsiMsg,
RecordFrameMsg]
@ -349,11 +375,14 @@ class MainUI(Node):
super().__init__(level=level)
def loop(self):
app = QApplication(sys.argv)
if platform.system() == 'Windows':
app.setStyle('windowsvista')
MainWindow = Adv(self)
# MainWindow.move(int(px), int(py))
# MainWindow.resize(int(sx), int(sy))
MainWindow.show()
app.exec()
try:
app = QApplication(sys.argv)
if platform.system() == 'Windows':
app.setStyle('windowsvista')
MainWindow = Adv(self)
# MainWindow.move(int(px), int(py))
# MainWindow.resize(int(sx), int(sy))
MainWindow.show()
app.exec()
except Exception as e:
print(e)

View File

@ -1,4 +1,4 @@
# Form implementation generated from reading ui file '.\Main.ui'
# Form implementation generated from reading ui file 'Main.ui'
#
# Created by: PyQt6 UI code generator 6.8.0
#
@ -12,103 +12,91 @@ from PyQt6 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(936, 479)
MainWindow.resize(936, 732)
self.centralwidget = QtWidgets.QWidget(parent=MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.gridLayout_7 = QtWidgets.QGridLayout()
self.gridLayout_7.setObjectName("gridLayout_7")
self.s_sid = QtWidgets.QSlider(parent=self.centralwidget)
self.s_sid.setOrientation(QtCore.Qt.Orientation.Horizontal)
self.s_sid.setObjectName("s_sid")
self.gridLayout_7.addWidget(self.s_sid, 3, 1, 1, 1)
self.sp_sid = QtWidgets.QSpinBox(parent=self.centralwidget)
self.sp_sid.setObjectName("sp_sid")
self.gridLayout_7.addWidget(self.sp_sid, 3, 2, 1, 1)
self.b_play_playback = QtWidgets.QPushButton(parent=self.centralwidget)
self.b_play_playback.setEnabled(False)
self.b_play_playback.setObjectName("b_play_playback")
self.gridLayout_7.addWidget(self.b_play_playback, 0, 0, 1, 3)
self.label_16 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_16.setObjectName("label_16")
self.gridLayout_7.addWidget(self.label_16, 1, 0, 1, 1)
self.label_4 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_4.setObjectName("label_4")
self.gridLayout_7.addWidget(self.label_4, 3, 0, 1, 1)
self.c_playback_seq_name = QtWidgets.QComboBox(parent=self.centralwidget)
self.c_playback_seq_name.setEnabled(False)
self.c_playback_seq_name.setEditable(False)
self.c_playback_seq_name.setObjectName("c_playback_seq_name")
self.c_playback_seq_name.addItem("")
self.gridLayout_7.addWidget(self.c_playback_seq_name, 1, 1, 1, 2)
self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
self.horizontalLayout_5.setObjectName("horizontalLayout_5")
self.label26 = QtWidgets.QLabel(parent=self.centralwidget)
self.label26.setObjectName("label26")
self.horizontalLayout_5.addWidget(self.label26)
self.l_seq_min = QtWidgets.QLabel(parent=self.centralwidget)
self.l_seq_min.setObjectName("l_seq_min")
self.horizontalLayout_5.addWidget(self.l_seq_min)
self.label_28 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_28.setObjectName("label_28")
self.horizontalLayout_5.addWidget(self.label_28)
self.l_seq_current = QtWidgets.QLabel(parent=self.centralwidget)
self.l_seq_current.setObjectName("l_seq_current")
self.horizontalLayout_5.addWidget(self.l_seq_current)
self.label_29 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_29.setObjectName("label_29")
self.horizontalLayout_5.addWidget(self.label_29)
self.l_seq_max = QtWidgets.QLabel(parent=self.centralwidget)
self.l_seq_max.setObjectName("l_seq_max")
self.horizontalLayout_5.addWidget(self.l_seq_max)
self.horizontalLayout_5.setStretch(1, 1)
self.horizontalLayout_5.setStretch(3, 1)
self.horizontalLayout_5.setStretch(5, 1)
self.gridLayout_7.addLayout(self.horizontalLayout_5, 2, 0, 1, 3)
self.gridLayout.addLayout(self.gridLayout_7, 1, 1, 1, 1)
self.gridLayout_6 = QtWidgets.QGridLayout()
self.gridLayout_6.setObjectName("gridLayout_6")
self.l_record_commit = QtWidgets.QLineEdit(parent=self.centralwidget)
self.l_record_commit.setEnabled(False)
self.l_record_commit.setObjectName("l_record_commit")
self.gridLayout_6.addWidget(self.l_record_commit, 1, 1, 1, 1)
self.label_17 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_17.setObjectName("label_17")
self.gridLayout_6.addWidget(self.label_17, 1, 0, 1, 1)
self.b_record = QtWidgets.QPushButton(parent=self.centralwidget)
self.b_record.setEnabled(False)
self.b_record.setObjectName("b_record")
self.gridLayout_6.addWidget(self.b_record, 1, 2, 1, 1)
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.label_18 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_18.setObjectName("label_18")
self.horizontalLayout_2.addWidget(self.label_18)
self.l_record_frames = QtWidgets.QLabel(parent=self.centralwidget)
self.l_record_frames.setObjectName("l_record_frames")
self.horizontalLayout_2.addWidget(self.l_record_frames)
self.label_25 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_25.setObjectName("label_25")
self.horizontalLayout_2.addWidget(self.label_25)
self.l_record_size = QtWidgets.QLabel(parent=self.centralwidget)
self.l_record_size.setObjectName("l_record_size")
self.horizontalLayout_2.addWidget(self.l_record_size)
self.label_26 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_26.setObjectName("label_26")
self.horizontalLayout_2.addWidget(self.label_26)
self.l_record_max_sid = QtWidgets.QLabel(parent=self.centralwidget)
self.l_record_max_sid.setObjectName("l_record_max_sid")
self.horizontalLayout_2.addWidget(self.l_record_max_sid)
self.horizontalLayout_2.setStretch(1, 1)
self.horizontalLayout_2.setStretch(3, 1)
self.horizontalLayout_2.setStretch(5, 1)
self.gridLayout_6.addLayout(self.horizontalLayout_2, 2, 0, 1, 3)
self.b_play_live = QtWidgets.QPushButton(parent=self.centralwidget)
self.b_play_live.setEnabled(False)
self.b_play_live.setObjectName("b_play_live")
self.gridLayout_6.addWidget(self.b_play_live, 0, 0, 1, 3)
self.gridLayout.addLayout(self.gridLayout_6, 1, 0, 1, 1)
self.gridLayout_3 = QtWidgets.QGridLayout()
self.gridLayout_3.setObjectName("gridLayout_3")
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.label_20 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_20.setObjectName("label_20")
self.horizontalLayout.addWidget(self.label_20)
self.c_live_seq_name = QtWidgets.QComboBox(parent=self.centralwidget)
self.c_live_seq_name.setEnabled(False)
self.c_live_seq_name.setObjectName("c_live_seq_name")
self.c_live_seq_name.addItem("")
self.horizontalLayout.addWidget(self.c_live_seq_name)
self.horizontalLayout.setStretch(1, 1)
self.gridLayout_3.addLayout(self.horizontalLayout, 3, 0, 1, 4)
self.b_device_enable = QtWidgets.QPushButton(parent=self.centralwidget)
self.b_device_enable.setEnabled(False)
self.b_device_enable.setObjectName("b_device_enable")
self.gridLayout_3.addWidget(self.b_device_enable, 2, 3, 1, 1)
self.b_device_connection = QtWidgets.QPushButton(parent=self.centralwidget)
self.b_device_connection.setObjectName("b_device_connection")
self.gridLayout_3.addWidget(self.b_device_connection, 2, 1, 1, 1)
self.label_24 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_24.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self.label_24.setObjectName("label_24")
self.gridLayout_3.addWidget(self.label_24, 1, 2, 2, 1)
self.lb_device_connection = QtWidgets.QLabel(parent=self.centralwidget)
self.lb_device_connection.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self.lb_device_connection.setObjectName("lb_device_connection")
self.gridLayout_3.addWidget(self.lb_device_connection, 1, 1, 1, 1)
self.l_online = QtWidgets.QLabel(parent=self.centralwidget)
font = QtGui.QFont()
font.setPointSize(15)
self.l_online.setFont(font)
self.l_online.setStyleSheet("background-color: pink;")
self.l_online.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self.l_online.setObjectName("l_online")
self.gridLayout_3.addWidget(self.l_online, 0, 0, 1, 4)
self.lb_device_enable = QtWidgets.QLabel(parent=self.centralwidget)
self.lb_device_enable.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self.lb_device_enable.setObjectName("lb_device_enable")
self.gridLayout_3.addWidget(self.lb_device_enable, 1, 3, 1, 1)
self.label_21 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_21.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self.label_21.setObjectName("label_21")
self.gridLayout_3.addWidget(self.label_21, 1, 0, 2, 1)
self.gridLayout_3.setColumnStretch(1, 1)
self.gridLayout_3.setColumnStretch(3, 1)
self.gridLayout.addLayout(self.gridLayout_3, 0, 0, 1, 1)
self.gridLayout_2 = QtWidgets.QGridLayout()
self.gridLayout_2.setObjectName("gridLayout_2")
self.l_robot_pos = QtWidgets.QLabel(parent=self.centralwidget)
font = QtGui.QFont()
font.setPointSize(15)
self.l_robot_pos.setFont(font)
self.l_robot_pos.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self.l_robot_pos.setObjectName("l_robot_pos")
self.gridLayout_2.addWidget(self.l_robot_pos, 1, 1, 1, 1)
self.l_robot_force = QtWidgets.QLabel(parent=self.centralwidget)
font = QtGui.QFont()
font.setPointSize(15)
self.l_robot_force.setFont(font)
self.l_robot_force.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self.l_robot_force.setObjectName("l_robot_force")
self.gridLayout_2.addWidget(self.l_robot_force, 2, 1, 1, 1)
self.label_22 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_22.setObjectName("label_22")
self.gridLayout_2.addWidget(self.label_22, 1, 0, 1, 1)
self.label_23 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_23.setObjectName("label_23")
self.gridLayout_2.addWidget(self.label_23, 2, 0, 1, 1)
self.label_19 = QtWidgets.QLabel(parent=self.centralwidget)
font = QtGui.QFont()
font.setPointSize(15)
self.label_19.setFont(font)
self.label_19.setStyleSheet("background-color: pink;")
self.label_19.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self.label_19.setObjectName("label_19")
self.gridLayout_2.addWidget(self.label_19, 0, 0, 1, 2)
self.gridLayout_2.setColumnStretch(1, 1)
self.gridLayout.addLayout(self.gridLayout_2, 0, 1, 1, 1)
self.gridLayout_4 = QtWidgets.QGridLayout()
self.gridLayout_4.setObjectName("gridLayout_4")
self.label_14 = QtWidgets.QLabel(parent=self.centralwidget)
@ -194,21 +182,31 @@ class Ui_MainWindow(object):
self.gridLayout.addLayout(self.gridLayout_4, 2, 1, 1, 1)
self.gridLayout_5 = QtWidgets.QGridLayout()
self.gridLayout_5.setObjectName("gridLayout_5")
self.spinBox_2 = QtWidgets.QSpinBox(parent=self.centralwidget)
self.spinBox_2.setObjectName("spinBox_2")
self.gridLayout_5.addWidget(self.spinBox_2, 3, 2, 1, 1)
self.label_5 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_5.setObjectName("label_5")
self.gridLayout_5.addWidget(self.label_5, 2, 0, 1, 1)
self.label_7 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_7.setObjectName("label_7")
self.gridLayout_5.addWidget(self.label_7, 4, 0, 1, 1)
self.label_6 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_6.setObjectName("label_6")
self.gridLayout_5.addWidget(self.label_6, 3, 0, 1, 1)
self.s_t_end = QtWidgets.QSlider(parent=self.centralwidget)
self.s_t_end.setMinimum(1)
self.s_t_end.setMaximum(1500)
self.s_t_end.setOrientation(QtCore.Qt.Orientation.Horizontal)
self.s_t_end.setObjectName("s_t_end")
self.gridLayout_5.addWidget(self.s_t_end, 2, 1, 1, 1)
self.s_t_start = QtWidgets.QSlider(parent=self.centralwidget)
self.s_t_start.setOrientation(QtCore.Qt.Orientation.Horizontal)
self.s_t_start.setObjectName("s_t_start")
self.gridLayout_5.addWidget(self.s_t_start, 1, 1, 1, 1)
self.horizontalSlider_2 = QtWidgets.QSlider(parent=self.centralwidget)
self.horizontalSlider_2.setOrientation(QtCore.Qt.Orientation.Horizontal)
self.horizontalSlider_2.setObjectName("horizontalSlider_2")
self.gridLayout_5.addWidget(self.horizontalSlider_2, 3, 1, 1, 1)
self.spinBox_12 = QtWidgets.QSpinBox(parent=self.centralwidget)
self.spinBox_12.setObjectName("spinBox_12")
self.gridLayout_5.addWidget(self.spinBox_12, 1, 2, 1, 1)
spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding)
self.gridLayout_5.addItem(spacerItem1, 5, 1, 1, 1)
self.spinBox_2 = QtWidgets.QSpinBox(parent=self.centralwidget)
self.spinBox_2.setObjectName("spinBox_2")
self.gridLayout_5.addWidget(self.spinBox_2, 3, 2, 1, 1)
self.spinBox_3 = QtWidgets.QSpinBox(parent=self.centralwidget)
self.spinBox_3.setObjectName("spinBox_3")
self.gridLayout_5.addWidget(self.spinBox_3, 4, 2, 1, 1)
self.label_2 = QtWidgets.QLabel(parent=self.centralwidget)
font = QtGui.QFont()
font.setPointSize(20)
@ -217,84 +215,77 @@ class Ui_MainWindow(object):
self.label_2.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self.label_2.setObjectName("label_2")
self.gridLayout_5.addWidget(self.label_2, 0, 0, 1, 3)
self.spinBox = QtWidgets.QSpinBox(parent=self.centralwidget)
self.spinBox.setObjectName("spinBox")
self.gridLayout_5.addWidget(self.spinBox, 2, 2, 1, 1)
self.s_t_end = QtWidgets.QSlider(parent=self.centralwidget)
self.s_t_end.setMinimum(1)
self.s_t_end.setMaximum(1500)
self.s_t_end.setOrientation(QtCore.Qt.Orientation.Horizontal)
self.s_t_end.setObjectName("s_t_end")
self.gridLayout_5.addWidget(self.s_t_end, 2, 1, 1, 1)
self.label_15 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_15.setObjectName("label_15")
self.gridLayout_5.addWidget(self.label_15, 1, 0, 1, 1)
self.horizontalSlider_4 = QtWidgets.QSlider(parent=self.centralwidget)
self.horizontalSlider_4.setOrientation(QtCore.Qt.Orientation.Horizontal)
self.horizontalSlider_4.setObjectName("horizontalSlider_4")
self.gridLayout_5.addWidget(self.horizontalSlider_4, 4, 1, 1, 1)
spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding)
self.gridLayout_5.addItem(spacerItem1, 5, 1, 1, 1)
self.spinBox = QtWidgets.QSpinBox(parent=self.centralwidget)
self.spinBox.setObjectName("spinBox")
self.gridLayout_5.addWidget(self.spinBox, 2, 2, 1, 1)
self.label_5 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_5.setObjectName("label_5")
self.gridLayout_5.addWidget(self.label_5, 2, 0, 1, 1)
self.horizontalSlider_2 = QtWidgets.QSlider(parent=self.centralwidget)
self.horizontalSlider_2.setOrientation(QtCore.Qt.Orientation.Horizontal)
self.horizontalSlider_2.setObjectName("horizontalSlider_2")
self.gridLayout_5.addWidget(self.horizontalSlider_2, 3, 1, 1, 1)
self.spinBox_3 = QtWidgets.QSpinBox(parent=self.centralwidget)
self.spinBox_3.setObjectName("spinBox_3")
self.gridLayout_5.addWidget(self.spinBox_3, 4, 2, 1, 1)
self.spinBox_12 = QtWidgets.QSpinBox(parent=self.centralwidget)
self.spinBox_12.setObjectName("spinBox_12")
self.gridLayout_5.addWidget(self.spinBox_12, 1, 2, 1, 1)
self.s_t_start = QtWidgets.QSlider(parent=self.centralwidget)
self.s_t_start.setOrientation(QtCore.Qt.Orientation.Horizontal)
self.s_t_start.setObjectName("s_t_start")
self.gridLayout_5.addWidget(self.s_t_start, 1, 1, 1, 1)
self.label_15 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_15.setObjectName("label_15")
self.gridLayout_5.addWidget(self.label_15, 1, 0, 1, 1)
self.label_6 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_6.setObjectName("label_6")
self.gridLayout_5.addWidget(self.label_6, 3, 0, 1, 1)
self.gridLayout.addLayout(self.gridLayout_5, 2, 0, 1, 1)
self.gridLayout_3 = QtWidgets.QGridLayout()
self.gridLayout_3.setObjectName("gridLayout_3")
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.label_20 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_20.setObjectName("label_20")
self.horizontalLayout.addWidget(self.label_20)
self.c_seq_meta = QtWidgets.QComboBox(parent=self.centralwidget)
self.c_seq_meta.setEnabled(False)
self.c_seq_meta.setObjectName("c_seq_meta")
self.c_seq_meta.addItem("")
self.horizontalLayout.addWidget(self.c_seq_meta)
self.horizontalLayout.setStretch(1, 1)
self.gridLayout_3.addLayout(self.horizontalLayout, 3, 0, 1, 4)
self.b_device_enable = QtWidgets.QPushButton(parent=self.centralwidget)
self.b_device_enable.setEnabled(False)
self.b_device_enable.setObjectName("b_device_enable")
self.gridLayout_3.addWidget(self.b_device_enable, 2, 3, 1, 1)
self.b_device_connection = QtWidgets.QPushButton(parent=self.centralwidget)
self.b_device_connection.setObjectName("b_device_connection")
self.gridLayout_3.addWidget(self.b_device_connection, 2, 1, 1, 1)
self.label_24 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_24.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self.label_24.setObjectName("label_24")
self.gridLayout_3.addWidget(self.label_24, 1, 2, 2, 1)
self.lb_device_connection = QtWidgets.QLabel(parent=self.centralwidget)
self.lb_device_connection.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self.lb_device_connection.setObjectName("lb_device_connection")
self.gridLayout_3.addWidget(self.lb_device_connection, 1, 1, 1, 1)
self.l_online = QtWidgets.QLabel(parent=self.centralwidget)
font = QtGui.QFont()
font.setPointSize(15)
self.l_online.setFont(font)
self.l_online.setStyleSheet("background-color: pink;")
self.l_online.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self.l_online.setObjectName("l_online")
self.gridLayout_3.addWidget(self.l_online, 0, 0, 1, 4)
self.lb_device_enable = QtWidgets.QLabel(parent=self.centralwidget)
self.lb_device_enable.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self.lb_device_enable.setObjectName("lb_device_enable")
self.gridLayout_3.addWidget(self.lb_device_enable, 1, 3, 1, 1)
self.label_21 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_21.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self.label_21.setObjectName("label_21")
self.gridLayout_3.addWidget(self.label_21, 1, 0, 2, 1)
self.gridLayout_3.setColumnStretch(1, 1)
self.gridLayout_3.setColumnStretch(3, 1)
self.gridLayout.addLayout(self.gridLayout_3, 0, 0, 1, 1)
self.gridLayout_7 = QtWidgets.QGridLayout()
self.gridLayout_7.setObjectName("gridLayout_7")
self.s_sid = QtWidgets.QSlider(parent=self.centralwidget)
self.s_sid.setEnabled(False)
self.s_sid.setOrientation(QtCore.Qt.Orientation.Horizontal)
self.s_sid.setObjectName("s_sid")
self.gridLayout_7.addWidget(self.s_sid, 3, 1, 1, 1)
self.sp_sid = QtWidgets.QSpinBox(parent=self.centralwidget)
self.sp_sid.setObjectName("sp_sid")
self.gridLayout_7.addWidget(self.sp_sid, 3, 2, 1, 1)
self.b_play_playback = QtWidgets.QPushButton(parent=self.centralwidget)
self.b_play_playback.setEnabled(False)
self.b_play_playback.setObjectName("b_play_playback")
self.gridLayout_7.addWidget(self.b_play_playback, 0, 0, 1, 3)
self.label_16 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_16.setObjectName("label_16")
self.gridLayout_7.addWidget(self.label_16, 1, 0, 1, 1)
self.label_4 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_4.setObjectName("label_4")
self.gridLayout_7.addWidget(self.label_4, 3, 0, 1, 1)
self.c_playback_seq_name = QtWidgets.QComboBox(parent=self.centralwidget)
self.c_playback_seq_name.setEnabled(False)
self.c_playback_seq_name.setEditable(False)
self.c_playback_seq_name.setObjectName("c_playback_seq_name")
self.c_playback_seq_name.addItem("")
self.gridLayout_7.addWidget(self.c_playback_seq_name, 1, 1, 1, 2)
self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
self.horizontalLayout_5.setObjectName("horizontalLayout_5")
self.label26 = QtWidgets.QLabel(parent=self.centralwidget)
self.label26.setObjectName("label26")
self.horizontalLayout_5.addWidget(self.label26)
self.l_seq_min = QtWidgets.QLabel(parent=self.centralwidget)
self.l_seq_min.setObjectName("l_seq_min")
self.horizontalLayout_5.addWidget(self.l_seq_min)
self.label_28 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_28.setObjectName("label_28")
self.horizontalLayout_5.addWidget(self.label_28)
self.l_seq_current = QtWidgets.QLabel(parent=self.centralwidget)
self.l_seq_current.setObjectName("l_seq_current")
self.horizontalLayout_5.addWidget(self.l_seq_current)
self.label_29 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_29.setObjectName("label_29")
self.horizontalLayout_5.addWidget(self.label_29)
self.l_seq_max = QtWidgets.QLabel(parent=self.centralwidget)
self.l_seq_max.setObjectName("l_seq_max")
self.horizontalLayout_5.addWidget(self.l_seq_max)
self.horizontalLayout_5.setStretch(1, 1)
self.horizontalLayout_5.setStretch(3, 1)
self.horizontalLayout_5.setStretch(5, 1)
self.gridLayout_7.addLayout(self.horizontalLayout_5, 2, 0, 1, 3)
self.gridLayout.addLayout(self.gridLayout_7, 1, 1, 1, 1)
self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
self.horizontalLayout_4.setObjectName("horizontalLayout_4")
self.label = QtWidgets.QLabel(parent=self.centralwidget)
@ -311,41 +302,63 @@ class Ui_MainWindow(object):
self.b_base.setObjectName("b_base")
self.horizontalLayout_4.addWidget(self.b_base)
self.gridLayout.addLayout(self.horizontalLayout_4, 3, 0, 1, 2)
self.gridLayout_2 = QtWidgets.QGridLayout()
self.gridLayout_2.setObjectName("gridLayout_2")
self.l_robot_pos = QtWidgets.QLabel(parent=self.centralwidget)
font = QtGui.QFont()
font.setPointSize(15)
self.l_robot_pos.setFont(font)
self.l_robot_pos.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self.l_robot_pos.setObjectName("l_robot_pos")
self.gridLayout_2.addWidget(self.l_robot_pos, 1, 1, 1, 1)
self.l_robot_force = QtWidgets.QLabel(parent=self.centralwidget)
font = QtGui.QFont()
font.setPointSize(15)
self.l_robot_force.setFont(font)
self.l_robot_force.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self.l_robot_force.setObjectName("l_robot_force")
self.gridLayout_2.addWidget(self.l_robot_force, 2, 1, 1, 1)
self.label_22 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_22.setObjectName("label_22")
self.gridLayout_2.addWidget(self.label_22, 1, 0, 1, 1)
self.label_23 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_23.setObjectName("label_23")
self.gridLayout_2.addWidget(self.label_23, 2, 0, 1, 1)
self.label_19 = QtWidgets.QLabel(parent=self.centralwidget)
font = QtGui.QFont()
font.setPointSize(15)
self.label_19.setFont(font)
self.label_19.setStyleSheet("background-color: pink;")
self.label_19.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self.label_19.setObjectName("label_19")
self.gridLayout_2.addWidget(self.label_19, 0, 0, 1, 2)
self.gridLayout_2.setColumnStretch(1, 1)
self.gridLayout.addLayout(self.gridLayout_2, 0, 1, 1, 1)
self.gridLayout_6 = QtWidgets.QGridLayout()
self.gridLayout_6.setObjectName("gridLayout_6")
self.l_record_commit = QtWidgets.QLineEdit(parent=self.centralwidget)
self.l_record_commit.setEnabled(False)
self.l_record_commit.setObjectName("l_record_commit")
self.gridLayout_6.addWidget(self.l_record_commit, 1, 1, 1, 1)
self.label_17 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_17.setObjectName("label_17")
self.gridLayout_6.addWidget(self.label_17, 1, 0, 1, 1)
self.b_record = QtWidgets.QPushButton(parent=self.centralwidget)
self.b_record.setEnabled(False)
self.b_record.setObjectName("b_record")
self.gridLayout_6.addWidget(self.b_record, 1, 2, 1, 1)
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.label_18 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_18.setObjectName("label_18")
self.horizontalLayout_2.addWidget(self.label_18)
self.l_record_frames = QtWidgets.QLabel(parent=self.centralwidget)
self.l_record_frames.setObjectName("l_record_frames")
self.horizontalLayout_2.addWidget(self.l_record_frames)
self.label_25 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_25.setObjectName("label_25")
self.horizontalLayout_2.addWidget(self.label_25)
self.l_record_size = QtWidgets.QLabel(parent=self.centralwidget)
self.l_record_size.setObjectName("l_record_size")
self.horizontalLayout_2.addWidget(self.l_record_size)
self.label_26 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_26.setObjectName("label_26")
self.horizontalLayout_2.addWidget(self.label_26)
self.l_record_max_sid = QtWidgets.QLabel(parent=self.centralwidget)
self.l_record_max_sid.setObjectName("l_record_max_sid")
self.horizontalLayout_2.addWidget(self.l_record_max_sid)
self.horizontalLayout_2.setStretch(1, 1)
self.horizontalLayout_2.setStretch(3, 1)
self.horizontalLayout_2.setStretch(5, 1)
self.gridLayout_6.addLayout(self.horizontalLayout_2, 2, 0, 1, 3)
self.b_play_live = QtWidgets.QPushButton(parent=self.centralwidget)
self.b_play_live.setEnabled(False)
self.b_play_live.setObjectName("b_play_live")
self.gridLayout_6.addWidget(self.b_play_live, 0, 0, 1, 3)
self.gridLayout.addLayout(self.gridLayout_6, 1, 0, 1, 1)
self.horizontalLayout_6 = QtWidgets.QHBoxLayout()
self.horizontalLayout_6.setObjectName("horizontalLayout_6")
self.cb_bscan = QtWidgets.QCheckBox(parent=self.centralwidget)
self.cb_bscan.setChecked(True)
self.cb_bscan.setObjectName("cb_bscan")
self.horizontalLayout_6.addWidget(self.cb_bscan)
self.checkBox = QtWidgets.QCheckBox(parent=self.centralwidget)
self.checkBox.setObjectName("checkBox")
self.horizontalLayout_6.addWidget(self.checkBox)
spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
self.horizontalLayout_6.addItem(spacerItem2)
self.gridLayout.addLayout(self.horizontalLayout_6, 4, 0, 1, 2)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(parent=MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 936, 18))
self.menubar.setGeometry(QtCore.QRect(0, 0, 936, 30))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(parent=MainWindow)
@ -358,6 +371,33 @@ class Ui_MainWindow(object):
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.label_20.setText(_translate("MainWindow", "DeviceConfig"))
self.c_live_seq_name.setItemText(0, _translate("MainWindow", "Empty"))
self.b_device_enable.setText(_translate("MainWindow", "Disconnect"))
self.b_device_connection.setText(_translate("MainWindow", "Connect"))
self.label_24.setText(_translate("MainWindow", "<html><head/><body><p style=\"line-height:0.3\" align=\"center\">Beam</p><p align=\"center\">Status</p></body></html>"))
self.lb_device_connection.setText(_translate("MainWindow", "Disconnected"))
self.l_online.setText(_translate("MainWindow", "Device Offline"))
self.lb_device_enable.setText(_translate("MainWindow", "Disabled"))
self.label_21.setText(_translate("MainWindow", "<html><head/><body><p style=\"line-height:0.3\" align=\"center\">Connection</p><p align=\"center\">Status</p></body></html>"))
self.l_robot_pos.setText(_translate("MainWindow", "0,0,0,0,0,0"))
self.l_robot_force.setText(_translate("MainWindow", "0,0,0,0,0,0"))
self.label_22.setText(_translate("MainWindow", "Position"))
self.label_23.setText(_translate("MainWindow", "Force"))
self.label_19.setText(_translate("MainWindow", "Robot Offline"))
self.label_14.setText(_translate("MainWindow", "Yal"))
self.label_13.setText(_translate("MainWindow", "Pitch"))
self.label_3.setText(_translate("MainWindow", "Probe Position"))
self.label_9.setText(_translate("MainWindow", "Y"))
self.label_10.setText(_translate("MainWindow", "Z"))
self.label_12.setText(_translate("MainWindow", "Roll"))
self.label_11.setText(_translate("MainWindow", "E"))
self.label_8.setText(_translate("MainWindow", "X"))
self.label_5.setText(_translate("MainWindow", "t_end"))
self.label_7.setText(_translate("MainWindow", "TextLabel"))
self.label_2.setText(_translate("MainWindow", "Imaging"))
self.label_15.setText(_translate("MainWindow", "t_start"))
self.label_6.setText(_translate("MainWindow", "TextLabel"))
self.b_play_playback.setText(_translate("MainWindow", "Playback"))
self.label_16.setText(_translate("MainWindow", "SeqName"))
self.label_4.setText(_translate("MainWindow", "Frame ID"))
@ -368,6 +408,9 @@ class Ui_MainWindow(object):
self.l_seq_current.setText(_translate("MainWindow", "0"))
self.label_29.setText(_translate("MainWindow", "Max:"))
self.l_seq_max.setText(_translate("MainWindow", "0"))
self.label.setText(_translate("MainWindow", "Base Path"))
self.b_select_base.setText(_translate("MainWindow", "Select"))
self.b_base.setText(_translate("MainWindow", "Open"))
self.label_17.setText(_translate("MainWindow", "RecordName"))
self.b_record.setText(_translate("MainWindow", "Record"))
self.label_18.setText(_translate("MainWindow", "Record Frames:"))
@ -377,33 +420,5 @@ class Ui_MainWindow(object):
self.label_26.setText(_translate("MainWindow", "Max SeqId:"))
self.l_record_max_sid.setText(_translate("MainWindow", "0"))
self.b_play_live.setText(_translate("MainWindow", "Live"))
self.label_14.setText(_translate("MainWindow", "Yal"))
self.label_13.setText(_translate("MainWindow", "Pitch"))
self.label_3.setText(_translate("MainWindow", "Probe Position"))
self.label_9.setText(_translate("MainWindow", "Y"))
self.label_10.setText(_translate("MainWindow", "Z"))
self.label_12.setText(_translate("MainWindow", "Roll"))
self.label_11.setText(_translate("MainWindow", "E"))
self.label_8.setText(_translate("MainWindow", "X"))
self.label_7.setText(_translate("MainWindow", "TextLabel"))
self.label_6.setText(_translate("MainWindow", "TextLabel"))
self.label_2.setText(_translate("MainWindow", "Imaging"))
self.label_5.setText(_translate("MainWindow", "t_end"))
self.label_15.setText(_translate("MainWindow", "t_start"))
self.label_20.setText(_translate("MainWindow", "DeviceConfig"))
self.c_seq_meta.setItemText(0, _translate("MainWindow", "Empty"))
self.b_device_enable.setText(_translate("MainWindow", "Disconnect"))
self.b_device_connection.setText(_translate("MainWindow", "Connect"))
self.label_24.setText(_translate("MainWindow", "<html><head/><body><p style=\"line-height:0.3\" align=\"center\">Beam</p><p align=\"center\">Status</p></body></html>"))
self.lb_device_connection.setText(_translate("MainWindow", "Disconnected"))
self.l_online.setText(_translate("MainWindow", "Device Offline"))
self.lb_device_enable.setText(_translate("MainWindow", "Disabled"))
self.label_21.setText(_translate("MainWindow", "<html><head/><body><p style=\"line-height:0.3\" align=\"center\">Connection</p><p align=\"center\">Status</p></body></html>"))
self.label.setText(_translate("MainWindow", "Base Path"))
self.b_select_base.setText(_translate("MainWindow", "Select"))
self.b_base.setText(_translate("MainWindow", "Open"))
self.l_robot_pos.setText(_translate("MainWindow", "0,0,0,0,0,0"))
self.l_robot_force.setText(_translate("MainWindow", "0,0,0,0,0,0"))
self.label_22.setText(_translate("MainWindow", "Position"))
self.label_23.setText(_translate("MainWindow", "Force"))
self.label_19.setText(_translate("MainWindow", "Robot Offline"))
self.cb_bscan.setText(_translate("MainWindow", "BSCAN"))
self.checkBox.setText(_translate("MainWindow", "FOCUS"))

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>936</width>
<height>479</height>
<height>732</height>
</rect>
</property>
<property name="windowTitle">
@ -27,7 +27,7 @@
</widget>
</item>
<item>
<widget class="QComboBox" name="c_seq_meta">
<widget class="QComboBox" name="c_live_seq_name">
<property name="enabled">
<bool>false</bool>
</property>
@ -446,6 +446,9 @@
<layout class="QGridLayout" name="gridLayout_7">
<item row="3" column="1">
<widget class="QSlider" name="s_sid">
<property name="enabled">
<bool>false</bool>
</property>
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
@ -660,10 +663,13 @@
<item row="4" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QCheckBox" name="checkBox_2">
<widget class="QCheckBox" name="cb_bscan">
<property name="text">
<string>BSCAN</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
@ -696,7 +702,7 @@
<x>0</x>
<y>0</y>
<width>936</width>
<height>18</height>
<height>30</height>
</rect>
</property>
</widget>

View File

@ -293,7 +293,7 @@
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout_3">
<item row="3" column="0">
<widget class="QComboBox" name="c_seq_meta"/>
<widget class="QComboBox" name="c_live_seq_name"/>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="b_device_enabled">

View File

@ -14,7 +14,7 @@ class BG(Enum):
MoveAxisMsg = auto()
ImageArgMsg = auto()
SelectSeqMsg = auto()
SeqMetaMsg = auto()
SetSeqMetaMsg = auto()
SeqIdMinMax = auto()
SetBaseMsg = auto()
SeqListMsg = auto()
@ -30,6 +30,8 @@ class BG(Enum):
RobotRtsiMsg = auto()
RecordFrameMsg = auto()
SeqIdList = auto()
SetWindowVisibleMsg = auto()
SetSidMsg = auto()
class Msg:
@ -94,6 +96,13 @@ class BoolMsg(Msg):
value: bool
@dataclasses.dataclass
class SetWindowVisibleMsg(Msg):
sender: str
name: str
value: bool
class SetDeviceEnabledMsg(BoolMsg):
pass
@ -143,7 +152,7 @@ class SetPlayMode(StrMsg):
@dataclasses.dataclass
class SeqMetaMsg(Msg):
class SetSeqMetaMsg(Msg):
target: str
name: str
@ -183,6 +192,9 @@ class RecordFrameMsg(Msg):
size: int
current_sid: int
@dataclasses.dataclass
class SetSidMsg(Msg):
value: int
class BMMsg(Msg):
def __init__(self, t: int, data: bytes):
@ -204,3 +216,14 @@ class BMMsg(Msg):
class RobotRtsiMsg(Msg):
pos: tuple[float, float, float, float, float, float]
force: tuple[float, float, float, float, float, float]
def test():
values = set(item.name for item in BG)
for k in globals().keys():
if k.endswith('Msg') and k not in ['Msg','BoolMsg']:
if k not in values:
raise RuntimeError(f"Unknown msg type: {k}")
test()

View File

@ -138,3 +138,7 @@ class RfMat:
def rotate90(self):
return self.copy(self.p.rot90(self.m, k=3))
if __name__ == '__main__':
cp.zeros((1, 2, 3)) + 1

View File

@ -6,28 +6,26 @@ from attr import dataclass
COMMIT_KEY = 'COMMIT'
class RfMeta:
@classmethod
@property
def p2a(clz):
gh = get_type_hints(clz, include_extras=True)
return {k: gh[k].__metadata__[0] for k in gh}
@classmethod
@property
def p2t(clz):
return get_type_hints(clz)
@classmethod
@property
def a2p(clz):
return {v: k for k, v in clz.p2a.items()}
return {v: k for k, v in clz.p2a().items()}
@property
def name(self):
p2a = self.p2a
p2t = self.p2t
a2p = self.a2p
p2a = self.p2a()
p2t = self.p2t()
a2p = self.a2p()
arr = []
if COMMIT_KEY in a2p:
cp = a2p[COMMIT_KEY]
@ -64,8 +62,8 @@ class RfMeta:
@classmethod
def from_name(clz, name: str):
p2t = clz.p2t
a2p = clz.a2p
p2t = clz.p2t()
a2p = clz.a2p()
c = clz()
sp = name.split(',')
if COMMIT_KEY in a2p:
@ -92,6 +90,7 @@ class RfFrameMeta(RfMeta):
robot_y: Annotated[int, 'Y'] = None
robot_z: Annotated[int, 'Z'] = None
@dataclass
class RfSequenceMeta(RfMeta):
class RfSequenceMode(Enum):
@ -102,3 +101,8 @@ class RfSequenceMeta(RfMeta):
shape: Annotated[tuple, 'S'] = None
mode: Annotated[RfSequenceMode, 'M'] = RfSequenceMode.PWI
us: Annotated[int, 'U'] = None
if __name__ == '__main__':
r = RfSequenceMeta.from_name('asdasd1,S=(64 1501),M=PWI,U=30')
print(r)

41
test/kdemain.py Normal file
View File

@ -0,0 +1,41 @@
import logging
import multiprocessing
from BusClient import BusClient
from nodes.Beamformer import Beamformer
from nodes.Broker import Broker
from nodes.Device import Device
from nodes.ImageCV import ImageCV
from nodes.Loader import Loader
from nodes.Robot import Robot
from nodes.WebRTC import WebRTC
from qtonly import kde_pyqt6_mainui
from utils.Msg import KillMsg
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
multiprocessing.set_start_method('spawn')
multiprocessing.Pool()
pps = []
ps = [
Broker(),
WebRTC(),
kde_pyqt6_mainui,
Device(level=logging.DEBUG),
ImageCV(level=logging.DEBUG),
Beamformer(),
Loader(),
Robot(),
]
for p in ps:
pps.append(multiprocessing.Process(target=p))
for p in pps:
p.start()
c = BusClient(KillMsg)
while True:
x: KillMsg = c.recv()
if x.name == '':
break
for p in pps:
p.kill()

23
test/qtonly.py Normal file
View File

@ -0,0 +1,23 @@
import logging
import logging
import os
import subprocess
from PyQt6 import QtWidgets
from nodes.MainUI import MainUI
def kde_pyqt6_mainui():
subprocess.run(['python', __file__],
env=dict(XDG_CURRENT_DESKTOP="KDE",
XDG_RUNTIME_DIR="/run/user/1000",
XDG_SESSION_TYPE="wayland",
PYTHONPATH=os.environ['PYTHONPATH'])
)
if __name__ == '__main__':
print(QtWidgets.QStyleFactory.keys())
logging.basicConfig(level=logging.INFO)
MainUI()()

6
test/so.py Normal file
View File

@ -0,0 +1,6 @@
from ctypes import CDLL
if __name__ == '__main__':
# libc = CDLL("libnvrtc.alt.so.12")
libc = CDLL("libnvrtc.so.12")
# print(libc.__dir__())

59
uv.lock
View File

@ -1,4 +1,5 @@
version = 1
revision = 1
requires-python = ">=3.12"
resolution-markers = [
"sys_platform == 'darwin'",
@ -11,7 +12,7 @@ resolution-markers = [
[manifest]
overrides = [
{ name = "av", marker = "sys_platform != 'linux' and sys_platform != 'win32'", specifier = ">=14.0.0" },
{ name = "av", marker = "sys_platform == 'linux'", path = "av-14.1.0-cp312-cp312-linux_amd64.whl" },
{ name = "av", marker = "sys_platform == 'linux'", path = "av-14.1.0-cp312-cp312-linux_x86_64.whl" },
{ name = "av", marker = "sys_platform == 'win32'", path = "av-14.1.0-cp312-cp312-win_amd64.whl" },
]
@ -103,7 +104,7 @@ source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "aioice" },
{ name = "av", version = "14.1.0", source = { registry = "https://pypi.org/simple" }, marker = "sys_platform != 'linux' and sys_platform != 'win32'" },
{ name = "av", version = "14.1.0", source = { path = "av-14.1.0-cp312-cp312-linux_amd64.whl" }, marker = "sys_platform == 'linux'" },
{ name = "av", version = "14.1.0", source = { path = "av-14.1.0-cp312-cp312-linux_x86_64.whl" }, marker = "sys_platform == 'linux'" },
{ name = "av", version = "14.1.0", source = { path = "av-14.1.0-cp312-cp312-win_amd64.whl" }, marker = "sys_platform == 'win32'" },
{ name = "cffi" },
{ name = "cryptography" },
@ -250,11 +251,24 @@ wheels = [
[[package]]
name = "av"
version = "14.1.0"
source = { path = "av-14.1.0-cp312-cp312-linux_amd64.whl" }
source = { path = "av-14.1.0-cp312-cp312-linux_x86_64.whl" }
resolution-markers = [
"platform_machine == 'aarch64' and sys_platform == 'linux'",
"platform_machine != 'aarch64' and sys_platform == 'linux'",
]
dependencies = [
{ name = "cython", marker = "sys_platform == 'linux'" },
{ name = "setuptools", marker = "sys_platform == 'linux'" },
]
wheels = [
{ filename = "av-14.1.0-cp312-cp312-linux_x86_64.whl", hash = "sha256:1fbd7c5d3194fbe88f1d4ffa3a34e130e0ea743fed7b7c1f59b0db75142e4bee" },
]
[package.metadata]
requires-dist = [
{ name = "cython", specifier = ">=3.0.12" },
{ name = "setuptools", specifier = ">=75.8.0" },
]
[[package]]
name = "av"
@ -263,8 +277,18 @@ source = { path = "av-14.1.0-cp312-cp312-win_amd64.whl" }
resolution-markers = [
"sys_platform == 'win32'",
]
dependencies = [
{ name = "cython", marker = "sys_platform == 'win32'" },
{ name = "setuptools", marker = "sys_platform == 'win32'" },
]
wheels = [
{ filename = "av-14.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:455065d7e423393a4ebcde38873d263288f6dd14ed2d00313422938e2cef6718" },
{ filename = "av-14.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:1fbd7c5d3194fbe88f1d4ffa3a34e130e0ea743fed7b7c1f59b0db75142e4bee" },
]
[package.metadata]
requires-dist = [
{ name = "cython", specifier = ">=3.0.12" },
{ name = "setuptools", specifier = ">=75.8.0" },
]
[[package]]
@ -510,6 +534,29 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321 },
]
[[package]]
name = "cython"
version = "3.0.12"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/5a/25/886e197c97a4b8e254173002cdc141441e878ff29aaa7d9ba560cd6e4866/cython-3.0.12.tar.gz", hash = "sha256:b988bb297ce76c671e28c97d017b95411010f7c77fa6623dd0bb47eed1aee1bc", size = 2757617 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ee/ab/adfeb22c85491de18ae10932165edd5b6f01e4c5e3e363638759d1235015/Cython-3.0.12-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7fec4f052b8fe173fe70eae75091389955b9a23d5cec3d576d21c5913b49d47", size = 3344337 },
{ url = "https://files.pythonhosted.org/packages/0d/72/743730d7c46b4c85abefb93187cbbcb7aae8de288d7722b990db3d13499e/Cython-3.0.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0faa5e39e5c8cdf6f9c3b1c3f24972826e45911e7f5b99cf99453fca5432f45e", size = 3517692 },
{ url = "https://files.pythonhosted.org/packages/09/a1/29a4759a02661f8c8e6b703f62bfbc8285337e6918cc90f55dc0fadb5eb3/Cython-3.0.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d53de996ed340e9ab0fc85a88aaa8932f2591a2746e1ab1c06e262bd4ec4be7", size = 3577057 },
{ url = "https://files.pythonhosted.org/packages/d6/f8/03d74e98901a7cc2f21f95231b07dd54ec2f69477319bac268b3816fc3a8/Cython-3.0.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ea3a0e19ab77266c738aa110684a753a04da4e709472cadeff487133354d6ab8", size = 3396493 },
{ url = "https://files.pythonhosted.org/packages/50/ea/ac33c5f54f980dbc23dd8f1d5c51afeef26e15ac1a66388e4b8195af83b7/Cython-3.0.12-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c151082884be468f2f405645858a857298ac7f7592729e5b54788b5c572717ba", size = 3603859 },
{ url = "https://files.pythonhosted.org/packages/a2/4e/91fc1d6b5e678dcf2d1ecd8dce45b014b4b60d2044d376355c605831c873/Cython-3.0.12-cp312-cp312-win32.whl", hash = "sha256:3083465749911ac3b2ce001b6bf17f404ac9dd35d8b08469d19dc7e717f5877a", size = 2610428 },
{ url = "https://files.pythonhosted.org/packages/ff/c3/a7fdec227b9f0bb07edbeb016c7b18ed6a8e6ce884d08b2e397cda2c0168/Cython-3.0.12-cp312-cp312-win_amd64.whl", hash = "sha256:c0b91c7ebace030dd558ea28730de8c580680b50768e5af66db2904a3716c3e3", size = 2794755 },
{ url = "https://files.pythonhosted.org/packages/34/de/ade0a80bea17197662e23d39d3d3fbf89e9e99e6ad91fd95ab87120edb3a/Cython-3.0.12-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57aefa6d3341109e46ec1a13e3a763aaa2cbeb14e82af2485b318194be1d9170", size = 3367198 },
{ url = "https://files.pythonhosted.org/packages/a8/30/7f48207ea13dab46604db0dd388e807d53513ba6ad1c34462892072f8f8c/Cython-3.0.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:879ae9023958d63c0675015369384642d0afb9c9d1f3473df9186c42f7a9d265", size = 3535849 },
{ url = "https://files.pythonhosted.org/packages/81/ab/f61c79fa14bd433a7dfd1548c5e00d9bd18b557c2f836aaece4fb1b22f34/Cython-3.0.12-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:36fcd584dae547de6f095500a380f4a0cce72b7a7e409e9ff03cb9beed6ac7a1", size = 3559079 },
{ url = "https://files.pythonhosted.org/packages/d0/d1/1dbf17061229ccd35d5c0eed659fab60c2e50d2eadfa2a5729e753b6f4d0/Cython-3.0.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:62b79dcc0de49efe9e84b9d0e2ae0a6fc9b14691a65565da727aa2e2e63c6a28", size = 3436649 },
{ url = "https://files.pythonhosted.org/packages/2d/d4/9ce42fff6de5550f870cdde9a1482d69ea66a1249a88fa0d0df9adebfb1a/Cython-3.0.12-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4aa255781b093a8401109d8f2104bbb2e52de7639d5896aefafddc85c30e0894", size = 3644025 },
{ url = "https://files.pythonhosted.org/packages/e3/89/b0c847f9df92af3ef11281b6811c000bd6f8ce0db02e4374397f8d67f829/Cython-3.0.12-cp313-cp313-win32.whl", hash = "sha256:77d48f2d4bab9fe1236eb753d18f03e8b2619af5b6f05d51df0532a92dfb38ab", size = 2604911 },
{ url = "https://files.pythonhosted.org/packages/a6/5f/bbfaf2b5f7bf78854ecbc82f8473a3892ae5580e0c5bd0d4a82580b39ed3/Cython-3.0.12-cp313-cp313-win_amd64.whl", hash = "sha256:86c304b20bd57c727c7357e90d5ba1a2b6f1c45492de2373814d7745ef2e63b4", size = 2786786 },
{ url = "https://files.pythonhosted.org/packages/27/6b/7c87867d255cbce8167ed99fc65635e9395d2af0f0c915428f5b17ec412d/Cython-3.0.12-py2.py3-none-any.whl", hash = "sha256:0038c9bae46c459669390e53a1ec115f8096b2e4647ae007ff1bf4e6dee92806", size = 1171640 },
]
[[package]]
name = "darkdetect"
version = "0.8.0"
@ -603,7 +650,7 @@ dependencies = [
{ name = "aiohttp-cors" },
{ name = "aiortc" },
{ name = "av", version = "14.1.0", source = { registry = "https://pypi.org/simple" }, marker = "sys_platform != 'linux' and sys_platform != 'win32'" },
{ name = "av", version = "14.1.0", source = { path = "av-14.1.0-cp312-cp312-linux_amd64.whl" }, marker = "sys_platform == 'linux'" },
{ name = "av", version = "14.1.0", source = { path = "av-14.1.0-cp312-cp312-linux_x86_64.whl" }, marker = "sys_platform == 'linux'" },
{ name = "av", version = "14.1.0", source = { path = "av-14.1.0-cp312-cp312-win_amd64.whl" }, marker = "sys_platform == 'win32'" },
{ name = "cupy-cuda12x" },
{ name = "jupyter" },
@ -621,7 +668,7 @@ requires-dist = [
{ name = "aiohttp-cors", specifier = ">=0.7.0" },
{ name = "aiortc", specifier = ">=1.9.0" },
{ name = "av", marker = "sys_platform != 'linux' and sys_platform != 'win32'" },
{ name = "av", marker = "sys_platform == 'linux'", path = "av-14.1.0-cp312-cp312-linux_amd64.whl" },
{ name = "av", marker = "sys_platform == 'linux'", path = "av-14.1.0-cp312-cp312-linux_x86_64.whl" },
{ name = "av", marker = "sys_platform == 'win32'", path = "av-14.1.0-cp312-cp312-win_amd64.whl" },
{ name = "cupy-cuda12x", specifier = ">=13.3.0" },
{ name = "jupyter", specifier = ">=1.1.1" },