mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-04 03:13:49 +00:00
first working parser for SwissTiming GPS packets with test case
This commit is contained in:
1 parent
ac8508e5f8
commit
66c031ccf4
12 files changed
+205
-11
No files matched your search
@@ -6,3 +6,4 @@ Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Vendor: SAP
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||
Require-Bundle: com.sap.sailing.domain
|
||||
Export-Package: com.sap.sailing.domain.swisstimingadapter
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>root</artifactId>
|
||||
<groupId>com.sap.sailing</groupId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>com.sap.sailing.domain.swisstimingadapter</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
</project>
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.sap.sailing.domain.swisstimingadapter;
|
||||
|
||||
public class SwissTimingFormatException extends Exception {
|
||||
private static final long serialVersionUID = -1210353206288437237L;
|
||||
|
||||
private final byte[] swissTimingMessage;
|
||||
|
||||
public SwissTimingFormatException(String errorMessage, byte[] swissTimingMessage) {
|
||||
super(errorMessage);
|
||||
this.swissTimingMessage = swissTimingMessage;
|
||||
}
|
||||
|
||||
public byte[] getSwissTimingMessage() {
|
||||
return swissTimingMessage;
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.sap.sailing.domain.swisstimingadapter;
|
||||
|
||||
import com.sap.sailing.domain.base.Position;
|
||||
import com.sap.sailing.domain.base.Speed;
|
||||
import com.sap.sailing.domain.base.TimePoint;
|
||||
|
||||
public interface SwissTimingMessage {
|
||||
String getRaceID();
|
||||
|
||||
int getPacketID();
|
||||
|
||||
TimePoint getTimestamp();
|
||||
|
||||
int getGpsID();
|
||||
|
||||
Position getPosition();
|
||||
|
||||
Speed getSpeed();
|
||||
|
||||
int getNumberOfSatellites();
|
||||
|
||||
int getBatteryPercent();
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.sap.sailing.domain.swisstimingadapter;
|
||||
|
||||
import com.sap.sailing.domain.swisstimingadapter.impl.SwissTimingMessageParserImpl;
|
||||
|
||||
public interface SwissTimingMessageParser {
|
||||
SwissTimingMessageParser INSTANCE = new SwissTimingMessageParserImpl();
|
||||
|
||||
SwissTimingMessage parse(byte[] message) throws SwissTimingFormatException;
|
||||
}
|
||||
+11
-10
@@ -1,21 +1,22 @@
|
||||
package com.sap.sailing.domain.swisstimingadapter;
|
||||
package com.sap.sailing.domain.swisstimingadapter.impl;
|
||||
|
||||
import com.sap.sailing.domain.base.Position;
|
||||
import com.sap.sailing.domain.base.Speed;
|
||||
import com.sap.sailing.domain.base.TimePoint;
|
||||
import com.sap.sailing.domain.swisstimingadapter.SwissTimingMessage;
|
||||
|
||||
public class GPSFix {
|
||||
public class SwissTimingMessageImpl implements SwissTimingMessage {
|
||||
private final String raceID;
|
||||
private final int packetID;
|
||||
private final TimePoint timestamp;
|
||||
private final short gpsID;
|
||||
private final int gpsID;
|
||||
private final Position position;
|
||||
private final Speed speed;
|
||||
private final byte numberOfSatellites;
|
||||
private final byte batteryPercent;
|
||||
private final int numberOfSatellites;
|
||||
private final int batteryPercent;
|
||||
|
||||
public GPSFix(String raceID, int packetID, TimePoint timestamp, short gpsID, Position position, Speed speed,
|
||||
byte numberOfSatellites, byte batteryPercent) {
|
||||
public SwissTimingMessageImpl(String raceID, int packetID, TimePoint timestamp, int gpsID, Position position, Speed speed,
|
||||
int numberOfSatellites, int batteryPercent) {
|
||||
super();
|
||||
this.raceID = raceID;
|
||||
this.packetID = packetID;
|
||||
@@ -39,7 +40,7 @@ public class GPSFix {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public short getGpsID() {
|
||||
public int getGpsID() {
|
||||
return gpsID;
|
||||
}
|
||||
|
||||
@@ -51,11 +52,11 @@ public class GPSFix {
|
||||
return speed;
|
||||
}
|
||||
|
||||
public byte getNumberOfSatellites() {
|
||||
public int getNumberOfSatellites() {
|
||||
return numberOfSatellites;
|
||||
}
|
||||
|
||||
public byte getBatteryPercent() {
|
||||
public int getBatteryPercent() {
|
||||
return batteryPercent;
|
||||
}
|
||||
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
package com.sap.sailing.domain.swisstimingadapter.impl;
|
||||
|
||||
import com.sap.sailing.domain.base.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.base.impl.KilometersPerHourSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.swisstimingadapter.SwissTimingFormatException;
|
||||
import com.sap.sailing.domain.swisstimingadapter.SwissTimingMessage;
|
||||
import com.sap.sailing.domain.swisstimingadapter.SwissTimingMessageParser;
|
||||
|
||||
public class SwissTimingMessageParserImpl implements SwissTimingMessageParser {
|
||||
|
||||
@Override
|
||||
public SwissTimingMessage parse(byte[] message) throws SwissTimingFormatException {
|
||||
int i=0;
|
||||
if (message[i] != 0x10 || message[i+1] != 0x00) {
|
||||
throw new SwissTimingFormatException("Didn't find start marker 0x1000", message);
|
||||
}
|
||||
i+=2;
|
||||
String raceID = new String(message, i, 9);
|
||||
i+=9;
|
||||
int packetID = parseInt(message, i);
|
||||
i+=4;
|
||||
long timestamp = parseLong(message, i);
|
||||
i+=8;
|
||||
byte packetType = message[i];
|
||||
if (packetType != 0x02) {
|
||||
throw new SwissTimingFormatException("Expected to find package type 0x02", message);
|
||||
}
|
||||
i+=1;
|
||||
short gpsID = parseShort(message, i);
|
||||
i+=2;
|
||||
int longitude = parseInt(message, i);
|
||||
i+=4;
|
||||
int latitude = parseInt(message, i);
|
||||
i+=4;
|
||||
int speedInDecimetersPerSecond = 0xFF & message[i];
|
||||
i+=1;
|
||||
int course = parseShort(message, i);
|
||||
i+=2;
|
||||
int numberOfSatellites = (message[i] & 0xF0) >> 4;
|
||||
int batteryPercent = 10 * (message[i] & 0x0F);
|
||||
i+=1;
|
||||
if (message[i] != 0x10 || message[i+1] != 0x30) {
|
||||
throw new SwissTimingFormatException("Didn't find end marker 0x1030", message);
|
||||
}
|
||||
i+=2;
|
||||
return new SwissTimingMessageImpl(raceID, packetID, new MillisecondsTimePoint(timestamp), gpsID,
|
||||
new DegreePosition((double) latitude / 10000000., (double) longitude / 10000000.),
|
||||
new KilometersPerHourSpeedWithBearingImpl(0.36*speedInDecimetersPerSecond, new DegreeBearingImpl(course)),
|
||||
numberOfSatellites, batteryPercent);
|
||||
}
|
||||
|
||||
private short parseShort(byte[] message, int offset) {
|
||||
short result = 0;
|
||||
for (int b=0; b<2; b++) {
|
||||
result <<= 8;
|
||||
result += (0xFF & message[offset+b]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private long parseLong(byte[] message, int offset) {
|
||||
long result = 0l;
|
||||
for (int b=0; b<8; b++) {
|
||||
result <<= 8;
|
||||
result += (0xFF & message[offset+b]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private int parseInt(byte[] message, int offset) {
|
||||
int result = 0;
|
||||
for (int b=0; b<4; b++) {
|
||||
result <<= 8;
|
||||
result += (0xFF & message[offset+b]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user