This commit is contained in:
flandre 2025-01-19 18:27:26 +08:00
parent f76fdf699f
commit 492a0df8b7
17 changed files with 1071 additions and 282 deletions

View File

@ -1,14 +1,21 @@
from pathlib import Path from pathlib import Path
SOCKET1 = '127.0.0.1:5003' PLAYBACK_SOCKET_PORT = 5003
PLAYBACK_SOCKET = f'127.0.0.1:{PLAYBACK_SOCKET_PORT}'
LIVE_SOCKET_IP = '11.6.1.66'
LIVE_REP_SOCKET_PORT = 5556
LIVE_SOCKET = f'{LIVE_SOCKET_IP}:5555'
LIVE_REP_SOCKET = f'{LIVE_SOCKET_IP}:{LIVE_REP_SOCKET_PORT}'
VIDEO_HEIGHT = 1920 VIDEO_HEIGHT = 1920
VIDEO_WIDTH = 1080 VIDEO_WIDTH = 1080
BASE = Path(__file__).parent.parent BASE = Path(__file__).parent.parent
DS = BASE / '@DS' DS = BASE / '@DS'
DOC = BASE / 'doc' DOC = BASE / 'doc'
CONFIG = BASE / 'config'
DS.mkdir(exist_ok=True, parents=True) DS.mkdir(exist_ok=True, parents=True)
DOC.mkdir(exist_ok=True, parents=True) DOC.mkdir(exist_ok=True, parents=True)
CONFIG.mkdir(exist_ok=True, parents=True)
CONFIG_FOLDER = BASE / 'config' CONFIG_FOLDER = BASE / 'config'
LAST_CONFIG = BASE / 'config' / 'last_imaging_config.json' LAST_CONFIG = BASE / 'config' / 'last_imaging_config.json'

39
src/main.py Normal file
View File

@ -0,0 +1,39 @@
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.MainUI import MainUI
from nodes.WebRTC import WebRTC
from utils.Msg import KillMsg
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
multiprocessing.set_start_method('spawn')
multiprocessing.Pool()
pps = []
ps = [
Broker(),
WebRTC(),
MainUI(),
Device(),
ImageCV(),
Beamformer(),
Loader(),
]
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()

View File

@ -1,56 +1,83 @@
import logging
import struct
import cupy as cp
import cv2 import cv2
import numpy as np import numpy as np
import zmq import zmq
from utils.Msg import BMMsg, ImageArgMsg, KillMsg from config import PLAYBACK_SOCKET, VIDEO_WIDTH, VIDEO_HEIGHT, LIVE_SOCKET
from config import SOCKET1, VIDEO_WIDTH, VIDEO_HEIGHT
from nodes.Node import Node from nodes.Node import Node
from utils.Msg import BMMsg, ImageArgMsg, KillMsg, SeqMetaMsg, SetPlayMode, SetDeviceConfigMsg
from utils.RfFile import RfFrame, RfSequenceMeta from utils.RfFile import RfFrame, RfSequenceMeta
from utils.RfMat import RfMat from utils.RfMat import RfMat
logger = logging.getLogger(__name__)
class Beamformer(Node): class Beamformer(Node):
topics = [ImageArgMsg] topics = [ImageArgMsg, SeqMetaMsg, SetPlayMode, SetDeviceConfigMsg]
def __init__(self): def __init__(self):
super(Beamformer, self).__init__() super(Beamformer, self).__init__()
self.arg = ImageArgMsg('', 1400) self.arg = ImageArgMsg('', v1=1499)
self.seq_meta = None
def process(self, data: bytes): def process(self, data: RfMat):
if data is None: if data is None:
return return
b = np.frombuffer(data, dtype=np.int16) d2 = (data
b = b.reshape((256, 1502)).astype(np.float32) .crop1(self.arg.v1)
b = b[:, :self.arg.v1] .rotate90()
b -= b.min() .grey()
b /= b.max() .cpu()
b *= 255 .resize((VIDEO_WIDTH, VIDEO_HEIGHT))
b = b.astype(np.uint8) .watermark()
b = cv2.rotate(b, cv2.ROTATE_90_CLOCKWISE) .call(cv2.cvtColor, cv2.COLOR_GRAY2RGBA)
b = cv2.resize(b, (VIDEO_WIDTH, VIDEO_HEIGHT)) )
b = cv2.cvtColor(b, cv2.COLOR_GRAY2RGBA, b) self.send(BMMsg(0, d2.__bytes__()))
self.send(BMMsg(0, b.tobytes()))
def loop(self): def loop(self):
s2 = self.context.socket(zmq.PULL) device_socket = self.context.socket(zmq.PULL)
s2.setsockopt(zmq.CONFLATE, 1) device_socket.setsockopt(zmq.CONFLATE, 1)
s2.connect(f"tcp://{SOCKET1}") device_socket.connect(f"tcp://{PLAYBACK_SOCKET}")
self.c.poller.register(s2, zmq.POLLIN) self.c.poller.register(device_socket, zmq.POLLIN)
buffer = None # RfSequenceMeta(
# commit='test',
# shape=(256, 1502),
# mode=RfSequenceMeta.RfSequenceMode.PWI,
# us=30
# )
mat = None
while True: while True:
socks = dict(self.c.poller.poll()) socks = dict(self.c.poller.poll())
if s2 in socks and socks[s2] == zmq.POLLIN: if device_socket in socks and socks[device_socket] == zmq.POLLIN:
buffer = s2.recv() buffer = device_socket.recv()
_, sequence_id, encoder = struct.unpack_from('=iqi', buffer)
RfMat(1, RfFrame.RfFrameMeta( s = buffer[4 + 8 + 4:]
1, 1 if self.seq_meta is not None:
), RfSequenceMeta()) fb1 = cp.frombuffer(s, dtype=cp.int16)
if fb1.shape[0] == np.prod(self.seq_meta.shape):
mat = RfMat(fb1.reshape(self.seq_meta.shape), RfFrame.RfFrameMeta(
encoder=encoder,
sequence_id=sequence_id,
), self.seq_meta)
if self.c.sub in socks and socks[self.c.sub] == zmq.POLLIN: if self.c.sub in socks and socks[self.c.sub] == zmq.POLLIN:
r = self.recv() msg = self.recv()
if isinstance(r, KillMsg): if isinstance(msg, KillMsg):
if r.name == '': if msg.name == '':
return return
if isinstance(r, ImageArgMsg): if isinstance(msg, SeqMetaMsg):
self.arg = r self.seq_meta = RfSequenceMeta.from_name(msg.s)
self.process(buffer) if isinstance(msg, ImageArgMsg):
self.arg = msg
if isinstance(msg, SetPlayMode):
if msg.value == 'live':
device_socket.disconnect(f"tcp://{PLAYBACK_SOCKET}")
device_socket.connect(f"tcp://{LIVE_SOCKET}")
elif msg.value == 'playback':
device_socket.disconnect(f"tcp://{LIVE_SOCKET}")
device_socket.connect(f"tcp://{PLAYBACK_SOCKET}")
self.process(mat)

