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