Skip to content

ARLab-VT/BLE-IMU-DistanceEstimation

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

IMU-RSSI Distance Estimation

This repository contains the code, data pipeline, and trained models for the paper:

"On-Body Distance Estimation Using IMU Orientation and BLE RSSI with a Quaternion-Based LSTM" (Under review)

The system estimates the distance between two wearable sensor nodes — one on the right forearm and one on the pelvis — by fusing BLE RSSI with IMU orientation quaternions using a deep learning model (QuaternionRNN).


Key Results

Method Median MAE (m) Mean MAE (m)
QuaternionRNN (Proposed) 0.056 0.069
RSSI Only (ML baseline) 0.132 0.156
UKF (RSSI only) 0.181 0.180
UKF (Orientation-aware) 0.222 0.313
EKF Baseline 0.306 0.576

Evaluated under leave-one-out cross-validation across 6 participants.


Hardware

Sensor Role Frequency
BNO-085 (custom build) IMU + BLE RSSI — worn on right forearm and pelvis 40 Hz
XSens MVN (motion capture suit) Ground truth position, orientation, acceleration 240 Hz

The BNO-085 measures 3D orientation (quaternion) and received signal strength (RSSI in dBm) simultaneously. XSens is used only to generate ground truth inter-sensor distance labels for training and evaluation.


Repository Structure

IMU_RSSI/
│
├── ML_analysis/                   # Main machine learning pipeline
│   ├── build_dataset.py           # Reads CSVs, builds HDF5 train/test splits
│   ├── common.py                  # Quaternion utilities (multiply, inverse, normalize)
│   ├── train.py                   # Training script (QuaternionRNN, per-participant)
│   ├── evaluate_all_models.py     # Evaluation and plotting for trained models
│   ├── compare_all.py             # Combines all method errors for comparison
│   │
│   ├── models/
│   │   └── quat_mlp/
│   │       └── quat_MLP.py        # QuaternionRNN model definition (LSTM-based)
│   │
│   ├── trained_weights/           # Saved model weights (.pth files)
│   │
│   ├── Dataset/
│   │   ├── all_data/              # Raw per-participant CSV files
│   │   └── output_data/           # HDF5 train/test splits per participant
│   │
│   ├── kalman_baseline/           # UKF and EKF baselines for comparison
│   │   ├── path_loss.py           # Log-distance path loss model fitting
│   │   ├── ukf_runner.py          # UKF variants (RSSI-only, orientation, accel-aided)
│   │   ├── load_raw_data.py       # Loads raw acceleration/orientation CSVs
│   │   ├── evaluate_comparison.py # Runs all methods and generates comparison plots
│   │   ├── plot_paper_comparison.py # Log-scale boxplot for paper figures
│   │   ├── plot_all_comparisons.py  # Grouped boxplots (3, 4, 5 method variants)
│   │   ├── run_comparison.ipynb   # Main notebook: run UKF comparison pipeline
│   │   ├── compare_all_methods.ipynb # Combines LSTM + RSS + EKF + UKF results
│   │   └── plot_comparisons.ipynb   # Re-plots from saved JSON (no recompute)
│   │
│   └── EKF_baseline/
│       └── ekf.py                 # Extended Kalman Filter implementation
│
├── Experiment_Data/               # Raw experiment recordings (P03-P08)
│   └── P03/, P04/, ...            # Per-participant folders with session subfolders
│
├── Codes/                         # Arduino/embedded firmware for BNO-085 sensors
│
├── ImuRssi_utils.py               # Quaternion math, rotation matrix utilities
├── XSens_BNO_data_utils.py        # Data loading utilities for XSens and BNO CSVs
│
└── Python Scripts[Jupyter notebooks]            # Data synchronization, cleaning, visualization

Setup

Python version: 3.10 or 3.11

pip install numpy pandas matplotlib torch h5py scipy scikit-learn
pip install pytransform3d open3d openpyxl filterpy

Data Format

Raw CSV files follow this naming convention:

{SYSTEM}_{PARTICIPANT}_{SESSION}_{LOCATION}_{DATATYPE}.csv
Field Values
SYSTEM BNO, XSENS
PARTICIPANT P03P08
SESSION S1, S2, S3
LOCATION PLV (pelvis), RFA (right forearm), PLV_RFA
DATATYPE ori (4 cols, quaternion), acc (3 cols), rssi (1 col), dist (1 col)

All files have no header row. Columns are ordered as described above.


Reproducing Results

1. Build the dataset

Open and run ML_analysis/build_dataset.py or the train_all_models.ipynb notebook. Set paths to your all_data/ directory and output directory.

2. Train the model

cd ML_analysis
python train.py

Trains one QuaternionRNN model per participant under leave-one-out cross-validation. Saves best weights to models/.

3. Evaluate

python evaluate_all_models.py

Generates scatter plots and boxplots of per-participant errors.

4. Run Kalman baseline comparison

Open ML_analysis/kalman_baseline/run_comparison.ipynb, set the config paths, and run all cells. This fits UKF/EKF baselines on training data and evaluates them on the same test splits as the LSTM.

5. Generate paper figures

Open ML_analysis/kalman_baseline/compare_all_methods.ipynb to combine all 5 methods and generate the grouped boxplot figures used in the paper.


Model Architecture

QuaternionRNN (ML_analysis/models/quat_mlp/quat_MLP.py)

  • Input: sliding window of length T=5 over 5-dimensional vectors [q_w, q_x, q_y, q_z, RSSI]
  • Architecture: 2-layer LSTM, hidden size 16, dropout 0.1
  • Output: scalar distance prediction (metres)
  • Loss: L1 (MAE)
  • Optimizer: Adam, lr=0.001, 300 epochs, batch size 2048

The relative quaternion q_norm = q_PLV^{-1} ⊗ q_RFA is computed during dataset building so the model sees orientation of the forearm relative to the pelvis, not in the global frame.


Kalman Filter Baselines

Three UKF variants are implemented in kalman_baseline/:

Variant Measurement model
UKF (RSSI only) RSSI = RSSI(d0) - 10·n·log10(d/d0) + v
UKF (Orientation-aware) Above + linear quaternion correction c·q
UKF (Accel-aided) Orientation-aware + adaptive process noise scaled by |a_RFA - a_PLV|

Path-loss reference: d0 = 0.61 m (24 inches), RSSI(d0) = -60 dBm (measured experimentally). All other parameters are fit from training data via OLS.


Citation

If you use this code or dataset, please cite:

[Citation to be added upon publication]

Contact

For questions about the code or dataset, please open a GitHub issue.

About

Repository containing the codes and ML model for inter-sensor distance estimation using BLE-RSSI

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors