5889 Commits
Author SHA1 Message Date
Axel Uhl e3c0e0f187 bug6241: feed already-known maneuvers to newly-set wind estimation
Closes the FIXME at TrackedRaceImpl.setWindEstimation. When a non-null
IncrementalWindEstimation is installed on a race (either because
setWindEstimation was called for the first time after the wind factory
service arrived, or because setPolarDataService recomputed the estimator's
context), the already-known maneuvers for each competitor are read from
maneuverCache -- which is polymorphic across the two SerializableManeuverCache
implementations, so it works both for DB-loaded races
(ManeuversFromDatabase) and for computed-maneuvers races
(ManeuversFromSmartFutureCache) -- and handed off to the estimator via
IncrementalWindEstimation.alreadyClassifiedManeuversAvailable. This
skips detection entirely; only the final wind-fix conversion runs on the
estimator side.

The hand-off is scheduled on the shared background executor per
competitor so that setWindEstimation returns quickly without blocking
its caller (typically the OSGi service-tracker thread or a
RaceAdditionListener callback thread) on maneuverCache.get(_, true)
which may wait for a pending detection to complete.

Each per-competitor task checks that the race's current windEstimation
is still the one it was scheduled with before doing the hand-off, so a
subsequent setWindEstimation that replaces the estimator does not
retroactively feed a stale estimator.

Removes the stale 'no need to trigger maneuver recalculation' comment
that was preventing exactly this feed, and removes the TODO about
'reusing the state of incremental maneuver detectors' which is now
addressed by this hand-off (we do reuse the computed / loaded maneuvers,
not the incremental detector state, but the effect is the same).

Removed the FIXME bug6142 (typo for bug6241) that this commit closes.
2026-07-14 14:44:09 +02:00
Axel Uhl e3f4b57d8c bug6241: IncrementalWindEstimation.alreadyClassifiedManeuversAvailable
Adds a hand-off for already-classified maneuvers (e.g., loaded from the
persistent maneuver cache after a fingerprint match, or held in memory
after a prior detection run) to be fed to the wind estimator without
re-running detection or the MST/HMM classification graph. The estimator
adapts each Maneuver into SimpleManeuverForEstimation +
SimpleManeuverWithEstimatedType, then runs only the final wind-fix
conversion step (WindTrackCalculator.getWindTrackFromManeuverClassifications)
and reconciles the resulting fixes into its estimated wind track.

The default interface method is empty so existing implementors remain
source- and binary-compatible; only
IncrementalMstHmmWindEstimationForTrackedRace overrides it.

Refactoring:
 * GraphRecalculationTask now polls a queue of PendingUpdate instances
   with two implementations: NewSpotsUpdate (the existing detection path)
   and PreClassifiedUpdate (the new DB-load / re-adaptation path).
 * The reconciliation body (windTrackCalculator + estimatedWindTrack
   merge) is factored into applyManeuverClassificationsToWindTrack and
   called from both paths, preserving the FIXME bug6026 note.
 * The domain->ManeuverTypeForClassification mapping is centralized as a
   static helper, matching ManeuverWithEstimatedTypeFromManeuverTest.
 * newManeuverSpotsDetected and alreadyClassifiedManeuversAvailable
   both go through a shared submit(PendingUpdate) method that enqueues
   and, if needed, starts a GraphRecalculationTask.

