Code Monkey home page Code Monkey logo

csikit's Introduction

CSIKit Build Downloads

Tools for extracting Channel State Information from formats produced by a range of WiFi hardware/drivers, written in Python with numpy.

Python 3.8+ required.

  • CSI parsing from Atheros, Intel (IWL5300/AX200/AX210), Nexmon, ESP32, FeitCSI and PicoScenes (USRP, etc) formats.
  • Processing and Visualisation using numpy and matplotlib.
  • CSV/JSON generators for dataset serialisation.
  • Library and Tools for parsing CSI for your own Python applications.

Documentation updates are incoming.

Don't have your own CSI data? Check out CSI-Data for a collection of public CSI datasets.

CSIKit Command Line Example

Description

CSIKit is a framework aimed at assisting data scientists, researchers, and programmers with performing experiments and tests using CSI-capable WiFi hardware.

While the various public extraction toolkits do include scripts for parsing CSI data from their specific formats, these are largely written for MATLAB. Given the increasing focus on using deep learning in CSI experimentation, Python tools for parsing and processing CSI data may be more desirable for some. This is aimed at improving the accessibility of CSI research for those who may be interested in the area but have little experience with network engineering.

As is usually the case with research-oriented software, documentation is in-progress.

CSIKit provides a command line tool for parsing, processing, converting, and visualisation of CSI data, as well as libraries for use in other Python applications such as those working with Tensorflow, PyTorch, etc.

csikit [OPTIONS] file[.pcap/.dat/.csv/.csi]

Installation

CSIKit can be installed via pip or used directly from source.

pip install csikit

Example

Command Line

csikit log.all_csi.6.7.6.dat
csikit --graph --graph_type all_subcarriers log.all_csi.6.7.6.dat
csikit --csv log.all_csi.6.7.6.dat

CSIKit library

Generic example:

from CSIKit.reader import get_reader

my_reader = get_reader("path/to/csi_file.dat/pcap")
csi_data = my_reader.read_file("path/to/my_csi_file.dat/pcap")

Hardware-specific (Intel IWL5300) example:

from CSIKit.reader import IWLBeamformReader

my_reader = IWLBeamformReader()
csi_data = my_reader.read_file("path/to/log.all_csi.6.7.6.dat")

Library

CSIKit exposes key components for use in other Python applications: Reader and csitools. As other sections of code become more refined, this will likely grow over time.

Note: This documentation is initial and brief. More will follow shortly.

A Reader is used to read a given CSI capture file and generate parsed traces and matrices. As each file format differs a significant amount, different readers are necessary for each piece of hardware. Using the get_reader method in CSIKit.reader, the correct reader can be automatically selected for a given file. Optionally, hardware-specific readers can be imported, as ATHBeamformReader, IWLBeamformReader, NEXBeamformReader, CSVBeamformReader, PicoScenesBemaformReader, FeitCSIBeamformReader.

Once instantiated, a Reader can be used to read a file using the read_file method. This method returns a CSIData object, which contain frames (CSIFrame objects), timestamps, and metadata from parsing (errors, device information, etc). Additional parsing options can be passed to read_file, including scaled (bool) to rescale CSI values from manufacturer's internal scaling.

CSIFrames will have a different type, based on the type of Reader used to parse them. All CSIFrames contain a csi_matrix (being the most significant part of the payload), however they also contain additional attributes for each frame. Some attributes may be common across the different frame types, however they can vary significantly from one type to another. Next steps for this library are aimed at further integrating these standards. The full list of attributes associated with each frame are listed below.

Using CSI Matrices

CSI matrices contain complex numbers representing the gain and phase of a signal at a given subcarrier. These are output in their complex form in CSIFrames, however csitools contains a function for retrieving CSI amplitude from them.

from CSIKit.reader import get_reader
from CSIKit.util import csitools

my_reader = get_reader("path/to/file.pcap")
csi_data = my_reader.read_file("path/to/file.pcap", scaled=True)
csi_matrix, no_frames, no_subcarriers = csitools.get_CSI(csi_data)

The returned tuple contains a modified matrix which contains CSI amplitudes in dBm, followed by the number of frames and subcarriers represented therein.

Once we have CSI amplitude data, we can also apply filters for preprocessing (as seen in many publications making use of CSI).

This example below loads a given CSI file, applies some basic preprocessing, and plots the data in a heatmap.

from CSIKit.filters.passband import lowpass
from CSIKit.filters.statistical import running_mean
from CSIKit.util.filters import hampel

from CSIKit.reader import get_reader
from CSIKit.tools.batch_graph import BatchGraph
from CSIKit.util import csitools

import numpy as np

my_reader = get_reader("/path/to/csi/file")
csi_data = my_reader.read_file("/path/to/csi/file", scaled=True)
csi_matrix, no_frames, no_subcarriers = csitools.get_CSI(csi_data, metric="amplitude")

# CSI matrix is now returned as (no_frames, no_subcarriers, no_rx_ant, no_tx_ant).
# First we'll select the first Rx/Tx antenna pairing.
csi_matrix_first = csi_matrix[:, :, 0, 0]
# Then we'll squeeze it to remove the singleton dimensions.
csi_matrix_squeezed = np.squeeze(csi_matrix_first)

# This example assumes CSI data is sampled at ~100Hz.
# In this example, we apply (sequentially):
#  - a lowpass filter to isolate frequencies below 10Hz (order = 5)
#  - a hampel filter to reduce high frequency noise (window size = 10, significance = 3)
#  - a running mean filter for smoothing (window size = 10)

for x in range(no_frames):
  csi_matrix_squeezed[x] = lowpass(csi_matrix_squeezed[x], 10, 100, 5)
  csi_matrix_squeezed[x] = hampel(csi_matrix_squeezed[x], 10, 3)
  csi_matrix_squeezed[x] = running_mean(csi_matrix_squeezed[x], 10)

BatchGraph.plot_heatmap(csi_matrix_squeezed, csi_data.timestamps)

ATHCSIFrame

Reference based on the Atheros CSI Tool User Guide.

  • timestamp: Timestamp of seconds since epoch for this CSI frame.
  • csi_length: Expected length of the CSI matrix payload.
  • tx_channel: Wireless channel the collecting device is receiving on (represented in Hz/frequency).
  • err_info: PHY error code. 0 when valid.
  • noise_floor: Current noise floor.
  • rate: Transmission rate (not yet sure if bitmask).
  • bandwidth: Transmission bandwidth (0->20MHz, 1->40MHz)
  • num_tones: Number of subcarriers (tones).
  • nr: Number of receiving antennas present.
  • nc: Number of transmitting antennas present.
  • rssi: Total observed RSSI (signal strength in dB).
  • rssi_1: Observed RSSI on the first receiving antenna.
  • rssi_2: Observed RSSI on the second receiving antenna (if present).
  • rssi_3: Observed RSSI on the third receiving antenna (if present).
  • payload_length: Expected length of the frame payload.

IWLCSIFrame

  • timestamp_low: Timestamp indicating the current state of the IWL5300's built-in clock.
  • bfee_count: Index of the frame out of all those observed during uptime.
  • n_rx: Number of receiving antennas present.
  • n_tx: Number of transmitting antennas present.
  • rssi_a: Observed RSSI (signal strength in dB) on the first receiving antenna.
  • rssi_b: Observed RSSI on the second receiving antenna (if present).
  • rssi_c: Observed RSSI on the third receiving antenna (if present).
  • noise: Current noise floor.
  • agc: Automatic gain control setting.
  • antenna_sel: Bitmask indicating the permutation setting.
  • length: Reported length of a CSI payload.
  • rate: Bitmask indicating the rate at which this frame was sent.

Hint :

IWLCSIFrame visualization can be count at ./docs

NEXCSIFrame

This format is based on the modified version of nexmon_csi (credit mzakharo) for BCM43455c0 with support for RSSI and Frame Control. If using the regular version of nexmon_csi, these fields will not contain this data.

  • rssi: Observed RSSI (signal strength in dB) on the receiving antenna.
  • frame_control: Frame Control bitmask.
  • source_mac: MAC address for the device which sent the packet.
  • sequence_no: Sequence number of the frame for which CSI was captured.
  • core: Binary field indicating the core being used.
  • spatial_stream: Binary field indicating the spatial stream being used.
  • channel_spec: Channel configuration, hex representation of the selected channel and bandwidth pairing.
  • chip: Broadcom chipset version of the collecting device.

FeitCSIFrame

Format based on FeitCSI format documentation

  • num_rx: Number of receiving antennas present.
  • num_tx: Number of transmitting antennas present.
  • num_subcarriers: Number of subcarriers
  • rssi_1: Observed RSSI on the first receiving antenna.
  • rssi_2: Observed RSSI on the second receiving antenna.
  • source_mac: MAC address for the device which sent the packet.
  • channel_width: Transmission bandwidth.
  • rate_format: Transmission rate.
  • mcs - MCS index.
  • antenna_a: 1 if active, 0 if deactive.
  • antenna_b: 1 if active, 0 if deactive.
  • ftm_clock: Clock tick, every tick 3.125ns.

Supported Hardware

  • Qualcomm Atheros 802.11n Chipsets
  • Intel IWL5300
  • Broadcom BCM4339, BCM4358, BCM43455c0, BCM4366c0
  • ESP32 via ESP32-CSI-Tool
  • Intel AX200/AX210 via PicoScenes
  • USRP SDRs (N2xx, B2xx, X3xx) via PicoScenes
  • Intel AX200/AX210 via FeitCSI

Coming Soon

Proper Documentation

  • Once my thesis is over.

Mistakes and Tests

If anything is wrong, let me know. I want to know why, and fix it!

I'm a PhD student working on several sensor data-focussed experiments, a few of which involve using CSI. I'm am by no means an RF engineer or particularly experienced this area. I have done and are doing as much as I can to make sure that anything produced with this is accurate. To that end, there are MATLAB .mat files included in the tests folder which have been generated using IWLBeamformReader, NEXBeamformReader, and scipy's savemat method. There are also MATLAB scripts in the scripts folder which can be used to check the validity of the output from this tool. In my experience I have found these tools to produce identical output to the MATLAB scripts offered by the following developers. If this is not the case, let me know.

Further to that, if there are any assertions I have made within code comments or otherwise which are factually incorrect, again let me know. I want to learn as much about this area as I reasonably can.

Reference Links

License

The code in this project is licensed under MIT license. If you are using this codebase for any research or other projects, I would greatly appreciate if you could cite this repository or one of my papers.

a) "G. Forbes. CSIKit: Python CSI processing and visualisation tools for commercial off-the-shelf hardware. (2021). https://github.com/Gi-z/CSIKit."

b) "Forbes, G., Massie, S. and Craw, S., 2020, November. WiFi-based Human Activity Recognition using Raspberry Pi. In 2020 IEEE 32nd International Conference on Tools with Artificial Intelligence (ICTAI) (pp. 722-730). IEEE."

