Predictive-maintenance prototype for Tata Technologies InnoVent 2026 (Automotive · Edge AI for Vehicle Health & Predictive Maintenance).
A lightweight 1D-CNN + LSTM model predicts the Remaining Useful Life (RUL) of degrading components from multivariate sensor windows, quantised to INT8 TFLite for on-device inference on a Raspberry Pi 4 / Jetson Nano.
| Roadmap phase (brief) | Module | State |
|---|---|---|
| Weeks 1–2 · Data pipeline + baseline model | src/data.py, src/model.py, src/train.py |
✅ runnable |
| Weeks 3–4 · Optimisation + TFLite export | src/export_tflite.py |
✅ runnable (INT8) |
| Weeks 5–8 · Edge sensor loop + on-device runtime | src/edge_runtime.py |
✅ runnable (replay + vibration fusion) |
| — · Vibration signal preprocessing | src/preprocessing.py |
✅ runnable |
| — · Transfer learning (cross-fault-mode) | src/transfer.py |
✅ runnable |
| Weeks 9–10 · Dashboard + alerts | dashboard/ (Expo RN) + src/server.py |
✅ runnable |
| Metric | Float Keras | INT8 TFLite |
|---|---|---|
| RMSE (cycles) | 13.75 | 14.06 |
| Within ±15 cycles | 74% | — |
| NASA CMAPSS score | 383.5 | — |
| Model size | 185 KB | 197.8 KB |
Reproduce: place the FD001 files in data/ (below) and run python -m src.train
then python -m src.export_tflite.
Data note: if the CMAPSS files are absent from
data/, the pipeline falls back to synthetic data so the code path stays testable offline. Synthetic metrics validate plumbing, not real accuracy. The numbers above are from the real dataset.
python3 -m venv --system-site-packages .venv # reuse a system TensorFlow if present
. .venv/bin/activate
pip install -r requirements.txtDownload the CMAPSS Jet Engine Simulated Data (NASA Prognostics Data
Repository / Kaggle mirror) and place these files in data/:
data/train_FD001.txt
data/test_FD001.txt
data/RUL_FD001.txt
src/data.py auto-detects them and switches off the synthetic fallback.
python -m src.data # inspect the prepared tensors / data source
python -m src.train # train + evaluate (RMSE, ±15-cycle acc, CMAPSS score)
python -m src.export_tflite # INT8 quantise + verify size & accuracy delta
python -m src.preprocessing # vibration cleaning + FFT-feature self-test
python -m src.edge_runtime --unit 24 # on-device loop + vibration fusion (replays a real engine)The edge device serves live health state over local WiFi; the mobile app renders an RUL gauge, trend sparkline, vibration/explainability stats, and alert banner. (BLE is the alternative transport on real hardware.)
# 1. On the edge device / laptop — stream a replayed engine:
python -m src.server --unit 24 --hz 2 --loop # http://0.0.0.0:8000
# 2. In dashboard/ — point config.js DEFAULT_HOST at the device LAN IP, then:
cd dashboard && npm install && npx expo start # open in Expo Go on your phoneServer endpoints: GET /api/state, /api/history, /api/stream (SSE), /healthz.
Pretrain where labelled degradation data is plentiful (FD001), then fine-tune onto a target domain with a different fault mode and far less data. FD003 (HPC + fan degradation) stands in for the OBD domain gap — the identical procedure applies to a labelled OBD trip dataset. CNN front-end is frozen; LSTM + head are fine-tuned at a lower learning rate.
python -m src.transfer --source FD001 --target FD003 --fractions 0.1 0.25 1.0Measured (FD003 test set; zero-shot FD001→FD003 ≈ 58 RMSE):
| Target data | Scratch RMSE | Transfer RMSE | Improvement |
|---|---|---|---|
| 10% | 83.5 | 18.5 | +77.9% |
| 25% | 20.5 | 17.0 | +16.8% |
| 100% | 13.9 | 16.8 | −20.2% |
Transfer wins decisively in the low-data regime (the realistic case for scarce automotive failure data); with abundant target data, training from scratch catches up since the frozen CNN caps capacity.
- RUL labelling: piecewise-linear, clipped at
rul_cap(125) so the model learns degradation instead of fitting flat healthy-life targets. - Normalisation: min-max fit on train only, applied to test (no leakage).
- Evaluation: RMSE + the NASA asymmetric CMAPSS score (late predictions penalised harder than early ones — under-warning is more dangerous).
- Quantisation: the LSTMs use
unroll=Trueso the graph is static, which is required for clean full-integer TFLite conversion.