View File

@ -1,63 +0,0 @@
import logging
import threading
from abc import abstractmethod
import zmq
from zmq import Context, Socket
from clients.Msg import Msg, KillMsg
class BusClient:
fp = 5001
bp = 5002
topics = [KillMsg.eid()]
def __init__(self, enable_init=True):
self.context: Context = None
self.pub_socket: Socket = None
self.sub_socket: Socket = None
self.enable_init = enable_init
self.isalive = True
# def recv(self):
# return self.sub_socket.recv()
#
# def send(self, msg):
# return self.pub_socket.send(msg)
def recv(self):
b = self.sub_socket.recv()
return Msg.decode_msg(b)
def send(self, msg: Msg):
return self.pub_socket.send(msg.encode_msg())
@abstractmethod
def loop(self):
pass
def __call__(self, *args, **kwargs):
logging.basicConfig(level=logging.INFO)
self.context = zmq.Context()
if self.enable_init:
self.pub_socket = self.context.socket(zmq.PUB)
self.pub_socket.connect(f"tcp://127.0.0.1:{self.fp}")
self.sub_socket = self.context.socket(zmq.SUB)
self.sub_socket.connect(f"tcp://127.0.0.1:{self.bp}")
if not self.topics:
self.sub_socket.setsockopt(zmq.SUBSCRIBE, b'')
else:
for topic in self.topics:
print(f"{self.__class__.__name__} Subscribing to topic {topic}")
self.sub_socket.setsockopt(zmq.SUBSCRIBE, topic)
self.loop()
print(self.__class__.__name__, 'exiting')
@classmethod
def sub(cls, ctx, *msgs: type(Msg)):
s = ctx.socket(zmq.SUB)
for msg in msgs:
s.setsockopt(zmq.SUBSCRIBE, msg.eid())
s.connect(f'tcp://127.0.0.1:{cls.bp}')
return s

130
src/nodes/Device.py Normal file
View File

@ -0,0 +1,130 @@
import logging
import time
import requests
import zmq
import subprocess
from config import LIVE_REP_SOCKET, LIVE_SOCKET_IP, LIVE_REP_SOCKET_PORT, CONFIG
from nodes.Node import Node
from utils.Msg import ImageArgMsg, KillMsg, SeqMetaMsg, SetDeviceConnectedMsg, SetDeviceEnabledMsg, DeviceEnabledMsg, \
DeviceConnectedMsg, SetDeviceConfigMsg, DeviceOnlineMsg, DeviceConfigListMsg
from utils.RfFile import RfSequenceMeta
import socket
logger = logging.getLogger(__name__)
class Device(Node):
topics = [SetDeviceConnectedMsg, SetDeviceEnabledMsg, SetDeviceConfigMsg]
def __init__(self):
super(Device, self).__init__()
self.arg = ImageArgMsg('', v1=1499)
self.seq_meta = None
self.device_rep_socket = None
self.ok = b'ok\x00'
def connect(self):
self.device_rep_socket.send(b'connect')
rb = self.device_rep_socket.recv()
if rb == self.ok:
self.send(DeviceConnectedMsg(True))
else:
logger.error(f"Device msg: {rb}")
def disconnect(self):
self.device_rep_socket.send(b'disconnect')
rb = self.device_rep_socket.recv()
if rb == self.ok:
self.send(DeviceConnectedMsg(False))
else:
logger.error(f"Device msg: {rb}")
def enable(self):
self.device_rep_socket.send(b'enable')
rb = self.device_rep_socket.recv()
if rb == self.ok:
self.send(DeviceEnabledMsg(True))
else:
logger.error(f"Device msg: {rb}")
def disable(self):
self.device_rep_socket.send(b'disable')
rb = self.device_rep_socket.recv()
if rb == self.ok:
self.send(DeviceEnabledMsg(False))
else:
logger.error(f"Device msg: {rb}")
def online(self):
code = subprocess.run(['curl', '-m', '1', 'http://11.6.1.66:22'], stderr=subprocess.DEVNULL,
stdout=subprocess.DEVNULL).returncode
if code == 28:
self.send(DeviceOnlineMsg(False))
return False
else:
self.send(DeviceOnlineMsg(True))
return True
def enabled(self):
self.device_rep_socket.send(b'enabled')
rb = self.device_rep_socket.recv()
match rb:
case b'true':
self.send(DeviceEnabledMsg(True))
case b'false':
self.send(DeviceEnabledMsg(False))
case _:
logger.error(f"Device msg: {rb}")
def connected(self):
self.device_rep_socket.send(b'connected')
rb = self.device_rep_socket.recv()
match rb:
case b'true':
self.send(DeviceConnectedMsg(True))
case b'false':
self.send(DeviceConnectedMsg(False))
case _:
logger.error(f"Device msg: {rb}")
def setfile(self, s: str):
self.device_rep_socket.send(b'file' + s.encode())
rb = self.device_rep_socket.recv()
if rb == self.ok:
pass
# self.send(DeviceConnectedMsg(True))
else:
logger.error(f"Device msg: {rb}")
def loop(self):
arr = []
self.device_rep_socket = self.context.socket(zmq.REQ)
self.device_rep_socket.connect(f"tcp://{LIVE_REP_SOCKET}")
time.sleep(1)
if self.online():
self.connected()
self.enabled()
for f in CONFIG.glob('*.txt'):
arr.append((f.stem, f.read_text()))
self.send(DeviceConfigListMsg(arr))
if arr.__len__() > 0:
self.setfile(arr[0][1])
while True:
msg = self.recv()
if isinstance(msg, KillMsg):
if msg.name == '':
return
elif isinstance(msg, SetDeviceEnabledMsg):
if msg.value:
self.enable()
else:
self.disable()
elif isinstance(msg, SetDeviceConnectedMsg):
if msg.value:
self.connect()
else:
self.disconnect()
elif isinstance(msg, SetDeviceConfigMsg):
self.setfile(msg.value)

View File