@electronic{csikit:gforbes,
    author = {Forbes, Glenn},
    title = {CSIKit: Python CSI processing and visualisation tools for commercial off-the-shelf hardware.},
    url = {https://github.com/Gi-z/CSIKit},
    year = {2021}
}

@inproceedings{forbes2020wifi,
  title={WiFi-based Human Activity Recognition using Raspberry Pi},
  author={Forbes, Glenn and Massie, Stewart and Craw, Susan},
  booktitle={2020 IEEE 32nd International Conference on Tools with Artificial Intelligence (ICTAI)},
  pages={722--730},
  year={2020},
  organization={IEEE}
}

csikit's People

Contributors

candyzorua avatar dingyiyi0226 avatar fredej avatar gi-z avatar joerieaerts avatar kuskosoft avatar tweigel-dev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

csikit's Issues

RSS RSSI dBm dB

Hay @Gi-z ,
I am very interested extracting csi with the intel5300. I noticed that you are using some snippets of the python PR by @pgawlowicz.
I didn't understand at his code, what the difference of rssi_db and rssi is because at rssi he doese some stuff with magic number 44 and the agc.

rssiA_db = rssiA - 44 - agc

Did you know that the 44 is ?
which roll does the agc play at the rssi value ?
The results are negativ at rssi_db .
what did you think is the unit of the rssiA value we are collecting directly from the udp-package?
In my eyes the definition of RSS and RSSI are unclear at the wifi usage.

Confusing about the method of reversing the AGC

Hi Glenn,

I'm quite appreciate for this great project. But I'm still confused about something that shown in this issue:#9 (comment).

First, why it requires a sqrt computation for the formula that is used for reversing the AGC? Is it due to the energy that we used to compute for this formula? As I this both components in this formula have the same unit, therefore, we may not need to do a sqrt computation.

Second, I saw that you multiply csi data with its conjecture and I think the result after doing this will only be a real value rather than a complex value. I think we may multiply csi data with itself. Am I missing something? Thank you so much in advance.

Best Regards

IndexError: list index out of range

Hey,

I have collected data using the Nexmon-CSI-Tool:
https://github.com/nexmonster/nexmon_csi/tree/pi-5.4.51-plus

I've collected the CSI data and store them in a pcap file :
output.zip

I dont even get an output of these File:
csikit output.pcap
Traceback (most recent call last):
File "/usr/local/bin/csikit", line 10, in <module> sys.exit(main())
File "/usr/local/lib/python3.7/dist-packages/CSIKit/__main__.py", line 57, in main display_info(args.file)
File "/usr/local/lib/python3.7/dist-packages/CSIKit/tools/get_info.py", line 7, in display_info metadata = csi_data.get_metadata()
File "/usr/local/lib/python3.7/dist-packages/CSIKit/csi/csidata.py", line 45, in get_metadata final_timestamp = timestamps[-1]
IndexError: list index out of range

If i use your examples, it works.
Thanks in advance!

RxSBasicSegment has no attribute cbw

Hi there,
I have some measurements using Picoscenes with two usrp n210 devices, however when I try parsing them with csikit, I get the following error:
Screenshot_20230324_131050
I am using the example code provided in the readme, and when I try and parse an example file py picoscenes it correctly reads the data in. Any Ideas on what this issue might be?

Unable to get example version of CSIKit library working

Hi there!

Thank you so much for your fantastic library, it is a really unique resource within the CSI community.

I have been able to use CSIKit from the command line just fine, but am struggling to get the library version working using the generic example. Would you be able to assist please? I have come across a couple of issues:

1. Unable to import CSIKit.filters

When attempting to import CSIKit.filters using the example line from CSIKit.filters import lowpass, hampel, running_mean I get the error: ImportError: cannot import name 'lowpass' from 'CSIKit.filters' (/usr/local/lib/python3.9/site-packages/CSIKit/filters/__init__.py).

I have been able to work around this by running from CSIKit.util.filters import lowpass, hampel, running_mean, but I'm not 100% if that is valid or if I'm just avoiding the issue.

2. Unable to process frames

Running for x in no_frames: using the example code gives me the error: TypeError: 'int' object is not iterable. This is even whilst using the example data and trying out both csv and pcap data. I'm guessing I may not be importing a required third party library but I'm not sure.

Setup

  • Python 3.9.7
  • macOS
import numpy as np 
from CSIKit.util.filters import lowpass, hampel, running_mean
from CSIKit.reader import get_reader
from CSIKit.util import csitools

my_reader = get_reader("/MY_PATH/csikit/CSIKit/data/esp32/example_data.csv")
csi_data = my_reader.read_file("/MY_PATH/csikit/CSIKit/data/esp32/example_data.csv", scaled=True)
csi_matrix, no_frames, no_subcarriers = csitools.get_CSI(csi_data, metric="amplitude", squeeze_output=True)
csi_matrix_trans = np.transpose(csi_matrix)

#This example assumes CSI data is sampled at ~100Hz.
#In this example, we apply (sequentially):
#  - a lowpass filter to isolate frequencies below 10Hz (order = 5)
#  - a hampel filter to reduce high frequency noise (window size = 10, significance = 3)
#  - a running mean filter for smoothing (window size = 10)

for x in no_frames:
  csi_matrix_trans[x] = lowpass(csi_matrix_trans[x], 10, 100, 5)
  csi_matrix_trans[x] = hampel(csi_matrix_trans[x], 10, 3)
  csi_matrix_trans[x] = running_mean(csi_matrix_trans[x], 10)

Thanks so much for your help!

PicoScenes installation error

Dear sir,
I hope this message finds you well, I am trying to install picoscenes on Ubuntu 20.04 LTS but the terminal always throws the same error:

dpkg: error processing oackage picoscenes-all (--configure):
dependancy problems - leaving unconfigured
Sub-process /usr/bin/dpkg returned an error code (1)

same error for picoscenes-plugins-demo-echoprobe-forwarder

Please help me with this,
Thank you

generates correct Phase Difference

Thanks a lot for your work.

  1. I am new in CSI and saw your code here, is there any clearer calculation on phase?

metric == "phasediff":
if scaled_entry.shape[1] >= 2:
#Not 100% sure this generates correct Phase Difference.

  1. I know the complex number is (gain, phase). how to transfer it to amplitude? why you use 20*log(gain)?

No module named 'CSIKit.filters'

Hi
I installed it just now, when I run csikit csi.dat, it works, but when I run csikit --graph csi.dat, I got No module named 'CSIKit.filters', and when I run csikit --graph --graph-type all_subcarriers csi.dat, I got this error: csikit: error: unrecognized arguments: --graph-type csi.dat. I don't know why.

extract the amplitude and phase information of csi from CSV file

Thanks for the code, but I only have the CSV file with csi obtained from esp32, I want to extract the amplitude and phase information from it, I can't see it is complex at all from the matrix of CSI_Data, how should I extract them? I'm not familiar with python, I'm good with matlab. thanks!

CSIKIT For atheros

The csikit return always an error with atheros data see please:
C:\CSIKit\CSIKit-master\CSIKit\data\atheros>csikit example_bigEndian.dat
Invalid code for beamforming measurement at 0x3.
Traceback (most recent call last):
File "C:\Users\userfso\AppData\Local\Programs\Python\Python39\Scripts\CSIKit-script.py", line 33, in
sys.exit(load_entry_point('CSIKit==0.0.21', 'console_scripts', 'CSIKit')())
File "c:\users\userfso\appdata\local\programs\python\python39\lib\site-packages\CSIKit_main_.py", line 35, in main
display_info(args.file)
File "c:\users\userfso\appdata\local\programs\python\python39\lib\site-packages\CSIKit\get_info.py", line 5, in display_info
reader = get_reader(path)
File "c:\users\userfso\appdata\local\programs\python\python39\lib\site-packages\CSIKit\reader.py", line 12, in get_reader
return IWLBeamformReader(path, scaled=True)
File "c:\users\userfso\appdata\local\programs\python\python39\lib\site-packages\CSIKit\read_bfee.py", line 36, in init
self.csi_trace = scale_timestamps(self.csi_trace)
File "c:\users\userfso\appdata\local\programs\python\python39\lib\site-packages\CSIKit\csitools.py", line 138, in scale_timestamps
csi_trace[0]["timestamp"] = 0
IndexError: list index out of range

can you please enlight me

Training CSIKit data

Hey there!

Thanks for the incredible toolkit! I am looking to take the CSIKit data and train it using TensorFlow. The ability to do this has been mentioned, but would love to better understand how to implement this and so have a couple of questions please. Although I imagine this should be tool-agnostic, I am using the ESP32.

  1. How should I append the training data labels to the data I pass into CSIKit? My data looks like this (data example courtesy of @Gi-z). Could I just create a new column with the label or would CSIKit not accept this?
  2. In what format should I export the CSI data from CSIKit?
  3. Does anyone have any tutorials they can recommend for training CSI data for novice ML engineers please? Page 5 of this research is the best I have found so far.

Thank you so much!

Do you have any information about Intel 5300 CSI data structure?

Thanks for your contribution and providing a powerful toolkit to help me finish the first step of CSI learning. However, when my teammate and I wanted to do more future research on this topic, we found that if we could not figure out the data structure or the definition of the CSI frame, we could not go anywhere.

Here is our equipment information:

Wi-Fi adapter: Intel 5300
OS information: Ubuntu 16.04 with the kernel version 4.15
CSI-related toolset:

If you can provide me with any detail about the CSI data frame definition, I would appreciate what you did.

Graph Dimension Mismatched

I'm new to this project and know very little about Nexmon and CSIKit.

When I tried using CSIKit to plot a graph using the command line provided as an example on my own pcap data, this error occurred:
ValueError: x and y must have same first dimension, but have shapes (250,) and (256, 1, 1)

Here is the info I got from using --info:

Backend: Nexmon CSI
Bandwidth: 80MHz
Antenna Configuration: 1 Rx, 1 Tx
Frame Count: 250
Subcarrier Count: 256
Length: 19.61s
Average Sample Rate: 12.70Hz
Average RSSI: -36.4dBm
CSI Shape: (250, 256, 1, 1)

Did I miss something or is something wrong with the data?

IndexError: List of Range

Hello, I am having similar issues this user, however i try to run another your work WiFi-based Human Activity Recognition using Raspberry Pi.

The actual issue is when the dataset for standup loaded for 50% it halts and throw this errors.

Loaded 52.34% for Activity: standup Loaded 53.27% for Activity: standup Traceback (most recent call last): File "main.py", line 60, in <module> runExperiments(config, datasets, resultsFile) File "main.py", line 46, in runExperiments experiment = Experiment(dataset, config, resultsFile) File "/home/jovyan/work/Wifi_activity_recog_pi/activity_recog/ICTAI-2020-Pi4-Activity-Recognition-main/experiment.py", line 45, in __init__ data = NewPi(config[dataset]["directory"], config[dataset]["config"]) File "/home/jovyan/work/Wifi_activity_recog_pi/activity_recog/ICTAI-2020-Pi4-Activity-Recognition-main/handlers/newpi.py", line 21, in __init__ self.initialiseData(directory, config["downsample"]) File "/home/jovyan/work/Wifi_activity_recog_pi/activity_recog/ICTAI-2020-Pi4-Activity-Recognition-main/handlers/newpi.py", line 123, in initialiseData self.x_all, self.y_all = self.loadDataForActivities(directory, saveToFile=True, downsample=downsample) File "/home/jovyan/work/Wifi_activity_recog_pi/activity_recog/ICTAI-2020-Pi4-Activity-Recognition-main/handlers/newpi.py", line 112, in loadDataForActivities inputArray, outputLabels = self.loadByActivityLabel(directory, activity, activities, saveToFile=saveToFile, windowSize=windowSize, step=step, downsample=downsample) File "/home/jovyan/work/Wifi_activity_recog_pi/activity_recog/ICTAI-2020-Pi4-Activity-Recognition-main/handlers/newpi.py", line 90, in loadByActivityLabel csiOutput = self.loadFromDat(inputFile, windowSize=windowSize, step=step) File "/home/jovyan/work/Wifi_activity_recog_pi/activity_recog/ICTAI-2020-Pi4-Activity-Recognition-main/handlers/newpi.py", line 27, in loadFromDat csi_data = reader.read_file(inputFile) File "/opt/conda/lib/python3.7/site-packages/CSIKit/reader/readers/read_pcap.py", line 284, in read_file data_frames = self.read_frames(self.pcap.frames, scaled, ret_data.bandwidth) File "/opt/conda/lib/python3.7/site-packages/CSIKit/reader/readers/read_pcap.py", line 417, in read_frames if frames[0].payloadHeader["sequence_no"] == frames[-1].payloadHeader["sequence_no"]: IndexError: list index out of range (pi2_env) jovyan@2867d1e59227:~/work/Wifi_activity_recog_pi/activity_recog/ICTAI-2020-Pi4-Activity-Recognition-main$

My best guess that it is related somehow to CSIKit. Any idea how to solve it? Thanks :)

