Tracking Protocol

tseval edited this page Nov 23, 2017 · 19 revisions

Overview

The Silent Wings tracking protocol is a simple HTTP-based protocol where the client can request new tracking data from the server at fixed intervals. The client can also request information about the pilots and task for a competition.

Commands

eventgroups command

This command is used to get a list of the available groups of events on the server.

An "Event Group" can for example be used to represent a competition, where each competition day is an event.

The Viewer application will call this when the user opens the events browser. When an event group is selected, the Viewer will use the Event command to get more detailed information for a selected event.

Usage host.url/eventgroups

The list of event groups should be presented as a JSON-array as in the example below.

[
    {
        /** Name of the event group 
          * @type String 
          */
        "name": "NewCompetition",
        /** Description of the event group
          * @type String 
          */
        "description": "A new competition",
        /** Optional: Url to a banner image that might be displayed in the viewer
          * @type String
          * Optimal resolutions tbd
          */
        "bannnerUrl": "",

        /** A list of the events (competition days, normally) 
          * @type Array of objects
          */
        "events": [
            {
                /** Event id. 
                  * @type String
                  */ 
                "id": "1",
                /** Task start time
                  * @type Integer
                  * Format is Unix Time (seconds).
                  */
                "startOpenTs": 1420286400
            },
            {
                "id": 2,
                "startOpenTs": 1420286400 
            }
        ]
    }, 
    {
        "name": "MoreComp",
        "description": "Another competition",
        "bannnerUrl": "",
        "events": [
            {
                "id": "3",
                "startOpenTs": 1420286400
            },
            {
                "id": "4",
                "startOpenTs": 1420286400 
            }
        ]
    }
]

event command

This command is used to get information about a given tracking event

Usage host.url/event?eventid=<eventId>

eventId is an unique string ID. An event is defined as a single competition day. The request should return a JSON document describing the event, structured like in the example below.

This event description consists of a section with information about the event itself, as well as a list of track descriptions describing each track, typically one for each tracked pilot.