@ -1,26 +1,48 @@
import io
import logging
import struct
from pathlib import Path
import zmq import zmq
from utils.RfFile import RfFolder from config import PLAYBACK_SOCKET_PORT
from utils.Msg import MoveAxisMsg, KillMsg from utils.RfFile import RfFolder, RfSequence
from utils.Msg import MoveAxisMsg, KillMsg, SelectSeqMsg, SeqMetaMsg, SeqIdMinMax, SetBaseMsg, SeqListMsg
from nodes.Node import Node from nodes.Node import Node
logger = logging.getLogger(__name__)
class Loader(Node): class Loader(Node):
topics = [MoveAxisMsg] topics = [MoveAxisMsg, SelectSeqMsg, SetBaseMsg]
def loop(self): def loop(self):
s2 = self.context.socket(zmq.PUSH) s2 = self.context.socket(zmq.PUSH)
s2.bind("tcp://*:5003") s2.bind(f"tcp://*:{PLAYBACK_SOCKET_PORT}")
rff = RfFolder.from_path('/run/media/lambda/b86dccdc-f134-464b-a310-6575ee9ae85c/cap4/trim/R1,L=30,C=PAR') # base = Path('/mnt/16T/private_dataset/us/')
all_files = rff.all base: Path | None = None
rff = None
while True: while True:
r = self.recv() r = self.recv()
if isinstance(r, MoveAxisMsg): if isinstance(r, MoveAxisMsg) and rff is not None:
for f in all_files: logger.debug(f'Move axis: {rff}')
if f.S == r.value: for frame in rff.frames:
# s2.send(np.zeros((256, 1500), dtype=np.uint16).tobytes()) if frame.meta.sequence_id == r.value:
s2.send(f.path.read_bytes()) buffer = io.BytesIO()
buffer.write(struct.pack('=iqi', 114514, frame.meta.sequence_id, frame.meta.encoder))
buffer.write(frame.bytes)
s2.send(buffer.getvalue())
elif isinstance(r, SelectSeqMsg):
if base is None:
continue
rff = RfSequence.from_folder(base / r.value)
self.send(SeqMetaMsg(rff.meta.name))
self.send(SeqIdMinMax(*rff.seq_id_minmax))
elif isinstance(r, SetBaseMsg):
base = Path(r.value)
self.send(SeqListMsg([f.name for f in base.glob('*')]))
elif isinstance(r, KillMsg): elif isinstance(r, KillMsg):
if r.name == '': if r.name == '':
break break

View File

@ -1,13 +1,17 @@
import logging
import sys import sys
from PyQt6 import QtCore from PyQt6 import QtCore
from PyQt6.QtCore import QByteArray from PyQt6.QtCore import QByteArray
from PyQt6.QtWidgets import QMainWindow, QApplication from PyQt6.QtWidgets import QMainWindow, QApplication, QFrame
from Main import Ui_MainWindow from Main import Ui_MainWindow
from utils.Msg import KillMsg, Msg, ImageArgMsg from utils.Msg import KillMsg, Msg, ImageArgMsg, SelectSeqMsg, SeqIdMinMax, MoveAxisMsg, SeqListMsg, SetBaseMsg, \
SeqMetaMsg, SetPlayMode, DeviceConnectedMsg, DeviceEnabledMsg, DeviceOnlineMsg, SetDeviceEnabledMsg, \
SetDeviceConnectedMsg, DeviceConfigListMsg, SetDeviceConfigMsg
from ZMQReceiver import ZMQReceiver from ZMQReceiver import ZMQReceiver
from nodes.Node import Node from nodes.Node import Node
from utils.RfFile import RfSequenceMeta
class Adv(QMainWindow, Ui_MainWindow): class Adv(QMainWindow, Ui_MainWindow):
@ -19,6 +23,48 @@ class Adv(QMainWindow, Ui_MainWindow):
zmq_receiver.zmq_event.connect(self.on_zmq_event) zmq_receiver.zmq_event.connect(self.on_zmq_event)
zmq_receiver.start() zmq_receiver.start()
self.horizontalSlider.valueChanged.connect(self.vc) self.horizontalSlider.valueChanged.connect(self.vc)
self.comboBox.currentIndexChanged.connect(self.cbc)
self.s_sid.valueChanged.connect(self.c_sid)
self.arg = ImageArgMsg('ui', v1=1499)
self.b_base.clicked.connect(lambda: self.p.send(SetBaseMsg(self.l_base.text())))
self.seq_meta: RfSequenceMeta | None = None
self.b_exit.clicked.connect(lambda: self.p.send(KillMsg('')))
self.b_play_live.clicked.connect(self.on_play_live)
self.b_play_playback.clicked.connect(self.on_play_playback)
self.b_record.clicked.connect(self.on_record)
self.record = False
self.device_connected = False
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_m)
def on_play_live(self):
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(self.c_seq_meta.itemText(self.c_seq_meta.currentIndex())))
self.p.send(SetPlayMode('live'))
self.comboBox.setEnabled(False)
def on_play_playback(self):
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(self.comboBox.itemText(self.comboBox.currentIndex())))
self.p.send(SetPlayMode('playback'))
self.comboBox.setEnabled(True)
def on_record(self):
if self.record:
self.record = False
self.b_record.setStyleSheet('')
else:
self.record = True
self.b_record.setStyleSheet('background-color: red;')
def on_zmq_event(self, msg: QByteArray): def on_zmq_event(self, msg: QByteArray):
msg = Msg.decode_msg(msg.data()) msg = Msg.decode_msg(msg.data())
@ -27,18 +73,80 @@ class Adv(QMainWindow, Ui_MainWindow):
self.close() self.close()
elif isinstance(msg, ImageArgMsg): elif isinstance(msg, ImageArgMsg):
self.horizontalSlider.setValue(msg.v1) self.horizontalSlider.setValue(msg.v1)
elif isinstance(msg, MoveAxisMsg):
match msg.axis:
case 'S':
self.s_sid.setValue(msg.value)
elif isinstance(msg, SeqIdMinMax):
self.s_sid.setMinimum(msg.min)
self.s_sid.setMaximum(msg.max)
self.s_sid.setValue(msg.min)
elif isinstance(msg, SeqListMsg):
self.comboBox.setEnabled(True)
self.comboBox.clear()
for name in msg.value:
self.comboBox.addItem(name)
self.p.send(SelectSeqMsg(self.comboBox.itemText(self.comboBox.currentIndex())))
self.b_play_playback.setEnabled(True)
elif isinstance(msg, SeqMetaMsg):
self.seq_meta = RfSequenceMeta.from_name(msg.s)
self.horizontalSlider.setMaximum(max(self.seq_meta.shape))
elif isinstance(msg, DeviceConnectedMsg):
if msg.value:
self.b_device_connected.setStyleSheet("background-color: red;")
self.device_connected = True
else:
self.b_device_connected.setStyleSheet("")
self.device_connected = False
elif isinstance(msg, DeviceEnabledMsg):
if msg.value:
self.b_device_enabled.setStyleSheet("background-color: red;")
self.device_enabled = True
else:
self.b_device_enabled.setStyleSheet("")
self.device_enabled = False
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)
@QtCore.pyqtSlot(int) @QtCore.pyqtSlot(int)
def vc(self, v): def vc(self, v):
if self.horizontalSlider.sender() is None: if self.horizontalSlider.sender() is None:
self.p.send(ImageArgMsg('ui', v)) self.arg.v1 = v
self.p.send(self.arg)
@QtCore.pyqtSlot(int)
def cbc(self, v):
if self.comboBox.sender() is None:
self.p.send(SelectSeqMsg(self.comboBox.itemText(v)))
@QtCore.pyqtSlot(int)
def c_sid(self, v):
if self.s_sid.sender() is None:
self.p.send(MoveAxisMsg('ui', 'S', v))
@QtCore.pyqtSlot(int)
def on_m(self, v):
if self.c_seq_meta.sender() is None or isinstance(self.c_seq_meta.sender(), QFrame):
self.p.send(SetDeviceConfigMsg(self.c_seq_meta.itemData(v)))
self.p.send(SeqMetaMsg(self.c_seq_meta.itemText(v)))
class MainUI(Node): class MainUI(Node):
topics = [ImageArgMsg] topics = [ImageArgMsg, SeqIdMinMax, MoveAxisMsg,
SeqListMsg, SeqMetaMsg,
DeviceConnectedMsg, DeviceEnabledMsg, DeviceOnlineMsg, DeviceConfigListMsg]
def __init__(self): def __init__(self, level=logging.INFO):
super().__init__() super().__init__(level=level)
def loop(self): def loop(self):
app = QApplication(sys.argv) app = QApplication(sys.argv)

