mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-16 01:01:02 +00:00
Fixed problems after merge and started adding and removal of waypoints.
This commit is contained in:
1 parent
fb7ddf870a
commit
fd2de1d475
5 files changed
+160
-106
No files matched your search
+66
-55
@@ -64,12 +64,15 @@ public abstract class AbstractMarkPassingTest extends OnlineTracTracBasedTest {
|
||||
|
||||
private void setUp(String raceNumber) throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
super.setUp();
|
||||
URI storedUri = new URI("file:///" + new File("resources/" + getFileName() + raceNumber + ".mtb").getCanonicalPath().replace('\\', '/'));
|
||||
super.setUp(new URL("file:///" + new File("resources/" + getFileName() + raceNumber + ".txt").getCanonicalPath()),
|
||||
/* liveUri */null, /* storedUri */storedUri, new ReceiverType[] { ReceiverType.MARKPASSINGS, ReceiverType.RACECOURSE, ReceiverType.MARKPOSITIONS,
|
||||
ReceiverType.RAWPOSITIONS });
|
||||
getTrackedRace().recordWind(new WindImpl(/* position */null, MillisecondsTimePoint.now(), new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(65))),
|
||||
new WindSourceImpl(WindSourceType.WEB));
|
||||
URI storedUri = new URI("file:///"
|
||||
+ new File("resources/" + getFileName() + raceNumber + ".mtb").getCanonicalPath().replace('\\', '/'));
|
||||
super.setUp(
|
||||
new URL("file:///" + new File("resources/" + getFileName() + raceNumber + ".txt").getCanonicalPath()),
|
||||
/* liveUri */null, /* storedUri */storedUri, new ReceiverType[] { ReceiverType.MARKPASSINGS,
|
||||
ReceiverType.RACECOURSE, ReceiverType.MARKPOSITIONS, ReceiverType.RAWPOSITIONS });
|
||||
getTrackedRace().recordWind(
|
||||
new WindImpl(/* position */null, MillisecondsTimePoint.now(), new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(65))), new WindSourceImpl(WindSourceType.WEB));
|
||||
|
||||
for (Waypoint w : getRace().getCourse().getWaypoints()) {
|
||||
waypoints.add(w);
|
||||
@@ -86,7 +89,8 @@ public abstract class AbstractMarkPassingTest extends OnlineTracTracBasedTest {
|
||||
|
||||
protected abstract String getFileName();
|
||||
|
||||
protected void testRace(String raceNumber) throws IOException, InterruptedException, URISyntaxException, ParseException {
|
||||
protected void testRace(String raceNumber) throws IOException, InterruptedException, URISyntaxException,
|
||||
ParseException {
|
||||
setUp(raceNumber);
|
||||
testWholeRace();
|
||||
testMiddleOfRace(0);
|
||||
@@ -155,7 +159,8 @@ public abstract class AbstractMarkPassingTest extends OnlineTracTracBasedTest {
|
||||
System.out.println("Both null" + "\n");
|
||||
}
|
||||
} else {
|
||||
long timeDelta = givenPasses.get(c).get(w).getTimePoint().asMillis() - computedPasses.get(c).get(w).getTimePoint().asMillis();
|
||||
long timeDelta = givenPasses.get(c).get(w).getTimePoint().asMillis()
|
||||
- computedPasses.get(c).get(w).getTimePoint().asMillis();
|
||||
if ((Math.abs(timeDelta) < tolerance)) {
|
||||
correctPasses++;
|
||||
if (printRight) {
|
||||
@@ -182,7 +187,8 @@ public abstract class AbstractMarkPassingTest extends OnlineTracTracBasedTest {
|
||||
}
|
||||
|
||||
double totalMarkPasses = numberOfCompetitors * waypoints.size();
|
||||
assertEquals(totalMarkPasses, incorrectPasses + correctPasses + wronglyNotComputed + correctlyNotComputed + wronglyComputed, 0);
|
||||
assertEquals(totalMarkPasses, incorrectPasses + correctPasses + wronglyNotComputed + correctlyNotComputed
|
||||
+ wronglyComputed, 0);
|
||||
double accuracy = (double) (correctPasses + correctlyNotComputed) / totalMarkPasses;
|
||||
if (printResult) {
|
||||
System.out.println("Total theoretical Passes: " + totalMarkPasses);
|
||||
@@ -200,62 +206,66 @@ public abstract class AbstractMarkPassingTest extends OnlineTracTracBasedTest {
|
||||
incorrect += incorrectPasses;
|
||||
skipped += wronglyNotComputed;
|
||||
extra += wronglyComputed;
|
||||
assertTrue("Expected accuracy to be at least 0.8 but was "+accuracy, accuracy >= 0.8);
|
||||
assertTrue("Expected accuracy to be at least 0.8 but was " + accuracy, accuracy >= 0.8);
|
||||
}
|
||||
|
||||
private void testMiddleOfRace(int waypoint) {
|
||||
CandidateFinder finder = new CandidateFinder(getTrackedRace());
|
||||
CandidateChooser chooser = new CandidateChooser(getTrackedRace());
|
||||
private void testMiddleOfRace(int zeroBasedIndexOfLastWaypointToBePassed) {
|
||||
CandidateFinder finder = new CandidateFinderImpl(getTrackedRace());
|
||||
CandidateChooser chooser = new CandidateChooserImpl(getTrackedRace());
|
||||
int mistakes = 0;
|
||||
Waypoint start = waypoints.get(waypoint);
|
||||
Waypoint second = waypoints.get(waypoint + 1);
|
||||
Waypoint lastWaypointToBePassed = waypoints.get(zeroBasedIndexOfLastWaypointToBePassed);
|
||||
Waypoint wayPointAfterwards = waypoints.get(zeroBasedIndexOfLastWaypointToBePassed + 1);
|
||||
for (Competitor c : getRace().getCompetitors()) {
|
||||
MarkPassing markPassing = givenPasses.get(c).get(wayPointAfterWards);
|
||||
if (markPassing == null) {
|
||||
if (givenPasses.get(c).get(start) != null && givenPasses.get(c).get(second) != null) {
|
||||
startTime = givenPasses.get(c).get(start).getTimePoint();
|
||||
secondPass = givenPasses.get(c).get(second).getTimePoint();
|
||||
TimePoint delta = new MillisecondsTimePoint(startTime.plus(secondPass.asMillis()).asMillis() / 2);
|
||||
TimePoint firstPassingOfNext = markPassing.getTimePoint().minus(20000);
|
||||
List<GPSFix> fixes = new ArrayList<GPSFix>();
|
||||
try {
|
||||
getTrackedRace().getTrack(c).lockForRead();
|
||||
for (GPSFixMoving fix : getTrackedRace().getTrack(c).getFixes()) {
|
||||
if (fix.getTimePoint().before(delta)) {
|
||||
if (fix.getTimePoint().before(firstPassingOfNext)) {
|
||||
fixes.add(fix);
|
||||
MarkPassing markPassing = givenPasses.get(c).get(wayPointAfterwards);
|
||||
if (markPassing != null) {
|
||||
if (givenPasses.get(c).get(lastWaypointToBePassed) != null
|
||||
&& givenPasses.get(c).get(wayPointAfterwards) != null) {
|
||||
TimePoint startTime = givenPasses.get(c).get(lastWaypointToBePassed).getTimePoint();
|
||||
TimePoint secondPass = givenPasses.get(c).get(wayPointAfterwards).getTimePoint();
|
||||
TimePoint delta = new MillisecondsTimePoint(startTime.plus(secondPass.asMillis()).asMillis() / 2);
|
||||
TimePoint firstPassingOfNext = markPassing.getTimePoint().minus(20000);
|
||||
List<GPSFix> fixes = new ArrayList<GPSFix>();
|
||||
try {
|
||||
getTrackedRace().getTrack(c).lockForRead();
|
||||
for (GPSFixMoving fix : getTrackedRace().getTrack(c).getFixes()) {
|
||||
if (fix.getTimePoint().before(delta)) {
|
||||
if (fix.getTimePoint().before(firstPassingOfNext)) {
|
||||
fixes.add(fix);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
getTrackedRace().getTrack(c).unlockAfterRead();
|
||||
}
|
||||
Pair<Iterable<Candidate>, Iterable<Candidate>> f = finder.getCandidateDeltas(c, fixes);
|
||||
chooser.calculateMarkPassDeltas(c, f.getA(), f.getB());
|
||||
boolean gotPassed = true;
|
||||
boolean gotOther = false;
|
||||
// System.out.println(c);
|
||||
for (Waypoint w : getRace().getCourse().getWaypoints()) {
|
||||
MarkPassing old = givenPasses.get(c).get(w);
|
||||
MarkPassing newm = getTrackedRace().getMarkPassing(c, w);
|
||||
// System.out.println(newm);
|
||||
if (waypoints.indexOf(w) <= zeroBasedIndexOfLastWaypointToBePassed) {
|
||||
if ((old == null) != (newm == null)) {
|
||||
gotPassed = false;
|
||||
}
|
||||
} else {
|
||||
if (w != wayPointAfterwards && newm != null) {
|
||||
gotOther = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
getTrackedRace().getTrack(c).unlockAfterRead();
|
||||
}
|
||||
Pair<Iterable<Candidate>, Iterable<Candidate>> f = finder.getCandidateDeltas(c, fixes);
|
||||
chooser.calculateMarkPassDeltas(c, f);
|
||||
boolean gotPassed = true;
|
||||
boolean gotOther = false;
|
||||
//System.out.println(c);
|
||||
for (Waypoint w : getRace().getCourse().getWaypoints()) {
|
||||
MarkPassing old = givenPasses.get(c).get(w);
|
||||
MarkPassing newm = getTrackedRace().getMarkPassing(c, w);
|
||||
//System.out.println(newm);
|
||||
if (waypoints.indexOf(w) <= zeroBasedIndexOfLastWaypointToBePassed) {
|
||||
if ((old == null) != (newm == null)) {
|
||||
gotPassed = false;
|
||||
}
|
||||
} else {
|
||||
if (w != wayPointAfterWards&&newm != null) {
|
||||
gotOther = true;
|
||||
}
|
||||
if (!gotPassed || gotOther) {
|
||||
mistakes++;
|
||||
}
|
||||
}
|
||||
if (!gotPassed || gotOther) {
|
||||
mistakes++;
|
||||
}
|
||||
}
|
||||
Assert.assertTrue(mistakes == 0);
|
||||
}
|
||||
Assert.assertTrue(mistakes == 0);
|
||||
}
|
||||
|
||||
|
||||
@AfterClass
|
||||
public static void createXML() throws IOException {
|
||||
double accuracy = correct / totalPasses;
|
||||
@@ -267,7 +277,8 @@ public abstract class AbstractMarkPassingTest extends OnlineTracTracBasedTest {
|
||||
System.out.println(different);
|
||||
System.out.println(allSkipped);
|
||||
System.out.println(allExtra);
|
||||
MeasurementXMLFile performanceReport = new MeasurementXMLFile("TEST-" + simpleName + ".xml", simpleName, className);
|
||||
MeasurementXMLFile performanceReport = new MeasurementXMLFile("TEST-" + simpleName + ".xml", simpleName,
|
||||
className);
|
||||
MeasurementCase performanceReportCase = performanceReport.addCase(simpleName);
|
||||
performanceReportCase.addMeasurement(new Measurement("Accurate", accuracy));
|
||||
performanceReportCase.addMeasurement(new Measurement("Different", different));
|
||||
|
||||
+4
-3
@@ -928,9 +928,7 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Distance getAverageSignedCrossTrackError(Competitor competitor, TimePoint timePoint,
|
||||
@@ -942,4 +940,7 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
||||
@Override
|
||||
public Distance getAverageSignedCrossTrackError(Competitor competitor, TimePoint from, TimePoint to,
|
||||
boolean upwindOnly, boolean waitForLatestAnalysis) throws NoWindException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+2
-5
@@ -53,9 +53,6 @@ public class MarkPassingCalculator {
|
||||
/* keepAliveTime */60, TimeUnit.SECONDS,
|
||||
/* workQueue */new LinkedBlockingQueue<Runnable>(), new ThreadFactoryWithPriority(Thread.NORM_PRIORITY - 1));
|
||||
|
||||
private MarkPassingUpdateListener listener;
|
||||
private AbstractCandidateFinder finder;
|
||||
private AbstractCandidateChooser chooser;
|
||||
private boolean suspended = false;
|
||||
|
||||
public MarkPassingCalculator(DynamicTrackedRace race, boolean listen) {
|
||||
@@ -128,8 +125,8 @@ public class MarkPassingCalculator {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateWaypoints(Integer smallestInterger) {
|
||||
Map<Competitor, Pair<Iterable<Candidate>, Iterable<Candidate>>> addedCandidates = finder.invalidateAfterCourseChange(smallestInterger);
|
||||
private void updateWaypoints(Integer zeroBasedIndexOfEarliestWaypointChanged) {
|
||||
Map<Competitor, Pair<Iterable<Candidate>, Iterable<Candidate>>> addedCandidates = finder.invalidateAfterCourseChange(zeroBasedIndexOfEarliestWaypointChanged);
|
||||
for (Entry<Competitor, Pair<Iterable<Candidate>, Iterable<Candidate>>> entry : addedCandidates.entrySet()) {
|
||||
Pair<Iterable<Candidate>, Iterable<Candidate>> deltas = entry.getValue();
|
||||
chooser.calculateMarkPassDeltas(entry.getKey(), deltas.getA(), deltas.getB());
|
||||
|
||||
+85
-39
@@ -6,6 +6,7 @@ import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@@ -56,6 +57,7 @@ public class CandidateFinderImpl implements CandidateFinder {
|
||||
private final double penaltyForDistanceCandidates = 0.8;
|
||||
|
||||
private static final Logger logger = Logger.getLogger(CandidateFinderImpl.class.getName());
|
||||
private Map<Competitor, LinkedHashMap<GPSFix, Map<Waypoint, Double>>> distanceCache = new LinkedHashMap<>();
|
||||
private Map<Competitor, TreeMap<GPSFix, Map<Waypoint, List<Double>>>> crossTrackErrors = new HashMap<>();
|
||||
private Map<Competitor, TreeMap<GPSFix, Map<Mark, Distance>>> distances = new HashMap<>();
|
||||
// Distance are calculated to each mark. Since the distance to a line relies on both marks, these line marks are
|
||||
@@ -114,7 +116,8 @@ public class CandidateFinderImpl implements CandidateFinder {
|
||||
affectedFixes.put(c, new ArrayList<GPSFix>());
|
||||
}
|
||||
for (GPSFix fix : markFixes) {
|
||||
Pair<TimePoint, TimePoint> timePoints = race.getOrCreateTrack(mark).getEstimatedPositionTimePeriodAffectedBy(fix);
|
||||
Pair<TimePoint, TimePoint> timePoints = race.getOrCreateTrack(mark)
|
||||
.getEstimatedPositionTimePeriodAffectedBy(fix);
|
||||
for (Entry<Competitor, List<GPSFix>> c : affectedFixes.entrySet()) {
|
||||
DynamicGPSFixTrack<Competitor, GPSFixMoving> track = race.getTrack(c.getKey());
|
||||
GPSFix comFix = track.getFirstFixAtOrAfter(timePoints.getA());
|
||||
@@ -143,8 +146,10 @@ public class CandidateFinderImpl implements CandidateFinder {
|
||||
List<Candidate> wrongCans = new ArrayList<>();
|
||||
calculatesDistances(c, fixes, marks);
|
||||
calculateCrossTrackErrors(c, fixes, race.getRace().getCourse().getWaypoints());
|
||||
Pair<List<Candidate>, List<Candidate>> distanceCandidates = checkForDistanceCandidateChanges(c, fixes, race.getRace().getCourse().getWaypoints());
|
||||
Pair<List<Candidate>, List<Candidate>> xteCandidates = checkForXTECandidatesChanges(c, fixes, race.getRace().getCourse().getWaypoints());
|
||||
Pair<List<Candidate>, List<Candidate>> distanceCandidates = checkForDistanceCandidateChanges(c, fixes, race
|
||||
.getRace().getCourse().getWaypoints());
|
||||
Pair<List<Candidate>, List<Candidate>> xteCandidates = checkForXTECandidatesChanges(c, fixes, race.getRace()
|
||||
.getCourse().getWaypoints());
|
||||
newCans.addAll(xteCandidates.getA());
|
||||
newCans.addAll(distanceCandidates.getA());
|
||||
wrongCans.addAll(xteCandidates.getB());
|
||||
@@ -157,28 +162,41 @@ public class CandidateFinderImpl implements CandidateFinder {
|
||||
|
||||
@Override
|
||||
public Map<Competitor, Pair<Iterable<Candidate>, Iterable<Candidate>>> invalidateAfterCourseChange(int indexOfChange) {
|
||||
// TODO Auto-generated method stub
|
||||
// TODO Doesnt remove actually removed waypoint, tries to remove added
|
||||
Course course = race.getRace().getCourse();
|
||||
List<Waypoint> changedWaypoints = new ArrayList<>();
|
||||
for (Waypoint w : course.getWaypoints()) {
|
||||
if (course.getIndexOfWaypoint(w) > indexOfChange - 2) {
|
||||
changedWaypoints.add(w);
|
||||
}
|
||||
}
|
||||
Map<Competitor, Iterable<Candidate>> removedCandidates = removeWaypoints(changedWaypoints);
|
||||
Map<Competitor, Iterable<Candidate>> addedCandidates = addWaypoints(changedWaypoints);
|
||||
Map<Competitor, Pair<Iterable<Candidate>, Iterable<Candidate>>> result = null;
|
||||
return null;
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected Map<Competitor, Pair<Iterable<Candidate>, Iterable<Candidate>>> addWaypoints(Collection<Waypoint> waypoints) {
|
||||
protected Map<Competitor, Iterable<Candidate>> addWaypoints(
|
||||
Collection<Waypoint> waypoints) {
|
||||
Map<Competitor, Iterable<Candidate>> result = new HashMap<>();
|
||||
Course course = race.getRace().getCourse();
|
||||
processNewWaypoint(waypoints, course.getFirstWaypoint(), course.getLastWaypoint());
|
||||
List<Mark> uniqueMarks = getUniqueMarksOfWaypoints(waypoints);
|
||||
for (Competitor c : race.getRace().getCompetitors()) {
|
||||
List<Candidate> cans = new ArrayList<>();
|
||||
Set<GPSFix> allFixes = getAllFixes(c);
|
||||
List<Mark> uniqueMarks = getUniqueMarksOfWaypoints(waypoints);
|
||||
calculatesDistances(c, allFixes, uniqueMarks);
|
||||
calculateCrossTrackErrors(c, allFixes, waypoints);
|
||||
cans.addAll(checkForDistanceCandidateChanges(c, allFixes, waypoints).getA());
|
||||
cans.addAll(checkForXTECandidatesChanges(c, allFixes, waypoints).getA());
|
||||
result.put(c, cans);
|
||||
}
|
||||
return null;
|
||||
return result;
|
||||
}
|
||||
|
||||
protected Map<Competitor, Pair<Iterable<Candidate>, Iterable<Candidate>>> removeWaypoints(Collection<Waypoint> waypoints) {
|
||||
protected Map<Competitor, Iterable<Candidate>> removeWaypoints(Collection<Waypoint> waypoints) {
|
||||
for (Mark m : getUniqueMarksOfWaypoints(waypoints)) {
|
||||
marks.remove(m);
|
||||
for (Map<GPSFix, Map<Mark, Distance>> map : distances.values()) {
|
||||
@@ -187,12 +205,14 @@ public class CandidateFinderImpl implements CandidateFinder {
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Waypoint w : waypoints) {
|
||||
passingInstructions.remove(w);
|
||||
lineMarks.remove(w);
|
||||
}
|
||||
Map<Competitor, Iterable<Candidate>> result = new HashMap<>();
|
||||
for (Competitor c : race.getRace().getCompetitors()) {
|
||||
List<Candidate> badCans = new ArrayList<>();
|
||||
for (Waypoint w : waypoints) {
|
||||
passingInstructions.remove(w);
|
||||
lineMarks.remove(w);
|
||||
for (Map<Waypoint, List<Double>> xtes : crossTrackErrors.get(c).values()) {
|
||||
xtes.remove(w);
|
||||
}
|
||||
@@ -205,7 +225,7 @@ public class CandidateFinderImpl implements CandidateFinder {
|
||||
}
|
||||
result.put(c, badCans);
|
||||
}
|
||||
return null;
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<Mark> getUniqueMarksOfWaypoints(Collection<Waypoint> waypoints) {
|
||||
@@ -295,8 +315,10 @@ public class CandidateFinderImpl implements CandidateFinder {
|
||||
/**
|
||||
* For each fix the distance to each waypoint is calculated. Then the fix is checked for being a candidate.
|
||||
*/
|
||||
private Pair<List<Candidate>, List<Candidate>> checkForDistanceCandidateChanges(Competitor c, Iterable<GPSFix> fixes, Iterable<Waypoint> waypoints) {
|
||||
Pair<List<Candidate>, List<Candidate>> result = new Pair<List<Candidate>, List<Candidate>>(new ArrayList<Candidate>(), new ArrayList<Candidate>());
|
||||
private Pair<List<Candidate>, List<Candidate>> checkForDistanceCandidateChanges(Competitor c,
|
||||
Iterable<GPSFix> fixes, Iterable<Waypoint> waypoints) {
|
||||
Pair<List<Candidate>, List<Candidate>> result = new Pair<List<Candidate>, List<Candidate>>(
|
||||
new ArrayList<Candidate>(), new ArrayList<Candidate>());
|
||||
Set<GPSFix> affectedFixes = new TreeSet<GPSFix>(comp);
|
||||
GPSFixTrack<Competitor, GPSFixMoving> track = race.getTrack(c);
|
||||
TreeMap<GPSFix, Map<Mark, Distance>> competitorDistances = distances.get(c);
|
||||
@@ -348,11 +370,13 @@ public class CandidateFinderImpl implements CandidateFinder {
|
||||
Map<Mark, Distance> fixDistances = competitorDistances.get(fix);
|
||||
Distance dis = fixDistances != null ? fixDistances.get(m) : null;
|
||||
Distance disBefore = fixBefore != null ? competitorDistances.get(fixBefore).get(m) : null;
|
||||
Distance disAfter = (fixAfter != null && competitorDistances.get(fixAfter) != null) ? competitorDistances.get(fixAfter).get(m) : null;
|
||||
Distance disAfter = (fixAfter != null && competitorDistances.get(fixAfter) != null) ? competitorDistances
|
||||
.get(fixAfter).get(m) : null;
|
||||
if (dis == null || disBefore == null || disAfter == null) {
|
||||
continue;
|
||||
}
|
||||
if (disBefore != null && disAfter != null && dis.getMeters() < disBefore.getMeters() && dis.getMeters() < disAfter.getMeters()) {
|
||||
if (disBefore != null && disAfter != null && dis.getMeters() < disBefore.getMeters()
|
||||
&& dis.getMeters() < disAfter.getMeters()) {
|
||||
t = fix.getTimePoint();
|
||||
p = fix.getPosition();
|
||||
if (cost != null) { // Candidate for both marks of a gate, the more likely one is chosen
|
||||
@@ -366,7 +390,8 @@ public class CandidateFinderImpl implements CandidateFinder {
|
||||
if (cost == null) {
|
||||
continue;
|
||||
}
|
||||
cost *= isOnCorrectSideOfWaypoint(w, p, t, portMark) ? penaltyForDistanceCandidates : penaltyForDistanceCandidates * penaltyForWrongSide;
|
||||
cost *= isOnCorrectSideOfWaypoint(w, p, t, portMark) ? penaltyForDistanceCandidates
|
||||
: penaltyForDistanceCandidates * penaltyForWrongSide;
|
||||
if (cost > penaltyForSkipping) {
|
||||
isCan = true;
|
||||
if (passingInstructions.get(w) == PassingInstruction.Gate) {
|
||||
@@ -389,14 +414,16 @@ public class CandidateFinderImpl implements CandidateFinder {
|
||||
}
|
||||
}
|
||||
if (!wasCan && isCan) {
|
||||
Candidate newCan = new CandidateImpl(race.getRace().getCourse().getIndexOfWaypoint(w) + 1, t, cost, w);
|
||||
Candidate newCan = new CandidateImpl(race.getRace().getCourse().getIndexOfWaypoint(w) + 1, t, cost,
|
||||
w);
|
||||
distanceCandidates.get(c).get(w).put(fix, newCan);
|
||||
result.getA().add(newCan);
|
||||
} else if (wasCan && !isCan) {
|
||||
distanceCandidates.get(c).get(w).remove(fix);
|
||||
result.getB().add(oldCan);
|
||||
} else if (wasCan && isCan && oldCan.getProbability() != cost) {
|
||||
Candidate newCan = new CandidateImpl(race.getRace().getCourse().getIndexOfWaypoint(w) + 1, t, cost, w);
|
||||
Candidate newCan = new CandidateImpl(race.getRace().getCourse().getIndexOfWaypoint(w) + 1, t, cost,
|
||||
w);
|
||||
distanceCandidates.get(c).get(w).put(fix, newCan);
|
||||
result.getA().add(newCan);
|
||||
result.getB().add(oldCan);
|
||||
@@ -430,8 +457,10 @@ public class CandidateFinderImpl implements CandidateFinder {
|
||||
*
|
||||
* @param waypointAsList
|
||||
*/
|
||||
private Pair<List<Candidate>, List<Candidate>> checkForXTECandidatesChanges(Competitor c, Iterable<GPSFix> fixes, Iterable<Waypoint> waypoints) {
|
||||
Pair<List<Candidate>, List<Candidate>> result = new Pair<List<Candidate>, List<Candidate>>(new ArrayList<Candidate>(), new ArrayList<Candidate>());
|
||||
private Pair<List<Candidate>, List<Candidate>> checkForXTECandidatesChanges(Competitor c, Iterable<GPSFix> fixes,
|
||||
Iterable<Waypoint> waypoints) {
|
||||
Pair<List<Candidate>, List<Candidate>> result = new Pair<List<Candidate>, List<Candidate>>(
|
||||
new ArrayList<Candidate>(), new ArrayList<Candidate>());
|
||||
for (GPSFix fix : fixes) {
|
||||
TimePoint t = fix.getTimePoint();
|
||||
TreeMap<GPSFix, Map<Waypoint, List<Double>>> competitorXTEs = crossTrackErrors.get(c);
|
||||
@@ -473,17 +502,19 @@ public class CandidateFinderImpl implements CandidateFinder {
|
||||
if (xte == 0) {
|
||||
newCandidates.put(Arrays.asList(fix, fix), createCandidate(c, 0, 0, t, t, w, true));
|
||||
} else {
|
||||
if (fixAfter != null && xtesAfter!=null) {
|
||||
if (fixAfter != null && xtesAfter != null) {
|
||||
List<Double> list = xtesAfter.get(w);
|
||||
Double xteAfter = list != null ? list.get(0) : null;
|
||||
if (xteAfter != null && xte < 0 != xteAfter <= 0) {
|
||||
newCandidates.put(Arrays.asList(fix, fixAfter), createCandidate(c, xte, xteAfter, t, tAfter, w, true));
|
||||
newCandidates.put(Arrays.asList(fix, fixAfter),
|
||||
createCandidate(c, xte, xteAfter, t, tAfter, w, true));
|
||||
}
|
||||
}
|
||||
if (fixBefore != null) {
|
||||
Double xteBefore = xtesBefore.get(w).get(0);
|
||||
if (xte < 0 != xteBefore <= 0) {
|
||||
newCandidates.put(Arrays.asList(fixBefore, fix), createCandidate(c, xteBefore, xte, tBefore, t, w, true));
|
||||
newCandidates.put(Arrays.asList(fixBefore, fix),
|
||||
createCandidate(c, xteBefore, xte, tBefore, t, w, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -493,16 +524,18 @@ public class CandidateFinderImpl implements CandidateFinder {
|
||||
if (xte == 0) {
|
||||
newCandidates.put(Arrays.asList(fix, fix), createCandidate(c, 0, 0, t, t, w, false));
|
||||
} else {
|
||||
if (fixAfter != null&&xtesAfter!=null) {
|
||||
if (fixAfter != null && xtesAfter != null) {
|
||||
Double xteAfter = xtesAfter.get(w).get(1);
|
||||
if (xte < 0 != xteAfter <= 0) {
|
||||
newCandidates.put(Arrays.asList(fix, fixAfter), createCandidate(c, xte, xteAfter, t, tAfter, w, false));
|
||||
newCandidates.put(Arrays.asList(fix, fixAfter),
|
||||
createCandidate(c, xte, xteAfter, t, tAfter, w, false));
|
||||
}
|
||||
}
|
||||
if (fixBefore != null) {
|
||||
Double xteBefore = xtesBefore.get(w).get(1);
|
||||
if (xte < 0 != xteBefore <= 0) {
|
||||
newCandidates.put(Arrays.asList(fixBefore, fix), createCandidate(c, xteBefore, xte, tBefore, t, w, false));
|
||||
newCandidates.put(Arrays.asList(fixBefore, fix),
|
||||
createCandidate(c, xteBefore, xte, tBefore, t, w, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -557,7 +590,8 @@ public class CandidateFinderImpl implements CandidateFinder {
|
||||
}
|
||||
}
|
||||
|
||||
private Candidate createCandidate(Competitor c, double xte1, double xte2, TimePoint t1, TimePoint t2, Waypoint w, Boolean portMark) {
|
||||
private Candidate createCandidate(Competitor c, double xte1, double xte2, TimePoint t1, TimePoint t2, Waypoint w,
|
||||
Boolean portMark) {
|
||||
long differenceInMillis = t2.asMillis() - t1.asMillis();
|
||||
double ratio = (Math.abs(xte1) / (Math.abs(xte1) + Math.abs(xte2)));
|
||||
TimePoint t = t1.plus((long) (differenceInMillis * ratio));
|
||||
@@ -596,15 +630,18 @@ public class CandidateFinderImpl implements CandidateFinder {
|
||||
}
|
||||
pos.add(po);
|
||||
}
|
||||
Bearing diff1 = pos.get(0).getBearingGreatCircle(p).getDifferenceTo(pos.get(0).getBearingGreatCircle(pos.get(1)));
|
||||
Bearing diff2 = pos.get(1).getBearingGreatCircle(p).getDifferenceTo(pos.get(1).getBearingGreatCircle(pos.get(0)));
|
||||
Bearing diff1 = pos.get(0).getBearingGreatCircle(p)
|
||||
.getDifferenceTo(pos.get(0).getBearingGreatCircle(pos.get(1)));
|
||||
Bearing diff2 = pos.get(1).getBearingGreatCircle(p)
|
||||
.getDifferenceTo(pos.get(1).getBearingGreatCircle(pos.get(0)));
|
||||
if (Math.abs(diff1.getDegrees()) > 90 || Math.abs(diff2.getDegrees()) > 90) {
|
||||
result = false;
|
||||
}
|
||||
|
||||
} else {
|
||||
Mark m = null;
|
||||
if (instruction == PassingInstruction.Port || instruction == PassingInstruction.Starboard || instruction == PassingInstruction.FixedBearing) {
|
||||
if (instruction == PassingInstruction.Port || instruction == PassingInstruction.Starboard
|
||||
|| instruction == PassingInstruction.FixedBearing) {
|
||||
m = w.getMarks().iterator().next();
|
||||
}
|
||||
if (instruction == PassingInstruction.Gate) {
|
||||
@@ -613,7 +650,8 @@ public class CandidateFinderImpl implements CandidateFinder {
|
||||
}
|
||||
if (m != null) {
|
||||
Pair<Position, Bearing> crossingInfo = Util.get(getCrossingInformation(w, t), portMark ? 0 : 1);
|
||||
result = p.crossTrackError(crossingInfo.getA(), crossingInfo.getB().add(new DegreeBearingImpl(90))).getMeters() < 0;
|
||||
result = p.crossTrackError(crossingInfo.getA(), crossingInfo.getB().add(new DegreeBearingImpl(90)))
|
||||
.getMeters() < 0;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -628,7 +666,8 @@ public class CandidateFinderImpl implements CandidateFinder {
|
||||
private boolean passesInTheRightDirection(Waypoint w, double xte1, double xte2, boolean portMark) {
|
||||
boolean result = true;
|
||||
PassingInstruction instruction = passingInstructions.get(w);
|
||||
if (instruction == PassingInstruction.Port || instruction == PassingInstruction.Line || (instruction == PassingInstruction.Gate && portMark)) {
|
||||
if (instruction == PassingInstruction.Port || instruction == PassingInstruction.Line
|
||||
|| (instruction == PassingInstruction.Gate && portMark)) {
|
||||
result = xte1 > xte2 ? true : false;
|
||||
} else if (instruction == PassingInstruction.Starboard || (instruction == PassingInstruction.Gate && !portMark)) {
|
||||
result = xte1 < xte2 ? true : false;
|
||||
@@ -642,7 +681,8 @@ public class CandidateFinderImpl implements CandidateFinder {
|
||||
private Double getDistanceBasedProbability(Waypoint w, TimePoint t, Distance distance) {
|
||||
Distance legLength = getLegLength(t, w);
|
||||
if (legLength != null) {
|
||||
double result = 1 / (strictnessOfDistanceBasedProbability/*Raising this will make is stricter*/* Math.abs(distance.getMeters() / legLength.getMeters()) + 1);
|
||||
double result = 1 / (strictnessOfDistanceBasedProbability/* Raising this will make is stricter */
|
||||
* Math.abs(distance.getMeters() / legLength.getMeters()) + 1);
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
@@ -687,7 +727,8 @@ public class CandidateFinderImpl implements CandidateFinder {
|
||||
Pair<Mark, Mark> pos = getPortAndStarboardMarks(t, w);
|
||||
Position p1 = race.getOrCreateTrack(pos.getA()).getEstimatedPosition(t, false);
|
||||
Position p2 = race.getOrCreateTrack(pos.getB()).getEstimatedPosition(t, false);
|
||||
distance = (p1 != null && p2 != null) ? p.getDistanceToLine(p1, p2) : p1 != null ? p.getDistance(p1) : p2 != null ? p.getDistance(p1) : null;
|
||||
distance = (p1 != null && p2 != null) ? p.getDistanceToLine(p1, p2) : p1 != null ? p.getDistance(p1)
|
||||
: p2 != null ? p.getDistance(p1) : null;
|
||||
}
|
||||
return distance;
|
||||
}
|
||||
@@ -738,13 +779,15 @@ public class CandidateFinderImpl implements CandidateFinder {
|
||||
Mark portMark = pos.getA();
|
||||
if (portMark != null) {
|
||||
Position portPosition = race.getOrCreateTrack(portMark).getEstimatedPosition(t, false);
|
||||
Bearing crossingPort = before.getBearingGreatCircle(portPosition).middle(after.getBearingGreatCircle(portPosition));
|
||||
Bearing crossingPort = before.getBearingGreatCircle(portPosition).middle(
|
||||
after.getBearingGreatCircle(portPosition));
|
||||
result.add(new Pair<Position, Bearing>(portPosition, crossingPort));
|
||||
}
|
||||
Mark starboardMark = pos.getB();
|
||||
if (starboardMark != null) {
|
||||
Position starboardPosition = race.getOrCreateTrack(starboardMark).getEstimatedPosition(t, false);
|
||||
Bearing crossingStarboard = before.getBearingGreatCircle(starboardPosition).middle(after.getBearingGreatCircle(starboardPosition));
|
||||
Bearing crossingStarboard = before.getBearingGreatCircle(starboardPosition).middle(
|
||||
after.getBearingGreatCircle(starboardPosition));
|
||||
result.add(new Pair<Position, Bearing>(starboardPosition, crossingStarboard));
|
||||
}
|
||||
} else {
|
||||
@@ -772,7 +815,8 @@ public class CandidateFinderImpl implements CandidateFinder {
|
||||
private Pair<Mark, Mark> getPortAndStarboardMarks(TimePoint t, Waypoint w) {
|
||||
List<Position> markPositions = new ArrayList<Position>();
|
||||
for (Mark mark : w.getMarks()) {
|
||||
final Position estimatedMarkPosition = race.getOrCreateTrack(mark).getEstimatedPosition(t, /* extrapolate */false);
|
||||
final Position estimatedMarkPosition = race.getOrCreateTrack(mark).getEstimatedPosition(t, /* extrapolate */
|
||||
false);
|
||||
if (estimatedMarkPosition == null) {
|
||||
return new Pair<Mark, Mark>(null, null);
|
||||
}
|
||||
@@ -781,11 +825,13 @@ public class CandidateFinderImpl implements CandidateFinder {
|
||||
final List<Leg> legs = race.getRace().getCourse().getLegs();
|
||||
final int indexOfWaypoint = race.getRace().getCourse().getIndexOfWaypoint(w);
|
||||
final boolean isStartLine = indexOfWaypoint == 0;
|
||||
final Bearing legDeterminingDirectionBearing = race.getTrackedLeg(legs.get(isStartLine ? 0 : indexOfWaypoint - 1)).getLegBearing(t);
|
||||
final Bearing legDeterminingDirectionBearing = race.getTrackedLeg(
|
||||
legs.get(isStartLine ? 0 : indexOfWaypoint - 1)).getLegBearing(t);
|
||||
if (legDeterminingDirectionBearing == null) {
|
||||
return new Pair<Mark, Mark>(null, null);
|
||||
}
|
||||
Distance crossTrackErrorOfMark0OnLineFromMark1ToNextWaypoint = markPositions.get(0).crossTrackError(markPositions.get(1), legDeterminingDirectionBearing);
|
||||
Distance crossTrackErrorOfMark0OnLineFromMark1ToNextWaypoint = markPositions.get(0).crossTrackError(
|
||||
markPositions.get(1), legDeterminingDirectionBearing);
|
||||
final Mark starboardMarkWhileApproachingLine;
|
||||
final Mark portMarkWhileApproachingLine;
|
||||
if (crossTrackErrorOfMark0OnLineFromMark1ToNextWaypoint.getMeters() < 0) {
|
||||
|
||||
+3
-4
@@ -930,10 +930,6 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getAverageSignedCrossTrackError(Competitor competitor, TimePoint timePoint,
|
||||
boolean waitForLatestAnalysis) throws NoWindException {
|
||||
@@ -944,4 +940,7 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
||||
@Override
|
||||
public Distance getAverageSignedCrossTrackError(Competitor competitor, TimePoint from, TimePoint to,
|
||||
boolean upwindOnly, boolean waitForLatestAnalysis) throws NoWindException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user