big fix not done

This commit is contained in:
remilia 2025-02-26 16:22:09 +08:00
parent d5ebfb4b8a
commit e4d54c6176
16 changed files with 646 additions and 592 deletions

View File

@ -0,0 +1,138 @@
[Root]
VersionDriverOEMPA=1.3.0.0
CycleCount=1
EnableFMC=1
FMCElementStart=0
FMCElementStop=255
FMCElementStep=1
DisableUSB3=1
AscanBitSize=14Bits
Enable256=0
[Cycle:0]
GainDigital=0.000000 dB
BeamCorrection=0.0 dB
Start=0.000000 us
Range=30.000000 us
TimeSlot=1495.900000 us
PointFactor=2
CompressionType=Decimation
Rectification=Signed
FilterIndex=0
GainAnalog=40.000000 dB
GateCount=0
[Cycle:0\Pulser]
WedgeDelay=0.0 us
Element.count=256
Element_0=0;1;2;3;4;5;6;7
Element_8=8;9;10;11;12;13;14;15
Element_16=16;17;18;19;20;21;22;23
Element_24=24;25;26;27;28;29;30;31
Element_32=32;33;34;35;36;37;38;39
Element_40=40;41;42;43;44;45;46;47
Element_48=48;49;50;51;52;53;54;55
Element_56=56;57;58;59;60;61;62;63
Element_64=64;65;66;67;68;69;70;71
Element_72=72;73;74;75;76;77;78;79
Element_80=80;81;82;83;84;85;86;87
Element_88=88;89;90;91;92;93;94;95
Element_96=96;97;98;99;100;101;102;103
Element_104=104;105;106;107;108;109;110;111
Element_112=112;113;114;115;116;117;118;119
Element_120=120;121;122;123;124;125;126;127
Element_128=128;129;130;131;132;133;134;135
Element_136=136;137;138;139;140;141;142;143
Element_144=144;145;146;147;148;149;150;151
Element_152=152;153;154;155;156;157;158;159
Element_160=160;161;162;163;164;165;166;167
Element_168=168;169;170;171;172;173;174;175
Element_176=176;177;178;179;180;181;182;183
Element_184=184;185;186;187;188;189;190;191
Element_192=192;193;194;195;196;197;198;199
Element_200=200;201;202;203;204;205;206;207
Element_208=208;209;210;211;212;213;214;215
Element_216=216;217;218;219;220;221;222;223
Element_224=224;225;226;227;228;229;230;231
Element_232=232;233;234;235;236;237;238;239
Element_240=240;241;242;243;244;245;246;247
Element_248=248;249;250;251;252;253;254;255
Delay.count=256;1
Delay_0=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_8=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_16=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_24=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_32=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_40=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_48=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_56=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_64=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_72=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_80=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_88=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_96=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_104=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_112=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_120=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_128=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_136=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_144=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_152=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_160=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_168=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_176=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_184=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_192=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_200=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_208=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_216=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_224=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_232=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_240=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Delay_248=0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000;0.000000 us
Width.count=256
Width_0=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_8=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_16=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_24=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_32=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_40=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_48=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_56=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_64=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_72=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_80=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_88=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_96=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_104=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_112=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_120=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_128=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_136=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_144=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_152=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_160=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_168=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_176=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_184=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_192=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_200=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_208=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_216=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_224=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_232=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_240=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
Width_248=0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000;0.100000 us
[Cycle:0\Receiver]
WedgeDelay=0.0 us
Element.count=1
Element=0
Focusing=Standard
Delay.count=1;1
Delay=0.0 us
Gain.count=1
Gain=0.0 dB
FocalTimeOfFlight.count=1
FocalTimeOfFlight=0.0 us

View File

