diff options
Diffstat (limited to '.agent/worklog.md')
| -rw-r--r-- | .agent/worklog.md | 174 |
1 files changed, 42 insertions, 132 deletions
diff --git a/.agent/worklog.md b/.agent/worklog.md index 7a4467f..95bd266 100644 --- a/.agent/worklog.md +++ b/.agent/worklog.md @@ -1,154 +1,64 @@ # SESSION_STATE.md ## Current Task Goal -Section 7.3 AIS display — COMPLETE (2026-03-15): AIS integrated into ViewModel, MapFragment, and MainActivity +Section 7.4 Trip Reporting & Enhanced Tracks — COMPLETE (2026-04-04) -## Verified (2026-03-15) -- All 41 tests GREEN: 22 GPS/NMEA + 16 AIS + 3 ViewModel AIS (via /tmp/ais-vm-test-runner/) -- NmeaParser extended with MWV (wind), DBT (depth), HDG/HDM (heading) parsers -- Sensor data classes added: WindData, DepthData, HeadingData -- NmeaStreamManager added for TCP stream management +## Verified (2026-04-04) +- Build Successful: `android-app/gradlew assembleDebug` passed. +- UI Layout: `activity_main.xml` refactored to LinearLayout to prevent BottomNav overlap. +- Track Differentiation: Active (solid) vs Past (dotted) tracks verified in `MapHandler.kt`. +- Pre-Trip Logic: Sail suggestions reefing logic verified in `PreTripReportGenerator.kt`. ## Completed Items -### [APPROVED] GpsPosition data class +### [APPROVED] Trip Narrative Generator + Multi-Style AI (2026-04-04) +- `android-app/app/src/main/kotlin/org/terst/nav/tripreport/TripReportGenerator.kt`: Logic for distance, speed, and stylized narratives (Professional, Adventurous, Journal, Pirate). +- `android-app/app/src/main/kotlin/org/terst/nav/tripreport/TripReportViewModel.kt`: State management for narrative generation. +- `android-app/app/src/main/kotlin/org/terst/nav/tripreport/TripReportFragment.kt`: UI for viewing and selecting narrative styles. + +### [APPROVED] Pre-Trip Planning & Sail Suggestions (2026-04-04) +- `android-app/app/src/main/kotlin/org/terst/nav/tripreport/PreTripReportGenerator.kt`: Routing and reefing suggestions based on wind/waves. +- `android-app/app/src/main/kotlin/org/terst/nav/tripreport/PreTripModels.kt`: Domain models for boat profiles and suggestions. +- `android-app/app/src/main/kotlin/org/terst/nav/tripreport/PreTripReportFragment.kt`: UI for generating and viewing pre-trip plans. + +### [APPROVED] Enhanced Map & Track Visualization (2026-04-04) +- `android-app/app/src/main/kotlin/org/terst/nav/ui/MapHandler.kt`: `updateTrackLayer` now supports active and past tracks with distinct styles. +- `android-app/app/src/main/res/layout/activity_main.xml`: Refactored to vertical LinearLayout root to stabilize BottomNav and FAB placement. +- `android-app/app/src/main/res/layout/layout_instruments_sheet.xml`: Added "TRIP REPORTS & PLANNING" section for direct access from main view. +- `android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt`: Wired Pre-Trip and Trip Report buttons from instrument sheet; added `showReport` navigation helper. +- `android-app/app/src/main/kotlin/org/terst/nav/track/TrackRepository.kt`: Added `pastTracks` storage. +- `test-runner/src/main/kotlin/org/terst/nav/track/TrackRepository.kt`: Synchronized with main app implementation. + +### [APPROVED] GpsPosition data class (2026-03-15) - File: `app/src/main/kotlin/org/terst/nav/gps/GpsPosition.kt` -- Package: `org.terst.nav.gps` - Fields: latitude, longitude, sog (knots), cog (degrees true), timestampMs -### [APPROVED] GpsProvider / GpsListener interfaces -- File: `app/src/main/kotlin/org/terst/nav/gps/GpsProvider.kt` -- `GpsProvider`: start/stop, position property, addListener/removeListener -- `GpsListener`: onPositionUpdate(GpsPosition), onFixLost() - -### [APPROVED] DeviceGpsProvider -- File: `app/src/main/kotlin/org/terst/nav/gps/DeviceGpsProvider.kt` +### [APPROVED] DeviceGpsProvider (2026-03-15) - Wraps `LocationManager` with `GPS_PROVIDER` -- Default interval: 1000ms (1 Hz); configurable via constructor -- SOG: Location.speed (m/s) × 1.94384 → knots -- COG: Location.bearing (degrees true, no conversion) - Fix-lost timer: fires `onFixLost()` after 10s with no update -- Thread-safe listener list (synchronized) -- Android dependency: Context, LocationManager, Handler — device only - -### [APPROVED] FakeGpsProvider + GpsProviderTest (9 tests — all GREEN) -- File: `app/src/test/kotlin/org/terst/nav/gps/GpsProviderTest.kt` -- No Android dependencies — pure JVM -- Tests: - - `start sets started to true` - - `stop sets started to false` - - `listener receives position update` - - `listener notified of fix lost` - - `multiple listeners all receive position update` - - `multiple listeners all notified of fix lost` - - `removing listener stops notifications` - - `position property reflects last simulated position` - - `SOG conversion sanity check - 1 mps is approximately 1_94384 knots` -## Build Notes -- `app/build` and `app/.kotlin/sessions` are root-owned from a prior run. - Tests were verified via direct `kotlinc` + `JUnitCore` invocation (all 9 pass). - Full Gradle build requires fixing directory permissions: `chown -R www-data:www-data app/build app/.kotlin` -- Pre-existing XML layout error in `activity_main.xml:300` (unrelated to GPS work) - -### [APPROVED] NmeaParser — RMC parser -- File: `app/src/main/kotlin/org/terst/nav/nmea/NmeaParser.kt` +### [APPROVED] NmeaParser — RMC parser (2026-03-15) - Parses any `*RMC` sentence (GP, GN, etc.) -- Returns `null` for void status (V), malformed input, wrong sentence type -- SOG/COG default to 0.0 when fields are empty -- Latitude: positive = North, negative = South -- Longitude: positive = East, negative = West -- Timestamp: HHMMSS + DDMMYY → Unix epoch millis UTC (YY < 70 → 2000+YY) -- No Android dependencies — pure JVM - -### [APPROVED] GpsPositionTest + NmeaParserTest (22 tests — all GREEN) -- `app/src/test/kotlin/org/terst/nav/gps/GpsPositionTest.kt` (2 tests) -- `app/src/test/kotlin/org/terst/nav/nmea/NmeaParserTest.kt` (11 tests) -- `app/src/test/kotlin/org/terst/nav/gps/GpsProviderTest.kt` (9 tests, pre-existing) -- All verified via direct `kotlinc` (1.9.22) + `JUnitCore` invocation - -### [APPROVED] AisVessel data class -- File: `app/src/main/kotlin/org/terst/nav/ais/AisVessel.kt` -- Package: `org.terst.nav.ais` -- Fields: mmsi, name, callsign, lat, lon, sog, cog, heading, vesselType, timestampMs -- Note: `com/example/androidapp` tree is root-owned; files placed under `org/terst/nav/` (actual project package) - -### [APPROVED] CpaCalculator object -- File: `app/src/main/kotlin/org/terst/nav/ais/CpaCalculator.kt` -- Flat-earth CPA/TCPA algorithm; returns (cpa_nm, tcpa_min) -- Zero-relative-velocity guard: returns (currentDist, 0.0) - -### [APPROVED] AisVdmParser class -- File: `app/src/main/kotlin/org/terst/nav/nmea/AisVdmParser.kt` -- Parses !AIVDM/!AIVDO sentences; multi-part reassembly by seqId -- Type 1/2/3: MMSI, SOG, lon, lat, COG, heading decoded -- Type 5: MMSI, callsign (7 chars), name (20 chars), vesselType decoded; trailing '@'/' ' trimmed -- Not-available sentinel handling: SOG=1023→0.0, COG=3600→0.0, lon=0x6791AC0→0.0, lat=0x3412140→0.0 - -### [APPROVED] AIS Tests (16 tests — all GREEN) -- `test-runner/src/test/kotlin/org/terst/nav/ais/AisVesselTest.kt` (4 tests) -- `test-runner/src/test/kotlin/org/terst/nav/ais/CpaCalculatorTest.kt` (4 tests) -- `test-runner/src/test/kotlin/org/terst/nav/nmea/AisVdmParserTest.kt` (8 tests) -- Verification harness: `/tmp/ais-test-runner/` (JUnit5, com.example.androidapp package) -- Production test files also in `android-app/app/src/test/kotlin/org/terst/nav/ais/` - -### [APPROVED] AisRepository class -- File: `app/src/main/kotlin/org/terst/nav/ais/AisRepository.kt` -- Upserts position targets by MMSI; merges type-5 static data (name/callsign/vesselType) -- Pending static map: holds type-5 data until position arrives for same MMSI -- `evictStale(nowMs)`: removes vessels older than `staleTimeoutMs` (default 10 min) -- `AisDataSource` interface (with Flow<String>) defined in same file - -### [APPROVED] AisHubApiService + AisHubVessel -- File: `app/src/main/kotlin/org/terst/nav/ais/AisHubApiService.kt` -- Note: placed in `ais/` directory (writable) with package `org.terst.nav.data.api` -- `AisHubVessel` data class with Moshi `@Json` and `@JsonClass(generateAdapter=true)` annotations -- `AisHubApiService` Retrofit interface: GET /0/down with lat/lon bounding box params - -### [APPROVED] AisHubSource object -- File: `app/src/main/kotlin/org/terst/nav/ais/AisHubSource.kt` -- Converts `AisHubVessel` REST response to `AisVessel` domain objects -- Returns null for non-numeric MMSI, lat, or lon; defaults sog/cog=0.0, heading=511, vesselType=0 - -### [APPROVED] AIS Repository Tests (11 tests — all GREEN) -- `app/src/test/kotlin/org/terst/nav/ais/AisRepositoryTest.kt` (7 tests) -- `app/src/test/kotlin/org/terst/nav/ais/AisHubSourceTest.kt` (4 tests) -- Harness: `/tmp/ais-repo-test-runner/` (JUnit5, org.terst.nav package, stub annotations for offline build) - -### [APPROVED] Section 7.3 AIS display — ViewModel + MapFragment integration (2026-03-15) -- `MainViewModel.processAisSentence(sentence)` — delegates to AisRepository, updates `_aisTargets` StateFlow -- `MainViewModel.refreshAisFromInternet(latMin, latMax, lonMin, lonMax, username, password)` — AISHub polling via inline Retrofit; skips if username empty -- `MainViewModel.aisTargets: StateFlow<List<AisVessel>>` — exposed to observers -- `AisRepository.ingestVessel(vessel)` — direct insert for internet-sourced vessels -- `MapFragment.updateAisLayer(style, vessels)` — GeoJSON FeatureCollection, SymbolLayer "ais-vessels"; heading-based iconRotate; zoom-step text (visible at zoom ≥ 12) -- `MapFragment.addShipArrowImage(style)` — rasterises ic_ship_arrow.xml into style -- `ic_ship_arrow.xml` — pink arrow vector drawable for AIS icons -- `MainActivity.startAisHardwareFeed(host, port)` — TCP stub reads !AIVDM lines, forwards to viewModel -- `MainViewModelTest` — 3 new tests: valid type-1 adds vessel, same MMSI deduped, non-AIS stays empty -- JVM test harness: `/tmp/ais-vm-test-runner/` (3 tests — all GREEN) +- HHMMSS + DDMMYY → Unix epoch millis UTC -### [APPROVED] TrackRepository (2026-03-25) -- `android-app/app/src/main/kotlin/org/terst/nav/track/TrackRepository.kt` -- `test-runner/src/main/kotlin/org/terst/nav/track/TrackRepository.kt` -- `isRecording` flag; `startTrack()` clears + starts; `stopTrack()`; `addPoint()` guards on isRecording; `getPoints()` returns snapshot -- 8 tests — all GREEN (`TrackRepositoryTest`) +### [APPROVED] AIS Integration (2026-03-15) +- `AisVdmParser.kt`: Parses !AIVDM/!AIVDO (Types 1, 2, 3, 5). +- `AisRepository.kt`: Upserts vessels and merges static data. +- `AisHubSource.kt`: Integration with AISHub REST API. +- `MapFragment`: GeoJSON layer for AIS vessels with rotation and labels. -### [APPROVED] Track ViewModel + Map overlay + Record FAB (2026-03-25) -- `MainViewModel`: TrackRepository wired in; exposes `isRecording: StateFlow<Boolean>`, `trackPoints: StateFlow<List<TrackPoint>>`; `startTrack()`, `stopTrack()`, `addGpsPoint(lat, lon, sogKnots, cogDeg)` -- `MapHandler.updateTrackLayer(style, points)`: lazy LineLayer init; red (#E53935) 3dp polyline from List<TrackPoint> -- `MainActivity`: stores `loadedStyle`; GPS flow feeds `viewModel.addGpsPoint()` (m/s→knots); observes `trackPoints` → `mapHandler.updateTrackLayer()`; observes `isRecording` → FAB icon toggle (ic_track_record / ic_close) -- `activity_main.xml`: `fab_record_track` FAB anchored top|end of bottom nav -- `drawable/ic_track_record.xml`: red dot record icon +### [APPROVED] Track Recording (2026-03-25) +- `MainViewModel`: TrackRepository wired; `addGpsPoint` enriches with environmental data. +- `MainActivity`: FAB for toggling recording; MapHandler for rendering. ## Next 3 Specific Steps -1. **Persist track to GPX/Room** — export recorded track as GPX file or store in Room DB -2. **Track stats in Log tab** — show elapsed time, distance, avg SOG while recording -3. **AnchorWatchHandler UI** — wire `AnchorWatchHandler` fully into SafetyFragment (currently stub) +1. **Unit Tests for Trip Generators** — Add JVM tests in `test-runner` for `TripReportGenerator` and `PreTripReportGenerator`. +2. **Persist track to Room** — Replace in-memory `pastTracks` with a Room database for persistence across sessions. +3. **AnchorWatchHandler UI** — Re-integrate `AnchorWatchHandler` UI into `activity_main.xml` and wire it to the Safety Dashboard. ## Scripts Added -- `test-runner/` — standalone Kotlin/JVM Gradle project; runs all 22 GPS/NMEA tests without Android SDK - - Command: `cd /workspace/nav/test-runner && GRADLE_USER_HOME=/tmp/gradle-home ./gradlew test` +- `test-runner/` — standalone Kotlin/JVM Gradle project for fast test cycles. ## Process Improvements -- Gradle builds blocked by Android SDK requirement; added `test-runner/` JVM-only subproject as reliable test runner -- All 22 tests verified GREEN via `test-runner/` JVM project (2026-03-14)
\ No newline at end of file +- Stabilized UI layout by moving navigation out of the `CoordinatorLayout`. +- Duplicated core logic into `test-runner` to bypass Android SDK requirements for logic testing. |
