# Run-time API
XPLORA offers an API to receive run-time settings over a TCP/IP or UDP connection, by running a server handling incoming requests. This can be useful when XPLORA is used within a Hardware in the Loop (HIL) setup. In principle, XPLORA provides two protocols a user can work with to make adaptions during simulation run-time. The user can choose between:
- Hardware-in-the-Loop (HIL) Datagrams
- SCPI format
Via the HIL Datagrams, the receiver can be steered, by adapting its position and velocity. When the SCPI format is used, the following five categories, where parameters can be applied, are as follows (see also Scenario Simulation):
- Receiver
- Satellites
- Multipath
- Jammer
- Spoofer
- Spectrum-matched Jammer
# Definition of Hardware in the Loop Datagrams
The HIL Datagrams are sent in form of byte packages to XPLORA. The byte order of the datagrams is big endian. Each datagram consists of a header and a payload:
Header
- Message ID
(unsigned char, 1 Byte) - Protocol Version
(unsigned char, 1 Byte) - Message Counter
(unsigned char, 1 Byte) - Reserved Byte
(unsigned char, 1 Byte)
- Message ID
Payload
- Latitude
[rad, WGS84] (double, 8 Bytes) - Longitude
[rad, WGS84] (double, 8 Bytes) - Height
[m, WGS84] (double, 8 Bytes) - Velocity North
(LLF, m/s) (double, 8 Bytes) - Velocity East
(LLF, m/s) (double, 8 Bytes) - Velocity Down
(LLF, m/s) (double, 8 Bytes)
- Latitude
Note
HIL Datagrams can be sent either via TCP/IP or UDP protocol. When packages are sent, a server response, whether the Datagram could be parsed or not, is sent back to the client. If the TCP/IP protocol is used, a newline character needs to be appended to the datagram.
# Definition of SCPI
In general, the Standard Commands for Programmable Instruments (SCPI) defines a standard for syntax and commands to use in controlling programmable test and measurement devices, such as automatic test equipment and electronic test equipment. There is a distinction between two types of commands:
- SET: With this type of command, certain settings can be set at instrument site. For example
SYSTem:COMMunicate:SERial:BAUD 2400sets the baudrate of a RS232 interface to 2400 bits/s. - QUERY: With this type of command, certain information of a current instrument setting can be queried. For example
SYSTem:COMMunicate:SERial:BAUD?gives the current set baudrate of the RS232 interface. Query operations always end with a question mark.
Some commands can both set and query an instrument at once (more information can be found at [1] and [2]).
# Definition of SCPI within XPLORA
The sending and receiving of run-time settings in XPLORA is realized via a TCP/IP interface, where SCPI commands are utilized.
- A TCP client shall be able to send a request (SET), for example new run-time settings, as a SCPI command. The server will not send a response back.
- A TCP client shall be able to send a request (QUERY), for example the current status of the TCP server, as a SCPI command. Here the server will send back an appropriate response.
In order to simplify things, only short-notation commands are used. Requests are handled as follows:
- For XPLORA, SET operations always send a
<json>string to the server. - For every request, the client shall create a new connection.
- The server shall parse a message if a defined
<end-char>is found. - The server shall parse a message if the connection is closed.
- Everything which is received after parsing a message shall be ignored.
- In case the request was a QUERY, the server shall send back a response in the same connection tunnel.
- In order to check if a SET operation was successful, an event queue can be read out, giving the current status caused by the latest request.
The run-time settings are split up to separate commands, depicting each category of setting SETS e.g. satellites, receivers, etc.
# Available SCPI commands
The following SET and QUERY operations can be send to the XPLORA TCP server:
NOTE
<json> defines the payload of a command.
NOTE
<end-char> is the character, which defines the end of the request. Currently, a newline character \n is defined to signalize the end of the payload.
# Available SETS
- Set new satellite run-time settings:
XPLORA:SETT:SAT <json> <end-char> - Set new receiver run-time settings:
XPLORA:SETT:REC <json> <end-char> - Set new jammer run-time settings:
XPLORA:SETT:JAM <json> <end-char> - Set new spoofer run-time settings:
XPLORA:SETT:SPF <json> <end-char> - Set new spectrum-jammer run-time settings:
XPLORA:SETT:SJ <json> <end-char> - Set new multipath run-time settings:
XPLORA:SETT:MP <json> <end-char>
# Available QUERIES
- Query current status from event queue:
XPLORA:STAT? <end-char> - Query current satellite run-time settings:
XPLORA:SETT:SAT? <end-char> - Query current receiver run-time settings:
XPLORA:SETT:REC? <end-char> - Query current jammer run-time settings:
XPLORA:SETT:JAM? <end-char> - Query current spoofer run-time settings:
XPLORA:SETT:SPF? <end-char> - Query current spectrum-jammer run-time settings:
XPLORA:SETT:SJ? <end-char> - Query current multipath run-time settings:
XPLORA:SETT:MP? <end-char>
# Available Status QUERIES
- Query current simulated receiver state:
XPLORA:STAT:REC? <end-char> - Query current simulated satellite skyplot:
XPLORA:STAT:SAT? <end-char> - Query current simulation progress:
XPLORA:STAT:SIM? <end-char>
# Definition of run-time setting categories
The definitions are composed in the JSON format.
# Receiver State
# SET
Set receiver state:
XPLORA:SETT:REC <json> <end-char>
JSON Payload as string:
{
"id": 1,
"state": {
// ellipsoidal WGS-84 (lat [deg], lon [deg], h [m])
"position": [47.1, 15.1, 350.0],
// local level (north [m/s], east [m/s], up [m/s])
"velocity": [12.5, 11.4, 10.3],
// local level (north [m/s²], east [m/s²], up [m/s²])
"acceleration": [1.6, 2.7, 3.8],
// body frame attitude (roll [°], pitch [°], yaw [°])
"attitude": [1.0, 0.0, 0.0],
// body frame rate of attitude (roll [°/s], pitch [°/s], yaw [°/s])
"attitude-dot": [-1.0, 0.0, 0.0],
}
}
NOTE
Position, velocity and acceleration as well as roll, pitch and yaw are optional. The following notation is used:
- x: position
- v: velocity
- a: acceleration
- r: roll
- p: pitch
- y: yaw
The following combinations are possible:
Combinations
- x:
- x, v:
- x, v, a:
- x, a:
- v:
- v, a:
- a:
- r, p, y:
- r-dot, p-dot, y-dot:
- r, p, y and r-dot, p-dot, y-dot:
All parameters (except the id) are optional:
| Name | Type | Optional |
|---|---|---|
| id | integer | no |
| state | double array | yes |
# QUERY
Query last receiver state:
XPLORA:SETT:REC? <end-char>
returns last receiver state set, i.e.:
{"STATUS": "applied", "COMMAND": {"id": 1, "state": {"acceleration": [0.0, 3.0, 0.0]}}}
# Satellite
# SET
Set satellite state:
XPLORA:SETT:SAT <json> <end-char>
JSON Payload as string:
{
"system": "SBAS",
"satellites": [
{
"prn": 120,
"active": true,
"healthy": false,
"received-signal-power": -165.0
}
]
}
NOTE
Multiple satellites for one system can be changed in one request
{
"system": "GPS",
"satellites": [
{ "prn": 1, "active": false, "received-signal-power": -170.0 },
{ "prn": 2, "active": true, "received-signal-power": -170.0 },
{ "prn": 3, "active": true, "received-signal-power": -170.0 },
{ "prn": 4, "active": true, "received-signal-power": -170.0 },
]
}
All parameters (except the prn) are optional, and it is possible to set more than one satellite per request:
| Name | Type | Optional |
|---|---|---|
| prn | integer | no |
| active | boolean | yes |
| healthy | boolean | yes |
| received-signal-power | double [dBW] | yes |
The active status can only be changed for satellites already active and actually simulated in the scenario.
# QUERY
Query last satellite commands:
XPLORA:SETT:SAT? <end-char>
returns last satellites set command:
{"STATUS": "applied", "COMMAND": {"satellites": [{"active": false, "prn": 1}], "system": "GPS"}}
Allowed SBAS PRNs
See Current Status of SBAS satellites for more information.
Use the flag SBAS for the following SBAS Systems:
| SBAS | Nat | PRN |
|---|---|---|
| EGNOS | EU | 120, 121, 123, 124 (reserved), 126, 136 |
| SDCM | Russia | 125, 140, 141 |
| GAGAN | India | 127, 128, 132 |
| MSAS | Japan | 129, 137 |
| BDSBAS | China | 130, 143, 144 |
| NSAS | Nigeria | 147 |
| WAAS | USA | 131, 137 |
Allowed GNSS PRNs
| GNSS | PRN | Example |
|---|---|---|
| GPS | 1 - 32 | {"satellites": [{"active": false, "prn": 24}], "system": "GPS"} |
| Galileo | 1 - 50 | {"satellites": [{"active": false, "prn": 2}], "system": "GALILEO"} |
| GLONASS | 1 - 63 | {"satellites": [{"active": false, "prn": 12}], "system": "GLONASS"} |
| SBAS | 120 - 158 | {"satellites": [{"active": false, "prn": 120}], "system": "SBAS"} |
| QZSS | 193 - 202 | {"satellites": [{"active": false, "prn": 193}], "system": "QZSS"} |
| BeiDou | 1 - 63 | {"satellites": [{"active": false, "prn": 1}], "system": "BEIDOU"} |
| NavIC | 1 - 14 | {"satellites": [{"active": false, "prn": 1}], "system": "NAVIC"} |
# Jammer
# SET
Set jammer state:
XPLORA:SETT:JAM <json> <end-char>
JSON Payload as string:
{
"id": 1,
"active": true,
"power": -130, // absolute power in dBW
"state": {
// ellipsoidal WGS-84 (lat [deg], lon [deg], h [m])
"position": [47.1, 15.1, 350.0],
// local level (north [m], east [m], up [m])
"velocity": [12.5, 11.4, 10.3],
// local level (north [m], east [m], up [m])
"acceleration": [1.6, 2.7, 3.8]
}
}
All parameters (except the id) are optional:
| Name | Type | Optional |
|---|---|---|
| id | integer | no |
| active | boolean | yes |
| power | double [dBW] | yes |
| state | double array | yes |
# QUERY
Query last jammer state:
XPLORA:SETT:JAM? <end-char>
returns last jammer state set, i.e.:
{"STATUS": "applied", "COMMAND": {"active": true, "id": 1, "power": -130}}
# Spoofer
# SET
Set spoofer state:
XPLORA:SETT:SPF <json> <end-char>
JSON Payload as string:
{
"id": 1,
"active": true,
// relative power (to authentic signals) in dB
"power": 5,
// spoofer state
"state-spoofer": {
// ellipsoidal WGS-84 (lat [deg], lon [deg], h [m])
"position": [47.1, 15.1, 350.0],
// local level (north [m], east [m], up [m])
"velocity": [12.5, 11.4, 10.3],
// local level (north [m], east [m], up [m])
"acceleration": [1.6, 2.7, 3.8]
},
// the state, which the spoofer assumes its target (victim) has
"state-target": {
// ellipsoidal WGS-84 (lat [deg], lon [deg], h [m])
"position": [47.1, 15.1, 350.0],
// local level (north [m], east [m], up [m])
"velocity": [12.5, 11.4, 10.3],
// local level (north [m], east [m], up [m])
"acceleration": [1.6, 2.7, 3.8]
},
// the state, which the spoofer forces on the overtaken receiver
"state-sim-rec": {
// ellipsoidal WGS-84 (lat [deg], lon [deg], h [m])
"position": [47.1, 15.1, 350.0],
// local level (north [m], east [m], up [m])
"velocity": [12.5, 11.4, 10.3],
// local level (north [m], east [m], up [m])
"acceleration": [1.6, 2.7, 3.8]
}
}
All parameters (except the id) are optional:
| Name | Type | Optional |
|---|---|---|
| id | integer | no |
| active | true or false | yes |
| power | double, [dB] | yes |
| state-spoofer | double array | yes |
| state-target | double array | yes |
| state-sim-rec | double array | yes |
# QUERY
Query last spoofer state:
XPLORA:SETT:SPF? <end-char>
returns last spoofer state set, i.e.:
{"STATUS": "applied", "COMMAND": {"active": true, "id": 1, "power": 5, "state-sim-rec": {"position": [47.1, 15.1, 500.0]}}}}
# Spectrum-matched Jammer
# SET
Set spectrum-jammer state:
XPLORA:SETT:SJ <json> <end-char>
JSON Payload as string:
{
"id": 1,
"active": true,
// relative power (to authentic signals) in dB
"power": 5,
// spectrum-jammer state
"state-sj": {
// ellipsoidal WGS-84 (lat [deg], lon [deg], h [m])
"position": [47.1, 15.1, 350.0],
// local level (north [m], east [m], up [m])
"velocity": [12.5, 11.4, 10.3],
// local level (north [m], east [m], up [m])
"acceleration": [1.6, 2.7, 3.8]
},
// the state, which the spectrum-jammer assumes its target (victim) has
"state-target": {
// ellipsoidal WGS-84 (lat [deg], lon [deg], h [m])
"position": [47.1, 15.1, 350.0],
// local level (north [m], east [m], up [m])
"velocity": [12.5, 11.4, 10.3],
// local level (north [m], east [m], up [m])
"acceleration": [1.6, 2.7, 3.8]
}
}
# QUERY
Query last spectrum-jammer state:
XPLORA:SETT:SJ? <end-char>
returns last spectrum-jammer state set, i.e.:
{"STATUS": "applied", "COMMAND": {"active": true, "id": 1, "power": 5, "state-sj": {"position": [47.1, 15.1, 500.0]}}}}
# Multipath
# SET
Set multipath settings:
XPLORA:SETT:MP <json> <end-char>
JSON Payload as string:
{"id": 1, "active": true, "mask": "tunnel"}
{"id": 1, "active": false, "mask": "none"}
| Name | Type | Optional | Note |
|---|---|---|---|
| id | integer | no | has to be a valid receiver id; otherwise the runtime setting is ignored as a whole |
| active | boolean | no | activates / deactivates multipath |
| mask | string | no | sets the mask identified by the string given; has to be part of the scenario; if the name is not found, the runtime setting is ignored as a whole |
# QUERY
Query last spoofer state:
XPLORA:SETT:MP? <end-char>
returns last multipath settings set, i.e.:
{"STATUS": "applied", "COMMAND": {"active": true, "id": 1, "mask": "obstruction"}}
# Query current computed states
Note
A maximum of 5 Hz to query states is proposed. Otherwise "Null" could be returned, since the TCP/IP interface is not fast enough to process all data and respond in time.
# Receiver State
Return the current computed receiver state as computed by the simulator:
XPLORA:STAT:REC? <end-char>
The result is an array of all computed receiver states for the current epoch.
[
{
"rec_id": 1,
"ant_id": 1,
"epoch": 6.0,
"pos": [47.000060004, 15.000060003, 409.999],
"vel": 5.605,
"acc": 0.0
}
]
Each array entry is a simulated receiver state composed of the following values:
| Name | Type | Note |
|---|---|---|
| rec_id | integer | receiver ID |
| ant_id | integer | antenna ID |
| epoch | double | Epoch in seconds from start of scenario |
| pos | double array | Receiver position (Phi [°], Lambda [°], Height [m], WGS-84) |
| vel | double | Absolute velocity of receiver in Local Level Frame [m/s] |
| acc | double | Absolute acceleration of receiver in Local Level Frame [m/s²] |
# Satellite Skyplot
Return the current computed satellite skyplot as computed by the simulator:
XPLORA:STAT:SAT? <end-char>
The result is an array of all computed skyplots for all receiver-antenna pairs:
[
{
"rec_id": 1,
"ant_id": 1,
"epoch": "2021-07-31T00:00:06.000Z",
"satellites": [
{
"prn": "GPS06",
"azi_ele": [41.34, 20.94]
},
{
"prn": "GPS08",
"azi_ele": [237.56, 38.99]
},
{
"prn": "GPS12",
"azi_ele": [81.7, 60.94]
},
{
"prn": "GPS13",
"azi_ele": [324.33, 11.82]
},
{
"prn": "GPS18",
"azi_ele": [145.36, 39.7]
},
{
"prn": "GPS23",
"azi_ele": [87.29, 2.56]
},
{
"prn": "GPS25",
"azi_ele": [332.91, 78.66]
},
{
"prn": "GPS27",
"azi_ele": [237.85, 71.88]
}
]
}
]
Each array entry is connected to a simulated receiver-antenna pair and composed of the following values:
| Name | Type | Note |
|---|---|---|
| rec_id | integer | receiver ID |
| ant_id | integer | antenna ID |
| epoch | string | Epoch in UTC format |
| satellites | object array | Array of skyplot data with skyplot objects (see below) |
| Name | Type | Note |
|---|---|---|
| prn | string | PRN Number of Satellite |
| azi_ele | double array | azimuth and elevation array (Azimuth [°], Elevation [°]) |
# Simulation Progress
Return the current simulation progress as computed by the simulator:
XPLORA:STAT:SIM? <end-char>
The result is an array with one entry containing the simulation progress for the current epoch.
[
{
"progress": 11,
"sim_time": "2021-07-31T00:00:06.000Z",
"droute": 2503.436,
"eta": 41.3
}
]
Each array entry contains the current simulation progress with the following values:
| Name | Type | Note |
|---|---|---|
| progress | integer | progress of simulation in % |
| sim_time | string | current time of simulation in UTC format |
| droute | double | distance if completed route in [m] |
| eta | double | estimated time-of-arrival in [s] |
# Multipath Status
Return the current MP status:
XPLORA:STAT:MP? <end-char>
The result is an array of all receivers and its first antenna:
[
{
"active": true,
"mp_obstruction_mask": "tunnel",
"rec_id": 1
}
]
# Test with UNIX command line tools
Send new receiver state to client via netcat nc:
echo -ne 'XPLORA:SETT:REC {"id": 1, "active": true, "state": {"position": [47.1, 15.1, 350.0], "velocity": [12.5, 11.4, 10.3], "acceleration": [1.6, 2.7, 3.8]}} \n' | nc localhost 8080
Query current status:
echo -ne 'XPLORA:SETT:REC? \n' | nc localhost 8080