Dependencies in the setup.py

Thanks, @Gi-z for this interesting work.

At present, your package has hard dependencies on the various libraries (numpy, matplotlib etc) i.e. you require specific versions of them. This is problematic if the user of the package is using either newer versions or older versions of them.

Here is the preferred way to specify the versions -

a) Ideally no version information. This should be the preferred choice.
b) If your package requires a minimum version then use >=

e.g.
install_requires =
numpy>=1.19.3
matplotlib>=3.3.4
scikit-learn>=0.24.1
pandas>=1.2.3

or

e.g.
install_requires =
numpy>=1.19
matplotlib>=3.3
scikit-learn>=0.24
pandas>=1.2

In this one, you are requiring that at a minimum both Major and Minor versions should be respected but it is okay to have a different revision number.

I do not know if you really need these specific versions or any version of numpy, matplotlib... etc is good enough. If that is the case then doing

install_requires =
numpy
matplotlib
scikit-learn
pandas

is recommended.

Thanks again for this work; I believe this kind of project will be really helpful to the community.

Regards
Kapil

TypeError: NEXBeamformReader.read_file() got an unexpected keyword argument 'filter_mac'

Hi there!

Thanks a lot for sharing this useful tool!!

I'm trying to use CSIKit to parse .pcap files from raspberry pi 4b. Yet, I'm getting the TypeError: NEXBeamformReader.read_file() got an unexpected keyword argument 'filter_mac'.
Example sample of files:
https://drive.google.com/file/d/1n0B2uxjvbpMWpXHOOPRzgtCmpQrq8Rum/view?usp=sharing