{
    /** Name of the event/competition
      * @type String
      */
    "name": "Example Championships",

    /** A description of the event
      * @type String
      */
    "description": "Day 523",

    /** Optional: Url to a banner image that might be displayed in the viewer
      * @type String
      * Optimal resolutions tbd
      */
    "bannerUrl": "http://my.site/banner.png",

    /** Current version of the event description. Should be incremented
      * whenever the description is modified (adding/removing tracks, modifying task, etc).
      * @type Integer
      */
    "eventRevision": 0,

    /** Object describing the event task
      * @type Object
      */
    "task": {

        /** Task name
          * @type String
          */
        "taskName": "Final"

        /** Task type
          * @type String
          * Currently only "SailplaneGrandPrix" is supported.
          * Planned types are
          * "SailplaneGrandPrix", "SailplaneRacing", "SailplaneAssignedArea", "CivlGap"
          */
        "taskType": "SailplaneGrandPrix",

        /** Task start time
          * @type Integer
          * Format is Unix Time (seconds).
          */
        "startOpenTs": 0,

        /** Array of task turnpoints
          * @type Array of objects
          */
        "turnpoints": [
            {
                /** Turnpoint name
                  * @type String
                  */

                "name": "002ZL030",

                /** Turnpoint type
                  * @type String
                  *
                  * Valid types are
                  * "Takeoff", "Start", "StartOfSpeedSection", "Turnpoint", "EndOfSpeedSection", "Finish", "Landing"
                  * For Sailplane racing, only Start, Turnpoint and Finish are relevant.
                  */
                "type": "Start",

                /** Latitude in degrees
                  * @type Double
                  */
                "latitude": 46.527216657002768,

                /** Longitude in degrees
                  * @type Double
                  */
                "longitude": 9.8783333460489917,

                /** Optional: maximum altitude in meters
                  * @type Double
                  */
                "maxAltitude": 100000,

                /** Optional: minimum altitude in meters
                  * @type Double
                  */
                "minAltitude": 0,

                /** Observation zone
                  * @type String
                  * Valid types are
                  * "Cylinder", "Sector", "Line", "Cone"
                  */
                "observationZone": "Line",

                /** Optional: Radius in meters.
                  * @type Double
                  * Ignored if observationZone is "Cone".
                  * Default values are 500.0 for Cylinder, 1000.0 for line.
                  * For Line, radius describes the half-length of the line (from center to either end)
                  */
                "radius": 1000,

                /** Optional: Trigger method
                  * @type String
                  * Valid types are
                  * "Enter", "Exit"
                  * Optional, mostly relevant for paragliding competitions.
                  * Default is "Enter" except for type "Start" where it is exit
                  * Ignored when observationZone = "Line"
          * @type Array
                  */
                "trigger": "Exit",

                /** Optional: Cone inclination
                  * @type Double
                  * Default value is 1.0/2.5² (0.16)
                  * Describes the cone inclination. Only for CIVL GAP scoring (paragliding) with observationZone = "Cone".
                  */
                "coneIncline": 0.16,

                /** Optional: Image texture
                  * @type String
                  * Default value is empty.
                  * Contains a URL (either http or file pointing to local disk) with an image
                  * that is mapped onto the turnpoint 3D graphic. This can typically be a sponsor 
                  * logo or similar.
                  */
                "texture": "http://mycompany/logo.png"
            },
            {
                "latitude": 46.404116662343341,
                "longitude": 9.9602666854858395,
                "name": "054Pers Gletscher",
                "observationZone": "Cylinder",
                "radius": 500,
                "type": "Turnpoint"
            },
            {
                "latitude": 46.527216657002768,
                "longitude": 9.8783333460489917,
                "maxAltitude": 100000,
                "minAltitude": 1350,
                "name": "002ZL030",
                "observationZone": "Line",
                "radius": 1000,
                "trigger": "Enter",
                "type": "Finish"
            }
        ]
    },

    /** Array of track descriptions for the event
      * @type Array of objects
      *
      */

    "tracks": [
        {
            /** Track ID. Unique string ID for this track (flight)
              * @type String
              * Note that the track ID must be unique for the whole server, not just the particular event.
              * Think of it as a unique IGC log filename. 
              */
            "trackId": "146574",

            /** Pilot's name
              * @type String
              */
            "pilotName": "Example Guy",

            /** Either glider competition ID or a trigraph based on the Pilots name. Should not have more than 3 letters.
              * @type String
              * This is used in all labels and compact score boards.
              */
            "competitionId": "10",

            /** Pilot's nationality
              * @type String
              * ISO 3-letter country codes are preferred.
              */
            "country": "SWE",

            /** Glider type/model
              * @type String
              */
            "aircraft": "LS 10-s-15",

            /** Optional: URL to a portrait image file of the pilot
              * @type String
              */
            "portraitUrl": "https://example.site/mug.png",

            /** Optional: Aircraft registration
              * @type String
              */
            "registration": "OM-1010",

            /** Optional: 3D-model to display
              * @type String
              * Some valid models are
              * "ls8", "ventus2", "balloon", "nova_mentor", "twin2"
              */
            "3dModel": "ventus2",

            /** Optional: 3D-model variant
              * @type String
              * For particular versions of a 3d model (advertising textures etc)
              */
            "3dModelVariant": "",

            /** Optional: array of 3 colors to be used on the 3D ribbons in the viewer
              * @type Array of 3 String
              * Colors can be described in any of the following formats:
              * hex: #RGB, #RRGGBB, #AARRGGBB, #RRRGGGBBB, #RRRRGGGGBBBB
              * SVG color keyword names, such as "green" or "steelblue".
              */
            "ribbonColors": [
                "red",
                "#04f",
                "steelblue"
            ],
        },
        {
            "trackId": "25364",
            "3dModel": "ventus2",
            "aircraft": "Unknown",
            "competitionId": "",
            "country": "NOR",
            "pilotName": "Unknown",
            "portraitUrl": "https://...",
            "registration": "Unknown",
            "ribbonColors": [
                "red",
                "#04f",
                "steelblue"
            ]
        }
    ]
}

trackpoints command

The viewer will do track requests for each track in the current event.