This is the wind-estimation side of the fix; the caller side (feeding
a race's cached maneuvers into a newly-installed estimator) comes in
subsequent commits.
2026-07-14 14:34:07 +02:00
Axel Uhl 0f9e3d2655 bug6241: PolarDataService.runWhenPolarLoadingFinishedFor(race, callback)
Adds a way to register a drain-callback on the polar-data loading
pipeline for a specific race without also triggering fresh ingestion of
that race's fixes (which is what raceFinishedLoading does). The new
method may be called any number of times, before or after
raceFinishedLoading, and coordinates with it via a per-miner gate so a
caller never accidentally registers a drain callback while the pipeline
is momentarily idle before this race's fixes have entered it.

PolarDataMiner now maintains:
 - callbacksWaitingForFixIngestion: parked callbacks for races whose
   fixes haven't been queued yet;
 - racesWithIngestedFixes: races whose fixes have been fully queued.

raceFinishedLoading, after queueing all of a race's competitor fixes,
promotes the race into racesWithIngestedFixes and registers all parked
callbacks (plus the caller-supplied one, if any) on the drain.
runWhenPolarLoadingFinishedFor either registers immediately (race
already ingested) or parks the callback for later promotion.

Removed the stale 'TODO bug6241:' comment atop raceFinishedLoading; the
mechanism it sketched is now in place (loading pipeline + drain
callback) so the TODO no longer applies.

This method is the building block that the per-race installation
primitive for the maneuver-based wind estimator (task 14) will
compose with TrackedRace.runWhenPastLoading.
2026-07-14 14:16:42 +02:00
Axel Uhl 88efe298da bug6241: add TrackedRace.runWhenPastLoading primitive
Introduces a listener-based primitive that fires a callback exactly once
when a tracked race reaches a status strictly beyond LOADING (TRACKING,
FINISHED, ERROR, or REMOVED via status transition), provided the race is
still a member of its regatta at that moment. If the race is removed
from its regatta before the status condition is met, the callback is
never fired and both the status listener and the regatta-removal
listener are torn down.

The 'strictly beyond LOADING' condition (rather than 'at or beyond
LOADING') is what makes this primitive work for RaceLogRaceTracker-tracked
races that transition directly from PREPARED to TRACKING without ever
entering the LOADING state.

This will be used to wait for the moment when a tracked race is ready
for maneuver-based wind estimation to be attached (i.e., loading is
done, whatever there was of it) without leaking listeners on races that
never make it there because the user removed them.

Implementations added on TrackedRaceImpl (real behavior), DummyTrackedRace
(no-op stub), and MockedTrackedRaceWithStartTimeAndRanks (no-op stub).
New test TrackedRaceRunWhenPastLoadingTest covers the fast path,
PREPARED->TRACKING skipping LOADING, exactly-once semantics across
multiple transitions, and the removal-before-firing cancellation path.
2026-07-14 13:50:49 +02:00
Axel Uhl f05792dfef bug6241: added FIXME comment 2026-07-09 16:18:41 +02:00
Axel Uhl ada3041d73 bug6241: started implementing waiting for Processor finishing elements 2026-07-08 17:04:08 +02:00
Axel Uhl 18af8fc20c fixing NPE in mark passing calculator when leg bearing is unknown 2026-07-07 18:46:02 +02:00
Axel Uhl b3970a8007 simplified SpeedWithBearing implementations by defaulting travelTo; avoid NPE 2026-07-07 18:17:48 +02:00
Axel Uhl 92231e426d bug6268: null handling for persistent maneuver cache 2026-07-02 11:09:09 +02:00
Axel Uhl 481d52da4e bug6226: added logging and fallback in case the CALCULATOR_VERSION is missing 2026-06-20 18:57:16 +02:00
Axel Uhl 4bba57d859 excluding ORC Light ("LITE") certificates from tests;
they don't contain values for GPH and long distance allowances which the
tests need
2026-04-21 18:52:33 +02:00
Axel Uhl 5bb42d2d8c bug6236: (WIP) moving towards notifying multiple fixes at once 2026-04-14 11:20:22 +02:00
Axel Uhl b3239227d4 bug5959 aftermath: don't count same RaceColumn multiple times when looking for attached TrackedRace;
Delegating leaderboards were adding to the count, although they refer to
the same RaceColumn to which the same TrackedRace is attached.
Therefore, waiting for the number of attached RaceLogs would wait
endlessly because only one race log got attached for the single
RaceColumn.
2026-04-09 15:00:59 +02:00
Axel Uhl e4e142d936 bug6229: removed now unused parameter for event/regatta time range filtering 2026-04-06 23:34:05 +02:00
Axel Uhl 1dd7658802 bug6229: removed EventResolver observer from FixLoaderAndTracker 2026-04-06 23:31:07 +02:00
Axel Uhl 0a8e0a1297 bug6229: added CourseArea observer pattern for FixLoaderAndTracker's event cache 2026-03-31 00:01:34 +02:00
Axel Uhl 863468baa2 bug6229: first implementation to filter by Regatta/Event end time during fix import 2026-03-30 18:35:05 +02:00
Axel Uhl 0716fd6a73 bug6222: keep ordering of fixes loaded from DB in TopLevelMasterdata;
this avoids the use of a HashSet and instead uses LinkedList to keep the
order of items added
2026-03-25 00:38:47 +01:00
Axel Uhl bbc8d9d6ed bug6222: this has the fix, trimming the queue of course approximator after removing from window 2026-03-22 23:20:14 +01:00
Axel Uhl aeb8a56561 bug6222: finally constructed a failing test case 2026-03-22 23:12:51 +01:00
Axel Uhl 7d473f4404 bug6222: fix for FixWindow's COG delta aggregation for out-of-order delivery;
initial commit with a test case supposed to be failing but not failing yet
2026-03-20 19:00:30 +01:00
Axel Uhl 0823e0c28c bug5959: instantiating the correct Maneuver implementation class when loading from DB 2026-03-17 17:23:22 +01:00
Axel Uhl 3bcb21b3ea bug6219: no need to invoke compareByBetterScore if no more than one medal race 2026-03-13 18:27:34 +01:00
Axel Uhl 2d936a6455 bug6219: fixed SchoringScheme.compareByMedalRaceScore implementation 2026-03-13 18:26:11 +01:00
Axel Uhl f7c52b6cb2 bug6219: implementation that lets formerly failing test pass;
if tied on medal series points, apply compareByBetterScore to the
scoring medal race columns
2026-03-13 17:47:24 +01:00
Axel Uhl 527eb51271 bug6219: formatting change only 2026-03-13 14:33:38 +01:00
Axel Uhl a904a14b23 added CPU metering for backend polar computation (key "BACKEND_POLARS") 2026-03-13 11:50:52 +01:00
Axel Uhl 97cf227b39 Merge remote-tracking branch 'github/main' 2026-03-12 18:01:42 +01:00
Axel Uhl 5bfc788029 improved Javadoc in ScoringScheme 2026-03-12 18:00:15 +01:00
Axel Uhl 5701220c45 show regatta name + race name for MarkPassingCalculator thread 2026-03-11 20:44:12 +01:00
Axel Uhl 1b13e05f13 bug5959 aftermath: activate late initialization of approximators 2026-03-11 15:28:57 +01:00
Axel Uhl 8503949ae3 bug5959: fixed Javadoc typo 2026-03-10 16:28:23 +01:00
Axel Uhl b2e4e7298a Merge branch 'main' into bug5959 2026-03-07 22:45:42 +01:00
Axel Uhl 58d9b23603 Merge branch 'bug6209' into bug5959 2026-03-04 15:57:40 +01:00
Axel Uhl f961bdeaf1 Merge branch 'bug6209' into bug6215 2026-03-04 00:39:56 +01:00
Axel Uhl 8a59e04a7b bug6209: synchronize GPSFix COG/SOG cache and return materialized cached value from cacheEstimatedSpeed(...) 2026-03-04 00:35:15 +01:00
Axel Uhl 542595eac1 Merge branch 'bug6209' into bug5959 2026-03-03 17:43:59 +01:00
Axel Uhl 22f180cee1 bug6215: moving Speed, Position, Bearing, Weigher and others to SSE; GWT CFSs not done yet 2026-03-03 17:30:56 +01:00
Axel Uhl 97d7852f00 bug6209: refactoring FixWindow fix logging into separate method 2026-03-03 16:36:45 +01:00
Axel Uhl 67601b6cf1 Merge branch 'bug6209' into bug5959 2026-02-20 17:43:42 +01:00
Axel Uhl 7acefefb5d bug6209: removed obsolete TODO 2026-02-20 17:43:32 +01:00
Axel Uhl cb282f1e26 bug6209: fixing differences between early and late approximator initialization;
The key was to extend the queue length in FixWindow to the duration used
for validity/outlier detection. This uses the averaging interval in
*both* directions starting from a fix, other than COG/SOG estimation
which uses fixes only in half that interval in each direction.
2026-02-20 17:35:41 +01:00
Axel Uhl 0b79e5d723 bug5959: fixed post-merge issues from bug6209 2026-02-20 11:36:13 +01:00
Axel Uhl d6126636a0 Merge branch 'bug6209' into bug5959 2026-02-20 11:01:20 +01:00
Axel Uhl dcac700217 bug6209: logging fixes for test case; focusing on failing track 2026-02-19 16:56:20 +01:00
Axel Uhl fec2015f71 bug6209: removed debug output and cleaned up;
There are still sporadic test failures, with maneuver candidates being
at slightly different time points between early and late initialization.
Another puzzle to solve?
2026-02-19 16:16:18 +01:00
Axel Uhl d9818f86dc bug6209: interims commit: test passes by consistently using compacted cached speed of fix in getEstimatedSpeed 2026-02-19 16:05:30 +01:00
Axel Uhl a3dabb8ccd bug6209: when validity changes for a fix, invalidate estimated speed for affected neighbours 2026-02-19 14:58:03 +01:00
Axel Uhl 8040141088 Merge branch 'bug6209' into bug5959 2026-02-18 11:30:02 +01:00
Axel Uhl f5a5399349 bug6209: fixed one remaining issue regarding out-of-order or duplicate time point fix insertion into approximator's queue 2026-02-18 11:29:27 +01:00