Merge branch 'master' of /home/trac/git

This commit is contained in:
Generic Wiki User
2018-03-03 23:50:02 +00:00
10 changed files with 204 additions and 31 deletions
@@ -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), //
@@ -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();
}
@@ -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);
@@ -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,5 +1,5 @@
package com.sap.sailing.domain.tractracadapter;
public enum ReceiverType {
MARKPASSINGS, MARKPOSITIONS, RACECOURSE, RACESTARTFINISH, RAWPOSITIONS
MARKPASSINGS, MARKPOSITIONS, RACECOURSE, RACESTARTFINISH, RAWPOSITIONS, SENSORDATA
}
@@ -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
@@ -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);
}
}
}
}
@@ -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);
}
}
}
@@ -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,