From 492a0df8b7d33c41a208daccd88c8258f7ed3bdf Mon Sep 17 00:00:00 2001 From: flandre Date: Sun, 19 Jan 2025 18:27:26 +0800 Subject: [PATCH] add many --- src/config.py | 11 +- src/main.py | 39 ++++ src/nodes/Beamformer.py | 93 ++++++---- src/nodes/BusClient.py.bak | 63 ------- src/nodes/Device.py | 130 +++++++++++++ src/nodes/Loader.py | 44 +++-- src/nodes/MainUI.py | 120 +++++++++++- src/nodes/Node.py | 5 +- src/nodes/WebRTC.py | 37 ++-- src/ui/Main.py | 206 ++++++++++++++++++++- src/ui/Main.ui | 369 +++++++++++++++++++++++++++++++++++-- src/utils/Msg.py | 76 ++++++++ src/utils/RfFile.py | 11 +- src/utils/RfMat.py | 6 + src/zmqmyclasstest.py | 137 -------------- test/drivercmd.py | 1 + test/tcp.py | 5 + 17 files changed, 1071 insertions(+), 282 deletions(-) create mode 100644 src/main.py delete mode 100644 src/nodes/BusClient.py.bak create mode 100644 src/nodes/Device.py delete mode 100644 src/zmqmyclasstest.py create mode 100644 test/tcp.py diff --git a/src/config.py b/src/config.py index 6df87c6..b7166ab 100644 --- a/src/config.py +++ b/src/config.py @@ -1,14 +1,21 @@ 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_WIDTH = 1080 BASE = Path(__file__).parent.parent DS = BASE / '@DS' DOC = BASE / 'doc' +CONFIG = BASE / 'config' DS.mkdir(exist_ok=True, parents=True) DOC.mkdir(exist_ok=True, parents=True) +CONFIG.mkdir(exist_ok=True, parents=True) CONFIG_FOLDER = BASE / 'config' LAST_CONFIG = BASE / 'config' / 'last_imaging_config.json' @@ -16,4 +23,4 @@ LAST_CONFIG = BASE / 'config' / 'last_imaging_config.json' CONFIG_FOLDER.mkdir(exist_ok=True) if __name__ == '__main__': - print(BASE) \ No newline at end of file + print(BASE) diff --git a/src/main.py b/src/main.py new file mode 100644 index 0000000..28336be --- /dev/null +++ b/src/main.py @@ -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() diff --git a/src/nodes/Beamformer.py b/src/nodes/Beamformer.py index a02bd9a..23fb64a 100644 --- a/src/nodes/Beamformer.py +++ b/src/nodes/Beamformer.py @@ -1,56 +1,83 @@ +import logging +import struct + +import cupy as cp import cv2 import numpy as np import zmq -from utils.Msg import BMMsg, ImageArgMsg, KillMsg -from config import SOCKET1, VIDEO_WIDTH, VIDEO_HEIGHT +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 from utils.RfFile import RfFrame, RfSequenceMeta from utils.RfMat import RfMat +logger = logging.getLogger(__name__) + class Beamformer(Node): - topics = [ImageArgMsg] + topics = [ImageArgMsg, SeqMetaMsg, SetPlayMode, SetDeviceConfigMsg] def __init__(self): 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: return - b = np.frombuffer(data, dtype=np.int16) - b = b.reshape((256, 1502)).astype(np.float32) - b = b[:, :self.arg.v1] - b -= b.min() - b /= b.max() - b *= 255 - b = b.astype(np.uint8) - b = cv2.rotate(b, cv2.ROTATE_90_CLOCKWISE) - b = cv2.resize(b, (VIDEO_WIDTH, VIDEO_HEIGHT)) - b = cv2.cvtColor(b, cv2.COLOR_GRAY2RGBA, b) - self.send(BMMsg(0, b.tobytes())) + d2 = (data + .crop1(self.arg.v1) + .rotate90() + .grey() + .cpu() + .resize((VIDEO_WIDTH, VIDEO_HEIGHT)) + .watermark() + .call(cv2.cvtColor, cv2.COLOR_GRAY2RGBA) + ) + self.send(BMMsg(0, d2.__bytes__())) def loop(self): - s2 = self.context.socket(zmq.PULL) - s2.setsockopt(zmq.CONFLATE, 1) - s2.connect(f"tcp://{SOCKET1}") - self.c.poller.register(s2, zmq.POLLIN) - buffer = None + device_socket = self.context.socket(zmq.PULL) + device_socket.setsockopt(zmq.CONFLATE, 1) + device_socket.connect(f"tcp://{PLAYBACK_SOCKET}") + self.c.poller.register(device_socket, zmq.POLLIN) + # RfSequenceMeta( + # commit='test', + # shape=(256, 1502), + # mode=RfSequenceMeta.RfSequenceMode.PWI, + # us=30 + # ) + mat = None while True: socks = dict(self.c.poller.poll()) - if s2 in socks and socks[s2] == zmq.POLLIN: - buffer = s2.recv() - - RfMat(1, RfFrame.RfFrameMeta( - 1, 1 - ), RfSequenceMeta()) + if device_socket in socks and socks[device_socket] == zmq.POLLIN: + buffer = device_socket.recv() + _, sequence_id, encoder = struct.unpack_from('=iqi', buffer) + s = buffer[4 + 8 + 4:] + if self.seq_meta is not None: + 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: - r = self.recv() - if isinstance(r, KillMsg): - if r.name == '': + msg = self.recv() + if isinstance(msg, KillMsg): + if msg.name == '': return - if isinstance(r, ImageArgMsg): - self.arg = r - self.process(buffer) + if isinstance(msg, SeqMetaMsg): + self.seq_meta = RfSequenceMeta.from_name(msg.s) + 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) diff --git a/src/nodes/BusClient.py.bak b/src/nodes/BusClient.py.bak deleted file mode 100644 index 24dc548..0000000 --- a/src/nodes/BusClient.py.bak +++ /dev/null @@ -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 diff --git a/src/nodes/Device.py b/src/nodes/Device.py new file mode 100644 index 0000000..b595c6a --- /dev/null +++ b/src/nodes/Device.py @@ -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) diff --git a/src/nodes/Loader.py b/src/nodes/Loader.py index 4b8526d..faa5680 100644 --- a/src/nodes/Loader.py +++ b/src/nodes/Loader.py @@ -1,26 +1,48 @@ +import io +import logging +import struct +from pathlib import Path + import zmq -from utils.RfFile import RfFolder -from utils.Msg import MoveAxisMsg, KillMsg +from config import PLAYBACK_SOCKET_PORT +from utils.RfFile import RfFolder, RfSequence +from utils.Msg import MoveAxisMsg, KillMsg, SelectSeqMsg, SeqMetaMsg, SeqIdMinMax, SetBaseMsg, SeqListMsg from nodes.Node import Node +logger = logging.getLogger(__name__) + class Loader(Node): - topics = [MoveAxisMsg] + topics = [MoveAxisMsg, SelectSeqMsg, SetBaseMsg] def loop(self): 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') - all_files = rff.all + # base = Path('/mnt/16T/private_dataset/us/') + base: Path | None = None + + rff = None while True: r = self.recv() - if isinstance(r, MoveAxisMsg): - for f in all_files: - if f.S == r.value: - # s2.send(np.zeros((256, 1500), dtype=np.uint16).tobytes()) - s2.send(f.path.read_bytes()) + if isinstance(r, MoveAxisMsg) and rff is not None: + logger.debug(f'Move axis: {rff}') + for frame in rff.frames: + if frame.meta.sequence_id == r.value: + 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): if r.name == '': break diff --git a/src/nodes/MainUI.py b/src/nodes/MainUI.py index 3b5386e..2123e90 100644 --- a/src/nodes/MainUI.py +++ b/src/nodes/MainUI.py @@ -1,13 +1,17 @@ +import logging import sys from PyQt6 import QtCore from PyQt6.QtCore import QByteArray -from PyQt6.QtWidgets import QMainWindow, QApplication +from PyQt6.QtWidgets import QMainWindow, QApplication, QFrame 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 nodes.Node import Node +from utils.RfFile import RfSequenceMeta 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.start() 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): msg = Msg.decode_msg(msg.data()) @@ -27,18 +73,80 @@ class Adv(QMainWindow, Ui_MainWindow): self.close() elif isinstance(msg, ImageArgMsg): 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) def vc(self, v): 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): - topics = [ImageArgMsg] + topics = [ImageArgMsg, SeqIdMinMax, MoveAxisMsg, + SeqListMsg, SeqMetaMsg, + DeviceConnectedMsg, DeviceEnabledMsg, DeviceOnlineMsg, DeviceConfigListMsg] - def __init__(self): - super().__init__() + def __init__(self, level=logging.INFO): + super().__init__(level=level) def loop(self): app = QApplication(sys.argv) diff --git a/src/nodes/Node.py b/src/nodes/Node.py index 298281b..71a7b4a 100644 --- a/src/nodes/Node.py +++ b/src/nodes/Node.py @@ -12,9 +12,10 @@ class Node: bp = BusClient.bp topics = [] - def __init__(self, enable_init=True): + def __init__(self, enable_init=True, level=logging.INFO): self.enable_init = enable_init self.isalive = True + self.level = level def recv(self): return self.c.recv() @@ -27,7 +28,7 @@ class Node: pass def __call__(self, *args, **kwargs): - logging.basicConfig(level=logging.INFO) + logging.basicConfig(level=self.level) self.context = zmq.Context() if self.enable_init: self.c = BusClient(*([KillMsg] + self.topics), poller=True) diff --git a/src/nodes/WebRTC.py b/src/nodes/WebRTC.py index 6a75be4..655bb11 100644 --- a/src/nodes/WebRTC.py +++ b/src/nodes/WebRTC.py @@ -1,8 +1,7 @@ import asyncio import json +import logging import os -import zmq.asyncio - import time from fractions import Fraction @@ -11,20 +10,21 @@ import aiohttp_cors import aiortc.rtcrtpsender import numpy as np import zmq +import zmq.asyncio from aiohttp import web, WSMessage from aiortc import MediaStreamTrack, RTCPeerConnection, RTCSessionDescription, RTCConfiguration, RTCRtpCodecCapability - from av import VideoFrame import H264NV from BusClient import BusClient -from utils.Msg import BMMsg, Msg, KillMsg, MoveAxisMsg, ImageArgMsg from config import VIDEO_WIDTH, VIDEO_HEIGHT +from utils.Msg import BMMsg, Msg, KillMsg, MoveAxisMsg, ImageArgMsg, SeqIdMinMax ROOT = os.path.dirname(__file__) from nodes.Node import Node web.WebSocketResponse() +logger = logging.getLogger(__name__) def generate_placeholder(): @@ -95,9 +95,9 @@ class WebRTC(Node): await asyncio.gather(*coros) pcs.clear() - async def t3(ws, name): + async def ws_send(ws, name): # 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: msg = await c.recv_async() if isinstance(msg, KillMsg): @@ -111,8 +111,22 @@ class WebRTC(Node): await ws.send_str(json.dumps(dict( 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) async for msg in ws: @@ -122,9 +136,10 @@ class WebRTC(Node): # await c.send_async(StrMsg(ss)) j = json.loads(ss) v = j["value"] + logger.debug(f'ws recv {j}') match j["type"]: - case "Move": - await c.send_async(MoveAxisMsg('S', v['s'])) + case "MoveAxisMsg": + await c.send_async(MoveAxisMsg(sender=name, axis=v['axis'], value=v['value'])) case "Arg": await c.send_async(ImageArgMsg(sender=name, **v)) elif msg.type == aiohttp.WSMsgType.ERROR: @@ -154,8 +169,8 @@ class WebRTC(Node): name = str(time.time()) - task1 = asyncio.create_task(t3(ws, name)) - task2 = asyncio.create_task(t4(ws, name)) + task1 = asyncio.create_task(ws_send(ws, name)) + task2 = asyncio.create_task(ws_recv(ws, name)) await asyncio.gather(task1, task2) # await task1 diff --git a/src/ui/Main.py b/src/ui/Main.py index 901562d..6f048c9 100644 --- a/src/ui/Main.py +++ b/src/ui/Main.py @@ -12,20 +12,196 @@ from PyQt6 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") - MainWindow.resize(457, 205) + MainWindow.resize(1177, 910) self.centralwidget = QtWidgets.QWidget(parent=MainWindow) self.centralwidget.setObjectName("centralwidget") self.gridLayout = QtWidgets.QGridLayout(self.centralwidget) 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.setMinimum(1) self.horizontalSlider.setMaximum(1500) self.horizontalSlider.setOrientation(QtCore.Qt.Orientation.Horizontal) 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) 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") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(parent=MainWindow) @@ -38,3 +214,27 @@ class Ui_MainWindow(object): def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate 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")) diff --git a/src/ui/Main.ui b/src/ui/Main.ui index 6e12269..ee68e10 100644 --- a/src/ui/Main.ui +++ b/src/ui/Main.ui @@ -6,25 +6,368 @@ 0 0 - 457 - 205 + 1177 + 910 MainWindow - + - - - 1 - - - 1500 - - - Qt::Horizontal + + + + + + + + Beam + + + + + + + Connect + + + + + + + background-color: pink; + + + Device Offline + + + + + + + + + + + 1 + + + 1500 + + + Qt::Horizontal + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + + + + + cut_t + + + + + + + Qt::Horizontal + + + + + + + + + + Imaging + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + + + + + + + + + + + false + + + + + + + false + + + background-color : red + + + Playback + + + + + + + false + + + Record + + + + + + + Qt::Horizontal + + + + + + + Frame ID + + + + + + + SetBase + + + + + + + /mnt/16T/private_dataset/us/ + + + + + + + Base Path + + + + + + + Live + + + + + + + false + + + false + + + + Unset + + + + + + + + + + + + + + + + + + + + + Z + + + + + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + + + + + + + + Qt::Horizontal + + + + + + + Y + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + + + + + Probe Position + + + + + + + E + + + + + + + X + + + + + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + + + + + Roll + + + + + + + Pitch + + + + + + + Yal + + + + + + + + + + + + + + + + + + + + + EXIT @@ -35,7 +378,7 @@ 0 0 - 457 + 1177 22 diff --git a/src/utils/Msg.py b/src/utils/Msg.py index f412b51..0acd471 100644 --- a/src/utils/Msg.py +++ b/src/utils/Msg.py @@ -13,6 +13,19 @@ class BG(Enum): StrMsg = auto() MoveAxisMsg = 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: @@ -72,8 +85,66 @@ class StrMsg(Msg): 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 class MoveAxisMsg(Msg): + sender: str axis: str value: int @@ -84,6 +155,11 @@ class ImageArgMsg(Msg): v1: int +@dataclasses.dataclass +class DeviceConfigListMsg(Msg): + arr: list[tuple[str, str]] + + class BMMsg(Msg): def __init__(self, t: int, data: bytes): self.data = data diff --git a/src/utils/RfFile.py b/src/utils/RfFile.py index 08b8261..4a5c0ac 100644 --- a/src/utils/RfFile.py +++ b/src/utils/RfFile.py @@ -201,7 +201,7 @@ class RfSequenceMeta(SM): PWI = auto() TFM = auto() - commit: Annotated[int, COMMIT_KEY] = None + commit: Annotated[str, COMMIT_KEY] = None shape: Annotated[tuple, 'S'] = None mode: Annotated[RfSequenceMode, 'M'] = RfSequenceMode.PWI us: Annotated[int, 'U'] = None @@ -230,6 +230,15 @@ class RfSequence: def query(self): 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__': # t = (1, 2) diff --git a/src/utils/RfMat.py b/src/utils/RfMat.py index d3ff84d..a22b3bb 100644 --- a/src/utils/RfMat.py +++ b/src/utils/RfMat.py @@ -53,6 +53,9 @@ class RfMat: return np return cp + def __bytes__(self): + return self.m.tobytes() + def init_cv(self): cv2.namedWindow('image') self.cv = True @@ -75,6 +78,9 @@ class RfMat: return self return self.copy(self.m.get()) + def crop1(self, v1): + return self.copy(self.m[:, :v1]) + def watermark(self, watermark=None): assert self.m.dtype == np.uint8 canvas = np.zeros(self.m.shape, dtype=np.uint8) diff --git a/src/zmqmyclasstest.py b/src/zmqmyclasstest.py deleted file mode 100644 index 2ba68e0..0000000 --- a/src/zmqmyclasstest.py +++ /dev/null @@ -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() diff --git a/test/drivercmd.py b/test/drivercmd.py index 2eeced3..fd72463 100644 --- a/test/drivercmd.py +++ b/test/drivercmd.py @@ -19,6 +19,7 @@ def cmd(c: str): sock = ctx.socket(zmq.REQ) sock.connect('tcp://11.6.1.66:5556') sock.send(c.encode()) + print(sock.recv().decode()) def file(): diff --git a/test/tcp.py b/test/tcp.py new file mode 100644 index 0000000..00ca3fc --- /dev/null +++ b/test/tcp.py @@ -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