mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-08 13:20:57 +00:00
Merge branch 'master' into jetty9
This commit is contained in:
commit
39f3af153c
11 files changed
+232
-97
No files matched your search
@@ -18,13 +18,15 @@ Like businesses, sailors need the latest information to make strategic decisions
|
||||
* Information for Developers
|
||||
* [[Cook Book|wiki/cook-book]]
|
||||
* [[OnBoarding Information|wiki/onboarding]]
|
||||
* [[Typical Development Scenarios|wiki/typical-development-scenarios]]
|
||||
* [[Server Replication|wiki/server-replication]]
|
||||
* [[Configure Races on Server|wiki/configure-races-on-server]]
|
||||
* [[Configure Races on Server|wiki/typical-development-scenarios]]
|
||||
* [[Development Environment|wiki/development-environment]]
|
||||
* [[Mobile Development|wiki/mobile-development]]
|
||||
* General Information
|
||||
* [[Architecture and Infrastructure|wiki/architecture-and-infrastructure]]
|
||||
* [[Sailing Domain Algorithms|wiki/sailing-domain-algorithms]]
|
||||
* [[Inventar|wiki/inventar-liste]]
|
||||
* [[Inventory|wiki/inventar-liste]]
|
||||
* [[Smartphone Tracking|wiki/smartphone-tracking]]
|
||||
* Planning and Event Information
|
||||
* [[Project Planning (bigger development)|wiki/planning]]
|
||||
|
||||
+1
-1
@@ -73,6 +73,6 @@ public class MarkImpl extends NamedImpl implements Mark {
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getId() + " " + getColor() + super.toString();
|
||||
return getId() + " " + (getColor()==null?"":(getColor()+" ")) + super.toString();
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -65,8 +65,8 @@ public class ManeuverAnalysisIDMChampionsFinalTest extends AbstractManeuverDetec
|
||||
TimePoint epoch = new MillisecondsTimePoint(0l);
|
||||
TimePoint now = MillisecondsTimePoint.now();
|
||||
Map<String, Position> markPositions = new HashMap<String, Position>();
|
||||
markPositions.put("G2 Start", new DegreePosition(53.96003300000019, 10.878697000000084));
|
||||
markPositions.put("Finish", new DegreePosition(53.9674420000693, 10.894410000058738));
|
||||
markPositions.put("G2 Start-Finish (1)", new DegreePosition(53.96003300000019, 10.878697000000084));
|
||||
markPositions.put("G2 Start-Finish (2)", new DegreePosition(53.9674420000693, 10.894410000058738));
|
||||
markPositions.put("G2 Mark4 (2)", new DegreePosition(53.96002200000019, 10.878875000000063));
|
||||
markPositions.put("G2 Mark4 (1)", new DegreePosition(53.9599880000002, 10.878665000000069));
|
||||
markPositions.put("G2 Mark1", new DegreePosition(53.96355800000006, 10.885751999999806));
|
||||
|
||||
+2
-16
@@ -147,25 +147,11 @@ public class MetadataParserImpl implements MetadataParser {
|
||||
String mark2UUID = controlPointMetadata.get("P2.UUID");
|
||||
String name1 = controlPointMetadata.get("P1.Name");
|
||||
if (name1 == null) {
|
||||
// as this is a gate and TracTrac is providing a dashed name
|
||||
// we can extract it here
|
||||
String[] markNames = controlPointName.split("-");
|
||||
if (markNames.length == 2) {
|
||||
name1 = markNames[0];
|
||||
} else {
|
||||
name1 = controlPointName + " (1)";
|
||||
}
|
||||
name1 = controlPointName + " (1)";
|
||||
}
|
||||
String name2 = controlPointMetadata.get("P2.Name");
|
||||
if (name2 == null) {
|
||||
// as this is a gate and TracTrac is providing a dashed name
|
||||
// we can extract it here
|
||||
String[] markNames = controlPointName.split("-");
|
||||
if (markNames.length == 2) {
|
||||
name2 = markNames[1];
|
||||
} else {
|
||||
name2 = controlPointName + " (2)";
|
||||
}
|
||||
name2 = controlPointName + " (2)";
|
||||
}
|
||||
final Serializable id1 = mark1UUID == null ? name1 : UUID.fromString(mark1UUID);
|
||||
ControlPointMetaData mark1Metadata = new ControlPointMetaDataImpl(name1, type1, color1, shape1, pattern1, id1);
|
||||
|
||||
+1
-9
@@ -29,17 +29,9 @@ public class WindJsonDeserializer implements JsonDeserializer<Wind> {
|
||||
Number timeStamp = (Number) object.get(WindJsonSerializer.FIELD_TIMEPOINT);
|
||||
Number direction = (Number) object.get(WindJsonSerializer.FIELD_DIRECTION);
|
||||
Number speedInKnots = (Number) object.get(WindJsonSerializer.FIELD_SPEED_IN_KNOTS);
|
||||
|
||||
Bearing degreeBearing = null;
|
||||
if (direction.doubleValue() >= 180) {
|
||||
degreeBearing = new DegreeBearingImpl(direction.doubleValue()-180);
|
||||
} else {
|
||||
degreeBearing = new DegreeBearingImpl(direction.doubleValue()+180);
|
||||
}
|
||||
|
||||
Bearing degreeBearing = new DegreeBearingImpl(direction.doubleValue());
|
||||
SpeedWithBearing speedBearing = new KnotSpeedWithBearingImpl(speedInKnots.doubleValue(), degreeBearing);
|
||||
Wind wind = new WindImpl(position, new MillisecondsTimePoint(timeStamp.longValue()), speedBearing);
|
||||
|
||||
return wind;
|
||||
}
|
||||
|
||||
|
||||
+15
-5
@@ -10,9 +10,6 @@ To export data from MongoDB you simply have to use the monogexport command. It w
|
||||
|
||||
`/opt/mongodb/bin/mongoexport --port 10202 -d winddb -c WIND_TRACKS -q "{'REGATTA_NAME': 'ESS 2013 Muscat (Extreme40)'}" > /tmp/ess2013-muscat-wind.json`
|
||||
|
||||
#### Score Corrections
|
||||
|
||||
`/opt/mongodb/bin/mongoexport --port 10202 -d winddb -c LEADERBOARDS -q "{LEADERBOARD_NAME: 'ESS 2013 Singapore (Extreme40)'}" > /tmp/singapore.json`
|
||||
|
||||
### Import to MongoDB
|
||||
|
||||
@@ -22,9 +19,22 @@ Importing requires data to be in JSON format (as exported by mongoexport). To ma
|
||||
|
||||
`/opt/mongodb/bin/mongoimport --port 10202 -d winddb -c WIND_TRACKS --upsert /tmp/ess2013-muscat-wind.json`
|
||||
|
||||
#### Score Corrections
|
||||
### Migrate Master Data along with Score Corrections, etc, without touching the mongodb console
|
||||
|
||||
`/opt/mongodb/bin/mongoimport --port 10202 -d winddb -c LEADERBOARDS --upsert /tmp/singapore.json`
|
||||
In the Admin Panel you can now find a tab called "Master Data Import". Here you can import all data corresponding to a leaderboard group from a remote server, excluding wind and the actual TrackedRaces.
|
||||
|
||||
#### Listing the available leaderboard groups
|
||||
|
||||
At first you need to enter the remote host. This could for example be "http://live2.sapsailing.com/" if you are on an archive server and you want to import the information of a recent live event that is still hosted on a live server. If you hit Enter or click the Button "Fetch Leaderboard Group List", all available leaderboard groups from the remote host will be displayed, if the connection was successful.
|
||||
|
||||
#### Importing all data for selected leaderboard groups
|
||||
|
||||
You can now select the leaderboard groups you want to import. Multi-selection is allowed. If you have already added objects like events or leaderboards where names collide with those that are to be imported, the "override" option becomes relevant. It should be checked if you want to have the same ID's, race-columns, race-log-events, score corrections as on the remote server, but it can overwrite some of the data you entered before.
|
||||
Now click "Import selected Leaderboard Groups" to start the actual import process. If successful, a pop-up will show you how many events, regattas, leaderboards and leaderboard groups where imported.
|
||||
|
||||
#### Media
|
||||
|
||||
For now, all media links are imported (even if they are not in the same time-frame as the leaderboard-grouped races). The process also looks for the override flag to decide whether it should overwrite the existing row, when there is an id-conflict.
|
||||
|
||||
### Hot Deploy Java Packages to a running Server
|
||||
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# Inventar Liste
|
||||
# Inventory Management
|
||||
|
||||
Diese Inventar-Liste wird unter https://docs.google.com/spreadsheet/ccc?key=0AvwMi5dSxETfdDdieDkwY1FyVmRyRVV6TkFkOUNjOWc&usp=sharing gepflegt.
|
||||
We manage our inventory for events by little paper placeholder cards. When taking a piece of equipment our of of the cupboards or from a pelicase, note your name, the date and a purpose on the placeholder card for that piece of equipment. If you can't find a card for the piece you're taking, create one, noting the type and ID of the item in the card's header. Should the item not have a label with an ID on it, create one using our label printer, then write it on the card.
|
||||
|
||||
Sollte jemand keinen Zugriff haben, dann bitte eine E-Mail an spamsch@gmail.com.
|
||||
Once you took the item, leave the card where the item was. We'll get you in case you should forget to return the item.
|
||||
|
||||
If you plan to hand the item to someone else, perform the above process recursively and leave the card where the item was after you took it, e.g., in the pelicase. This may help you once we go after you to return the item so you know whom to go after in order to get the item back.
|
||||
|
||||
Please note that particularly the smaller-sized items such as chargers and HDMI adapters fall under this policy because they tend to get lost even more often.
|
||||
|
||||
Thanks for your support and co-operation :-)
|
||||
@@ -0,0 +1,9 @@
|
||||
# Mobile Development
|
||||
|
||||
The native Android projects are in the mobile/ folder in git which is next to the java/ folder. To build them successfully, you need to install the Android SDK which is available [here](http://developer.android.com/sdk/index.html). Also, you need to use the Eclipse update site https://dl-ssl.google.com/android/eclipse and install the Eclipse ADT plugins.
|
||||
|
||||
Currently (2013-07-18), the Race Committee App uses the Google APIs Version 13 (Android 3.2) which you need to install through the Android SDK Manager (see Eclipse toolbar after installing the Eclipse ADT plugin). In the Android Virtual Device manager which can also be found in the Eclipse toolbar you can configure an emulated device. One successful approach was using a 10.1" WXGA (Tablet) device in the emulator configuration and choose "Google APIs (Google Inc.) - API Level 13" as the target.
|
||||
|
||||
After that it should be possible to choose "Debug as --> Android application" in the com.sap.sailing.racecommittee.app project's context menu, then pick the emulator you're previously created.
|
||||
|
||||
If you want to run the app against your locally-running server, go into the Settings and choose http://10.0.2.2:8888 as the JSON URL. See also [here](http://developer.android.com/tools/devices/emulator.html#emulatornetworking) for more details on the emulator's network behavior.
|
||||
@@ -12,6 +12,8 @@
|
||||
|
||||
[[Advanced Wind Field Analysis|wiki/planning/AdvancedWindFieldAnalysis]]
|
||||
|
||||
[[Support Specific Analysis Scenarios|wiki/planning/AnalysisScenarios]]
|
||||
|
||||
[[Google Earth as Map|wiki/planning/GoogleEarth]]
|
||||
|
||||
[[AirMAX vs. MikroTik|/wiki/planning/AirMAXvsMikroTik]]
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# Analysis Scenarios
|
||||
|
||||
We find that users would like certain analysis scenarios be supported in easier ways than they currently are. For example, one scenario could be "start analysis" and another one "maneuver analysis" whereas a third one could be "wind analysis." Special UI shortcuts and pre-configured perspectives shall support the user in these typical activities.
|
||||
|
||||
We need to understand what the ideal UI approach supporting this would be. Is this a portal with portlets and widgets, or is it a set of pre-configured existing components? We will need UID consultancy for this.
|
||||
+182
-59
@@ -3,7 +3,12 @@
|
||||
[[_TOC_]]
|
||||
|
||||
## Introduction
|
||||
Some important decisions and interface specifications for smartphone tracking are recorded on this page.
|
||||
On this page the decisions, architecture and API's for using smartphones as an additional input channel for Sailing Analytics are documented. Meanwhile, the architecture of this solution is designed to be flexible enough to support other types of input devices in the future, e.g. [Igtimi](http://www.igtimi.com/) trackers.
|
||||
|
||||
## Branches
|
||||
* `cmd-reuse-racelog-for-cmd-tracking`: server side development of using the RaceLog to create a tracking adapter for Commodity Mobile Devices (CMD) such as smartphones
|
||||
* `race-board-admin`: manual UI based entry of mark passings for the time being, while we do not have a detection algorithm
|
||||
* `cmd-android-tracking`: client side development branch for the tracking application, which enhances the existent race committee app
|
||||
|
||||
## Communication Channels
|
||||
The current plan is to use up to three channels for communicating:
|
||||
@@ -12,41 +17,54 @@ The current plan is to use up to three channels for communicating:
|
||||
|
||||
2. **RaceLog:** All the "master data" communication concerning one race in particular should piggyback on the existing RaceLog-mechanism, which already deals with semi-connectedness, persistence and replication. Examples for this are: adding competitors to a race, mapping tracking devices to competitors, starting a race, defining the course layout.
|
||||
|
||||
3. **Other:** The actual tracking data (perhaps also additional data: wind etc.) also has to be transferred. As we also have to deal with semi-connectedness, one idea is to reuse the communication mechanism which the RaceLog is built on top of. In case this cannot deal with the large amounts of data produced by tracking devices, or is to tightly coupled with the RaceLog semantics, a possible alternative is using CouchDB and its replication mechanism. The downside here is a further increased technology stack on client and server side, and a hetorgenous communication mechanisms between client and server. This makes setting up a development environment, understanding the architecture, development and lifecycle management of the used technologies on the server (OSGi, RabbitMQ with Erlang, MongoDB, and possibly CouchDB) even more difficult.
|
||||
3. **Other:** The actual tracking data (perhaps also additional data: wind etc.) also has to be transferred. On client side we want to reuse the communication mechanism which the RaceLog is built on top of.
|
||||
|
||||
## Server-side Architecture
|
||||
On the server-side, the architecture of smartphone tracking is intended to be open for extension, so that different types of input devices can be used for tracking one race. Currently, some parts are still tightly coupled to smartphone tracking (e.g. `RacingEventService#createTrackedRaceForSmartphoneTracking()`), but these can be refactored to be generic.
|
||||
|
||||
Generic device identifiers, that are qualified through a device type, are used for mapping a device to a competitor in the race log. When the race is then created, the OSGi service registry is used to find services to which the appropriate device mappings in the race log are provided, e.g. a smartphone adapter registers a `RaceLogTrackingDeviceHandler` service for the device type `smartphoneImei`, and then recieves all smartphone device mappings from the race log once the race is created. The same OSGi service logic is used to find services that deal with persisting device identifiers, so that loading and persisting race log events can be used for all types of device identifiers.
|
||||
|
||||
The reason for using the OSGi service registry is that it enables decentralized implementation of different kinds of device adapters. E.g., implementing a new Igtimi adapter does not mean that you have to modify the object factory for device identifier objects in the persistence bundle, but simply register a new service from within your own bundle. This is more hindering than helpful in this stage of development, but - in future - means that other device adapters could be developed without having to touch the Sailing Analytics core code, so a vendor of tracking devices could recieve a current Sailing Analytics version as an SDK and implement additional bundles only.
|
||||
|
||||
## Mark Passings
|
||||
Without a tracking provider that implements a mark passing algorithm, we have to identify mark passings on our own in the context of smartphone tracking, for Sailing Analytics to be able to do any analytics at all. While the mid-term goal definitely is to implement such a detection algorithm, as a workaround a UI entry option has been provided, that can be found in the branch `race-board-admin`, in which the mark passings can be set by hand. This can be accessed by clicking the _Administer Race_ button of a race in the leaderboard detail table, which can be found in the leaderboard configuration panel of the admin console.
|
||||
|
||||
## Servlets
|
||||
### `/smartphone/createFlexibleLeaderboard`
|
||||
`CreateFlexibleLeaderboardPostServlet`
|
||||
The servlets are listed in the chronological order that they can be called. First, persistent competitors are needed, so that they can later on be registered for the race (`createPersistentCompetitor`). These can then be listed (`getPersistentCompetitors`). When this is completed, a race in its pre-race phase can be created (`createRace`), which is then also shown in `getRaceLogsInPreRacePhase`. By selecting one of these RaceLogs and sending `RaceLogPersistentCompetitorRegisteredEvent`s, `RaceLogCourseDefinitionChangedEvent`s, the race can then be moved from its pre race phase into the tracking phase by sending the `RaceLogPreRacePhaseEndedEvent` via the race log. From this moment on - given the fact that all necessary information was already included in the RaceLog, tracking data can be added to the race. On the one hand, marks can be pinged (`pingMark`, for which knowledge of the course layout is necessary, which can be accessed through `currentcourse`), on the other hand fixes of competitors can be recorded (`recordFixes`). Pinging the marks is of course only the first step, the plan is to allow the mapping of tracking devices such as smartphones to marks as well as competitors.
|
||||
|
||||
**Expects**
|
||||
* POST request body: LeaderboardDTO-JSON (see `LeaderboardDTOJsonSerializer`)
|
||||
**Remember to set a start time via the race log**, as the race map relies heavily on it (e.g., the course based wind estimation needs a start time, and without any other wind sources a missing start time results in no boats and marks being displayed at all, as the `SailingService#getRaceMapData()` then fails with a no wind exception).
|
||||
|
||||
**Returns**
|
||||
* `200` Leaderboard created, body: LeaderboardDTO as JSON
|
||||
To test the servlets manually, in addition to the unit tests, the chrome plugin [Postman](https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm) in combination with this collection of [HTTP requests](http://www.getpostman.com/collections/d4eb46b5e4f566e6b7a3) for the servlets described below may come in handy.
|
||||
|
||||
**Throws**
|
||||
* `400` Invalid JSON in request
|
||||
* `409` Leaderboard with name %s already exists
|
||||
|
||||
### `/smartphone/createRaceColumn?leaderboard=<leaderboardName>`
|
||||
`CreateFlexibleLeaderboardPostServlet`
|
||||
|
||||
**Expects**
|
||||
* POST request body: RaceColumnDTO-JSON (see `RaceColumnDTODeserializer`)
|
||||
|
||||
**Returns**
|
||||
* `200` RaceColumn created, body: RaceColumn-DTO as JSON
|
||||
|
||||
**Throws**
|
||||
* `400` Missing parameter / Invalid JSON in request
|
||||
* `404` Leaderboard not found
|
||||
* `409` RaceColumn with name %s already exists / Error adding RaceColumn
|
||||
|
||||
### `/smartphone/createPersistentCompetitor`
|
||||
### `/sailingserver/racelogtracking/createPersistentCompetitor`
|
||||
`CreatePersistentCompetitorPostServlet`
|
||||
|
||||
**Expects**
|
||||
* POST request body: Competitor-JSON with a nested Boat-JSON and Team-JSON (see `CompetitorDeserializer`)
|
||||
* POST request body: Competitor-JSON with a nested Boat-JSON and Team-JSON (see `CompetitorJsonDeserializer`)
|
||||
```
|
||||
{"id": "",
|
||||
"name": "Competitor Fredrik",
|
||||
"sailID": "1234",
|
||||
"team": {
|
||||
"name": "Team Fredrik",
|
||||
"sailors": [
|
||||
{
|
||||
"name": "Fredrik",
|
||||
"description": "",
|
||||
"dateOfBirth": 2394820480284,
|
||||
"nationality": {"IOC": "GER"}
|
||||
}
|
||||
]
|
||||
},
|
||||
"boat": {
|
||||
"name": "Boat Fredrik",
|
||||
"sailID": "1234",
|
||||
"boatClass": {
|
||||
"name": "49er"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Returns**
|
||||
* `200` Competitor created, body: Competitor as JSON
|
||||
@@ -54,7 +72,7 @@ The current plan is to use up to three channels for communicating:
|
||||
**Throws**
|
||||
* `400` Invalid JSON in request
|
||||
|
||||
### `/smartphone/getPersistentCompetitors`
|
||||
### `/sailingserver/racelogtracking/getPersistentCompetitors`
|
||||
`PersistentCompetitorsGetServlet`
|
||||
|
||||
**Expects**
|
||||
@@ -63,27 +81,107 @@ The current plan is to use up to three channels for communicating:
|
||||
**Returns**
|
||||
* `200` body: JSON array of Competitor objects
|
||||
|
||||
### `/smartphone/createRace?leaderboard=<leaderboardName>&raceColumn=<raceColumnName>&fleet=<fleetName>`
|
||||
`CreateRacePostServlet`
|
||||
|
||||
**Precondition**
|
||||
* `RaceLogPreRacePhaseEndedEvent` recieved via RaceLog beforehand
|
||||
### `/sailingserver/racelogtracking/getRaceLogsInPreRacePhase`
|
||||
`RaceLogsInPreRacePhaseGetServlet`
|
||||
|
||||
**Expects**
|
||||
* POST request: no body
|
||||
* GET request
|
||||
|
||||
**Returns**
|
||||
* `200` body: RaceDTO-JSON
|
||||
* `200` body: JSON array of String Triples that act as RaceLog identifiers (leaderboard name, race column name, fleet name)
|
||||
|
||||
### `/sailingserver/racelogtracking/createRace`
|
||||
`CreateRaceLogTrackedRacePostServlet`
|
||||
|
||||
**Expects**
|
||||
* POST request body: JSON with Leaderboard-DTO, RaceColumn-DTO and BoatClass (see CreateRaceLogTrackedRaceJsonSerializer)
|
||||
```
|
||||
{"leaderboard": {
|
||||
"name": "test",
|
||||
"displayName": "test",
|
||||
"discardThresholds": [1,2],
|
||||
"scoringScheme": "LOW_POINT",
|
||||
"courseAreaId": "Kiel"
|
||||
},
|
||||
"raceColumn": {
|
||||
"name": "test",
|
||||
"isMedalRace": false
|
||||
},
|
||||
"boatClass": {
|
||||
"name": "49er",
|
||||
"typicallyStartsUpwind": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Returns**
|
||||
* `200` RaceLog Identifier Triple JSON
|
||||
|
||||
**Throws**
|
||||
* `400` Missing parameter
|
||||
* `404` Leaderboard/RaceColumn/Fleet not found
|
||||
* `409` Race has already been created, pre-race phase has not been ended
|
||||
* `400` Invalid JSON in request
|
||||
* `409` RaceColumn and RaceLog already exist in Leaderboard
|
||||
|
||||
### `/smartphone/position`
|
||||
* remember to also replicate this
|
||||
* then an incoming fix can be added to the TrackedRace
|
||||
* RaceLogConnector, where mapping etc. is stored should be better!
|
||||
**Comments**
|
||||
* If a leaderboard with the supplied does not already exist, a FlexibleLeaderboard is created. Otherwise, the existing Leaderboard is used without raising an error. An existing RaceColumn will raise an error however, as this also means a RaceLog already exists.
|
||||
|
||||
### `/smartphone/recordFixes`
|
||||
`RecordFixesPostServlet`
|
||||
**Precondition**
|
||||
* race has already been started by sending a `RaceLogPreRacePhaseEndedEvent`
|
||||
|
||||
**Expects**
|
||||
* POST request body: DeviceIdentifierWithGPSFixMovingsDTO as JSON
|
||||
```
|
||||
{"imei": "12345678",
|
||||
"data": [
|
||||
{"unixtime": 2394820480284,
|
||||
"nmea" : "$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A"
|
||||
},
|
||||
{"unixtime": 2394820480285,
|
||||
"nmea" : "$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Returns**
|
||||
* `200`: fixes recorded
|
||||
|
||||
**Throws**
|
||||
* `409` Device not mapped to race and competitor
|
||||
|
||||
### `/sailingserver/racelogtracking/pingMark?leaderboard=<leaderboardName>&raceColumn=<raceColumnName>&fleet=<fleetName>`
|
||||
`PingMarkPostServlet`
|
||||
**Precondition**
|
||||
* race has already been started by sending a `RaceLogPreRacePhaseEndedEvent` and has not been stopped yet
|
||||
|
||||
**Expects**
|
||||
* POST request body: PingMark as JSON
|
||||
```
|
||||
{"unixtime": 2394820480284,
|
||||
"nmea" : "$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A"
|
||||
}
|
||||
```
|
||||
|
||||
**Returns**
|
||||
* `200`: mark pinged
|
||||
|
||||
**Throws**
|
||||
* `404` Leaderboard, RaceColumn or Fleet not found
|
||||
* `409` Race not in tracking state
|
||||
|
||||
### `/sailingserver/rc/currentcourse`
|
||||
`CourseJsonExportServlet`
|
||||
|
||||
**Expects**
|
||||
* GET request
|
||||
|
||||
**Returns**
|
||||
* `200` body: CourseBase JSON
|
||||
|
||||
**Comments**
|
||||
* Does not use the latest `RaceLogCourseDefinitionChangedEvent`, but instead requires the presence of a `TrackedRace` for this racelog, from which the `RaceDefinition` is acquired to get the course. We could build our own servlet, but as we can only ping the marks after having created the race anyway, this isn't too much of a problem.
|
||||
|
||||
|
||||
## RaceLog Events
|
||||
@@ -91,15 +189,13 @@ The current plan is to use up to three channels for communicating:
|
||||
Includes a `Competitor` as well a `SmartphoneIdentifier`. On the one hand, every comptitor that is thus registered will be included in the `RaceDefinition` as soon as the race is created, on the other hand the mapping between smartphone identifier (e.g. IMEI for european phones) and competitor is later used for mapping the incoming fixes to the correct competitor.
|
||||
|
||||
### RaceLogPreRacePhaseEndedEvent
|
||||
This does not include any additional data, and merely indicates that the race can be transformed from its pre-race definition state (e.g. waiting for competitors to register, waiting for boat class, waiting for course definition) to an actual race, where no additional competitors can be added, the boat class is fixes, and tracking may begin. This existence of this event in the RaceLog is a precondition for the `createRace` servlet to be callable successfully.
|
||||
This does not include any additional data, and merely indicates that the race can be transformed from its pre-race definition state (e.g. waiting for competitors to register, waiting for boat class, waiting for course definition) to an actual race, where no additional competitors can be added, the boat class is fixes, and tracking may begin. This event is picked up by the `RaceLogRaceTracker`, which then creates the actual tracked race from the data in the RaceLog. For successful creation, at least one competitor has to be registered, and a course must have been set through a `RaceLogCourseDefinitionChangedEvent`.
|
||||
|
||||
### Events that are still needed
|
||||
* Set boat class
|
||||
* Set course (reuse of existing events that Potsdam students already use)
|
||||
* Remove registered competitor (also use in RegisteredCompetitorFinder)
|
||||
|
||||
##Tracking App Architecture
|
||||
|
||||

|
||||
|
||||
### `LocationChangedReceiver`
|
||||
This class gets notified of location changes via intents. Depending on whether the App is in local or remote broadcast mode the corresponding service is started by using intents.
|
||||
|
||||
@@ -112,16 +208,43 @@ Sends the location information to a web service.
|
||||
### `SAP Sailor Tracker Service`
|
||||
Background process for starting, pausing and stopping tracking. Registers all receivers on a pending intent, which is send periodically.
|
||||
|
||||
### `doPostTask`
|
||||
Async task that handles the execution of post requests.
|
||||
|
||||
### `doGetTask`
|
||||
Async task that handles the execution of get requests.
|
||||
|
||||
### `AppPreferences`
|
||||
Helper Class for accessing the App Preferences specified in settings_view.xml
|
||||
|
||||
### `DataStore`
|
||||
Interface for the DataStore which stores all data that is relevant for the App (managed Races, Competitors, ...)
|
||||
Implementation: InMemoryDataStore
|
||||
|
||||
### `DataLoader`
|
||||
AsyncDataLoader which does an HTTP GET to a given URL, parses the data (with a DataParser) and sends the data to a DataHandler.
|
||||
|
||||
## ToDo
|
||||
* Server
|
||||
* persist tracking data (GPSFixStore)
|
||||
* user management (Competitors as users, credentials so not everybody can do everything)
|
||||
-> integrate with OAuth, ISAF competitors etc.?
|
||||
* security (not everybody can start race, goes hand in hand with user management)
|
||||
* load stored tracked smartphone race (Panel in Admin Console, RaceLogConnector, only present such races with the necessary data in the racelog, and allow user to select whole leaderboard to restore)
|
||||
* use course update events in racelog locally, do not send to TracTrac
|
||||
* support dynamic mapping of smartphone to competitor -> so that it can change during the race
|
||||
* find methods for persistent competitors
|
||||
* support other input channels (e.g. Igtimi)
|
||||
* Android
|
||||
* abstract sending service, so that all POST / GET requests and not only RaceLogEvents can be sent using the semi-connectedness functionality
|
||||
|
||||
### Server
|
||||
* set fleet when creating race
|
||||
* editing course in the RaceBoardAdmin
|
||||
* persist tracking data (GPSFixStore)
|
||||
* load stored tracked smartphone race (Panel in Admin Console, RaceLogConnector, only present such races with the necessary data in the racelog, and allow user to select whole leaderboard to restore)
|
||||
* mapping devices to marks
|
||||
* generic method for registering listener for NMEA sentence types (e.g. to then process wind) -> move servlet for receiving NMEA out of smartphoneadapter
|
||||
* accepting / removing competitors
|
||||
* for this we first need racelog replication back to all clients
|
||||
* also, not everybody should be able to do this -> see user management
|
||||
* user management (Competitors as users, credentials so not everybody can do everything)
|
||||
* -> integrate with OAuth, ISAF competitors etc.?
|
||||
* security (not everybody can start race, goes hand in hand with user management)
|
||||
* support dynamic mapping of smartphone to competitor -> so that it can change during the race
|
||||
* support other input channels (e.g. Igtimi)
|
||||
* Servlet for getting Competitors for a certain race: Have a look how this is implemented in the serverside-counterpart of the racecommittee-app: /sailingserver/rc/competitors?leaderboard="+raceGroupName+"&raceColumn"+raceColumnName+ "&fleet="+fleetName
|
||||
|
||||
### Android
|
||||
* reuse existing course design functionality to create RaceLogCourseDesignChangedEvent before sending RaceLogPreRacePhaseEndedEvent
|
||||
* abstract sending service, so that all POST / GET requests and not only RaceLogEvents can be sent using the semi-connectedness functionality --> just write JSONObjects/Strings directly into the file. The Servlet has to handle deserialization and the client doesn't have to know what type of object it is after having saved it (is this really the case?)
|
||||
* simplify settings
|
||||
* login/register Activity for registering the Team and Sailor the first time the App is started
|
||||
Reference in new issue
Block a user