image

Any suggestions you can offer would be hugely appreciated - thank you again !

Modifying `read_pcap.py` to interpret `Nexmonster's pi-5.4.51-plus`

CSIKit works as expected with captures generated from the nexmonster pi-5.4.51
However, I want to extract RSSI data so I am attempting to modify the read_pcap.py for Nexmonster's pi-5.4.51-plus

My changes thus far can be seen in my fork

  • Warning, I thought it was going to be simply replacing a few offsets, but then after that didn't work I started somewhat arbitrarily changing numbers to see what would happen.

One interesting thing to note is that I was expecting the Chip Version to be at position 41 into the payload, however instead it was at 42.

Cannot understand the meaning of the amplitude.

Thanks for your work, I am using your library to read CSI packets generated from Nexmon CSI, but I have some questions about the data.

  1. The channel statement information in 802.11 is calculated by H = Y/X, where H is the CSI. The value of this should have ranged from 0 to 1, 0 means the signal faded significantly and 1 means the signal has no fading after the channel. Due to the multipath channel, the value could be a little bit larger than 1. But the original data obtained by CSIKit are very big, the image below shows the CSI amplitude data in a linear format.
    image
  2. The data looks reasonable after setting the scaled to True, csi_data = my_reader.read_file("DATASET-pi-2\Empty-21.pcap", scaled=True). Could you explain how is the scale works?

Thanks in advance!!

IWL5300 realtime csi gathering

Hay @Gi-z ,
Your tool is very helpful extracting CSI of the Intel5300. Thanks for sharing this.

I see that you implemented some legacy code that extracts CSI directly from the UPD stream. why you discarded this functionality?
The comments of the IWLBreamformReader says that it extracts realtime Data, but the functions seems to be not implemented yet.
In your readme is describing that it is only possible to read the .pcap and die .data files.

I my use-case it would be great to extract CSI at realtime.

How to interpret Atheros data

Hi,

I have collected data using the Atheros-CSI-Tool, I am having issues interpreting it.

from CSIKit.reader import get_reader 
from CSIKit.util import csitools
from CSIKit.util.filters import lowpass, hampel, running_mean
from CSIKit.reader.readers import read_atheros
from CSIKit.csi.frames import ATHCSIFrame 

my_reader = get_reader('data_session2.dat')
csi_data = my_reader.read_file('data_session2.dat')

csi_matrix, no_frames, no_subcarriers = csitools.get_CSI(csi_data)

csi_matrix_trans = np.transpose(csi_matrix)

x = ATHCSIFrame(csi_matrix_trans, csi_matrix)

It throws up an error:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-64-c1e4870f44fa> in <module>
     12 csi_matrix_trans = np.transpose(csi_matrix)
     13 
---> 14 x = ATHCSIFrame(csi_matrix_trans, csi_matrix)

/anaconda3/lib/python3.7/site-packages/CSIKit/csi/frames/ath.py in __init__(self, header_data, csi_matrix)
      9     __slots__ = ["timestamp", "csi_length", "tx_channel", "err_info", "noise_floor", "rate", "bandwidth", "num_tones", "nr", "nc", "rssi", "rssi_1", "rssi_2", "rssi_3", "payload_length", "csi_matrix"]
     10     def __init__(self, header_data: namedtuple, csi_matrix: np.array):
---> 11         self.timestamp = header_data.timestamp
     12         self.csi_length = header_data.csi_length
     13         self.tx_channel = header_data.tx_channel

AttributeError: 'numpy.ndarray' object has no attribute 'timestamp'

but when I get the info I suppose it data is correct because:

from CSIKit.tools.get_info import display_info

x = display_info('data_session2.dat')

gives the output:

Hardware: Atheros 802.11n-compatible
Bandwidth: 40MHz
Antenna Configuration: 2 Rx, 2 Tx
Frame Count: 1
Subcarrier Count: 114
Length: 0.00s
Average Sample Rate: 0.00Hz
CSI Shape: (1, 114, 2, 2)

How can I get the output in form of the ATHCSIFrame(and all the parameters in it)?

Decoding the CSIData section in the frame payload