View File

@ -12,9 +12,10 @@ class Node:
bp = BusClient.bp bp = BusClient.bp
topics = [] topics = []
def __init__(self, enable_init=True): def __init__(self, enable_init=True, level=logging.INFO):
self.enable_init = enable_init self.enable_init = enable_init
self.isalive = True self.isalive = True
self.level = level
def recv(self): def recv(self):
return self.c.recv() return self.c.recv()
@ -27,7 +28,7 @@ class Node:
pass pass
def __call__(self, *args, **kwargs): def __call__(self, *args, **kwargs):
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=self.level)
self.context = zmq.Context() self.context = zmq.Context()
if self.enable_init: if self.enable_init:
self.c = BusClient(*([KillMsg] + self.topics), poller=True) self.c = BusClient(*([KillMsg] + self.topics), poller=True)

View File

@ -1,8 +1,7 @@
import asyncio import asyncio
import json import json
import logging
import os import os
import zmq.asyncio
import time import time
from fractions import Fraction from fractions import Fraction
@ -11,20 +10,21 @@ import aiohttp_cors
import aiortc.rtcrtpsender import aiortc.rtcrtpsender
import numpy as np import numpy as np
import zmq import zmq
import zmq.asyncio
from aiohttp import web, WSMessage from aiohttp import web, WSMessage
from aiortc import MediaStreamTrack, RTCPeerConnection, RTCSessionDescription, RTCConfiguration, RTCRtpCodecCapability from aiortc import MediaStreamTrack, RTCPeerConnection, RTCSessionDescription, RTCConfiguration, RTCRtpCodecCapability
from av import VideoFrame from av import VideoFrame
import H264NV import H264NV
from BusClient import BusClient from BusClient import BusClient
from utils.Msg import BMMsg, Msg, KillMsg, MoveAxisMsg, ImageArgMsg
from config import VIDEO_WIDTH, VIDEO_HEIGHT from config import VIDEO_WIDTH, VIDEO_HEIGHT
from utils.Msg import BMMsg, Msg, KillMsg, MoveAxisMsg, ImageArgMsg, SeqIdMinMax
ROOT = os.path.dirname(__file__) ROOT = os.path.dirname(__file__)
from nodes.Node import Node from nodes.Node import Node
web.WebSocketResponse() web.WebSocketResponse()
logger = logging.getLogger(__name__)
def generate_placeholder(): def generate_placeholder():
@ -95,9 +95,9 @@ class WebRTC(Node):
await asyncio.gather(*coros) await asyncio.gather(*coros)
pcs.clear() pcs.clear()
async def t3(ws, name): async def ws_send(ws, name):
# s = BusClient.sub(zmq.asyncio.Context(), KillMsg, TickMsg) # s = BusClient.sub(zmq.asyncio.Context(), KillMsg, TickMsg)
c = BusClient(KillMsg, ImageArgMsg, ctx=zmq.asyncio.Context(), pub=False) c = BusClient(KillMsg, ImageArgMsg, SeqIdMinMax, MoveAxisMsg, ctx=zmq.asyncio.Context(), pub=False)
while True: while True:
msg = await c.recv_async() msg = await c.recv_async()
if isinstance(msg, KillMsg): if isinstance(msg, KillMsg):
@ -111,8 +111,22 @@ class WebRTC(Node):
await ws.send_str(json.dumps(dict( await ws.send_str(json.dumps(dict(
type='Arg', value=dc type='Arg', value=dc
))) )))
if isinstance(msg, SeqIdMinMax):
await ws.send_str(json.dumps(dict(
type='SeqIdMinMax', value=dict(
min=msg.min,
max=msg.max,
)
)))
if isinstance(msg, MoveAxisMsg):
if name != msg.sender:
dc = msg.__dict__.copy()
del dc['sender']
await ws.send_str(json.dumps(dict(
type='MoveAxisMsg', value=dc
)))
async def t4(ws, name): async def ws_recv(ws, name):
c = BusClient(ctx=zmq.asyncio.Context(), sub=False) c = BusClient(ctx=zmq.asyncio.Context(), sub=False)
async for msg in ws: async for msg in ws:
@ -122,9 +136,10 @@ class WebRTC(Node):
# await c.send_async(StrMsg(ss)) # await c.send_async(StrMsg(ss))
j = json.loads(ss) j = json.loads(ss)
v = j["value"] v = j["value"]
logger.debug(f'ws recv {j}')
match j["type"]: match j["type"]:
case "Move": case "MoveAxisMsg":
await c.send_async(MoveAxisMsg('S', v['s'])) await c.send_async(MoveAxisMsg(sender=name, axis=v['axis'], value=v['value']))
case "Arg": case "Arg":
await c.send_async(ImageArgMsg(sender=name, **v)) await c.send_async(ImageArgMsg(sender=name, **v))
elif msg.type == aiohttp.WSMsgType.ERROR: elif msg.type == aiohttp.WSMsgType.ERROR:
@ -154,8 +169,8 @@ class WebRTC(Node):
name = str(time.time()) name = str(time.time())
task1 = asyncio.create_task(t3(ws, name)) task1 = asyncio.create_task(ws_send(ws, name))
task2 = asyncio.create_task(t4(ws, name)) task2 = asyncio.create_task(ws_recv(ws, name))
await asyncio.gather(task1, task2) await asyncio.gather(task1, task2)
# await task1 # await task1

