Files

273 lines
8.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Kettenöler CAN Reverse-Engineering Toolkit
Toolsuite (GUI + CLI) zum Analysieren von CAN-Logs im **Kettenöler-Format**.
Funktionen: Logs **splitten** (pro CAN-ID), **explorative Visualisierung** (8-/16-Bit, LE/BE), **Batch-Analysen** über viele `.trace`, **Ranking** plausibler Signale und **Range-Fit** (lineare Abbildung `phys = raw*scale + offset`), optional **unsupervised** ohne vorgegebene Range.
---
## Features (Überblick)
* **Einheitliche GUI** (`main.py`) mit globalem Header (Workdir, Ordnerstruktur, Log-Auswahl).
* **Gemeinsame Trace-Auswahl** in allen Trace-Tabs (gleiches Panel, synchronisiert über Tabs):
* **ID Explorer** (Multi-Select)
* **Traces Batch-Analyse** (Multi-Select oder kompletter Ordner)
* **Range-Fit** (Single-Select, supervised *oder* unsupervised)
* **Splitter**: Logs → `.trace` pro CAN-ID (`traces/…`, inkl. `overview_ids.csv`).
* **Einzel-ID-Explorer**: Plots aller Byte-Kanäle (8-Bit) und Nachbar-Wortkombis (16-Bit LE/BE) + Kurzstatistik.
* **Batch-Analyzer**: Kennzahlen/Plots für alle `.trace` in einem Ordner, globales Ranking.
* **Range-/Unsupervised-Fit**:
* *Supervised*: findet `scale` & `offset` für Zielbereich `[rmin, rmax]` (Offset via Intervall-Überdeckung, Scale aus plausibler Menge).
* *Unsupervised*: identifiziert „ruhige“ physikalische Kandidaten ohne Range (Smoothness/Varianz/Rate/Spannweite).
* **Output-Hygiene**: Ergebnisse stets unter `analyze_out/<timestamp>_<tool>/…`, optionale Zeitstempel-Unterordner verhindern Überschreiben.
* **Projektdatei** (`Projekt.json`): speichert Workdir, Subfolder, Log-Auswahl, aktiven Traces-Ordner, etc.
* **„Neuester Split“**-Button: springt in den jüngsten Unterordner von `traces/`.
---
## Repository-Komponenten
* **GUI**
* `main.py` zentrales Frontend mit Tabs (Multi-Log Analyse, ID Explorer, Traces Batch-Analyse, Range-Fit).
* **CLI-Tools**
* `can_split_by_id.py` Splittet Logs nach CAN-ID → `.trace`.
* `id_signal_explorer.py` Visualisiert/analysiert eine `.trace` (8-Bit, 16-Bit LE/BE) + `summary_stats.csv`.
* `trace_batch_analyzer.py` Batch-Analyse für viele `.trace` + globales Ranking.
* `trace_signal_fitter.py` **Range-Fit** (scale/offset) **oder** **Unsupervised-Fit** (ohne Range).
> Optional/Alt: `can_universal_signal_finder.py` ursprünglicher Multi-Log-Analyzer (Ranking auf Rohdatenebene).
---
## Installation
* **Python** ≥ 3.10
* Abhängigkeiten: `pandas`, `numpy`, `matplotlib`
* Setup:
```bash
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
```
---
## Logformat (Kettenöler)
Eine Zeile pro Frame:
```
<timestamp_ms> <TX|RX> 0x<ID_HEX> <DLC> <byte0> <byte1> ... <byte7>
```
Beispiel:
```
123456 RX 0x208 8 11 22 33 44 55 66 77 88
```
---
## Projekt-/Ordnerstruktur
Ein **Workdir** bündelt alles zu einem Fahrzeug/Projekt:
```
<Workdir>/
Projekt.json # GUI-Einstellungen
logs/ # Input-Logs
traces/ # per-ID .trace (vom Split)
analyze_out/ # Ergebnisse; je Run eigener Timestamp-Unterordner
```
**Namenskonventionen**
* Split-Ergebnisse: `traces/<timestamp?>/0x<ID>_<ursprungslog>.trace`
* Outputs: `analyze_out/<YYYYMMDD_HHMMSS>_<tool>/…`
---
## Modelle-Ordner & Git
Wenn du pro Modell arbeitest, z. B.:
```
models/
Triumph 2023/
logs/
traces/
analyze_out/
Projekt.json
```
Lege in `models/` folgende **`.gitignore`** ab, damit `traces/` und `analyze_out/` **in jedem Modell-Unterordner** ignoriert werden `logs/` und `.json` bleiben versioniert:
```gitignore
*/traces/
*/traces/**
*/analyze_out/
*/analyze_out/**
traces/
traces/**
analyze_out/
analyze_out/**
# optional: typos
*/analyze.out/
*/analyze.out/**
analyze.out/
analyze.out/**
```
Leere Ordner wie `logs/` ggf. mit `.gitkeep` befüllen.
---
## GUI-Benutzung
```bash
python3 main.py
```
### Globaler Header (immer oben)
* **Workdir** wählen, **Logs scannen** → Liste aller gefundenen Logfiles (Multi-Select).
* Subfolder einstellen: `logs`, `traces`, `analyze_out` (alle **parallel** im Workdir).
* **Projekt speichern/laden** (`Projekt.json`).
* Beim Workdir-Wechsel/Projekt-Laden setzt die GUI den **aktiven Traces-Ordner** automatisch auf `traces/` bzw. den **jüngsten** Unterordner.
### Einheitliches Trace-Panel (in allen Trace-Tabs)
* Links: Liste der `.trace`
* Rechts: **Traces-Ordner wählen**, **Workdir/traces**, **Neuester Split**, **Refresh**, (optional **Alle**, **Keine**)
* Änderungen am Ordner/Liste wirken **sofort in allen Tabs**.
### Tab: Multi-Log Analyse
* Ranking direkt aus Logs (Include/Exclude-IDs, optional Range mit `scale/offset`).
* Output: `analyze_out/<ts>_multilog/…`
* Optional: „Jede Logdatei separat“ → je Log eigener Unterordner.
### Tab: ID Explorer
* **Split** (aus Header-Logauswahl): Logs → `.trace` nach `traces[/<ts>]`, plus `overview_ids.csv`.
Danach wird der neue Traces-Pfad **automatisch aktiviert**.
* **Einzel-ID Analyse** (Multi-Select):
* Plots: Byte\[0..7] (8-Bit) + LE/BE für Paare (0-1 … 6-7)
* `summary_stats.csv` pro Trace
* Output: `analyze_out/<ts>_id_explore/…`
### Tab: Traces Batch-Analyse
* Nutzt die gemeinsame Trace-Liste.
* **Ohne Auswahl** → kompletter Ordner; **mit Auswahl** → es wird ein Subset-Ordner gebaut (Hardlinks/Kopie) und nur dieses analysiert.
* Parameter: `--rx-only`, `scale`, `offset`, `range-min/max`, `top`, `--plots`.
* Output:
* je Trace: `*_combostats.csv` (+ Plots),
* global: `summary_top_combinations.csv`
* unter `analyze_out/<ts>_trace_batch/…`
### Tab: Range-Fit (Single-Select)
* **Zwei Modi**:
1. **Supervised** (Range-Min/Max gesetzt): findet `scale` & `offset`, maximiert **Hit-Ratio** im Zielbereich.
Output: `<trace>_encoding_candidates.csv` + phys-Plots (Top-N).
2. **Unsupervised** (Range leer): bewertet Kandidaten nach **Smoothness**, **Spannweite**, **Varianz**, **Rate**, **Uniqueness**.
Output: `<trace>_unsupervised_candidates.csv` + Roh-Plots (Top-N).
* Optionen: `nur RX`, `negative Scale erlauben` (nur supervised), `Min. Hit-Ratio`, `Min. Smoothness`, `Plots Top-N`, `Output-Label`.
* Output: `analyze_out/<ts>_rangefit/…`
---
## CLI-Quickstart
### 1) Splitten
```bash
python3 can_split_by_id.py logs/run1.log logs/run2.log \
--outdir <Workdir>/traces/20250827_1200 \
--rx-only
```
### 2) Einzel-ID-Explorer
```bash
python3 id_signal_explorer.py <Workdir>/traces/20250827_1200/0x208_run1.trace \
--outdir <Workdir>/analyze_out/20250827_1210_id_explore
```
### 3) Batch-Analyse
```bash
python3 trace_batch_analyzer.py \
--traces-dir <Workdir>/traces/20250827_1200 \
--outdir <Workdir>/analyze_out/20250827_1220_trace_batch \
--rx-only --plots --top 8 \
--range-min 31 --range-max 80
```
### 4) Range-/Unsupervised-Fit (eine `.trace`)
```bash
# Supervised (z. B. Kühlmittel 31..80°C)
python3 trace_signal_fitter.py <trace> \
--rmin 31 --rmax 80 \
--outdir <Workdir>/analyze_out/20250827_1230_rangefit \
--plots-top 8 --min-hit 0.5 --allow-neg-scale
# Unsupervised (ohne Range)
python3 trace_signal_fitter.py <trace> \
--outdir <Workdir>/analyze_out/20250827_1240_unsupervised \
--plots-top 8 --min-smooth 0.2
```
---
## Algorithmen & Heuristiken
* **Kombinationen**:
* 8-Bit: `D0..D7`
* 16-Bit (adjazent): LE & BE für Paare `(0,1)…(6,7)`
*(32-Bit & bit-gepackte Felder: auf der Roadmap)*
* **Prefilter** (für „ruhige“ physikalische Größen):
Mindestanzahl Samples, nicht (nahezu) konstant, keine exzessiven Sprünge (p95 der |Δ| relativ zur Spannweite).
* **Range-Fit**:
Für jeden Kandidaten `raw` wird über eine Menge plausibler **Scales** gesucht; für jedes `scale` wird das **Offset** via **Intervall-Überdeckung** bestimmt (`rmin ≤ scale*raw_i + offset ≤ rmax`). Ranking: Hit-Ratio ↓, dann Glattheit (p95 phys) ↑, Rate ↓, n ↓.
* **Unsupervised**:
**Smoothness** = `1 clamp(p95(|Δ|)/span, 0..1)`; zusätzlich **span**, **var**, **rate**, **uniq\_ratio**. Ranking auf diese Metriken.
---
## Tipps & Troubleshooting
* **Keine Kandidaten (Range-Fit)**: `--min-hit` senken, `--allow-neg-scale` testen, Range prüfen, längeres/variableres Log nutzen.
* **Alles wird gefiltert (Unsupervised)**: `--min-smooth` senken; ggf. `--rx-only` aktivieren.
* **Leere/komische Plots**: DLC < 8 teils keine 16-Bit-Kombis; Frames sehr selten Rate niedrig.
* **Ordner stets sauber**: Zeitstempel-Unterordner aktiv lassen; pro Run eigene Artefakte.
---
## Roadmap
* 32-Bit-Kombinationen, bit-gepackte Felder.
* Histogramme, Autokorrelation, Ausreißer-Detektoren.
* vordefinierte Signal-Profile (z. B. *WheelSpeed*, *CoolantTemp*).
---
## Lizenz / Haftung
Nur zu Analyse-/Reverse-Engineering-Zwecken. Nutzung auf eigene Verantwortung.