@ -3,7 +3,7 @@ name = "flandre"
version = "0.1.0" version = "0.1.0"
description = "Add your description here" description = "Add your description here"
readme = "README.md" readme = "README.md"
requires-python = ">=3.12" requires-python = ">=3.12,<3.13"
dependencies = [ dependencies = [
"aiohttp-cors>=0.7.0", "aiohttp-cors>=0.7.0",
"aiortc>=1.9.0", "aiortc>=1.9.0",
@ -17,6 +17,7 @@ dependencies = [
"vtk>=9.4.0", "vtk>=9.4.0",
"jupyter>=1.1.1", "jupyter>=1.1.1",
"av", "av",
"python-miio>=0.5.12",
] ]
[tool.uv] [tool.uv]
@ -27,5 +28,5 @@ override-dependencies = [
[tool.uv.sources] [tool.uv.sources]
av = [ av = [
{ path = "./av-14.1.0-cp312-cp312-win_amd64.whl", marker = "sys_platform == 'win32'" }, { path = "./av-14.1.0-cp312-cp312-win_amd64.whl", marker = "sys_platform == 'win32'" },
{ path = "./av-14.1.0-cp312-cp312-linux_x86_64.whl", marker = "sys_platform == 'linux'" }, { path = "./av-14.2.0rc1-cp312-cp312-linux_x86_64.whl", marker = "sys_platform == 'linux'" },
] ]

View File

@ -23,7 +23,7 @@ class BusClient:
if sub: if sub:
self.sub = self.ctx.socket(zmq.SUB) self.sub = self.ctx.socket(zmq.SUB)
for msg in msgs: for msg in msgs:
self.sub.setsockopt(zmq.SUBSCRIBE, msg.eid()) self.sub.setsockopt(zmq.SUBSCRIBE, msg.magic() + msg.eid())
if conflare: if conflare:
self.sub.setsockopt(zmq.CONFLATE, 1) self.sub.setsockopt(zmq.CONFLATE, 1)
self.sub.connect(f'tcp://127.0.0.1:{self.bp}') self.sub.connect(f'tcp://127.0.0.1:{self.bp}')

View File

@ -6,13 +6,18 @@ from PIL.TiffImagePlugin import SOFTWARE
PLAYBACK_SOCKET_PORT = 5003 PLAYBACK_SOCKET_PORT = 5003
PLAYBACK_SOCKET = f'127.0.0.1:{PLAYBACK_SOCKET_PORT}' PLAYBACK_SOCKET = f'127.0.0.1:{PLAYBACK_SOCKET_PORT}'
LIVE_SOCKET_IP = '11.6.1.66' LIVE_SOCKET_IP = '11.6.1.71'
LIVE_REP_SOCKET_PORT = 5556 LIVE_REP_SOCKET_PORT = 5556
LIVE_SOCKET = f'{LIVE_SOCKET_IP}:5555' LIVE_SOCKET = f'{LIVE_SOCKET_IP}:5555'
LIVE_REP_SOCKET = f'{LIVE_SOCKET_IP}:{LIVE_REP_SOCKET_PORT}' LIVE_REP_SOCKET = f'{LIVE_SOCKET_IP}:{LIVE_REP_SOCKET_PORT}'
VIDEO_HEIGHT = 1920 VIDEO_HEIGHT = 1920
VIDEO_WIDTH = 1080 VIDEO_WIDTH = 1080
SWITCH1_IP = 'c1'
SWITCH1_TOKEN = '7ad51e0016e7a9d22f753d5110f76c7d'
SWITCH2_IP = 'c2'
SWITCH2_TOKEN = 'bf5a7b77a1ba3761ea63fafd8427b7d6'
BASE = Path(__file__).parent.parent BASE = Path(__file__).parent.parent
DS = BASE / '@DS' DS = BASE / '@DS'
DOC = BASE / 'doc' DOC = BASE / 'doc'

View File

@ -8,6 +8,7 @@ from nodes.Device import Device
from nodes.ImageCV import ImageCV from nodes.ImageCV import ImageCV
from nodes.Loader import Loader from nodes.Loader import Loader
from nodes.MainUI import MainUI from nodes.MainUI import MainUI
from nodes.Muxer import Receiver
from nodes.Robot import Robot from nodes.Robot import Robot
from nodes.WebRTC import WebRTC from nodes.WebRTC import WebRTC
from utils.Msg import KillMsg from utils.Msg import KillMsg
@ -25,6 +26,7 @@ if __name__ == '__main__':
ImageCV(), ImageCV(),
Beamformer(), Beamformer(),
Loader(), Loader(),
Receiver(),
Robot(), Robot(),
] ]
for p in ps: for p in ps:

