From b6a687982df4b28809cd1f2eac14c99a6bef2391 Mon Sep 17 00:00:00 2001 From: Ashin Walpola Date: Tue, 1 Sep 2026 15:07:57 +0200 Subject: [PATCH] Update the README for the ESP32-C5 path and the two documents The README still described the project as it was before Phase 03. Several claims had become actively wrong rather than merely dated, and the last one is the kind a reviewer would catch: - "no ASN.1 encoding in the app" - the app hand-encodes and decodes CAM, DENM and SPATEM bit by bit on the ESP32-C5 path. domain/asn1/ is now the highest-risk code in the project, and the README denied it existed. - The phase table listed Phase 03 as Bluetooth BLE. Phase 03 is the ESP32-C5; Bluetooth is not implemented and the requirements leave it open. - "communicates with the OBU exclusively via the consider it MQTT API v6" is true of one of the two hardware paths. - The feature list claimed MAP and CPM display. There is no MAPEM decoder and nothing in the tree supports CPM, so both claims are dropped rather than carried forward. - DENM transmission was listed as a headline feature with no indication that it is a manual antenna and range test tool, CiT One only, and deliberately never triggered by a detected event or a use case alert. That decoupling is the project's central architectural rule and the README implied the opposite. - The architecture tree predated domain/asn1, domain/usecase, domain/cam, data/cam, the serial transport, obu-firmware/ and asn1/. Added: the project goal, the two hardware paths and the point where they converge, a verification section, a documentation index, and a status section. The convergence point is worth stating in the README rather than only in the technical document, because it is what makes the second OBU a drop-in rather than a fork: both paths normalise into the domain Cam type at CamUseCaseRepository, and everything above it is shared and transport-agnostic. The status section says plainly that requirement 11.6 is not met, that messages are not signed, and that the detection thresholds are untuned estimates. Someone arriving at this repository should learn that from the front page rather than from page forty of a Word document. --- README.md | 132 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 105 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 6006d33..8f9c900 100644 --- a/README.md +++ b/README.md @@ -2,78 +2,156 @@ Android companion app for the micrOBU; a compact V2X on-board unit developed by HAW Hamburg and consider it GmbH for vulnerable road users (cyclists, e-bike riders, pedestrians). -The app serves as the HMI for the micrOBU hardware, handling V2X message display, sensor data collection, trip recording, and OBU communication over USB-C, Wi-Fi (dev), and Bluetooth (upcoming). +The app is the HMI for the OBU hardware and, on one of the two supported hardware paths, the entire V2X protocol stack. It handles V2X message display, use case detection, sensor collection, trip recording, and OBU communication over USB-C. -**Platform:** Android (Kotlin) · **Min SDK:** 29 (Android 10) · **Target SDK:** 36 +**Platform:** Android (Kotlin) / **Min SDK:** 29 (Android 10) / **Target SDK:** 36 / **Version:** 0.5.0 (Phase 03) + +## Project goal + +Demonstrate V2X communication with at least one C2C-CC bicycle safety use case working on the ESP32-C5, specifically intersection movement assist: a car approaching an intersection on a path that conflicts with the rider's. + +That use case is driven entirely from the periodic position and kinematics vehicles broadcast. It needs no traffic light state and no intersection lane geometry, which is why several scope decisions in this repository look deliberately narrow. + +## Two hardware paths + +The project began against the consider it CiT One and later added the ESP32-C5 as a second option. Both paths are supported at runtime and selected by the rider in Settings > OBU Hardware. + +| | consider it CiT One | ESP32-C5 | +|---|---|---| +| What it is | Complete V2X on-board unit | Development board acting as a plain radio | +| Transport | IP over USB tethering, MQTT | Framed binary protocol over USB CDC serial | +| Reaches the phone as | Processed JSON | Raw ASN.1 UPER bytes | +| V2X stack lives | On the OBU | On the phone, except the radio and GeoNetworking | +| Own CAM generated by | The OBU, autonomously | The phone, transmitted on the phone's clock | +| DENM trigger | Available (manual test tool) | Not available | +| Needs a network | Yes, internally | No | + +Both paths converge at `CamUseCaseRepository`, which normalises whatever arrived into the domain `Cam` type. Everything above that point, including the entire use case detection engine and all UI, is shared and transport-agnostic. That is what makes the ESP32-C5 a drop-in second OBU rather than a fork of the application. ## What it does -**Real-time V2X monitoring**; subscribes to the OBU's MQTT broker and displays live CAM, DENM, SPAT, MAP, and CPM messages grouped by topic with pretty-printed JSON and TX/RX badges. +**Real-time V2X monitoring**; live CAM, DENM and SPATEM with a station list, active hazards, live signal phase, and a map view. On the CiT One path the topic viewer additionally shows whatever the broker publishes, grouped by topic with pretty-printed JSON and TX/RX badges. -**DENM transmission**; triggers DENM use cases (e.g. stationary vehicle warning `hln-sv`) on the OBU via the consider it Use Case API (`v2x-uca/input/denmtrg`) with a single tap. +**CAM-based use case detection**; correlates the rider's own state with a short per-station history of received CAMs to evaluate five C2C-CC bicycle safety use cases (IMA-B, IMA-S, RTW-B, LTW-B, SMVA/BCW-B) and raises alerts under the three-tier Info / Awareness / Warning model. None of these use cases generates a DENM. -**Sensor monitoring**; live readout of phone GNSS, accelerometer, gyroscope, magnetometer, and barometer alongside OBU GNSS for cross-reference. +**Phone-generated CAM**; on the ESP32-C5 path the app builds a CAM from live GNSS and IMU, UPER-encodes it, and pushes it down the serial link for the board to broadcast over ITS-G5. + +**DENM transmission**; CiT One path only. Triggers the stationary vehicle profile (`hln-sv`, causeCode 94) via the consider it Use Case API. This is a manual antenna and range test tool. It is never triggered by a detected event or a use case alert, and the control is hidden entirely on the ESP32-C5 path. **Trip recording**; foreground service records all sensor streams and detects cycling events (braking, turning, stopping) using orientation-independent signal processing. Works fully offline with no OBU connected. **Trip review**; past trips displayed on an OpenStreetMap layer with detected events overlaid as coloured pins. Tap any pin for event details. -**CSV export**; every sensor sample written to a timestamped CSV in real time during a session. Shareable via the standard Android share sheet. +**CSV export**; every sensor sample written to a timestamped CSV in real time. Trip exports additionally include the V2X messages received and their RSSI. Shareable via the standard Android share sheet. ## Architecture MVVM with Repository pattern throughout. Jetpack Compose for all UI (no XML layouts). Hilt for dependency injection. ``` -ui/screens/ Compose screens (Dashboard, V2X Monitor, Sensors, Recording, Trip History, Settings…) +ui/screens/ Compose screens (Dashboard, Record, Trips, V2X Monitor, Settings...) ui/navigation/ Navigation graph and bottom nav bar viewmodel/ MqttViewModel, SensorViewModel, TripRecordingViewModel data/mqtt/ MQTT repository, Paho client, exponential-backoff reconnection -data/transport/ USB tethering detection and gateway IP resolution -data/db/ Room database (sessions, trips, detected events) -data/ SensorRepository, TripRepository, CsvExporter +data/transport/ UsbSerialTransport, SerialFrame, UsbNetworkDetector, ObuHardware +data/cam/ CamUseCaseRepository; where both hardware paths converge +data/db/ Room database (sessions, trips, detected events, V2X messages) +data/ SensorRepository, TripRepository, CsvExporter, TripExporter +domain/asn1/ BitReader/BitWriter and the CAM, DENM and SPATEM UPER codecs +domain/usecase/ UseCaseDetectionEngine, UseCaseDetectionConfig, AlertLevel, GeoMath domain/detection/ EventDetector, RunningStats sliding window (orientation-independent) -service/ TripRecordingService (foreground service) +domain/cam/ Cam, CamParser, PhoneCamBuilder, CamTransmitConfig +service/ TripRecordingService, CamTransmitLoop, CamPinger +obu-firmware/ ESP32-C5 firmware (serial link, GeoNetworking, 802.11 OCB, raw TX) +asn1/ Vendored ETSI ASN.1 modules the codecs are verified against ``` +The `domain/` packages contain no Android imports. That is what makes the 41-test JVM suite possible without an emulator or instrumentation. + ## Connectivity -The app uses a phased transport strategy. The MQTT client, topic subscriptions, and all UI are identical across transports; only the underlying network path changes. +USB-C on both hardware paths. Bluetooth is **not implemented** and remains an open question in the requirements. -| Phase | Transport | Status | -|---|---|----------| -| Phase 01 | Wi-Fi | Complete | -| Phase 02 | USB-C tethering | Active | -| Phase 03 | Bluetooth BLE | Future | +| Transport | Path | Status | +|---|---|---| +| USB-C tethering (IP + MQTT) | CiT One | Active | +| USB-C serial (framed binary) | ESP32-C5 | Active | +| Wi-Fi | CiT One | Developer builds only | +| Bluetooth | Either | Not implemented | -The MQTT broker runs on the OBU hardware (Mosquitto 2.0.11, port 1883). In Phase 02, Android USB tethering exposes the OBU as a virtual Ethernet interface at `192.168.42.x`. The app auto-detects the gateway IP on plug-in. +On the CiT One path the MQTT broker runs on the OBU (Mosquitto 2.0.11, port 1883); Android USB tethering exposes it as a virtual Ethernet interface at `192.168.42.x` and the app auto-detects the gateway IP on plug-in. On the ESP32-C5 path there is no network layer at all: a private framed protocol runs over the board's native USB-C port as a CDC-ACM device. + +## Verification + +The app hand-encodes and decodes ETSI messages bit by bit on the ESP32-C5 path, which is the highest-risk code in the project. Round-trip tests through the project's own codecs structurally cannot catch a shared mistake about a field's bit width, and this project shipped exactly that bug three times (`CurvatureCalculationMode`, the GeoNetworking reserved bytes, `yawRateConfidence`). Phone and ESP32 agreed with each other and with nothing else. + +Verification therefore uses an independent oracle: `asn1tools` compiled from the ETSI modules vendored in `asn1/`. + +- **Golden-byte fixtures** assert exact encoder output, with expected values produced by the oracle rather than by this encoder. +- **Bulk replay** compares every field over real captures: 79,042 SPATEMs and 1,885 DENMs, zero mismatches. +- **Off-air confirmation**: 26 of this project's own CAMs captured back by an independent receiver, all accepted. + +Never regenerate a golden fixture from this project's own encoder output. See `asn1/README.md`. + +## Documentation + +| Document | Audience | +|---|---| +| [docs/MicrOBU-User-Guide.docx](docs/MicrOBU-User-Guide.docx) | Riders. Setup, screens, what the alerts mean, troubleshooting | +| [docs/MicrOBU-Technical-Documentation.docx](docs/MicrOBU-Technical-Documentation.docx) | Supervisors and stakeholders. Architecture, message path, verification, results, decisions | +| [docs/01-requirements-traceability.md](docs/01-requirements-traceability.md) | Requirements chapters 0 to 13 mapped to implementation and evidence | +| [05-obu-bench-test-2026-08-25.md](05-obu-bench-test-2026-08-25.md) | Bench campaign T1 to T9, measured results | +| [04-transmit-setup.md](04-transmit-setup.md) | Transmitter bring-up, radio configuration diagnosis, the TX bypass | +| [obu-firmware/FLASHING.md](obu-firmware/FLASHING.md) | Toolchain setup, flashing, phone-to-board bring-up checklist | +| [asn1/README.md](asn1/README.md) | ASN.1 module provenance and the fixture regeneration rule | +| [docs/references.bib](docs/references.bib) | Standards references as BibTeX | ## Key dependencies | Library | Purpose | |---|---| | Jetpack Compose + Material3 | UI | -| Eclipse Paho MQTT | OBU communication | +| Eclipse Paho MQTT | CiT One path communication | +| usb-serial-for-android | ESP32-C5 path communication (custom probe table for Espressif VID/PID) | | Room | Local database | | Hilt | Dependency injection | -| OSMDroid | Trip review map | +| OSMDroid | Trip review and live V2X map | | DataStore | Settings persistence | | FusedLocationProviderClient | GNSS | ## Getting started -1. Open in Android Studio (Hedgehog or newer). +1. Open in Android Studio and build the `app` module. Gradle 8.10.2. 2. Connect a device running Android 10+ (API 29). -3. Build and run the `app` module. -4. For Phase 02 testing: plug the phone into the OBU via USB-C, enable USB tethering on the phone, and the app will detect the interface and connect automatically. Broker IP can be overridden manually in Settings → Connection. -5. For standalone trip recording: no OBU required. Go to the Record tab and tap Record. +3. Choose your hardware in Settings > OBU Hardware. -The Wi-Fi transport (Phase 01 broker at `192.168.3.202`) remains available in developer builds and can be toggled in Settings → Developer. +**CiT One path.** Plug the phone into the OBU via USB-C, enable USB tethering on the phone, and the app detects the interface and connects automatically. Broker IP can be overridden in Settings > Connection. + +**ESP32-C5 path.** Flash `obu-firmware/` (see `obu-firmware/FLASHING.md`), then plug the phone into the board's **native** USB-C port, not the UART bridge port used for flashing. Tap Connect and grant the USB permission. Use the CAM Pinger on the V2X screen to verify the link and radio without starting a trip. + +**Standalone trip recording.** No OBU required. Go to the Record tab and tap REC. + +The Wi-Fi transport (broker at `192.168.3.202`) remains available in developer builds via Settings > Developer. + +Firmware and app must be flashed and installed together: `SERIAL_LINK_MAX_PAYLOAD` is 512 on both sides and a mismatch silently rejects every large frame. + +## Status and known limitations + +Bench verified against live ITS-G5 traffic on 2026-08-25: 2868 frames over 305 seconds, zero decode failures, zero USB errors, zero crashes. Not yet road validated. + +- **Requirement 11.6, Phase A success criteria, is not met.** The bench proves reception. It cannot prove the use case behaves correctly with two genuinely moving stations, because nothing on the bench moves. This is the main open evidence gap for the project's central claim. +- **No message signing.** ETSI TS 103 097 is out of scope. Secured frames are rejected rather than mis-parsed. +- **Detection thresholds are untuned engineering estimates**, not calibrated against real intersection data. +- **512-byte serial payload cap.** Roughly 70% of real road RSU SPATEMs would be dropped as oversize. Accepted deliberately: the intersection use case is CAM-driven and needs none of it. +- **No automatic reconnect** after USB re-enumeration; requires a manual Connect. +- **Station IDs rotate**, so they cannot identify a physical unit over time. +- **No backend, no login.** Everything is on-device. +- **No MAPEM decoder**, so signal groups cannot yet be associated with the rider's lane. ## Project context -The micrOBU project is funded under the ZIM program (BMWK) and targets micromobility users in Hamburg. The companion app offloads processing from the compact OBU hardware to the smartphone; GNSS fusion, event detection, and future antenna coordination all run on the phone to keep the OBU lightweight and power-efficient. +The micrOBU project is funded under the ZIM program (BMWK) and targets micromobility users in Hamburg. The companion app offloads processing from the compact OBU hardware to the smartphone; GNSS fusion, event detection, and on the ESP32-C5 path the full ASN.1 encoding and decoding all run on the phone to keep the OBU lightweight and power-efficient. -V2X communication uses ITS-G5 (IEEE 802.11p / DSRC) at 5.9 GHz. The app communicates with the OBU exclusively via the consider it MQTT API v6 (processed JSON messages); no ASN.1 encoding in the app. +V2X communication uses ITS-G5 (IEEE 802.11p) at 5.9 GHz. On the CiT One path the app communicates via the consider it MQTT API v6 (processed JSON). On the ESP32-C5 path the app performs its own ASN.1 UPER encoding and decoding against the ETSI modules vendored in `asn1/`. **Owner:** HAW Hamburg