View File

@ -12,20 +12,196 @@ from PyQt6 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object): class Ui_MainWindow(object):
def setupUi(self, MainWindow): def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow") MainWindow.setObjectName("MainWindow")
MainWindow.resize(457, 205) MainWindow.resize(1177, 910)
self.centralwidget = QtWidgets.QWidget(parent=MainWindow) self.centralwidget = QtWidgets.QWidget(parent=MainWindow)
self.centralwidget.setObjectName("centralwidget") self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget) self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout") self.gridLayout.setObjectName("gridLayout")
self.gridLayout_3 = QtWidgets.QGridLayout()
self.gridLayout_3.setObjectName("gridLayout_3")
self.c_seq_meta = QtWidgets.QComboBox(parent=self.centralwidget)
self.c_seq_meta.setObjectName("c_seq_meta")
self.gridLayout_3.addWidget(self.c_seq_meta, 3, 0, 1, 1)
self.b_device_enabled = QtWidgets.QPushButton(parent=self.centralwidget)
self.b_device_enabled.setObjectName("b_device_enabled")
self.gridLayout_3.addWidget(self.b_device_enabled, 2, 0, 1, 1)
self.b_device_connected = QtWidgets.QPushButton(parent=self.centralwidget)
self.b_device_connected.setObjectName("b_device_connected")
self.gridLayout_3.addWidget(self.b_device_connected, 1, 0, 1, 1)
self.l_online = QtWidgets.QLabel(parent=self.centralwidget)
self.l_online.setStyleSheet("background-color: pink;")
self.l_online.setObjectName("l_online")
self.gridLayout_3.addWidget(self.l_online, 0, 0, 1, 1)
self.gridLayout.addLayout(self.gridLayout_3, 0, 0, 1, 1)
self.gridLayout_5 = QtWidgets.QGridLayout()
self.gridLayout_5.setObjectName("gridLayout_5")
self.horizontalSlider = QtWidgets.QSlider(parent=self.centralwidget) self.horizontalSlider = QtWidgets.QSlider(parent=self.centralwidget)
self.horizontalSlider.setMinimum(1) self.horizontalSlider.setMinimum(1)
self.horizontalSlider.setMaximum(1500) self.horizontalSlider.setMaximum(1500)
self.horizontalSlider.setOrientation(QtCore.Qt.Orientation.Horizontal) self.horizontalSlider.setOrientation(QtCore.Qt.Orientation.Horizontal)
self.horizontalSlider.setObjectName("horizontalSlider") self.horizontalSlider.setObjectName("horizontalSlider")
self.gridLayout.addWidget(self.horizontalSlider, 0, 0, 1, 1) self.gridLayout_5.addWidget(self.horizontalSlider, 1, 1, 1, 1)
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding)
self.gridLayout_5.addItem(spacerItem, 4, 1, 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, 3, 1, 1, 1)
self.label_5 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_5.setObjectName("label_5")
self.gridLayout_5.addWidget(self.label_5, 1, 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, 2, 1, 1, 1)
self.spinBox = QtWidgets.QSpinBox(parent=self.centralwidget)
self.spinBox.setObjectName("spinBox")
self.gridLayout_5.addWidget(self.spinBox, 1, 2, 1, 1)
self.label_2 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_2.setObjectName("label_2")
self.gridLayout_5.addWidget(self.label_2, 0, 0, 1, 3)
self.label_6 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_6.setObjectName("label_6")
self.gridLayout_5.addWidget(self.label_6, 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, 3, 0, 1, 1)
self.spinBox_2 = QtWidgets.QSpinBox(parent=self.centralwidget)
self.spinBox_2.setObjectName("spinBox_2")
self.gridLayout_5.addWidget(self.spinBox_2, 2, 2, 1, 1)
self.spinBox_3 = QtWidgets.QSpinBox(parent=self.centralwidget)
self.spinBox_3.setObjectName("spinBox_3")
self.gridLayout_5.addWidget(self.spinBox_3, 3, 2, 1, 1)
self.gridLayout.addLayout(self.gridLayout_5, 1, 0, 1, 1)
self.gridLayout_2 = QtWidgets.QGridLayout()
self.gridLayout_2.setObjectName("gridLayout_2")
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_2.addWidget(self.l_record_commit, 1, 1, 1, 1)
self.b_play_playback = QtWidgets.QPushButton(parent=self.centralwidget)
self.b_play_playback.setEnabled(False)
self.b_play_playback.setStyleSheet("background-color : red")
self.b_play_playback.setObjectName("b_play_playback")
self.gridLayout_2.addWidget(self.b_play_playback, 2, 0, 1, 1)
self.b_record = QtWidgets.QPushButton(parent=self.centralwidget)
self.b_record.setEnabled(False)
self.b_record.setObjectName("b_record")
self.gridLayout_2.addWidget(self.b_record, 1, 2, 1, 1)
self.s_sid = QtWidgets.QSlider(parent=self.centralwidget)
self.s_sid.setOrientation(QtCore.Qt.Orientation.Horizontal)
self.s_sid.setObjectName("s_sid")
self.gridLayout_2.addWidget(self.s_sid, 3, 1, 1, 1)
self.label_4 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_4.setObjectName("label_4")
self.gridLayout_2.addWidget(self.label_4, 3, 0, 1, 1)
self.b_base = QtWidgets.QPushButton(parent=self.centralwidget)
self.b_base.setObjectName("b_base")
self.gridLayout_2.addWidget(self.b_base, 0, 2, 1, 1)
self.l_base = QtWidgets.QLineEdit(parent=self.centralwidget)
self.l_base.setObjectName("l_base")
self.gridLayout_2.addWidget(self.l_base, 0, 1, 1, 1)
self.label = QtWidgets.QLabel(parent=self.centralwidget)
self.label.setObjectName("label")
self.gridLayout_2.addWidget(self.label, 0, 0, 1, 1)
self.b_play_live = QtWidgets.QPushButton(parent=self.centralwidget)
self.b_play_live.setObjectName("b_play_live")
self.gridLayout_2.addWidget(self.b_play_live, 1, 0, 1, 1)
self.comboBox = QtWidgets.QComboBox(parent=self.centralwidget)
self.comboBox.setEnabled(False)
self.comboBox.setEditable(False)
self.comboBox.setObjectName("comboBox")
self.comboBox.addItem("")
self.gridLayout_2.addWidget(self.comboBox, 2, 1, 1, 2)
self.spinBox_7 = QtWidgets.QSpinBox(parent=self.centralwidget)
self.spinBox_7.setObjectName("spinBox_7")
self.gridLayout_2.addWidget(self.spinBox_7, 3, 2, 1, 1)
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.spinBox_4 = QtWidgets.QSpinBox(parent=self.centralwidget)
self.spinBox_4.setObjectName("spinBox_4")
self.gridLayout_4.addWidget(self.spinBox_4, 1, 2, 1, 1)
self.spinBox_6 = QtWidgets.QSpinBox(parent=self.centralwidget)
self.spinBox_6.setObjectName("spinBox_6")
self.gridLayout_4.addWidget(self.spinBox_6, 3, 2, 1, 1)
self.label_10 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_10.setObjectName("label_10")
self.gridLayout_4.addWidget(self.label_10, 3, 0, 1, 1)
self.horizontalSlider_3 = QtWidgets.QSlider(parent=self.centralwidget)
self.horizontalSlider_3.setOrientation(QtCore.Qt.Orientation.Horizontal)
self.horizontalSlider_3.setObjectName("horizontalSlider_3")
self.gridLayout_4.addWidget(self.horizontalSlider_3, 1, 1, 1, 1)
self.horizontalSlider_5 = QtWidgets.QSlider(parent=self.centralwidget)
self.horizontalSlider_5.setOrientation(QtCore.Qt.Orientation.Horizontal)
self.horizontalSlider_5.setObjectName("horizontalSlider_5")
self.gridLayout_4.addWidget(self.horizontalSlider_5, 2, 1, 1, 1)
self.horizontalSlider_6 = QtWidgets.QSlider(parent=self.centralwidget)
self.horizontalSlider_6.setOrientation(QtCore.Qt.Orientation.Horizontal)
self.horizontalSlider_6.setObjectName("horizontalSlider_6")
self.gridLayout_4.addWidget(self.horizontalSlider_6, 3, 1, 1, 1)
self.spinBox_5 = QtWidgets.QSpinBox(parent=self.centralwidget)
self.spinBox_5.setObjectName("spinBox_5")
self.gridLayout_4.addWidget(self.spinBox_5, 2, 2, 1, 1)
self.horizontalSlider_9 = QtWidgets.QSlider(parent=self.centralwidget)
self.horizontalSlider_9.setOrientation(QtCore.Qt.Orientation.Horizontal)
self.horizontalSlider_9.setObjectName("horizontalSlider_9")
self.gridLayout_4.addWidget(self.horizontalSlider_9, 5, 1, 1, 1)
self.label_9 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_9.setObjectName("label_9")
self.gridLayout_4.addWidget(self.label_9, 2, 0, 1, 1)
spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding)
self.gridLayout_4.addItem(spacerItem1, 8, 1, 1, 1)
self.horizontalSlider_7 = QtWidgets.QSlider(parent=self.centralwidget)
self.horizontalSlider_7.setOrientation(QtCore.Qt.Orientation.Horizontal)
self.horizontalSlider_7.setObjectName("horizontalSlider_7")
self.gridLayout_4.addWidget(self.horizontalSlider_7, 7, 1, 1, 1)
self.label_3 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_3.setObjectName("label_3")
self.gridLayout_4.addWidget(self.label_3, 0, 0, 1, 3)
self.label_11 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_11.setObjectName("label_11")
self.gridLayout_4.addWidget(self.label_11, 7, 0, 1, 1)
self.label_8 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_8.setObjectName("label_8")
self.gridLayout_4.addWidget(self.label_8, 1, 0, 1, 1)
self.horizontalSlider_8 = QtWidgets.QSlider(parent=self.centralwidget)
self.horizontalSlider_8.setOrientation(QtCore.Qt.Orientation.Horizontal)
self.horizontalSlider_8.setObjectName("horizontalSlider_8")
self.gridLayout_4.addWidget(self.horizontalSlider_8, 6, 1, 1, 1)
self.horizontalSlider_10 = QtWidgets.QSlider(parent=self.centralwidget)
self.horizontalSlider_10.setOrientation(QtCore.Qt.Orientation.Horizontal)
self.horizontalSlider_10.setObjectName("horizontalSlider_10")
self.gridLayout_4.addWidget(self.horizontalSlider_10, 4, 1, 1, 1)
self.label_12 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_12.setObjectName("label_12")
self.gridLayout_4.addWidget(self.label_12, 4, 0, 1, 1)
self.label_13 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_13.setObjectName("label_13")
self.gridLayout_4.addWidget(self.label_13, 5, 0, 1, 1)
self.label_14 = QtWidgets.QLabel(parent=self.centralwidget)
self.label_14.setObjectName("label_14")
self.gridLayout_4.addWidget(self.label_14, 6, 0, 1, 1)
self.spinBox_8 = QtWidgets.QSpinBox(parent=self.centralwidget)
self.spinBox_8.setObjectName("spinBox_8")
self.gridLayout_4.addWidget(self.spinBox_8, 4, 2, 1, 1)
self.spinBox_9 = QtWidgets.QSpinBox(parent=self.centralwidget)
self.spinBox_9.setObjectName("spinBox_9")
self.gridLayout_4.addWidget(self.spinBox_9, 5, 2, 1, 1)
self.spinBox_10 = QtWidgets.QSpinBox(parent=self.centralwidget)
self.spinBox_10.setObjectName("spinBox_10")
self.gridLayout_4.addWidget(self.spinBox_10, 6, 2, 1, 1)
self.spinBox_11 = QtWidgets.QSpinBox(parent=self.centralwidget)
self.spinBox_11.setObjectName("spinBox_11")
self.gridLayout_4.addWidget(self.spinBox_11, 7, 2, 1, 1)
self.gridLayout.addLayout(self.gridLayout_4, 1, 1, 1, 1)
self.b_exit = QtWidgets.QPushButton(parent=self.centralwidget)
self.b_exit.setObjectName("b_exit")
self.gridLayout.addWidget(self.b_exit, 2, 0, 1, 2)
MainWindow.setCentralWidget(self.centralwidget) MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(parent=MainWindow) self.menubar = QtWidgets.QMenuBar(parent=MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 457, 22)) self.menubar.setGeometry(QtCore.QRect(0, 0, 1177, 22))
self.menubar.setObjectName("menubar") self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar) MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(parent=MainWindow) self.statusbar = QtWidgets.QStatusBar(parent=MainWindow)
@ -38,3 +214,27 @@ class Ui_MainWindow(object):
def retranslateUi(self, MainWindow): def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate _translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.b_device_enabled.setText(_translate("MainWindow", "Beam"))
self.b_device_connected.setText(_translate("MainWindow", "Connect"))
self.l_online.setText(_translate("MainWindow", "Device Offline"))
self.label_5.setText(_translate("MainWindow", "cut_t"))
self.label_2.setText(_translate("MainWindow", "Imaging"))
self.label_6.setText(_translate("MainWindow", "TextLabel"))
self.label_7.setText(_translate("MainWindow", "TextLabel"))
self.b_play_playback.setText(_translate("MainWindow", "Playback"))
self.b_record.setText(_translate("MainWindow", "Record"))
self.label_4.setText(_translate("MainWindow", "Frame ID"))
self.b_base.setText(_translate("MainWindow", "SetBase"))
self.l_base.setText(_translate("MainWindow", "/mnt/16T/private_dataset/us/"))
self.label.setText(_translate("MainWindow", "Base Path"))
self.b_play_live.setText(_translate("MainWindow", "Live"))
self.comboBox.setItemText(0, _translate("MainWindow", "Unset"))
self.label_10.setText(_translate("MainWindow", "Z"))
self.label_9.setText(_translate("MainWindow", "Y"))
self.label_3.setText(_translate("MainWindow", "Probe Position"))
self.label_11.setText(_translate("MainWindow", "E"))
self.label_8.setText(_translate("MainWindow", "X"))
self.label_12.setText(_translate("MainWindow", "Roll"))
self.label_13.setText(_translate("MainWindow", "Pitch"))
self.label_14.setText(_translate("MainWindow", "Yal"))
self.b_exit.setText(_translate("MainWindow", "EXIT"))