View File

@ -11,7 +11,7 @@ import zmq
from config import PLAYBACK_SOCKET, VIDEO_WIDTH, VIDEO_HEIGHT, LIVE_SOCKET, IMAGING_CONFIG from config import PLAYBACK_SOCKET, VIDEO_WIDTH, VIDEO_HEIGHT, LIVE_SOCKET, IMAGING_CONFIG
from nodes.Node import Node from nodes.Node import Node
from utils.Msg import BMMsg, ImageArgMsg, KillMsg, SetSeqMetaMsg, SetPlayMode, SetDeviceConfigMsg, SetRecordMsg, \ from utils.Msg import BMMsg, ImageArgMsg, KillMsg, SetSeqMetaMsg, SetPlayMode, SetDeviceConfigMsg, SetRecordMsg, \
RecordFrameMsg, ImagingConfigNameListMsg RecordFrameMsg, ImagingConfigNameListMsg, Msg, RfFrameMsg
from utils.RfFile import RfFrame, RfSequenceMeta from utils.RfFile import RfFrame, RfSequenceMeta
from utils.RfMat import RfMat from utils.RfMat import RfMat
from utils.RfMeta import RfFrameMeta from utils.RfMeta import RfFrameMeta
@ -20,23 +20,16 @@ logger = logging.getLogger(__name__)
class Beamformer(Node): class Beamformer(Node):
topics = [ImageArgMsg, SetSeqMetaMsg, SetPlayMode, SetDeviceConfigMsg, SetRecordMsg] topics = [RfFrameMsg]
def __init__(self, level=logging.INFO): def __init__(self, level=logging.INFO):
super(Beamformer, self).__init__(level=level) super(Beamformer, self).__init__(level=level)
self.arg = ImageArgMsg('', t_start=0, t_end=1499)
self.seq_meta_live = None
self.seq_meta_playback = None
self.record_enable = False
self.record_commit = None
self.record_path: Path | None = None
self.play_mode = None
def process(self, data: RfMat): def process(self, data: RfMat, arg: ImageArgMsg):
if data is None: if data is None:
return return
d2 = (data d2 = (data
.crop(self.arg.t_start, self.arg.t_end) .crop(arg.t_start, arg.t_end)
.rotate90() .rotate90()
.grey() .grey()
.cpu() .cpu()
@ -46,84 +39,25 @@ class Beamformer(Node):
) )
self.send(BMMsg(0, d2.__bytes__())) self.send(BMMsg(0, d2.__bytes__()))
@property
def current_seq_meta(self):
seq_meta = None
match self.play_mode:
case 'live':
seq_meta = self.seq_meta_live
case 'playback':
seq_meta = self.seq_meta_playback
return seq_meta
def loop(self): def loop(self):
device_socket = self.context.socket(zmq.PULL) req_socket = self.context.socket(zmq.REQ)
device_socket.setsockopt(zmq.CONFLATE, 1) req_socket.connect('tcp://127.0.0.1:5559')
self.c.poller.register(device_socket, zmq.POLLIN)
mat = None
time.sleep(1) time.sleep(1)
self.send(ImagingConfigNameListMsg([path.stem for path in IMAGING_CONFIG.glob('*.json')]))
while True: while True:
socks = dict(self.c.poller.poll()) req_socket.send(b'')
if device_socket in socks and socks[device_socket] == zmq.POLLIN: r = req_socket.recv()
buffer = device_socket.recv() if r.__len__() > 0:
logger.debug(f'device receive {buffer.__len__()}') id2 = r.index(Msg.magic(), 1)
_, sequence_id, encoder = struct.unpack_from('=iqi', buffer) id3 = r.index(Msg.magic(), id2 + 1)
s = buffer[4 + 8 + 4:] print(id2, id3)
logger.debug(f'live meta {self.seq_meta_live}, playback meta {self.seq_meta_playback}') seq_msg: SetSeqMetaMsg = Msg.decode_msg(r[:id2])
seq_meta: RfSequenceMeta | None = { arg_msg: ImageArgMsg = Msg.decode_msg(r[id2:id3])
"live": self.seq_meta_live, b_msg: RfFrameMsg = Msg.decode_msg(r[id3:])
"playback": self.seq_meta_playback, s = b_msg.data
}.get(self.play_mode, None) fb1 = cp.frombuffer(s, dtype=cp.int16)
if seq_meta is not None: seq_meta = RfSequenceMeta.from_name(seq_msg.name)
fb1 = cp.frombuffer(s, dtype=cp.int16) mat = RfMat(fb1.reshape(seq_meta.shape), RfFrameMeta(
if fb1.shape[0] == np.prod(seq_meta.shape): encoder=b_msg.encoder,
mat = RfMat(fb1.reshape(seq_meta.shape), RfFrameMeta( sequence_id=b_msg.sequence_id,
encoder=encoder, ), seq_meta)
sequence_id=sequence_id, self.process(mat, arg_msg)
), seq_meta)
if self.record_enable:
bs = mat.__bytes__()
(self.record_path / mat.frame_meta.filename).write_bytes(bs)
self.send(RecordFrameMsg(bs.__len__(), sequence_id))
if self.c.sub in socks and socks[self.c.sub] == zmq.POLLIN:
msg = self.recv()
if isinstance(msg, KillMsg):
if msg.name == '':
return
if isinstance(msg, SetSeqMetaMsg):
match msg.target:
case 'live':
self.seq_meta_live = RfSequenceMeta.from_name(msg.name)
case 'playback':
self.seq_meta_playback = RfSequenceMeta.from_name(msg.name)
if isinstance(msg, ImageArgMsg):
self.arg = msg
if isinstance(msg, SetPlayMode):
logger.debug(f'set playmode {msg}')
self.play_mode = msg.value
if msg.value == 'live':
try:
device_socket.disconnect(f"tcp://{PLAYBACK_SOCKET}")
except:
pass
device_socket.connect(f"tcp://{LIVE_SOCKET}")
elif msg.value == 'playback':
try:
device_socket.disconnect(f"tcp://{LIVE_SOCKET}")
except:
pass
device_socket.connect(f"tcp://{PLAYBACK_SOCKET}")
logger.debug('connect to playback')
if isinstance(msg, SetRecordMsg):
self.record_enable = msg.enable
if msg.enable:
seq_meta = self.current_seq_meta
self.record_commit = msg.commit
seq_meta.commit = msg.commit
p = Path(msg.base) / seq_meta.name
p.mkdir(parents=True, exist_ok=True)
self.record_path = p
self.process(mat)

