Files
MicrOBU/docs/01-requirements-traceability.md
T
Ashin Walpola 1ad123a6f8 Make the event detector a CAM rate input, not a ride-stats readout
The detector's only live consumer is the CAM transmit-rate policy: every
emitted event calls CamTransmitLoop.onDetectedEvent, raising the beacon
rate from 1 Hz to the elevated rate for five seconds so nearby stations
get denser updates through a manoeuvre. Counting one's own braking events
is not a goal of this project, so the display is gone and the detector
stays: the live per-type counters and their notification text, the event
pins and detail sheet on the trip review map, and the event chip on the
history card. Events are still persisted and exported to CSV, which is
the only route to the tuning measurement section 11.3 says is missing.

Fix two defects found while documenting the detector.

TripRecordingService overrode nine of DetectionConfig's twelve parameters
in its constructor, so the tests validated the Phase A defaults while the
phone ran something materially less sensitive. The tuned values are now
the defaults and the override is deleted; the numbers moved location, not
value, so detector sensitivity is unchanged. EventDetectorTest now sets
only windowSize and the sustained-frame counts and inherits every signal
threshold, which cannot drift again. That was not a free change and makes
the same point from the other side: at the real thresholds the old stimuli
triggered nothing. Accel alternating 3.5/0.5 gives a std dev of 1.5 and
never clears 1.8, and the moderate-braking case used a 0.8 m/s drop that
never clears 1.0. Those stimuli are re-derived against the real values.

brakingHighConfidenceRate was documented as a rate but has always been
compared against the peak cumulative drop from the onset speed, which
grows with episode length, so HIGH was assigned more readily than the name
implied. Renamed to brakingHighConfidencePeakDrop rather than changing the
comparison: "lost more than 1.5 m/s in one episode" is coherent, whereas a
rate off a 1 Hz speed signal sampled at 50 Hz spikes on a near-zero
divisor early in an episode. Output is unchanged, so the existing
confidence assertions stay evidence instead of being re-baselined.

Docs 11.3/11.4 updated in place, including the correction of a claim that
detected events do not reach the V2X side; the rate-bump path already
existed when that was written. 55 tests, 0 failures.
2026-09-08 16:20:14 +02:00