Hi, for some reason my project has to process the frame payload in format of hex string, each I extracted directly from each frame captured by Nexmon.
By calculating the length of hex string and comparing with number of subcarriers, I noted that the CSI data for each subcarrier is a hex string in length of 8, such as 3715 b616.
However, by examine the read_pcap.py, I didn't understand how CSIKit decode this hex string into a complex float np data. Is there some method that can help with decoding?

The harware we are using is 4366c0 (RT-AC86U), and consider this type of frame:

0000   ff ff ff ff ff ff 4e 45 58 4d 4f 4e 08 00 45 00
0010   01 2e 00 01 00 00 01 11 a4 ab 0a 0a 0a 0a ff ff
0020   ff ff 15 7c 15 7c 01 1a 00 00 11 11 cd 00 fc d9
0030   08 45 38 da 50 f1 00 00 64 d0 6a 00 f4 25 23 2d         # CSI Data start from here: f4 25 23 2d
0040   77 23 5a 14 77 5e ae 13 f7 93 46 11 b6 a6 b3 1e
0050   f6 f1 c7 17 f7 15 8f 08 f5 f9 1b 2a 77 2e 07 00
0060   37 1a 6b 24 b7 00 77 28 f6 9f f7 36 b6 28 8f 3c
0070   76 b0 ea 3e 77 12 36 30 76 63 80 3d f6 ce ac 3a
0080   f6 3e 0d 35 36 82 cd 2d 36 9d 69 26 f6 98 71 02
0090   36 00 7d 26 36 1c b5 10 76 9d 54 15 36 11 ac 16
00a0   76 85 ba 14 76 08 2b 0d f6 4e d7 02 27 08 0f 02
00b0   00 ce d1 d3 d3 00 00 00 f1 0f fa 38 f2 1f 81 24
00c0   b1 7f fd 08 30 60 0a 1c 2d 02 13 10 76 82 11 00
00d0   36 65 3d 0b 36 fa f4 13 f6 7a 3c 1a 76 2b d6 1b
00e0   b6 ba 86 1a f6 3f 3b 17 f7 db 33 0a f7 0e 83 04
00f0   f7 23 7b 20 f7 28 cb 25 37 0b eb 2a 36 c1 f7 3f
0100   77 98 de 33 f7 3c 52 36 f7 20 08 37 37 80 f4 35
0110   b7 d5 08 34 f7 1c 35 30 77 4f 25 2b 37 6f e9 25
0120   37 3d f1 0e b7 6c d5 04 f7 4d 91 09 b7 29 cd 0d
0130   77 e6 98 10 37 ac f4 12 b7 6d 9c 14

Thank you!

Questions and issues with csi matrix

Hello! I am completely new to the topic of CSI and trying to extract it for using it with detecting human poses, and etc. I've obtained a .pcap file type from extracting it on a Raspberry Pi using Nexmon's tool, and I just now need to use CSIKit to parse that data and obtain the CSI matrix. However, when I ran the code with Python and turned it into the format of a .mat file, all the values in the matrix table were negative numbers and doubles. I was told that I am supposed to receive complex doubles and a mix of positive/negative numbers. How do I solve this issue? My code is down below here that I've did some changes on to convert into .mat

from CSIKit.reader import get_reader
from CSIKit.util import csitools
import scipy.io as sio

pcap_file = "path/to/file.pcap"

my_reader = get_reader(pcap_file)

csi_data = my_reader.read_file(pcap_file, scaled=True)

csi_matrix, no_frames, no_subcarriers = csitools.get_CSI(csi_data)

data_for_matlab = {
'csi_matrix': csi_matrix,
'no_frames': no_frames,
'no_subcarriers': no_subcarriers
}

mat_file = "path/to/file.pcap"
sio.savemat(mat_file, data_for_matlab)

Help with this would be greatly appreciated.

CSI data collection issues

I am using a Raspberry Pi (A) to collect CSI data, and keep pinging data to the router through another Raspberry Pi (B). I can collect CSI data, but I don’t know which communication chain the CSI data I collected is. Road data, is this related to the MAC address set by my makecsiparams?
Can anyone answer my question? Thank you so much!

how can i solve this problem? (empty part of data)

Hello, I'm new to nexmon extractor & CSIkit. I was able to extract the pcap file correctly according to the instructions. But I have a few questions. I tried to visualize the data using Gi-z's CSIKit, but there is a part in the middle where there is no data (white part). How can I solve this phenomenon? And there's one more thing. Visualizing the data extracts the same 2000 packets, each of which has a different part about time on the x-axis. Is there a way to time each extraction data?

channel 6 bandwidth 20MHz (there is no last data)
Figure 2023-05-28 210636

channel 44 bandwidth 80MHz (data is empty between.)
ch44bw80


from CSIKit.filters.passband import lowpass
from CSIKit.filters.statistical import running_mean
from CSIKit.util.filters import hampel

from CSIKit.reader import get_reader
from CSIKit.tools.batch_graph import BatchGraph
from CSIKit.util import csitools

import numpy as np

my_reader = get_reader("path pcap file")
csi_data = my_reader.read_file("path pcap file", scaled=True)
csi_matrix, no_frames, no_subcarriers = csitools.get_CSI(csi_data, metric="amplitude")

csi_matrix_first = csi_matrix[:, :, 0, 0]
csi_matrix_squeezed = np.squeeze(csi_matrix_first)

for x in range(no_frames):
csi_matrix_squeezed[x] = lowpass(csi_matrix_squeezed[x], 10, 100, 5)
csi_matrix_squeezed[x] = hampel(csi_matrix_squeezed[x], 10, 3)
csi_matrix_squeezed[x] = running_mean(csi_matrix_squeezed[x], 10)

BatchGraph.plot_heatmap(csi_matrix_squeezed, csi_data.timestamps)

CSI deals with issues

Hello, I read your paper WiFi-based Human Activity Recognition usingRaspberry Pi. I have some doubts,I'm doing related work. In the preprocessing part of the data, I want to add low-pass filtering, but I don't know how to set the cutoff frequency, and I don't know what the filtered result should look like, which makes it impossible for me to judge. Are the filter parameter settings correct?