View File

@ -96,15 +96,6 @@ class Device(Node):
case _: case _:
logger.error(f"Device msg: {rb}") logger.error(f"Device msg: {rb}")
def setfile00(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 setfile(self, config_str: str): def setfile(self, config_str: str):
if self.enabled(): if self.enabled():
self.disable() self.disable()
@ -124,10 +115,16 @@ class Device(Node):
logger.error(f"Device msg: {rb}") logger.error(f"Device msg: {rb}")
return False return False
def loop(self): def data(self):
arr = [] self.device_rep_socket.send(b'data')
return self.device_rep_socket.recv()
def custom_setup(self):
self.device_rep_socket = self.context.socket(zmq.REQ) self.device_rep_socket = self.context.socket(zmq.REQ)
self.device_rep_socket.connect(f"tcp://{LIVE_REP_SOCKET}") self.device_rep_socket.connect(f"tcp://{LIVE_REP_SOCKET}")
def loop(self):
arr = []
time.sleep(1) time.sleep(1)
if self.online(): if self.online():
self.connected() self.connected()

126
src/nodes/Muxer.py Normal file
View File

@ -0,0 +1,126 @@
import logging
import struct
import time
from pathlib import Path
import cupy as cp
import cv2
import numpy as np
import zmq
from config import PLAYBACK_SOCKET, VIDEO_WIDTH, VIDEO_HEIGHT, LIVE_SOCKET, IMAGING_CONFIG
from nodes.Node import Node
from utils.Msg import BMMsg, ImageArgMsg, KillMsg, SetSeqMetaMsg, SetPlayMode, SetDeviceConfigMsg, SetRecordMsg, \
RecordFrameMsg, ImagingConfigNameListMsg, RfFrameMsg
from utils.RfFile import RfFrame, RfSequenceMeta
from utils.RfMat import RfMat
from utils.RfMeta import RfFrameMeta
logger = logging.getLogger(__name__)
class Muxer(Node):
topics = [SetSeqMetaMsg, SetPlayMode, SetDeviceConfigMsg, SetRecordMsg]
def __init__(self, level=logging.INFO):
super(Muxer, self).__init__(level=level)
self.seq_meta = None
self.seq_meta_live = None
self.seq_meta_playback = None
self.record_enable = False
self.record_commit = None
self.record_path: Path | None = None
self.play_mode = None
@property
def current_seq_meta(self):
seq_meta = None
match self.play_mode:
case 'live':
seq_meta = self.seq_meta_live
case 'playback':
seq_meta = self.seq_meta_playback
return seq_meta
def loop(self):
device_socket = self.context.socket(zmq.PULL)
device_socket.setsockopt(zmq.CONFLATE, 1)
rep_socket = self.context.socket(zmq.REP)
rep_socket.bind('tcp://*:5559')
self.arg = ImageArgMsg('', t_start=0, t_end=1499)
self.c.poller.register(device_socket, zmq.POLLIN)
self.c.poller.register(rep_socket, zmq.POLLIN)
rfframemsg: RfFrameMsg | None = None
time.sleep(1)
self.send(ImagingConfigNameListMsg([path.stem for path in IMAGING_CONFIG.glob('*.json')]))
while True:
socks = dict(self.c.poller.poll())
if device_socket in socks and socks[device_socket] == zmq.POLLIN:
buffer = device_socket.recv()
device_socket.disconnect(f"tcp://{LIVE_SOCKET}")
device_socket.connect(f"tcp://{LIVE_SOCKET}")
logger.debug(f'device receive {buffer.__len__()}')
_, sequence_id, encoder = struct.unpack_from('=iqi', buffer)
buf = buffer[4 + 8 + 4:]
logger.debug(f'live meta {self.seq_meta_live}, playback meta {self.seq_meta_playback}')
seq_meta: RfSequenceMeta | None = {
"live": self.seq_meta_live,
"playback": self.seq_meta_playback,
}.get(self.play_mode, None)
if seq_meta is not None:
if (buf.__len__() // 2) == np.prod(seq_meta.shape):
self.seq_meta = seq_meta
rfframemsg = RfFrameMsg(sequence_id, encoder, buf)
fm = RfFrameMeta(
encoder=encoder,
sequence_id=sequence_id,
)
if self.record_enable:
(self.record_path / fm.filename).write_bytes(buf)
self.send(RecordFrameMsg(buf.__len__(), sequence_id))
if rep_socket in socks and socks[rep_socket] == zmq.POLLIN:
rep_socket.recv()
if rfframemsg is None or self.seq_meta is None:
rep_socket.send(b'')
else:
rep_socket.send(SetSeqMetaMsg('any', self.seq_meta.name).encode_msg() +
self.arg.encode_msg() +
rfframemsg.encode_msg())
if self.c.sub in socks and socks[self.c.sub] == zmq.POLLIN:
msg = self.recv()
if isinstance(msg, KillMsg):
if msg.name == '':
return
if isinstance(msg, ImageArgMsg):
self.arg = msg
if isinstance(msg, SetSeqMetaMsg):
match msg.target:
case 'live':
self.seq_meta_live = RfSequenceMeta.from_name(msg.name)
case 'playback':
self.seq_meta_playback = RfSequenceMeta.from_name(msg.name)
if isinstance(msg, SetPlayMode):
logger.debug(f'set playmode {msg}')
self.play_mode = msg.value
if msg.value == 'live':
try:
device_socket.disconnect(f"tcp://{PLAYBACK_SOCKET}")
except:
pass
device_socket.connect(f"tcp://{LIVE_SOCKET}")
elif msg.value == 'playback':
try:
device_socket.disconnect(f"tcp://{LIVE_SOCKET}")
except:
pass
device_socket.connect(f"tcp://{PLAYBACK_SOCKET}")
logger.debug('connect to playback')
if isinstance(msg, SetRecordMsg):
self.record_enable = msg.enable
if msg.enable:
seq_meta = self.current_seq_meta
self.record_commit = msg.commit
seq_meta.commit = msg.commit
p = Path(msg.base) / seq_meta.name
p.mkdir(parents=True, exist_ok=True)
self.record_path = p

View File

@ -28,12 +28,22 @@ class Node:
def loop(self): def loop(self):
pass pass
def __call__(self, *args, **kwargs): def setup(self):
self.base_setup()
self.custom_setup()
def custom_setup(self):
pass
def base_setup(self):
FORMAT = '[%(asctime)s] p%(process)s {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s' FORMAT = '[%(asctime)s] p%(process)s {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s'
FORMAT = '"%(pathname)s:%(lineno)d" %(levelname)s - %(message)s' FORMAT = '"%(pathname)s:%(lineno)d" %(levelname)s - %(message)s'
logging.basicConfig(level=self.level, format=FORMAT) logging.basicConfig(level=self.level, format=FORMAT)
self.context = zmq.Context() self.context = zmq.Context()
if self.enable_init: if self.enable_init:
self.c = BusClient(*([KillMsg] + self.topics), poller=True, conflare=self.conflare) self.c = BusClient(*([KillMsg] + self.topics), poller=True, conflare=self.conflare)
def __call__(self, *args, **kwargs):
self.setup()
self.loop() self.loop()
print(self.__class__.__name__, 'exiting') print(self.__class__.__name__, 'exiting')

View File

@ -33,36 +33,40 @@ class BG(Enum):
SetWindowVisibleMsg = auto() SetWindowVisibleMsg = auto()
SetSidMsg = auto() SetSidMsg = auto()
ImagingConfigNameListMsg = auto() ImagingConfigNameListMsg = auto()
RfFrameMsg = auto()
class Msg: class Msg:
MAGIC = 1919810
@classmethod @classmethod
def decode_base(clz, data: bytes) -> 'Msg': def decode_base(cls, data: bytes) -> 'Msg':
# c = clz() return cls(**json.loads(data.decode()))
# c.__dict__.update(json.loads(data.decode()))
# return c
return clz(**json.loads(data.decode()))
def encode(self) -> bytes: def encode(self) -> bytes:
return json.dumps(self.__dict__).encode() return json.dumps(self.__dict__).encode()
@classmethod @classmethod
def decode(self, data: bytes) -> 'Msg': def decode(cls, data: bytes) -> 'Msg':
return self.decode_base(data) return cls.decode_base(data)
@staticmethod @classmethod
def decode_msg(msg): def decode_msg(cls, msg: bytes):
eid = struct.unpack('I', msg[:4])[0] magic, eid = struct.unpack('II', msg[:8])
assert magic == cls.MAGIC
class_: 'Msg' = globals()[BG(eid).name] class_: 'Msg' = globals()[BG(eid).name]
return class_.decode(msg[4:]) return class_.decode(msg[8:])
@classmethod @classmethod
def eid(cls): def eid(cls):
return struct.pack('I', BG[cls.__name__].value) return struct.pack('I', BG[cls.__name__].value)
@classmethod
def magic(cls):
return struct.pack('I', cls.MAGIC)
def encode_msg(self): def encode_msg(self):
return self.eid() + self.encode() return self.magic() + self.eid() + self.encode()
@dataclasses.dataclass @dataclasses.dataclass
@ -224,13 +228,34 @@ class BMMsg(Msg):
return struct.pack('I', self.t) + self.data return struct.pack('I', self.t) + self.data
@classmethod @classmethod
def decode(clz, data: bytes) -> 'Msg': def decode(cls, data: bytes) -> 'Msg':
return clz( return cls(
struct.unpack('I', data[:4])[0], struct.unpack('I', data[:4])[0],
data[4:] data[4:]
) )
class RfFrameMsg(Msg):
def __init__(self, sequence_id: int, encoder: int, data: bytes):
self.sequence_id = sequence_id
self.encoder = encoder
self.data = data
def encode(self) -> bytes:
return struct.pack(
'II',
self.sequence_id,
self.encoder,
) + self.data
@classmethod
def decode(cls, data: bytes) -> 'Msg':
return cls(
*struct.unpack('II', data[:8]),
data[8:]
)
@dataclasses.dataclass @dataclasses.dataclass
class RobotRtsiMsg(Msg): class RobotRtsiMsg(Msg):
pos: tuple[float, float, float, float, float, float] pos: tuple[float, float, float, float, float, float]

55
src/utils/mi.py Normal file
View File

@ -0,0 +1,55 @@
from miio.miioprotocol import MiIOProtocol
from config import SWITCH1_IP, SWITCH1_TOKEN, SWITCH2_IP, SWITCH2_TOKEN
def c1():
return MiIOProtocol(
SWITCH1_IP, SWITCH1_TOKEN,
)
def c2():
return MiIOProtocol(
SWITCH2_IP, SWITCH2_TOKEN,
)
def c1_set_connect(status: bool):
c1().send('set_properties', [{'did': 'MYDID', 'siid': 2, 'piid': 1, 'value': status}])
def c1_connect():
c1_set_connect(True)
def c1_disconnect():
c1_set_connect(False)
def c1_connected():
return c1().send('get_properties', [{'did': 'MYDID', 'siid': 2, 'piid': 1}])[0]['value']
def c1_power():
return c1().send('get_properties', [{'did': '845778715', 'siid': 11, 'piid': 2}])[0]['value']
def c2_set_connect(status: bool):
c2().send('set_properties', [{'did': 'MYDID', 'siid': 2, 'piid': 1, 'value': status}])
def c2_connect():
c2_set_connect(True)
def c2_disconnect():
c2_set_connect(False)
def c2_connected():
return c2().send('get_properties', [{'did': 'MYDID', 'siid': 2, 'piid': 1}])[0]['value']
if __name__ == '__main__':
print(c2_connect())

View File

@ -7,6 +7,7 @@ from nodes.Broker import Broker
from nodes.Device import Device from nodes.Device import Device
from nodes.ImageCV import ImageCV from nodes.ImageCV import ImageCV
from nodes.Loader import Loader from nodes.Loader import Loader
from nodes.Muxer import Receiver
from nodes.Robot import Robot from nodes.Robot import Robot
from nodes.WebRTC import WebRTC from nodes.WebRTC import WebRTC
from qtonly import kde_pyqt6_mainui from qtonly import kde_pyqt6_mainui
@ -25,6 +26,7 @@ if __name__ == '__main__':
ImageCV(level=logging.DEBUG), ImageCV(level=logging.DEBUG),
Beamformer(), Beamformer(),
Loader(), Loader(),
Receiver(),
Robot(), Robot(),
] ]
for p in ps: for p in ps:

