From 81c7b04fe79d51eda303d34edbf717be30aee818 Mon Sep 17 00:00:00 2001 From: Christos Falas Date: Thu, 2 Jan 2025 11:27:10 +0000 Subject: [PATCH] send tensor over queue instead of aoa object --- src/__main__.py | 6 ++---- src/aoa.py | 18 +++++++++--------- src/config.py | 2 ++ src/ingest.py | 4 ++-- src/visualise/__init__.py | 15 ++++++++++----- 5 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/__main__.py b/src/__main__.py index ca41293..0d3c647 100644 --- a/src/__main__.py +++ b/src/__main__.py @@ -32,12 +32,10 @@ receivers = [ # Start injecting CSI frames transmitter = ingest.FeitTransmitter() -webapp_queue: "mp.Queue[aoa.AoA]" = manager.Queue(config.SAMPLE_RATE) - -visualise.aoa_queue = webapp_queue +webapp_queue: "mp.Queue[aoa.AoA]" = mp.Queue(config.SAMPLE_RATE) # Start webapp in background process -webapp = mp.Process(target=visualise.start) +webapp = mp.Process(target=visualise.start, args=(webapp_queue,)) webapp.start() receiver_processes = [ diff --git a/src/aoa.py b/src/aoa.py index d6ff4fb..8f2ffde 100644 --- a/src/aoa.py +++ b/src/aoa.py @@ -48,7 +48,7 @@ class AoA: return H_sm - def update(self, data: torch.Tensor): + def update(self, data: torch.Tensor) -> torch.Tensor: self.timestamp = datetime.now() H_sm = self.smooth(data) @@ -74,9 +74,10 @@ class AoA: # and the largest span the signal subspace. eigvals, eigvecs = torch.linalg.eigh(R) logging.debug(f"Eigenvalues: {eigvals}") - self.E_n = eigvecs[:, torch.abs(eigvals) < config.EIGVAL_THRESHOLD] + return eigvecs[:, torch.abs(eigvals) < config.EIGVAL_THRESHOLD] - def steering_vector(self, theta: float, tof: float): + @staticmethod + def steering_vector(theta: float, tof: float): omega_t = torch.exp( torch.tensor([-2j * torch.pi * config.DELTA_F * tof], dtype=torch.complex64) ) @@ -97,24 +98,23 @@ class AoA: omega_t = torch.unsqueeze(omega_t, dim=-1) phi_theta = torch.unsqueeze(phi_theta, dim=-1) - antenna_v = omega_t ** torch.arange(self.N_subcarriers // 2) - phis = phi_theta ** torch.arange(self.N_rx // 2) + antenna_v = omega_t ** torch.arange((config.N_SUBCARRIERS - 2) // 2) + phis = phi_theta ** torch.arange((len(config.ANTENNA_ORDER)) // 2) antenna_v = torch.unsqueeze(antenna_v, dim=-1) print(antenna_v.shape, phis.shape) steering = antenna_v[0] * phis print(steering.shape) return steering.T.reshape(-1) - def evaluate(self, theta: float, tof: float): + @staticmethod + def evaluate(E_n: torch.Tensor, theta: float, tof: float): try: - steering = self.steering_vector(theta, tof) + steering = AoA.steering_vector(theta, tof) steering_h = torch.conj(steering).T except Exception as e: logger.exception(e) return 0 - assert isinstance(self.E_n, torch.Tensor) - E_n = self.E_n E_n_H = torch.conj(E_n).T c = 1 / (0.001 + (steering_h @ E_n @ E_n_H @ steering)) return torch.abs(c.real) diff --git a/src/config.py b/src/config.py index f1b7129..5dae68d 100644 --- a/src/config.py +++ b/src/config.py @@ -34,3 +34,5 @@ C = 299_792_458 # m/s VISUALISE_RAW = False HEATMAP_FPS = 10 + +N_SUBCARRIERS = 56 diff --git a/src/ingest.py b/src/ingest.py index 4247dcd..25a60db 100644 --- a/src/ingest.py +++ b/src/ingest.py @@ -100,10 +100,10 @@ class CSIProcessor: processed = preprocess.preprocess(all_data) processed_tensor = torch.tensor(processed, device=device) # visualise.add_data(all_data_tensor, processed) - aoa.update(processed_tensor) + E_n = aoa.update(processed_tensor) logger.info("Processed data") if not webserver.full(): - webserver.put(aoa) + webserver.put(E_n) @staticmethod def process_forever( diff --git a/src/visualise/__init__.py b/src/visualise/__init__.py index aaa5722..9f769d7 100644 --- a/src/visualise/__init__.py +++ b/src/visualise/__init__.py @@ -5,8 +5,10 @@ import numpy.typing as npt from simple_websocket import Server import time from datetime import datetime -import multiprocessing as mp +import torch.multiprocessing as mp +import torch +from functools import partial import matplotlib.pyplot as plt import io import logging @@ -92,7 +94,7 @@ def add_data( del subscriber_settings[subscriber] -def make_heatmap(aoa: AoA, max_tof: float): +def make_heatmap(aoa_E_n: torch.Tensor, max_tof: float): logger.info(f"Making heatmap with aoa of {aoa.timestamp}") fig = plt.figure() ax = fig.add_axes([0, 0, 1, 1], polar=True) @@ -101,7 +103,8 @@ def make_heatmap(aoa: AoA, max_tof: float): R, Theta = np.meshgrid(r, theta) # Create a 2D grid of r and theta # Compute the function values - Z = np.log(np.vectorize(aoa.evaluate)(Theta, R)) + eval_func = partial(AoA.evaluate, aoa_E_n) + Z = np.log(np.vectorize(eval_func)(Theta, R)) ax.pcolormesh(Theta, R, Z, edgecolors="face") buf = io.BytesIO() @@ -119,11 +122,11 @@ def gather_aoa(max_tof: float): while True: while (datetime.now() - prev_frame).total_seconds() < 1 / config.HEATMAP_FPS: time.sleep(0.01) + while not aoa_queue.empty(): logger.debug("Receiving from aoa pipe") aoa = aoa_queue.get() prev_frame = datetime.now() - logger.debug(f"Generating heatmap of time {aoa.timestamp}") buf = make_heatmap(aoa, max_tof) yield (b"--frame\r\nContent-Type: image/jpeg\r\n\r\n" + buf.read() + b"\r\n") buf.close() @@ -141,5 +144,7 @@ def aoa_tof(): ) -def start(): +def start(queue: "mp.Queue[torch.Tensor]"): + global aoa_queue + aoa_queue = queue app.run(debug=True, use_reloader=False, host="0.0.0.0")