dissertation/examples/motion_detector.py
2025-05-16 01:11:22 +01:00

84 lines
2.2 KiB
Python

"""Motion Detection example
This example shows how to use the CSI framework to connect to a FeitCSI host and
detect changes in the environment
"""
import numpy as np
import numpy.typing as npt
from where_fi.application import CSIApplication
from where_fi.collection.ingest import RealtimeCSIProducer
from where_fi.config import config
from where_fi.visualise import server as visualise
# Connect to a FeitCSI host
app = CSIApplication(visualise_raw=True)
# Register visualisations
app.register_figure(
"magn-diff",
visualise.figures.PerAntennaFigure(
[
visualise.figures.SimpleLineChart(
"Magnitude diff", "Subcarrier", "Magnitude"
),
],
[lambda x: x],
),
)
app.register_figure(
"phase-diff",
visualise.figures.PerAntennaFigure(
[
visualise.figures.SimpleLineChart("Phase diff", "Subcarrier", "Phase"),
],
[lambda x: x],
),
)
MAGN_THRESHOLD = 0.2
PHASE_THRESHOLD = 0.02
QUEUE_SIZE = 20
# Stores historical data for each receiving antenna, for each subcarrier
historical = np.zeros(
(QUEUE_SIZE, config.subcarriers, config.antennas.count, 1), dtype=np.complex64
)
sample_position = 0
@app.on_process
def _(sample: npt.NDArray[np.complex64]) -> None:
"""
Process the CSI data and detect changes in the environment.
This function is called by the framework at a fixed interval, with the latest CSI
sample received.
It is used to detect changes in the environment caused by motion, by comparing each
entry in the matrix with a moving average
"""
global sample_position
historical[sample_position] = sample
sample_position = (sample_position + 1) % QUEUE_SIZE
mean = np.mean(historical, axis=0)
magn_diff = np.abs(mean - sample)
phase_diff = np.abs(np.angle(mean) - np.angle(sample))
app.visualise_data(magn_diff, "magn-diff")
app.visualise_data(phase_diff, "phase-diff")
if (magn_diff > MAGN_THRESHOLD).any() or (phase_diff > PHASE_THRESHOLD).any():
print("Motion detected!")
else:
print("No motion detected!")
if __name__ == "__main__":
# Start the application
print("Starting app")
app.set_producer(RealtimeCSIProducer())
app.start()