84 lines
2.2 KiB
Python
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()
|