View File

@ -6,16 +6,49 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>457</width> <width>1177</width>
<height>205</height> <height>910</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>MainWindow</string> <string>MainWindow</string>
</property> </property>
<widget class="QWidget" name="centralwidget"> <widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0">
<item row="0" column="0"> <item row="0" column="0">
<layout class="QGridLayout" name="gridLayout_3">
<item row="3" column="0">
<widget class="QComboBox" name="c_seq_meta"/>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="b_device_enabled">
<property name="text">
<string>Beam</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="b_device_connected">
<property name="text">
<string>Connect</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="l_online">
<property name="styleSheet">
<string notr="true">background-color: pink;</string>
</property>
<property name="text">
<string>Device Offline</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QGridLayout" name="gridLayout_5">
<item row="1" column="1">
<widget class="QSlider" name="horizontalSlider"> <widget class="QSlider" name="horizontalSlider">
<property name="minimum"> <property name="minimum">
<number>1</number> <number>1</number>
@ -28,6 +61,316 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="1">
<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>
<item row="3" column="1">
<widget class="QSlider" name="horizontalSlider_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>cut_t</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSlider" name="horizontalSlider_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="spinBox"/>
</item>
<item row="0" column="0" colspan="3">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Imaging</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QSpinBox" name="spinBox_2"/>
</item>
<item row="3" column="2">
<widget class="QSpinBox" name="spinBox_3"/>
</item>
</layout>
</item>
<item row="0" column="1">
<layout class="QGridLayout" name="gridLayout_2" columnstretch="0,1,0">
<item row="1" column="1">
<widget class="QLineEdit" name="l_record_commit">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="b_play_playback">
<property name="enabled">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true">background-color : red</string>
</property>
<property name="text">
<string>Playback</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="b_record">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Record</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSlider" name="s_sid">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Frame ID</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="b_base">
<property name="text">
<string>SetBase</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="l_base">
<property name="text">
<string>/mnt/16T/private_dataset/us/</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Base Path</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="b_play_live">
<property name="text">
<string>Live</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QComboBox" name="comboBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="editable">
<bool>false</bool>
</property>
<item>
<property name="text">
<string>Unset</string>
</property>
</item>
</widget>
</item>
<item row="3" column="2">
<widget class="QSpinBox" name="spinBox_7"/>
</item>
</layout>
</item>
<item row="1" column="1">
<layout class="QGridLayout" name="gridLayout_4">
<item row="1" column="2">
<widget class="QSpinBox" name="spinBox_4"/>
</item>
<item row="3" column="2">
<widget class="QSpinBox" name="spinBox_6"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Z</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSlider" name="horizontalSlider_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSlider" name="horizontalSlider_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSlider" name="horizontalSlider_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QSpinBox" name="spinBox_5"/>
</item>
<item row="5" column="1">
<widget class="QSlider" name="horizontalSlider_9">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Y</string>
</property>
</widget>
</item>
<item row="8" column="1">
<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="7" column="1">
<widget class="QSlider" name="horizontalSlider_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="0" colspan="3">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Probe Position</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>E</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>X</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QSlider" name="horizontalSlider_8">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QSlider" name="horizontalSlider_10">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Roll</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Pitch</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
<string>Yal</string>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QSpinBox" name="spinBox_8"/>
</item>
<item row="5" column="2">
<widget class="QSpinBox" name="spinBox_9"/>
</item>
<item row="6" column="2">
<widget class="QSpinBox" name="spinBox_10"/>
</item>
<item row="7" column="2">
<widget class="QSpinBox" name="spinBox_11"/>
</item>
</layout>
</item>
<item row="2" column="0" colspan="2">
<widget class="QPushButton" name="b_exit">
<property name="text">
<string>EXIT</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<widget class="QMenuBar" name="menubar"> <widget class="QMenuBar" name="menubar">
@ -35,7 +378,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>457</width> <width>1177</width>
<height>22</height> <height>22</height>
</rect> </rect>
</property> </property>

