ESP32 link indicators, trip export with V2X + RSSI, trip/CSV cleanup

UI:
- Top bar shows a USB glyph reflecting the serial link on the ESP32-C5 path,
  instead of a Wi-Fi glyph driven by an MQTT state that is permanently
  disconnected there.
- Recording screen's OBU stream row follows whichever transport the selected
  hardware uses. It previously read as offline throughout a recording that was
  actively beaconing CAMs.
- Live map uses distinct markers: a centred dot for own position (a fact about
  the viewer, not a tracked object) and a teardrop pin for remote stations,
  tinted by alert severity. Both were osmdroid's identical default pin before,
  and severity required tapping a marker to read its label.
- Sensor Monitor moves out of the bottom nav to Settings > Developer. A live
  phone-sensor feed is a bench tool; the Dashboard already reports GNSS/IMU
  health. Screen and route are unchanged, just not in the rider's way.

Detection engine on the ESP32 path:
- Seed our own StationID from the persisted value CamTransmitLoop transmits.
  It was null here (the CiT One learns it from v2x/rx/obu_gnss, which doesn't
  exist on this path), so the self-heard-TX filter never fired: the ESP32 runs
  promiscuous for raw TX to work at all, hears our own CAMs back off the air,
  and they were tracked as a remote station - a ghost vehicle on top of the ego
  position, fed to the engine as a collision partner for itself.

RSSI:
- The firmware has always sent per-frame RSSI in byte 0 of every CAM_RX frame;
  the app discarded it. Now carried on Cam, persisted per V2X message, shown per
  station in the received-CAM list, and exported. Null for own CAMs and the
  whole CiT One path, neither of which has a measurement.

Trips, CSV and export (schema v3 -> v4):
- trips.sessionId links a trip to the CSV session recorded alongside it. The two
  are written by independent subsystems that the Recording button happens to
  start together; without the link, deleting a trip orphaned its CSV forever.
  Timestamp matching was rejected - close recordings would delete the wrong file.
- Deleting a trip now removes the CSV file AND its sessions row, so it stops
  appearing in the Session Log pointing at nothing.
- Per-trip combined CSV export: GPS track, detected events, V2X messages (with
  RSSI) and the raw sensor samples in one file, keyed by a leading type column.
  One file rather than a zip of tables because the point of the export is
  correlating those streams, and splitting them pushes the join downstream.
- Export takes the Activity context. Sharing from the ViewModel's Application
  context threw AndroidRuntimeException on startActivity - this crashed on the
  first tap of the share button.

Trips recorded before v4 have a null sessionId, so their exports omit raw sensor
rows and their CSVs still need clearing by hand once.
This commit is contained in:
Ashin Walpola
2026-08-11 15:47:54 +02:00
parent f507a8a9fd
commit f1770e11dd
22 changed files with 496 additions and 34 deletions
+2
View File
@@ -111,6 +111,7 @@
<string name="log_session_number">Session #%1$d</string>
<string name="log_share_cd">Share CSV</string>
<string name="log_save_cd">Save to device</string>
<string name="trip_export_cd">Export trip CSV</string>
<string name="log_delete_cd">Delete session</string>
<string name="log_empty_title">No sessions yet</string>
<string name="log_empty_desc">Go to Record and start a session</string>
@@ -212,6 +213,7 @@
<string name="v2x_cam_rx_kinematics">%1$.1f km/h · heading %2$.0f°</string>
<string name="v2x_cam_rx_distance">%1$.0f m</string>
<string name="v2x_cam_rx_distance_unknown">— m</string>
<string name="v2x_cam_rx_rssi">%1$d dBm</string>
<!-- DENM map pins -->
<string name="v2x_map_denm_labeled">Hazard: cause %1$d/%2$d (station %3$d)</string>