View File

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

33
test/testDevice.py Normal file
View File

@ -0,0 +1,33 @@
import time
from pathlib import Path
from nodes.Device import Device
def test1():
d = Device()
d.setup()
d.connect()
d.enable()
print(d.setfile(
Path('/home/lambda/source/scarlet/flandre/config/device/AA256,U=30,M=PWI,S=(256 1502).txt').read_text()))
d.disable()
d.disconnect()
def test2():
d = Device()
d.setup()
# d.connect()
# d.enable()
# d.setfile(Path('/home/lambda/source/scarlet/flandre/config/device/AA256,U=30,M=PWI,S=(256 1502).txt').read_text())
# time.sleep(2)
while True:
d.data()
print(1)
# d.disable()
# d.disconnect()
if __name__ == '__main__':
test2()

10
test/testmiio.py Normal file
View File

@ -0,0 +1,10 @@
from miio.miioprotocol import MiIOProtocol
from config import SWITCH1_IP, SWITCH1_TOKEN, SWITCH2_IP, SWITCH2_TOKEN
from miio import Device
if __name__ == '__main__':
m = MiIOProtocol(
SWITCH1_IP, SWITCH1_TOKEN,
)
r = m.send('get_properties', [{'did': 'MYDID', 'siid': 2, 'piid': 1}])
print(r[0]['value'])

660
uv.lock

File diff suppressed because it is too large Load Diff