mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-21 05:05:31 +00:00
Merge branch 'master' of /home/trac/git
This commit is contained in:
+3
@@ -20,10 +20,13 @@ import com.sap.sailing.domain.common.tracking.DoubleVectorFix;
|
||||
* into the {@link DoubleVectorFix}.
|
||||
*/
|
||||
public enum BravoExtendedSensorDataMetadata implements ColumnMetadata {
|
||||
// START ----- DONT CHANGE UNLESS BravoSensorDataMetadata CHANGES TOO ------
|
||||
RIDE_HEIGHT_PORT_HULL("RideHeightPort", /* expectedInLogfile */ true), //
|
||||
RIDE_HEIGHT_STBD_HULL("RideHeightStbd", /* expectedInLogfile */ true), //
|
||||
HEEL("Heel", /* expectedInLogfile */ true), //
|
||||
PITCH("PitchRate", /* expectedInLogfile */ true), //
|
||||
// END ----- DONT CHANGE UNLESS BravoSensorDataMetadata CHANGES TOO ------
|
||||
|
||||
DB_RAKE_PORT("DaggerBoardRakeAnglePort", /* expectedInLogfile */ true), //
|
||||
DB_RAKE_STBD("DaggerBoardRakeAngleStbd", /* expectedInLogfile */ true), //
|
||||
RUDDER_RAKE_PORT("RudderRakeAnglePort", /* expectedInLogfile */ true), //
|
||||
|
||||
+6
@@ -21,4 +21,10 @@ public interface SensorFix extends Timed {
|
||||
*/
|
||||
double get(String valueName) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Obtains the data array containing the raw values making this sensor fix.
|
||||
* The array returned is a copy, and writing to it will not affect this fix
|
||||
* in any way.
|
||||
*/
|
||||
Double[] get();
|
||||
}
|
||||
|
||||
+7
@@ -26,6 +26,13 @@ public abstract class SensorFixImpl implements SensorFix {
|
||||
return fix.getTimePoint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double[] get() {
|
||||
Double[] result = new Double[fix.get().length];
|
||||
System.arraycopy(fix.get(), 0, result, 0, result.length);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double get(String valueName) {
|
||||
final ColumnMetadata columnMetadata = resolveMetadataFromValueName(valueName);
|
||||
|
||||
+5
@@ -505,6 +505,11 @@ public class SensorFixStoreAndLoadTest {
|
||||
return fix.get(TEST_COLUMN_INDEX);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double[] get() {
|
||||
return Arrays.copyOf(fix.get(), fix.get().length);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class TestFixTrackImpl<ItemType extends WithID & Serializable> extends SensorFixTrackImpl<ItemType, TestFixImpl> {
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
package com.sap.sailing.domain.tractracadapter;
|
||||
|
||||
public enum ReceiverType {
|
||||
MARKPASSINGS, MARKPOSITIONS, RACECOURSE, RACESTARTFINISH, RAWPOSITIONS
|
||||
MARKPASSINGS, MARKPOSITIONS, RACECOURSE, RACESTARTFINISH, RAWPOSITIONS, SENSORDATA
|
||||
}
|
||||
|
||||
+7
-2
@@ -430,7 +430,11 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
result.add(new RaceStartedAndFinishedReceiver(
|
||||
trackedRegatta, tractracEvent, simulator, this, eventSubscriber, raceSubscriber, timeoutInMilliseconds));
|
||||
break;
|
||||
}
|
||||
case SENSORDATA:
|
||||
result.add(new SensorDataReceiver(
|
||||
trackedRegatta, tractracEvent, simulator, this, eventSubscriber, raceSubscriber, timeoutInMilliseconds));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -446,7 +450,8 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
raceDefinitionSetToUpdate, trackedRegattaRegistry, raceLogResolver, courseDesignUpdateURI,
|
||||
tracTracUsername, tracTracPassword, eventSubscriber, raceSubscriber,
|
||||
useInternalMarkPassingAlgorithm, timeoutInMilliseconds, ReceiverType.RACECOURSE,
|
||||
ReceiverType.MARKPASSINGS, ReceiverType.MARKPOSITIONS, ReceiverType.RACESTARTFINISH, ReceiverType.RAWPOSITIONS);
|
||||
ReceiverType.MARKPASSINGS, ReceiverType.MARKPOSITIONS, ReceiverType.RACESTARTFINISH, ReceiverType.RAWPOSITIONS,
|
||||
ReceiverType.SENSORDATA);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+22
-22
@@ -48,27 +48,27 @@ public class RawPositionReceiver extends AbstractReceiverWithQueue<IRaceCompetit
|
||||
|
||||
@Override
|
||||
protected void handleEvent(Triple<IRaceCompetitor, IPosition, Void> event) {
|
||||
if (!event.getA().getCompetitor().isNonCompeting()) {
|
||||
if (received++ % 1000 == 0) {
|
||||
System.out.print("P");
|
||||
if ((received / 1000 + 1) % 80 == 0) {
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
IRace race = event.getA().getRace();
|
||||
DynamicTrackedRace trackedRace = getTrackedRace(race);
|
||||
if (trackedRace != null) {
|
||||
final GPSFixMoving fix = getDomainFactory().createGPSFixMoving(event.getB());
|
||||
Competitor competitor = getDomainFactory().getOrCreateCompetitor(event.getA().getCompetitor());
|
||||
if (getSimulator() != null) {
|
||||
getSimulator().scheduleCompetitorPosition(competitor, fix);
|
||||
} else {
|
||||
trackedRace.recordFix(competitor, fix);
|
||||
}
|
||||
} else {
|
||||
logger.warning("Couldn't find tracked race for race " + race.getName()
|
||||
+ ". Dropping raw position event " + event);
|
||||
}
|
||||
}
|
||||
if (!event.getA().getCompetitor().isNonCompeting()) {
|
||||
if (received++ % 1000 == 0) {
|
||||
System.out.print("P");
|
||||
if ((received / 1000 + 1) % 80 == 0) {
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
IRace race = event.getA().getRace();
|
||||
DynamicTrackedRace trackedRace = getTrackedRace(race);
|
||||
if (trackedRace != null) {
|
||||
final GPSFixMoving fix = getDomainFactory().createGPSFixMoving(event.getB());
|
||||
Competitor competitor = getDomainFactory().getOrCreateCompetitor(event.getA().getCompetitor());
|
||||
if (getSimulator() != null) {
|
||||
getSimulator().scheduleCompetitorPosition(competitor, fix);
|
||||
} else {
|
||||
trackedRace.recordFix(competitor, fix);
|
||||
}
|
||||
} else {
|
||||
logger.warning("Couldn't find tracked race for race " + race.getName()
|
||||
+ ". Dropping raw position event " + event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
package com.sap.sailing.domain.tractracadapter.impl;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.common.sensordata.BravoSensorDataMetadata;
|
||||
import com.sap.sailing.domain.common.tracking.BravoFix;
|
||||
import com.sap.sailing.domain.common.tracking.impl.BravoFixImpl;
|
||||
import com.sap.sailing.domain.common.tracking.impl.DoubleVectorFixImpl;
|
||||
import com.sap.sailing.domain.tracking.BravoFixTrack;
|
||||
import com.sap.sailing.domain.tracking.DynamicBravoFixTrack;
|
||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
|
||||
import com.sap.sailing.domain.tracking.impl.CompetitorBravoFixTrackImpl;
|
||||
import com.sap.sailing.domain.tractracadapter.DomainFactory;
|
||||
import com.sap.sse.common.Util.Triple;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.tractrac.model.lib.api.event.IEvent;
|
||||
import com.tractrac.model.lib.api.event.IRace;
|
||||
import com.tractrac.model.lib.api.event.IRaceCompetitor;
|
||||
import com.tractrac.model.lib.api.sensor.ISensorData;
|
||||
import com.tractrac.subscription.lib.api.IEventSubscriber;
|
||||
import com.tractrac.subscription.lib.api.IRaceSubscriber;
|
||||
import com.tractrac.subscription.lib.api.competitor.ICompetitorSensorDataListener;
|
||||
|
||||
/**
|
||||
* Subscribes an
|
||||
*
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public class SensorDataReceiver extends AbstractReceiverWithQueue<IRaceCompetitor, ISensorData, Void> {
|
||||
private static final Logger logger = Logger.getLogger(SensorDataReceiver.class.getName());
|
||||
private final ICompetitorSensorDataListener listener;
|
||||
private int received;
|
||||
|
||||
public SensorDataReceiver(DynamicTrackedRegatta trackedRegatta, IEvent tractracEvent,
|
||||
Simulator simulator, DomainFactory domainFactory, IEventSubscriber eventSubscriber,
|
||||
IRaceSubscriber raceSubscriber, long timeoutInMilliseconds) {
|
||||
super(domainFactory, tractracEvent, trackedRegatta, simulator, eventSubscriber, raceSubscriber, timeoutInMilliseconds);
|
||||
listener = new ICompetitorSensorDataListener() {
|
||||
@Override
|
||||
public void gotSensorData(IRaceCompetitor raceCompetitor, ISensorData sensorData) {
|
||||
enqueue(new Triple<>(raceCompetitor, sensorData, null));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribe() {
|
||||
getRaceSubscriber().subscribeCompetitorSensorData(listener);
|
||||
startThread();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void unsubscribe() {
|
||||
getRaceSubscriber().unsubscribeCompetitorSensorData(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for valid, non-{@code null} components for ride height port/starboard, heel and trim
|
||||
* in the {@link ISensorData} object. All those values are copied into a {@link BravoFix} and
|
||||
* inserted into the competitor's bravo fix track.
|
||||
*/
|
||||
@Override
|
||||
protected void handleEvent(Triple<IRaceCompetitor, ISensorData, Void> event) {
|
||||
if (received++ % 1000 == 0) {
|
||||
System.out.print("S");
|
||||
if ((received / 1000 + 1) % 80 == 0) {
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
final IRace race = event.getA().getRace();
|
||||
DynamicTrackedRace trackedRace = getTrackedRace(race);
|
||||
if (trackedRace != null) {
|
||||
final ISensorData sensorData = event.getB();
|
||||
if (sensorData != null) {
|
||||
final Float rideHeightPortInMeters = sensorData.getRideHeightPort();
|
||||
final Float rideHeightStarboardInMeters = sensorData.getRideHeightStarboard();
|
||||
final Float heelInDegrees = sensorData.getHeel();
|
||||
final Float trimInDegrees = sensorData.getTrim();
|
||||
final Double[] fixData = new Double[BravoSensorDataMetadata.getTrackColumnCount()];
|
||||
boolean create = false; // only create fix if at least one metric is present
|
||||
// fill the port/starboard columns as well because their minimum defines the true ride height
|
||||
if (rideHeightPortInMeters != null) {
|
||||
fixData[BravoSensorDataMetadata.RIDE_HEIGHT_PORT_HULL.getColumnIndex()] = Double.valueOf(rideHeightPortInMeters);
|
||||
create = true;
|
||||
}
|
||||
if (rideHeightStarboardInMeters != null) {
|
||||
fixData[BravoSensorDataMetadata.RIDE_HEIGHT_STBD_HULL.getColumnIndex()] = Double.valueOf(rideHeightStarboardInMeters);
|
||||
create = true;
|
||||
}
|
||||
if (heelInDegrees != null) {
|
||||
fixData[BravoSensorDataMetadata.HEEL.getColumnIndex()] = Double.valueOf(heelInDegrees);
|
||||
create = true;
|
||||
}
|
||||
if (trimInDegrees != null) {
|
||||
fixData[BravoSensorDataMetadata.PITCH.getColumnIndex()] = Double.valueOf(trimInDegrees);
|
||||
create = true;
|
||||
}
|
||||
if (create) {
|
||||
final BravoFix fix = new BravoFixImpl(new DoubleVectorFixImpl(new MillisecondsTimePoint(sensorData.getTimestamp()), fixData));
|
||||
final Competitor competitor = getDomainFactory().getOrCreateCompetitor(event.getA().getCompetitor());
|
||||
DynamicBravoFixTrack<Competitor> bravoFixTrack =
|
||||
trackedRace.getOrCreateSensorTrack(competitor, BravoFixTrack.TRACK_NAME,
|
||||
() -> new CompetitorBravoFixTrackImpl(competitor, BravoFixTrack.TRACK_NAME, /* hasExtendedFixes */ false,
|
||||
trackedRace.getTrack(competitor)));
|
||||
if (getSimulator() != null) {
|
||||
getSimulator().scheduleCompetitorSensorData(bravoFixTrack, fix);
|
||||
} else {
|
||||
bravoFixTrack.add(fix);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.warning("Couldn't find tracked race for race " + race.getName()
|
||||
+ ". Dropping sensor event " + event);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+31
-6
@@ -14,8 +14,12 @@ import com.sap.sailing.domain.common.Wind;
|
||||
import com.sap.sailing.domain.common.WindSource;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.WindImpl;
|
||||
import com.sap.sailing.domain.common.tracking.BravoFix;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.common.tracking.impl.BravoFixImpl;
|
||||
import com.sap.sailing.domain.common.tracking.impl.DoubleVectorFixImpl;
|
||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
||||
import com.sap.sailing.domain.tracking.DynamicBravoFixTrack;
|
||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
import com.sap.sailing.domain.tracking.RaceListener;
|
||||
@@ -272,20 +276,40 @@ public class Simulator {
|
||||
scheduleFixRecording(mark, markFix, recorder);
|
||||
}
|
||||
|
||||
private <T> void scheduleFixRecording(final T object, GPSFixMoving fix, final RecordGPSFix<T> recorder) {
|
||||
public void scheduleCompetitorSensorData(DynamicBravoFixTrack<Competitor> bravoFixTrack, BravoFix fix) {
|
||||
final TimePoint transformedTimepoint = advance(fix.getTimePoint());
|
||||
final GPSFixMoving transformedMarkFix = new GPSFixMovingImpl(fix.getPosition(), transformedTimepoint, fix.getSpeed());
|
||||
long waitTime = getWaitTimeInMillisUntil(transformedMarkFix.getTimePoint());
|
||||
final BravoFix transformedFix = new BravoFixImpl(new DoubleVectorFixImpl(transformedTimepoint, fix.get()));
|
||||
long waitTime = getWaitTimeInMillisUntil(transformedFix.getTimePoint());
|
||||
if (waitTime <= 0) {
|
||||
recorder.recordFix(object, transformedMarkFix);
|
||||
bravoFixTrack.add(transformedFix);
|
||||
} else {
|
||||
timer.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
recorder.recordFix(object, transformedMarkFix);
|
||||
bravoFixTrack.add(transformedFix);
|
||||
} catch (Exception e) {
|
||||
logger.throwing(Simulator.class.getName(), "scheduleMarkPosition", e);
|
||||
logger.throwing(Simulator.class.getName(), "scheduleSensorData", e);
|
||||
}
|
||||
}
|
||||
}, transformedTimepoint.asDate());
|
||||
}
|
||||
}
|
||||
|
||||
private <T> void scheduleFixRecording(final T object, GPSFixMoving fix, final RecordGPSFix<T> recorder) {
|
||||
final TimePoint transformedTimepoint = advance(fix.getTimePoint());
|
||||
final GPSFixMoving transformedFix = new GPSFixMovingImpl(fix.getPosition(), transformedTimepoint, fix.getSpeed());
|
||||
long waitTime = getWaitTimeInMillisUntil(transformedFix.getTimePoint());
|
||||
if (waitTime <= 0) {
|
||||
recorder.recordFix(object, transformedFix);
|
||||
} else {
|
||||
timer.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
recorder.recordFix(object, transformedFix);
|
||||
} catch (Exception e) {
|
||||
logger.throwing(Simulator.class.getName(), "schedulePosition", e);
|
||||
}
|
||||
}
|
||||
}, transformedTimepoint.asDate());
|
||||
@@ -297,4 +321,5 @@ public class Simulator {
|
||||
timer.cancel();
|
||||
stopped = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ Export-Package: com.tractrac.asio.lib.api,
|
||||
com.tractrac.model.lib.api.event,
|
||||
com.tractrac.model.lib.api.metadata,
|
||||
com.tractrac.model.lib.api.route,
|
||||
com.tractrac.model.lib.api.sensor,
|
||||
com.tractrac.model.lib.api.spatial,
|
||||
com.tractrac.model.lib.impl,
|
||||
com.tractrac.model.lib.impl.attachment,
|
||||
|
||||
Reference in New Issue
Block a user