View File

@ -13,6 +13,19 @@ class BG(Enum):
StrMsg = auto() StrMsg = auto()
MoveAxisMsg = auto() MoveAxisMsg = auto()
ImageArgMsg = auto() ImageArgMsg = auto()
SelectSeqMsg = auto()
SeqMetaMsg = auto()
SeqIdMinMax = auto()
SetBaseMsg = auto()
SeqListMsg = auto()
SetPlayMode = auto()
SetDeviceEnabledMsg = auto()
SetDeviceConnectedMsg = auto()
DeviceEnabledMsg = auto()
DeviceConnectedMsg = auto()
SetDeviceConfigMsg = auto()
DeviceOnlineMsg = auto()
DeviceConfigListMsg = auto()
class Msg: class Msg:
@ -72,8 +85,66 @@ class StrMsg(Msg):
value: str = '' value: str = ''
@dataclasses.dataclass
class BoolMsg(Msg):
value: bool
class SetDeviceEnabledMsg(BoolMsg):
pass
class SetDeviceConnectedMsg(BoolMsg):
pass
class DeviceEnabledMsg(BoolMsg):
pass
class DeviceConnectedMsg(BoolMsg):
pass
class DeviceOnlineMsg(BoolMsg):
pass
class SetDeviceConfigMsg(StrMsg):
pass
class SetBaseMsg(StrMsg):
pass
@dataclasses.dataclass
class SeqListMsg(Msg):
value: list[str]
class SelectSeqMsg(StrMsg):
pass
class SetPlayMode(StrMsg):
pass
@dataclasses.dataclass
class SeqMetaMsg(Msg):
s: str = ''
@dataclasses.dataclass
class SeqIdMinMax(Msg):
min: int
max: int
@dataclasses.dataclass @dataclasses.dataclass
class MoveAxisMsg(Msg): class MoveAxisMsg(Msg):
sender: str
axis: str axis: str
value: int value: int
@ -84,6 +155,11 @@ class ImageArgMsg(Msg):
v1: int v1: int
@dataclasses.dataclass
class DeviceConfigListMsg(Msg):
arr: list[tuple[str, str]]
class BMMsg(Msg): class BMMsg(Msg):
def __init__(self, t: int, data: bytes): def __init__(self, t: int, data: bytes):
self.data = data self.data = data

