summaryrefslogtreecommitdiff
path: root/test-runner/src/main
diff options
context:
space:
mode:
authorClaude <noreply@anthropic.com>2026-05-20 22:18:38 +0000
committerClaude <noreply@anthropic.com>2026-05-20 22:18:38 +0000
commit62cc93086498d57ef7298eddb40cc382dfc10c6d (patch)
tree5203af49d29d97a7109909ad905fae1fa9a668e8 /test-runner/src/main
parent494e2f0f9ff3e89d1ff7409da096efee57be08b7 (diff)
Fix Long overflow in TackDetector: var lastTackMs = Long.MIN_VALUE caused subtraction overflow, filtering every tack
Diffstat (limited to 'test-runner/src/main')
-rw-r--r--test-runner/src/main/kotlin/org/terst/nav/track/TackDetector.kt20
1 files changed, 10 insertions, 10 deletions
diff --git a/test-runner/src/main/kotlin/org/terst/nav/track/TackDetector.kt b/test-runner/src/main/kotlin/org/terst/nav/track/TackDetector.kt
index b392f67..b0d256b 100644
--- a/test-runner/src/main/kotlin/org/terst/nav/track/TackDetector.kt
+++ b/test-runner/src/main/kotlin/org/terst/nav/track/TackDetector.kt
@@ -3,23 +3,23 @@ package org.terst.nav.track
import kotlin.math.abs
object TackDetector {
- private const val HALF_WIN = 2 // look 2 points before and after
- private const val MIN_DELTA = 60.0
- private const val MAX_DELTA = 140.0
- private const val SKIP_AFTER = 5 // suppress re-detection for this many indices
- private const val STABILITY_MAX = 30.0 // max internal spread of a before/after pair
+ private const val HALF_WIN = 2
+ private const val MIN_DELTA = 60.0
+ private const val MAX_DELTA = 140.0
+ private const val STABILITY_MAX = 30.0
+ private const val MIN_GAP_MS = 45_000L // 45 s minimum between tacks
+ private const val START_SKIP_MS = 120_000L // skip first 2 min (GPS cold-start noise)
fun detectTacks(points: List<TrackPoint>): List<TackEvent> {
if (points.size < 2 * HALF_WIN + 1) return emptyList()
val results = mutableListOf<TackEvent>()
- var nextCandidate = 0
+ var lastTackMs: Long? = null
for (i in HALF_WIN until points.size - HALF_WIN) {
- if (i < nextCandidate) continue
+ if (points[i].timestampMs - points.first().timestampMs < START_SKIP_MS) continue
+ if (lastTackMs != null && points[i].timestampMs - lastTackMs < MIN_GAP_MS) continue
- // Require both "before" and "after" pairs to be internally stable;
- // if one spans the transition itself, that window is noise.
val spreadBefore = abs(angleDiff(points[i - 2].cogDeg, points[i - 1].cogDeg))
val spreadAfter = abs(angleDiff(points[i + 1].cogDeg, points[i + 2].cogDeg))
if (spreadBefore > STABILITY_MAX || spreadAfter > STABILITY_MAX) continue
@@ -30,7 +30,7 @@ object TackDetector {
if (delta in MIN_DELTA..MAX_DELTA) {
results += TackEvent(i, points[i].lat, points[i].lon, cogBefore, cogAfter)
- nextCandidate = i + SKIP_AFTER
+ lastTackMs = points[i].timestampMs
}
}
return results