Update MEMORY.md, MEMORY.md, bachelor-thesis-summary.md, and 76 more files
This commit is contained in:
commit
4426388063
79 files changed
+6169
No files matched your search
@@ -0,0 +1,37 @@
|
||||
# BLE Indoor Positioning - Bachelor Thesis Summary Agent Memory
|
||||
|
||||
## Projekt-Kontext
|
||||
- Bachelorarbeit an einer Fachhochschule, ca. 50 Seiten
|
||||
- Thema: BLE-basierte Indoor-Lokalisierung mit ESP32 iBeacons + Android-App (Kotlin)
|
||||
- Forschungsfrage: Zuverlaessigkeit BLE-basierter Indoor-Navigation fuer sehbehinderte Personen
|
||||
- Fokus: Elektrotechnische Betrachtung, RSSI-Modellierung, Machbarkeitsstudie
|
||||
- Abgrenzung: Keine sicherheitskritische/medizinische Anwendung
|
||||
|
||||
## Technische Architektur (Key Details)
|
||||
- 5-stufige Pipeline: BleScanner -> BeaconFilterManager -> PositionCalculator -> PositionSmoother -> UI
|
||||
- RSSI-Filter: Kalman (primaer), EMA, MovingAverage als Alternativen (RssiFilter-Interface)
|
||||
- Positionsberechnung: IDW (Exponent 4) -> Gauss-Newton -> Blending (0.5-1.5m Uebergang)
|
||||
- Ausreisser-Schwellwert: 20 dBm; Beacon-Frische: 3s
|
||||
- Kalibrierung: RSSI_AT_ONE_METER=-65 dBm, PATH_LOSS_EXPONENT=5.5
|
||||
- Raum: 3.5x4.5m, 3 Beacons
|
||||
|
||||
## Akademische Konventionen
|
||||
- Expose-Struktur: Projektvorstellung (~40%) -> Umsetzungskonzept (~50%) -> Fazit/Ausblick (~10%)
|
||||
- Sprache: Deutsch, akademisch aber verstaendlich, keine Umlaute (ASCII-kompatibel fuer Textdateien)
|
||||
- Umfang einseitige Zusammenfassung: ca. 400-500 Woerter
|
||||
- Keine Code-Snippets in Zusammenfassungen, technische Aspekte in Prosa
|
||||
|
||||
## Gliederung der Bachelorarbeit
|
||||
1. Einleitung & Motivation (4-5 S.)
|
||||
2. Grundlagen (10-12 S.)
|
||||
3. Stand der Technik (8-9 S.)
|
||||
4. Systemkonzept (8-9 S.)
|
||||
5. Implementierung (7-8 S.)
|
||||
6. Evaluation & Messergebnisse (8-9 S.)
|
||||
7. Fazit & Ausblick (3-4 S.)
|
||||
|
||||
## Lessons Learned
|
||||
- Quellcode ist komplett deutsch kommentiert
|
||||
- Kein DI-Framework, direkte Instanziierung in MainActivity
|
||||
- StateFlow fuer reaktive UI-Updates (Compose)
|
||||
- Expose als reine Textdatei (kein Markdown) mit ASCII-Umlauten (ae, oe, ue, ss)
|
||||
@@ -0,0 +1,118 @@
|
||||
# Gemini-Delegator Memory
|
||||
|
||||
## Bug-Patterns
|
||||
|
||||
### State-Initialisierung bei Scan-Start
|
||||
**Problem identifiziert:** In BleScanner wurde `PositionCalculator` nur beim `startScanning()` initialisiert. Config-Änderungen während eines laufenden Scans wurden nicht übernommen.
|
||||
|
||||
**Lösung:** Extrahiere Initialisierungs-Logik in separate Methode (`initializePositionCalculator()`), biete öffentliche `reloadConfig()` Methode an. UI ruft diese nach Config-Änderung auf.
|
||||
|
||||
**Pattern:** Bei Langlebigen Objekten (Scanner) die State von kurzlebiger Config abhängt → Reload-Mechanismus vorsehen.
|
||||
|
||||
### KeyboardType für negative Zahlen
|
||||
**Problem:** `KeyboardType.Decimal` und `KeyboardType.Number` erlauben in Android Compose **kein Minuszeichen**.
|
||||
|
||||
**Lösung:** `KeyboardType.Text` für Felder verwenden, die negative Werte akzeptieren müssen (Koordinaten, RSSI). Validierung via `toDoubleOrNull()` bleibt bestehen.
|
||||
|
||||
**Betroffene Felder:** Beacon-Koordinaten (X/Y), Raum-Positionen (X/Y), RSSI-Werte (immer negativ).
|
||||
|
||||
## Hardware-Debugging
|
||||
|
||||
### BLE-Unsichtbarkeit (ESP32 + Android)
|
||||
**Problem:** Ein spezifischer ESP32-C3 wird auf einem spezifischen Android-Handy NICHT gefunden (auch nicht mit nRF Connect), auf anderen Handys aber schon. Andere ESP32s funktionieren auf dem problematischen Handy.
|
||||
|
||||
**Ursache (wahrscheinlich):** MAC-Adress-Kollision oder Android BLE-Controller-Blacklisting auf Hardware-Level.
|
||||
|
||||
**Diagnose-Schritte:**
|
||||
1. Original BLE-MAC auslesen (`esp_bt_dev_get_address()` nach `BLEDevice::init()`)
|
||||
2. Mit MAC auf funktionierendem Handy (nRF Connect) vergleichen
|
||||
3. Custom-MAC setzen via `esp_base_mac_addr_set()` **VOR** `BLEDevice::init()`
|
||||
|
||||
**Lösung:** Custom-MAC flashen mit locally administered Address (Byte 0 = `0x02`), eindeutige Werte wählen.
|
||||
|
||||
**Code-Pattern (ESP32):**
|
||||
```cpp
|
||||
#include "esp_bt_device.h" // Für MAC-Ausgabe
|
||||
#include "esp_mac.h" // Für MAC-Setzen
|
||||
|
||||
uint8_t custom_mac[6] = {0x02, 0xAA, 0xBB, 0xCC, 0xDD, 0x05};
|
||||
esp_base_mac_addr_set(custom_mac); // VOR BLEDevice::init()
|
||||
BLEDevice::init("Name");
|
||||
const uint8_t* ble_mac = esp_bt_dev_get_address(); // Ausgeben
|
||||
```
|
||||
|
||||
**Quellen:** [Random Nerd Tutorials](https://randomnerdtutorials.com/get-change-esp32-esp8266-mac-address-arduino/), [Nordic DevZone BLE Invisibility](https://devzone.nordicsemi.com/f/nordic-q-a/77366/nrf-ble-android---my-blescannercompat-doesn-t-detect-a-device-but-nrf-connect-does)
|
||||
|
||||
## Projekt-Spezifisches
|
||||
|
||||
### BLE Indoor Positioning App
|
||||
- **Aktive Version:** `/App v2/` (vorher `/App v1_2/`)
|
||||
- **Config-Persistierung:** SharedPreferences via `ConfigRepository`
|
||||
- **Datenfluss:** ConfigRepository → BleScanner → PositionCalculator → UI
|
||||
- **Keine DI:** Direkte Instanziierung, StateFlow für Reaktivität
|
||||
- **Sprache:** Kotlin, Compose UI, Kommentare auf Deutsch
|
||||
- **Koordinaten:** Beliebige Werte möglich (auch negativ) – Bounding Box wird aus Räumen + Beacons berechnet
|
||||
|
||||
### Kritische Klassen
|
||||
- `BleScanner`: Zentrale BLE-Logik, verwaltet Scanner, Filter, Calculator, Smoother
|
||||
- `PositionCalculator`: Trilateration (IDW + Gauss-Newton + Blending)
|
||||
- `ConfigRepository`: Lädt/Speichert AppConfig (Raumgröße + Beacon-Positionen)
|
||||
- `BeaconFilterManager`: Verwaltet RSSI-Filter pro Beacon (Kalman/EMA/MA)
|
||||
|
||||
### Häufige Fehlerquellen
|
||||
- Config-Änderungen während laufender Operationen
|
||||
- Initialisierung nur bei Start ohne Reload-Mechanismus
|
||||
- Fehlende Synchronisation zwischen UI-State und Scanner-State
|
||||
|
||||
### Config-Modell Pattern (erweitert)
|
||||
**Gelernt bei:** Individuelle pathLossExponent + rssiAtOneMeter pro Beacon
|
||||
- `@Serializable data class` mit Default-Werten → Abwärtskompatibilität (alte Configs ohne neue Felder laden mit Defaults)
|
||||
- Neue Felder in **beiden** Dialogen:
|
||||
- **AddBeaconDialog:** Neue Beacons (Default-Werte vorbelegen: `mutableStateOf("5.5")`)
|
||||
- **EditBeaconDialog:** Bearbeitung (beacon.field.toString() initialisieren)
|
||||
- Config-Anzeige: LazyColumn erweitern (neue Felder anzeigen)
|
||||
- Beacon-Liste klickbar: `.clickable { showEditBeaconDialog = beacon }`
|
||||
- Berechnungs-Methoden: Per-Beacon-Lookup mit Fallback → `beacons.find { it.minor == beaconMinor }?.field ?: globalDefault`
|
||||
|
||||
## Gemini-Interaktion
|
||||
|
||||
### Rate Limits
|
||||
Gemini: 429 RESOURCE_EXHAUSTED möglich, liefert oft trotzdem Ergebnisse nach Retries (am Ende der Ausgabe).
|
||||
|
||||
### Gemini Prompt Best Practices
|
||||
- Kontext vollständig angeben (relevante Code-Ausschnitte mit Line-Nummern)
|
||||
- Aufgabe strukturiert (nummeriert), Dateipfade explizit
|
||||
- Output-Format: "OUTPUT ONLY unified diff, no explanations"
|
||||
|
||||
### Wann selbst fixen vs. Gemini
|
||||
- **Selbst:** Klare Anforderung, minimale Änderung (z.B. KeyboardType-Wechsel)
|
||||
- **Gemini:** Große Refactorings, komplexe Algorithmen
|
||||
- **Nach Gemini:** IMMER fachlich prüfen (Typ, Logik, Patterns)
|
||||
|
||||
### Gemini Fehler-Pattern
|
||||
**Problem:** Gemini generiert Diffs mit falschen Annahmen über Datenstrukturen
|
||||
- **Beispiel (2026-02-10):** Negative Koordinaten – Gemini verwendete `.corners` (nicht existent) statt `.x/.y/.width/.height`
|
||||
- **Lösung:** Bei strukturellen Änderungen (Datenmodell, API) relevante Klassen vollständig in Prompt inkludieren
|
||||
- **Warnung:** Gemini erfindet manchmal Pfade (`com.example` statt `com.erik`) → Diff-Pfade immer prüfen
|
||||
|
||||
### Color-Parameter in @Composable mit Canvas (2026-02-10)
|
||||
**Problem:** Gemini versuchte `beaconColor: Color = MaterialTheme.colorScheme.primary` als Default-Parameter in Funktionssignatur zu setzen – funktioniert NICHT, da kein @Composable-Context in Parameter-Defaults verfügbar ist.
|
||||
|
||||
**Lösung:** Color-Parameter MIT Defaults direkt in der @Composable-Funktion deklarieren (wo MaterialTheme verfügbar ist). Bei Helper-Funktionen (z.B. drawRooms) Parameter ohne Defaults durchreichen.
|
||||
|
||||
**Korrektur:** Nach Gemini-Output selbst gefixt – Color-Parameter in FloorplanView mit MaterialTheme-Defaults versehen, drawRooms()-Signatur manuell erweitert.
|
||||
|
||||
### Material Icons Verfügbarkeit (2026-02-10)
|
||||
**Problem:** Gemini generiert oft nicht-existierende Material Icons (z.B. `DarkMode`, `LightMode`, `Brightness4`, `Brightness7`, `Nightlight`, `WbSunny`).
|
||||
|
||||
**Lösung:** Nach Gemini-Output IMMER Icon-Verfügbarkeit prüfen:
|
||||
- Nur Icons aus `Icons.Default.*` verwenden, die in bestehenden Dateien bereits verwendet werden (z.B. `Settings`, `Place`, `Info`)
|
||||
- Falls spezielle Icons benötigt werden: Im Projekt nach verwendeten Icons greppen (`Icons\.Default\.`)
|
||||
- Fallback: Generische Icons wie `Info`, `Check`, `Star` verwenden
|
||||
|
||||
**Warnung:** `Icons.Outlined`/`Icons.Filled` sind oft nicht vollständig in älteren Material Icons Versionen verfügbar.
|
||||
|
||||
### remember() außerhalb @Composable (2026-02-10)
|
||||
**Problem:** Gemini verwendete `var isDarkMode by remember { mutableStateOf(...) }` in `MainActivity.onCreate()` – `remember` funktioniert NICHT außerhalb von `@Composable` Funktionen.
|
||||
|
||||
**Lösung:** Direkt `mutableStateOf()` als Property verwenden (`private var isDarkMode by mutableStateOf(false)`) oder `rememberSaveable` INNERHALB `setContent { }` Block nutzen.
|
||||
Reference in new issue
Block a user