119 lines
3.6 KiB
Python
119 lines
3.6 KiB
Python
import logging
|
|
|
|
import numpy as np
|
|
import torch
|
|
|
|
from where_fi.application import CSIApplication
|
|
from where_fi.collection import CSIMatrix
|
|
from where_fi.collection.ingest import RealtimeCSIProducer
|
|
from where_fi.config import config
|
|
from where_fi.processing.aoa import AoA
|
|
from where_fi.visualise import server as visualise
|
|
|
|
app = CSIApplication(visualise_raw=True)
|
|
|
|
logging.basicConfig(level=logging.INFO)
|
|
|
|
T = 500
|
|
|
|
N_sub1 = config.antennas.count // 2
|
|
N_sub2 = config.subcarriers // 2
|
|
L2 = config.subcarriers - N_sub2 + 1
|
|
L1 = config.antennas.count - N_sub1 + 1
|
|
N_sensors = config.subcarriers * config.antennas.count
|
|
historical = torch.zeros(T, N_sensors, N_sensors, dtype=torch.complex64)
|
|
|
|
cnt = 0
|
|
|
|
|
|
@app.on_sample
|
|
def _(sample: CSIMatrix) -> None:
|
|
global cnt
|
|
sample_before_resize = sample[:, :, 0].T
|
|
sample_after = sample_before_resize.reshape(-1, 1)
|
|
sample_tensor = torch.tensor(sample_after)
|
|
historical[cnt] = sample_tensor @ torch.conj(sample_tensor).T
|
|
print(
|
|
f"{sample.shape} => {sample_before_resize.shape} => {sample_after.shape} "
|
|
f"=> {historical[cnt].shape}"
|
|
)
|
|
cnt = (cnt + 1) % T
|
|
|
|
|
|
def get_steering(theta: float, tau: float) -> torch.Tensor:
|
|
"""
|
|
Calculate the alpha value for the given angle and time delay.
|
|
"""
|
|
sub, ant = np.indices((N_sub1, N_sub2))
|
|
alpha = np.exp(
|
|
-1j
|
|
* (
|
|
2 * np.pi * (sub * config.delta_f * tau)
|
|
+ 2
|
|
* np.pi
|
|
* (
|
|
ant
|
|
* config.antennas.spacing
|
|
* np.sin(theta)
|
|
* 299_792_458
|
|
/ (config.central_freq_hz + (sub - 28) * config.delta_f)
|
|
)
|
|
)
|
|
)
|
|
alpha = sub + 1j * ant
|
|
alpha = alpha.reshape(-1, 1)
|
|
return torch.tensor(alpha, dtype=torch.complex64)
|
|
|
|
|
|
aoa = AoA()
|
|
|
|
|
|
@app.on_process
|
|
def _(_: CSIMatrix) -> None:
|
|
R: torch.Tensor = torch.mean(historical, axis=0)
|
|
# Rss = torch.zeros(N_sub1 * N_sub2, N_sub1 * N_sub2, dtype=torch.complex64)
|
|
# for i in range(L1):
|
|
# for j in range(L2):
|
|
# Rss += R[i : i + N_sub1 * N_sub2, j : j + N_sub1 * N_sub2]
|
|
# Rss /= L1 * L2
|
|
Rss = R
|
|
|
|
aoa.historical_autocorr = torch.unsqueeze(Rss, 0)
|
|
aoa.heatmap(app.visualise_data)
|
|
|
|
# eigvals, eigvecs = torch.linalg.eig(Rss)
|
|
# app.visualise_data(eigvals.numpy(), visualise.figures.Figure.MUSIC_EIGENVALUES)
|
|
# E_n = eigvecs[:, torch.abs(eigvals) < config.music.eigval_threshold]
|
|
# E_n_H = torch.conj(E_n.T)
|
|
|
|
# heatmap = np.zeros(
|
|
# (config.music.heatmap.tof_resolution, config.music.heatmap.theta_resolution)
|
|
# )
|
|
# for i_theta, theta in enumerate(
|
|
# np.linspace(0, np.pi, config.music.heatmap.theta_resolution)
|
|
# ):
|
|
# for i_tau, tau in enumerate(
|
|
# np.linspace(
|
|
# 0, config.music.heatmap.tof_max, config.music.heatmap.tof_resolution
|
|
# )
|
|
# ):
|
|
# steering = get_steering(theta, tau)
|
|
# steering_h = torch.conj(steering.T)
|
|
# c = 1 / (steering_h @ E_n @ E_n_H @ steering)
|
|
# heatmap[i_tau, i_theta] = torch.abs(c)
|
|
# print(steering)
|
|
# app.visualise_data(heatmap, visualise.figures.Figure.AOA_HEATMAP)
|
|
# eigvals, eigvecs = torch.linalg.eig(Rss)
|
|
# app.visualise_data(eigvals.numpy(), visualise.figures.Figure.MUSIC_EIGENVALUES)
|
|
# E_n = eigvecs[:, torch.abs(eigvals) < config.music.eigval_threshold]
|
|
|
|
# print(E_n)
|
|
# c: torch.Tensor = 1 / (steering_h @ E_n @ E_n_H @ steering)
|
|
# return torch.abs(c)[:, 0, 0]
|
|
|
|
|
|
if __name__ == "__main__":
|
|
producer = RealtimeCSIProducer()
|
|
app.set_producer(producer)
|
|
app.start()
|