Raw CSI data

How to preprocess raw CSI data? and can be used for further steps for example train and test with ML
I am using ESP32, OS windows

Filtering Methods

Does CSIKit supports reading data on specific subcarrier and apply filtering on each subcarrier on time-axis?
And could you please explain why applying filter (e.g. lowpass and running mean) along the subcarrier beneficial?

Noise data in nexmon_csi

Greetings

Thank you for proposing this excellent project. However, I found that the noise data, which is important in calculating the SNR, do not include in nexmon_csi. I notice that fwil_type.h in nexmon_csi includes phy_noise and SNR. Could you please take a look at this issue or give me some suggestions?

Thank you so much for your help

Using a routine to process data collected by PicoScene generates an error: struct.error: unpack requires a buffer of 4 bytes

This is my main function:

from CSIKit.filters.passband import lowpass
from CSIKit.filters.statistical import running_mean
from CSIKit.util.filters import hampel

from CSIKit.reader.readers.read_pico import PicoScenesBeamformReader
from CSIKit.tools.batch_graph import BatchGraph
from CSIKit.util import csitools

import numpy as np

my_reader = PicoScenesBeamformReader()
csi_data = my_reader.read_file("./data/rx_usrp_240316_144918.csi", scaled=True)
csi_matrix, no_frames, no_subcarriers = csitools.get_CSI(csi_data, metric="amplitude")

# CSI matrix is now returned as (no_frames, no_subcarriers, no_rx_ant, no_tx_ant).
# First we'll select the first Rx/Tx antenna pairing.
csi_matrix_first = csi_matrix[:, :, 0, 0]
# Then we'll squeeze it to remove the singleton dimensions.
csi_matrix_squeezed = np.squeeze(csi_matrix_first)

# This example assumes CSI data is sampled at ~100Hz.
# In this example, we apply (sequentially):
#  - a lowpass filter to isolate frequencies below 10Hz (order = 5)
#  - a hampel filter to reduce high frequency noise (window size = 10, significance = 3)
#  - a running mean filter for smoothing (window size = 10)

for x in range(no_frames):
  csi_matrix_squeezed[x] = lowpass(csi_matrix_squeezed[x], 10, 100, 5)
  csi_matrix_squeezed[x] = hampel(csi_matrix_squeezed[x], 10, 3)
  csi_matrix_squeezed[x] = running_mean(csi_matrix_squeezed[x], 10)