View File

@ -201,7 +201,7 @@ class RfSequenceMeta(SM):
PWI = auto() PWI = auto()
TFM = auto() TFM = auto()
commit: Annotated[int, COMMIT_KEY] = None commit: Annotated[str, COMMIT_KEY] = None
shape: Annotated[tuple, 'S'] = None shape: Annotated[tuple, 'S'] = None
mode: Annotated[RfSequenceMode, 'M'] = RfSequenceMode.PWI mode: Annotated[RfSequenceMode, 'M'] = RfSequenceMode.PWI
us: Annotated[int, 'U'] = None us: Annotated[int, 'U'] = None
@ -230,6 +230,15 @@ class RfSequence:
def query(self): def query(self):
pass pass
@property
def seq_id_minmax(self):
mmin = 1000000
mmax = 0
for f in self.frames:
mmin = min(mmin, f.meta.sequence_id)
mmax = max(mmax, f.meta.sequence_id)
return mmin, mmax
if __name__ == '__main__': if __name__ == '__main__':
# t = (1, 2) # t = (1, 2)

View File

@ -53,6 +53,9 @@ class RfMat:
return np return np
return cp return cp
def __bytes__(self):
return self.m.tobytes()
def init_cv(self): def init_cv(self):
cv2.namedWindow('image') cv2.namedWindow('image')
self.cv = True self.cv = True
@ -75,6 +78,9 @@ class RfMat:
return self return self
return self.copy(self.m.get()) return self.copy(self.m.get())
def crop1(self, v1):
return self.copy(self.m[:, :v1])
def watermark(self, watermark=None): def watermark(self, watermark=None):
assert self.m.dtype == np.uint8 assert self.m.dtype == np.uint8
canvas = np.zeros(self.m.shape, dtype=np.uint8) canvas = np.zeros(self.m.shape, dtype=np.uint8)

View File

@ -1,137 +0,0 @@
import logging
import multiprocessing
import time
from pathlib import Path
import cv2
import numpy as np
from tqdm import tqdm
from nodes.Beamformer import Beamformer
from nodes.Broker import Broker
from nodes.ImageCV import ImageCV
from nodes.ImageQt import ImageQt
from nodes.Loader import Loader
from nodes.MainUI import MainUI
from nodes.Node import Node
from BusClient import BusClient
from Msg import Msg1, Msg2, BMMsg, TickMsg, StrMsg, KillMsg
from nodes.WebRTC import WebRTC
class M1(Node):
def loop(self):
cnt = 0
while True:
cnt += 1
self.send(str(cnt).encode())
time.sleep(1)
class M2(Node):
def loop(self):
while True:
print(self.recv())
class M3(Node):
topics = [StrMsg]
def loop(self):
arr = []
for img in tqdm(list(Path('/home/lambda/Videos/pngs/New Folder/').glob('*.png'))):
img = cv2.imread(str(img))
# img = cv2.resize(img, (1920 // 2, 1080 // 2))
img = img.reshape(1080, 1920, 3)
z = np.zeros((1080, 1920, 4), dtype=np.uint8)
z[:, :, :3] = img
img = z
img = cv2.cvtColor(img, cv2.COLOR_BGRA2RGBA)
arr.append(img.tobytes())
# while self.isalive:
# for b in arr:
# self.send(BMMsg(0, b))
# # self.pub_socket.send(b)
# # self.send(b)
# r = self.c.poller.poll(int(1000 / 60))
# # print(r)
# if r and Msg.decode_msg(r[0][0].recv()).name == '':
# self.isalive = False
# break
# # time.sleep(1 / 60)
while self.isalive:
for b in arr:
msg = self.recv()
if isinstance(msg, KillMsg):
if msg.name == '':
self.isalive = False
break
self.send(BMMsg(0, b))
# if r and Msg.decode_msg(r[0][0].recv()).name == '':
class M4(Node):
def loop(self):
while True:
self.send(Msg1())
time.sleep(1)
class MTIME(Node):
def loop(self):
while True:
t = time.time()
self.send(TickMsg(t))
time.sleep(10)
# print(t)
class MLISTEN(Node):
topics = [StrMsg]
def loop(self):
while self.isalive:
r = self.recv()
print(r)
if isinstance(r, KillMsg) and r.name == '':
self.isalive = False
break
self.send(TickMsg(time.time()))
class M6(Node):
topics = [Msg2.eid()]
def loop(self):
while True:
print(self.recv())
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
multiprocessing.set_start_method('spawn')
pps = []
ps = [
Broker(),
WebRTC(),
# M3(),
MainUI(),
ImageCV(),
MLISTEN(),
Beamformer(),
Loader(),
]
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()

View File

@ -19,6 +19,7 @@ def cmd(c: str):
sock = ctx.socket(zmq.REQ) sock = ctx.socket(zmq.REQ)
sock.connect('tcp://11.6.1.66:5556') sock.connect('tcp://11.6.1.66:5556')
sock.send(c.encode()) sock.send(c.encode())
print(sock.recv().decode())
def file(): def file():

5
test/tcp.py Normal file
View File

@ -0,0 +1,5 @@
import subprocess
if __name__ == '__main__':
code = subprocess.run(['curl', '-m', '1', 'http://11.6.1.66:22'], stderr=subprocess.DEVNULL,
stdout=subprocess.DEVNULL).returncode