The reason we have chosen to do separate requests for each single track is because during a live event, some trackers tend to get lost for some period of time, before coming back again. As the viewer only requests fixpoints for timestamps more recent than the last points that were received, the requests need to be kept separate.

Usage

host.url/trackpoints?trackid=<trackId>&eventid=<eventId>&begin=1282834064

  • trackid is the unique track ID given for each track in an event.
  • begin is optional and indicates that each trackpoint returned must have a timestamp equal or newer than the begin value. All timestamps are Unix Time in seconds.

When the viewer has received some track points, it will only request points that have a timestamp newer than what has received earlier to avoid downloading the same data repeatedly.

If "begin" is omitted then it should be considered as zero, meaning sending all available track points.

The viewer will ignore any trackpoints that it has already received.

The trackpoint request should return JSON like in the example below.

{
    /** The track ID which much match the trackID in the URL request.
      * @type String
      */
    "trackId": "1",

    /** Live data indicator
      * @type Bool
      * If the track still is ongoing (live), this value must be set to true.
      * The viewer will then continue to request new trackpoints
      * at some interval (normally every 15 seconds or more).
      * Once the track is known to be complete, the value should be set to
      * false. This will prevent the viewer from unnecessary polling, and is
      * especially useful for archived events.
      */
    "live": false,

    /** Event revision.
      * @type Integer
      * Should match the most recent event revision.
      * If the viewer finds a higher value here than the value previously
      * received from the event description, it will trigger requesting
      * the event descrption again, to update whatever did change.
      * Most common use case is probably when the start time is delayed.
      */
    "eventRevision": 1,

    /** Array of trackpoints
      * @type Array of objects
      *
      * Note that since these arrays may become quite large, the variable
      * names have been kept as short as possible to save some
      * bandwidth.
      *
      * The array must be sorted on timestamps in increasing order.
      */
    "track": [
        {
            /** Timestamp in Unix Time seconds
              * @type Double
              */
            "t": 1282834064,

            /** Latitude in degrees (n is short for "north", use negative values for south)
              * @type Double
              */
            "n": 46.529349994659427,
            /** Longitude in degrees (e is short for "east", use negative values for west)
              * @type Double
              */
            "e": 9.8795000076293942,
            /** Altitude in meters
              * @type Double
              */
            "a": 1640.52
        },
        {
            "a": 1640,
            "e": 9.8794833501180008,
            "n": 46.529349994659427,
            "t": 1282834065
        },
        {
            "a": 1640,
            "e": 9.8794833501180008,
            "n": 46.529349994659427,
            "t": 1282834066
        },
        {
            "a": 1640,
            "e": 9.8794666926066075,
            "n": 46.529349994659427,
            "t": 1282834067
        },
        {
            "a": 1640,
            "e": 9.8794499715169266,
            "n": 46.529349994659427,
            "t": 1282834068
        },
        {
            "a": 1640,
            "e": 9.8794333140055333,
            "n": 46.529349994659427,
            "t": 1282834069
        },
        {
            "a": 1640,
            "e": 9.8794166564941399,
            "n": 46.529349994659427,
            "t": 1282834070
        },
        {
            "a": 1640,
            "e": 9.8793999989827466,
            "n": 46.529349994659427,
            "t": 1282834071
        },
        {
            "a": 1641,
            "e": 9.879383341471355,
            "n": 46.529349994659427,
            "t": 1282834072
        },
        {
            "a": 1641,
            "e": 9.8793666839599616,
            "n": 46.529349994659427,
            "t": 1282834073
        },
        {
            "a": 1640,
            "e": 9.8793500264485683,
            "n": 46.529333337148032,
            "t": 1282834074
        },
        {
            "a": 1641,
            "e": 9.8793333053588874,
            "n": 46.529333337148032,
            "t": 1282834075
        },
        {
            "a": 1641,
            "e": 9.8793333053588874,
            "n": 46.529333337148032,
            "t": 1282834076
        },
        {
            "a": 1641,
            "e": 9.8793166478474941,
            "n": 46.529333337148032,
            "t": 1282834077
        }
    ]
}
Clone this wiki locally
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.