BatchGraph.plot_heatmap(csi_matrix_squeezed, `csi_data.timestamps)

Running the routine code directly given by the author results in an error:

File "C:\ProgramData\anaconda3\envs\data_process\lib\site-packages\CSIKit\reader\readers\pico\ModularPicoScenesFrame.py", line 27, in parse_header
self.log_exception("Unsupported frame version")
AttributeError: 'ModularPicoScenesFrame' object has no attribute 'log_exception'

image

No error is reported in this step after commenting the following code, but a new error has occurred:

image

image

When I debug, I find that the variable offset becomes a particularly large number after the second loop, resulting in the subsequent buffer array index out of range resulting in an error, but since I am only a Python beginner, I am not sure how to solve this problem.

In the get_block section of the read_pico.py file, the offset is normal the first time the for loop is performed:

image

The second time the for loop is performed, offset becomes a large number, causing the array to exceed the index:

image

The data for processing was obtained on the Ubuntu server using the x310 with PicoScenes software and can be opened using the PicoScenes toolbox on MATLAB. If you can provide relevant help or ideas, I would appreciate it.

RuntimeWarning encountered when using CSIkit with Nexmon's CSI

Hello,

I am currently using Nexmon's CSI acquisition tool to capture CSI for a 4x2 antenna configuration. My setup involves an Asus RT-AC86U as the receiver and a PC as the transmitter, with another Asus RT-AC86U for monitoring. I am using iperf for communication.

When I attempt to run CSIkit on the pcap file I obtained from this setup, I encounter the following error:

RuntimeWarning: invalid value encountered in multiply
return csi * np.sqrt(scale)

I suspect there may be an issue with the data I am capturing. I am aiming to capture CSI for 8 paths, but the pcap file shows that 16 paths are being received, with 8 of them having a value of 0.

I have attached an image of the pcap file for your reference.

I would greatly appreciate any insights or advice you might have on this issue.

Best regards,
スクリーンショット 2023-06-23 142407
スクリーンショット 2023-06-23 142342

Rasberrypi 4(bcm43455c0) IndexError: list index out of range

Thank you for your awesome tools.
i am a studying indoor localization using CSI

(CSIKit) C:\git\CSIKit-master>csikit -c output2.pcap
Traceback (most recent call last):
File "C:\Anaconda\envs\CSIKit\lib\runpy.py", line 192, in _run_module_as_main
return run_code(code, main_globals, None,
File "C:\Anaconda\envs\CSIKit\lib\runpy.py", line 85, in run_code
exec(code, run_globals)
File "C:\Anaconda\envs\CSIKit\Scripts\csikit.exe_main
.py", line 7, in
File "C:\Anaconda\envs\CSIKit\lib\site-packages\CSIKit_main
.py", line 47, in main
generate_csv(args.file, args.csv_dest, args.csv_metric)
File "C:\Anaconda\envs\CSIKit\lib\site-packages\CSIKit\tools\convert_csv.py", line 8, in generate_csv
csi_data = reader.read_file(path)
File "C:\Anaconda\envs\CSIKit\lib\site-packages\CSIKit\reader\readers\read_pcap.py", line 284, in read_file
data_frames = self.read_frames(self.pcap.frames, scaled, ret_data.bandwidth)
File "C:\Anaconda\envs\CSIKit\lib\site-packages\CSIKit\reader\readers\read_pcap.py", line 417, in read_frames
if frames[0].payloadHeader["sequence_no"] == frames[-1].payloadHeader["sequence_no"]:
IndexError: list index out of range

i want to convert .pcap to .csv
So I used the data that I have.
I collected CSI through Raspberry Pi4 using Nexmon_csi.(1000 CSI)

How can i solve this problem?
i hope you give me an answer.
thank you

Visualizing ESP32 data

Hello. Thank you so much for the tool. I have been trying to visualize my CSI Data from ESP32. Is heatmap the only way? I do not see much change in the heatmap when the surrounding is affected. Do I have to use anything in addition to it to visualize the data properly. My goal is to recognize human movements using CSI Data. Thanks again.

Nexmon IndexError: list index out of range

Hi there!

I am trying to use CSIKit to parse .pcap files from raspberry pi 4B. However, I'm constantly facing an error "IndexError: list index out of range". I used to think there was something wrong with my hardware, but the same problem still occurs when sampling with another device.

I have tried these files:
output.pcap, output2.pcap or outputhome.pcap

When I try running the "Using CSI Matrices" sample code you provide

from CSIKit.filters.passband import lowpass
from CSIKit.filters.statistical import running_mean
from CSIKit.util.filters import hampel

from CSIKit.reader import get_reader
from CSIKit.tools.batch_graph import BatchGraph
from CSIKit.util import csitools

import numpy as np

my_reader = get_reader(r"C:\Users\HoChunHi\OneDrive\Desktop\Work\FYP_python\output2.pcap")
csi_data = my_reader.read_file(r"C:\Users\HoChunHi\OneDrive\Desktop\Work\FYP_python\output2.pcap", scaled=True)
csi_matrix, no_frames, no_subcarriers = csitools.get_CSI(csi_data)

# CSI matrix is now returned as (no_frames, no_subcarriers, no_rx_ant, no_tx_ant).
# First we'll select the first Rx/Tx antenna pairing.
csi_matrix_first = csi_matrix[:, :, 0, 0]
# Then we'll squeeze it to remove the singleton dimensions.
csi_matrix_squeezed = np.squeeze(csi_matrix_first)

# This example assumes CSI data is sampled at ~100Hz.
# In this example, we apply (sequentially):
#  - a lowpass filter to isolate frequencies below 10Hz (order = 5)
#  - a hampel filter to reduce high frequency noise (window size = 10, significance = 3)
#  - a running mean filter for smoothing (window size = 10)

for x in range(no_frames):
  csi_matrix_squeezed[x] = lowpass(csi_matrix_squeezed[x], 10, 100, 5)
  csi_matrix_squeezed[x] = hampel(csi_matrix_squeezed[x], 10, 3)
  csi_matrix_squeezed[x] = running_mean(csi_matrix_squeezed[x], 10)

BatchGraph.plot_heatmap(csi_matrix_squeezed, csi_data.timestamps)

then it return the error:

Traceback (most recent call last):
  File "c:\Users\HoChunHi\OneDrive\Desktop\Work\FYP_python\tempCodeRunnerFile.py", line 12, in <module>
    csi_data = my_reader.read_file(r"C:\Users\HoChunHi\OneDrive\Desktop\Work\FYP_python\output2.pcap", scaled=True)
  File "C:\Users\HoChunHi\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\CSIKit\reader\readers\read_pcap.py", line 284, in read_file
    data_frames = self.read_frames(self.pcap.frames, scaled, ret_data.bandwidth)
  File "C:\Users\HoChunHi\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\CSIKit\reader\readers\read_pcap.py", line 417, in read_frames
    if frames[0].payloadHeader["sequence_no"] == frames[-1].payloadHeader["sequence_no"]:
IndexError: list index out of range

Any idea how to solve it ? Hope you can offer me some suggestions!!

IWL5300 IndexError: list index out of range

Hi there!

Thanks so much for putting together this super cool tool, huge fan!!

I'm trying to use CSIKit to parse .dat files from IWL5300, however I'm constantly getting the IndexError: list index out of range error. I noticed this error came up once before, however I think that was resolved with a new version of CSIKit, and I am using the latest version of CSIKit (2.3).

My attempt

Example sample of files I have tried: example_1.dat, example_2.dat or example_3.dat

Running csikit file_here.dat, returns:

james@james ~ % csikit file_here.dat 
Traceback (most recent call last):
  File "/usr/local/bin/csikit", line 8, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.9/site-packages/CSIKit/__main__.py", line 57, in main
    display_info(args.file)
  File "/usr/local/lib/python3.9/site-packages/CSIKit/tools/get_info.py", line 8, in display_info
    metadata = csi_data.get_metadata()
  File "/usr/local/lib/python3.9/site-packages/CSIKit/csi/csidata.py", line 38, in get_metadata
    unmodified_csi_matrix = self.frames[0].csi_matrix
IndexError: list index out of range

Any suggestions you can offer would be hugely appreciated - thank you!

Questions about CSIKit

CSIKit This is a good job, but I have some doubts。

My understanding is that CSI information is collected through nexmon, and CSIKit can parse CSI data, process and visualize it. I don’t know if this understanding is correct?

spatial stream index of nexmon daa

greetings,

Thanks for the good work!

@Gi-z it looks like the spatial stream index is NOT implement, do you have any clue for that?

It is pretty easy, in matlab it is like

payloadbytes = typecast(payload,'uint8');
if strcmp(DEVICE,'ASUS')
    
    core = bitand(payloadbytes(56),3); %
    rxss = bitand(bitshift(payloadbytes(56),-3),3);
    Nss(k) = core*4 + rxss;
    
else
    % payloadbytes(55)
    % 0 8 16 24
   % for NEXUS phone and PI
    Nss(k) =  round( payloadbytes(55)/8);
end

right after line 36 at csireader.m

Best

Jet

Visualisation is in dBm

When using CSIkit from the command line, the graph has dBm as a unit. When I use CSIkit as a library, I get results in the same order of magnitude. Could it be that the CSIkit library does the transformation to dBm while reading in a file? Or does the Atheros CSI tool put out CSI in dBm form?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.