247 lines
15 KiB
Markdown
Raw 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.
# Requirements traceability matrix
Maps every section of `V2X_MicrOBU_Android_App_Requirements_v15.pdf` (37 pages, chapters 0–13) to
its implementation and to the evidence that it works.
**Status as of 2026-08-25**, commit `cc35994`. Test counts refer to `app/src/test/` (41 tests,
0 failures); bench measurements refer to `05-obu-bench-test-2026-08-25.md`.
## How to read this
The project began against the **consider it CiT One OBU** and later added the **ESP32-C5** as a
second hardware path (requirements chapter 13). That transition is the single biggest source of
divergence in this table, and it is deliberate rather than drift: chapter 13 was written to describe
it. Where a requirement was authored assuming the CiT One, the ESP32-C5 path may satisfy it by a
different mechanism, satisfy it only partly, or make it inapplicable.
Status values:
| status | meaning |
|---|---|
| **Done** | implemented and exercised on both hardware paths |
| **Done (CiT One)** | implemented; applies only to the CiT One path by design |
| **Done (ESP32-C5)** | implemented; applies only to the ESP32-C5 path by design |
| **Partial** | implemented in part, with the remainder identified |
| **Backlog** | explicitly deferred in the requirements themselves |
| **Superseded** | the ESP32-C5 transition changed the answer; see the note |
| **Not started** | no implementation |
"Cited" means a source file names the section in a KDoc comment — 23 files do. Absence of a citation
is **not** absence of implementation; several well-covered areas were written before that convention
and are mapped here by inspection.
---
## 0. Project Context & Main Goal
| § | Title | Status | Implementation | Evidence |
|---|---|---|---|---|
| 0.1 | Technological Innovation Context | n/a | context, not a requirement | — |
| 0.2 | Bicycle Safety Use Case Foundation (C2C-CC) | **Done** | `DenmUseCase.kt` *(cited)*, `UseCaseType.kt` | use cases 1.1/1.2 below |
**Note.** 0.2 is the origin of the project's central architectural rule: the CAM-based use cases
never generate DENM. `DenmUseCase.kt` records this, and it survived the ESP32 transition unchanged.
## 1. Phase 01 — Data Collection
| § | Title | Status | Implementation | Evidence |
|---|---|---|---|---|
| 1.1 | Test Intersections & Use Cases | **Done** | `UseCaseDetectionEngine.kt`, `UseCaseType.kt` *(both cited)* | IMA-S observed firing on hardware, 2026-08-25 |
| 1.2 | C2C-CC Use Case Mapping & Roadmap | **Done** | `UseCaseType.kt`, `UseCaseDetectionConfig.kt` *(both cited)* | 5 use cases enumerated: IMA-B, IMA-S, RTW-B, LTW-B, SMVA/BCW-B |
## 2. Functional Requirements
| § | Title | Status | Implementation | Evidence |
|---|---|---|---|---|
| 2.1 | Screens & Features | **Done** | `ui/screens/` — Dashboard, Record, Trips, V2X, Settings | bench screenshots |
| 2.2 | User Interactions | **Done** | `UseCaseAlertPreferences.kt` *(cited)*, Settings screen | per-use-case toggles |
| 2.3 | Backend, Database & Login | **Partial** | `data/db/` (Room: sessions, trips, events, V2X messages) | no login/backend; local-only by design |
**Gap.** 2.3's backend and login have no implementation. Everything is on-device. Worth stating
explicitly in the thesis as a scope boundary rather than leaving it to be discovered.
## 3. Non-Functional Requirements
| § | Title | Status | Implementation | Evidence |
|---|---|---|---|---|
| 3.1 | Android Version & Target Devices | **Done** | `minSdk 29`, `targetSdk 36` | runs on Pixel 9 Pro |
| 3.2 | Performance & Offline | **Done** | offline by construction on the ESP32-C5 path | 210 MB PSS, 43 threads, no GC pressure attributable to the app |
**ESP32-C5 note.** 3.2's offline requirement is *more* satisfied after the transition: the ESP32-C5
path needs no MQTT broker and no network at all.
## 4. Technical Requirements
| § | Title | Status | Implementation | Evidence |
|---|---|---|---|---|
| 4.1 | Development Environment | **Done** | Gradle 8.10.2, AGP, Android Studio JBR | builds from CLI |
| 4.2 | Architecture | **Done** | `UseCaseDetectionEngine.kt` *(cited)*; MVVM + Hilt + repositories | pure-domain classes unit-tested without Android |
| 4.3 | Key Libraries | **Done** | Compose, Room, Hilt, osmdroid, usb-serial-for-android, Paho MQTT | — |
| 4.4 | Security Requirements (future) | **Backlog** | — | see note |
**Security note (4.4).** ETSI TS 103 097 message signing is not implemented and is out of scope. The
firmware rejects secured packets (GN `NextHeader=2`) rather than mis-parsing them; 75 such frames
were observed on the bench. The OBU under test runs `ItsGnSecurity = 0`, so this has not blocked
anything. **This is the most likely reviewer question and the answer should be pre-written.**
## 5. Design Requirements
| § | Title | Status | Implementation | Evidence |
|---|---|---|---|---|
| 5.1–5.4 | Visual language, system bars, UX, wireframes | **Done** | Compose Material 3, edge-to-edge | screenshots |
| 5.5 | Alert Level Model (C2C-CC three-tier) | **Done** | `AlertLevel.kt`, `UseCaseDetectionConfig.kt`, `UseCaseDetectionEngine.kt` *(all cited)* | Info / Awareness / Warning; observed WARNING on hardware |
## 6. Sensor Data Streams (Phase 01)
| § | Title | Status | Implementation | Evidence |
|---|---|---|---|---|
| 6 | Sensor Data Streams | **Done** | `SensorRepository.kt`, `CamUseCaseRepository.kt` *(cited)* | GNSS, accel, gyro, magnetometer, barometer |
## 7. Recording Session & Data Export
| § | Title | Status | Implementation | Evidence |
|---|---|---|---|---|
| 7.1 | Recording Mode | **Done** | `TripRecordingService.kt`, `RecordingScreen.kt` | — |
| 7.2 | CSV Export Format | **Done** | `CsvExporter.kt`, `TripExporter.kt` | export includes V2X messages and RSSI |
## 8. Connectivity
| § | Title | Status | Implementation | Evidence |
|---|---|---|---|---|
| 8.1 | Connection Phase Roadmap | **Superseded** | `ObuHardware.kt`, `TransportType.kt` | chapter 13 replaced the roadmap |
| 8.2 | Transport Methods Detail | **Partial** | `UsbSerialTransport.kt`, `UsbNetworkDetector.kt`, `MqttRepository.kt` | USB-C both paths; **Bluetooth not implemented** (13.9 keeps it open) |
## 9. Phase 01 Key Design Principles
| § | Title | Status | Implementation | Evidence |
|---|---|---|---|---|
| 9 | Key Design Principles | **Done** | pure-domain `domain/` packages, no Android imports | `EventDetectorTest`, `UseCaseDetectionEngine` unit-testable |
## 10. Phase 02 — OBU Communication (CAM-based use cases)
| § | Title | Status | Implementation | Evidence |
|---|---|---|---|---|
| 10.1 | USB-C Wired Transport | **Done (CiT One)** | `UsbNetworkDetector.kt` (IP over USB tethering) | superseded on the ESP32-C5 path by USB serial |
| 10.2 | CAM Reception & Use Case Detection | **Done** | `Cam.kt`, `CamUseCaseRepository.kt`, `MqttViewModel.kt`, `MqttTopicViewerScreen.kt` *(all cited)* | 1244 CAMs decoded in 305 s, 0 failures |
| 10.2.1 | Detection Algorithm Detail | **Done** | `UseCaseDetectionEngine.kt`, `UseCaseDetectionConfig.kt` | IMA-S fired with TTC 4.8 s on hardware |
| 10.3 | Test and Verification Procedure | **Done** | `CamParser.kt`, `UseCaseDetectionConfig.kt`, `UseCaseDetectionEngine.kt` *(all cited)* | extended well beyond the original procedure — see chapter 14 below |
| 10.4 | New/Updated UI Elements | **Done** | `MqttTopicViewerScreen.kt` *(cited)* | alert panel, list/topics/map |
| 10.5 | Phase 02 Key Technical Decisions | **Done** | `DenmUseCase.kt` | DENM decoupled from sensor triggers |
**Transition note (10.1).** Phase 02 assumed IP-over-USB tethering to the CiT One. The ESP32-C5 path
uses a custom framed serial protocol over USB CDC instead. Both are "USB-C wired transport", but they
share no code. The requirement is satisfied twice, by different means.
## 11. Phase A — Trip Recording & Cyclist Event Detection
| § | Title | Status | Implementation | Evidence |
|---|---|---|---|---|
| 11.1 | Orientation-Independent Sensor Strategy | **Done** | `SensorRepository.kt` (magnitude-based) | — |
| 11.2 | Running Standard Deviation Event Detector | **Done** | `EventDetector.kt`, `RunningStats.kt` | **18 unit tests, 0 failures** |
| 11.3 | Trip Recording Architecture | **Done** | `TripRepository.kt`, `TripRecordingService.kt` *(cited)* | — |
| 11.4 | Data Model | **Done** | `data/db/` Room entities *(cited)* | — |
| 11.5 | New UI Elements for Phase A | **Partial — scope reduced** | `TripHistoryScreen.kt`, `TripReviewScreen.kt` | event pins/counters removed by decision, see note |
| 11.6 | Phase A Success Criteria | **Partial** | — | needs a real ride; see Open Items |
**Correction note (11.2).** Four `EventDetectorTest` cases had been failing since the initial commit.
Investigation (2026-08-25) established the **detector was correct and the tests were wrong**: they
described stimuli the detector cannot physically see, because they ignored the settling time of the
rolling standard-deviation window. Tests corrected, assertions unchanged, detector untouched. This is
worth reporting — it is a finding about test design, not a defect.
**Scope note (11.5).** The event-detection UI — the live per-type counters on the recording screen,
the coloured event pins and detail sheet on the trip review map, and the event count on the trip
history card — was removed deliberately. A count of the rider's own braking events is not a goal of
this project. The detector itself still runs: it is the input to the CAM transmit-rate policy
(§ 13), which raises the beacon rate from 1 Hz to the elevated rate for five seconds after a
detected manoeuvre. Events remain persisted and exported to CSV for offline analysis.
**Defect note (11.2).** Two defects found while documenting the detector were fixed on 2026-09-07.
The nine threshold overrides in `TripRecordingService`'s constructor were promoted to
`DetectionConfig`'s defaults and the override deleted, so there is one configuration and
`EventDetectorTest` exercises the shipping thresholds rather than the superseded Phase A ones;
detector sensitivity is unchanged, and the synthetic stimuli were re-derived because several no
longer cleared the stricter real thresholds. `brakingHighConfidenceRate` was renamed
`brakingHighConfidencePeakDrop`: it was documented as a rate but has always been compared against
the peak cumulative speed drop. The name was corrected rather than the comparison, so detector
output is unchanged and the confidence assertions remain valid evidence.
## 12. Future Architecture & Open Design Questions
| § | Title | Status | Notes |
|---|---|---|---|
| 12.1 | Multi-Vehicle Handling & Notification Limits | **Partial** | engine tracks per-station history; no notification cap |
| 12.2 | Intersection Ambiguity: Traffic-Light State | **Partial — advanced** | **SPATEM now decoded** (`SpatemUperCodec.kt`), see below |
| 12.3 | Shared-Road / Bike Lane Awareness Dataset | **Not started** | would need MAPEM lane geometry |
| 12.4 | Geo-Server for Crowdsourced Trajectory Data | **Not started** | related to the 2.3 backend gap |
| 12.5 | Geofencing Around High-Risk Intersections | **Not started** | — |
| 12.6 | Sensor Fusion Roadmap (Kalman Filter) | **Not started** | — |
| 12.7 | EventDetector Evolution | **Not started** | — |
**12.2 is the notable movement.** The requirements listed traffic-light state as future/backlog. It
is now partly delivered: SPATEM is received over the air and decoded to per-signal-group phase and
timing, validated against 79,042 real messages. What remains is the *association* problem — knowing
which signal group applies to the rider's lane — which needs MAPEM geometry (12.3). Worth presenting
as a backlog item advanced ahead of schedule, with the remaining half named precisely.
## 13. Phase 03 — ESP32-C5 Dual-OBU & Phone-Generated CAM
The transition chapter. Cited by **16 source files**, more than any other.
| § | Title | Status | Implementation | Evidence |
|---|---|---|---|---|
| 13.1 | ESP32-C5 as a Second OBU Option | **Done** | `obu-firmware/`, `ObuHardware.kt` | bench campaign T1–T9 |
| 13.2 | Transport: USB-C to ESP32 | **Done** | `SerialFrame.kt`, `serial_link.c` | 2868 frames / 305 s, 0 errors |
| 13.3 | Settings: OBU Hardware Selection | **Done** | `ObuHardwarePreferences.kt`, Settings | both paths selectable |
| 13.4 | DENM Trigger Retained for CiT One Only | **Done (CiT One)** | `MqttTopicViewerScreen.kt` gating | trigger hidden on the ESP32-C5 path |
| 13.5 | Phone-Generated CAM | **Done (ESP32-C5)** | `PhoneCamBuilder.kt`, `CamUperCodec.kt`, `CamTransmitLoop.kt` | **golden-byte test**; 26 own CAMs verified off-air by an independent decoder |
| 13.6 | Adaptive CAM Transmission Rate | **Partial** | `CamTransmitConfig.kt` | fixed 1 Hz pinger; adaptive rate not implemented |
| 13.7 | UI Updates: Map View & Dashboard | **Done** | `V2xLiveMapView.kt`, `DashboardScreen.kt` | screenshots |
| 13.8 | Detection Engine: Unchanged for Reception | **Done** | `UseCaseDetectionEngine.kt` | engine is transport-agnostic; confirmed by inspection — zero SPATEM/MAPEM references |
| 13.9 | Bluetooth Transport (Open Discussion) | **Not started** | — | remains open, as the requirement says |
**13.8 is the load-bearing claim of the transition** and it holds: the same detection engine serves
both hardware paths, fed by `CamUseCaseRepository` from either MQTT or serial. That is what makes the
ESP32-C5 a drop-in second OBU rather than a fork of the application.
---
## Beyond the requirements
Work delivered that chapter 13 does not cover, because it postdates v15 of the document. For a
publication these are contributions rather than scope creep, and they need their own section.
| area | what | evidence |
|---|---|---|
| DENM over-the-air receive | GeoBroadcast unwrapping, `DenmUperCodec` | 1885 DENMs cross-checked, 0 mismatches |
| SPATEM receive | `SpatemUperCodec`, live signal phase UI | 79,042 messages cross-checked, 0 mismatches |
| RSU CAM support | `rsuContainerHighFrequency` decoding | 611 RSU CAMs decoded on the bench |
| Verification methodology | independent ETSI oracle, golden bytes, real captures | three encoding bugs found that self-consistent tests structurally cannot catch |
## Open items
Ranked by what a reviewer is most likely to probe.
1. **11.6 Phase A success criteria** — needs a real ride. The bench proves reception; it cannot
prove the use case behaves correctly with two genuinely moving stations. This is the main
remaining evidence gap for the central claim.
2. **4.4 Security** — no message signing. Pre-write the answer.
3. **2.3 Backend & login** — not implemented; state as a scope boundary.
4. **13.6 Adaptive CAM rate** — fixed 1 Hz.
5. **8.2 / 13.9 Bluetooth** — not implemented; the requirements leave it open.
6. **12.2 remainder** — signal-group-to-lane association needs MAPEM.
## Known limitations carried deliberately
Documented decisions, not oversights. Each has its reasoning recorded in the commit history and in
`05-obu-bench-test-2026-08-25.md`.
- **512-byte serial payload cap.** ~70% of *road* RSU SPATEMs would be dropped. Accepted: the
intersection use case is CAM-driven and needs none of it, and raising the cap would put a
measured, zero-failure chain at risk for an add-on. CAM 26–211 B and DENM 402 B both fit.
- **No MAPEM decoder.** Nothing on air transmits it; it exists only in recorded drive data.
- **Secured messages rejected**, not mis-parsed.
- **No auto-reconnect** after USB re-enumeration; requires a manual Connect.
- **Station IDs rotate** (observed twice within one session), so they cannot identify a physical
unit over time.