Sylphase SDGPS
The software-defined GPS(/GNSS) toolkit
Config

All SDGPS streams are prefixed with a configuration data structure that describes the information that is present in the stream. The raw, cooked, cooked2, and observables interface types share a common format that is described on this page. The solution interface has its own unique config format that is described on its page.

The only time that configs should need to be directly interacted with is when you're tweaking or creating a novel system model for a simulation.

Format

Note: keys that are indented are nested within their parent, less-indented key. If a key is marked as required, it is only required if its parent is present.

Key Type Unit Required Description
max_stream_jitter Real seconds Yes The maximum duration by which packets can be out of order in a stream, relative to their "stream times"
gnss_streams Array of Objects No One object for each GNSS sample stream (each of which would typically correspond to one GNSS frontend IC capturing a given band from a given antenna)
    i_bits            
Integer bits Yes Number of I (in-phase) bits of the raw GNSS bandband samples (typically 1, 2, or 3)
    q_bits            
Integer bits Yes Number of Q (quadrature) bits of the raw GNSS bandband samples (typically 1, 2, or 3)
    samples_per_packet
Integer samples Yes Number of samples per GNSSSamplePacket (typically set so that sample packets are issued at about 20 Hz)
    sample_latency    
Real seconds Yes The approximate duration between the last sample of a GNSSSamplePacket being captured and the packet occurring within the stream
    sample_period     
Real seconds Yes The duration between samples
    spectrum_info     
Object No (see SpectrumInfo )
    substreams        
Array of Objects No (see Substream )
imu Object No A description of the IMU, if an IMU is present
(Note: the IMU must be present at the body-frame origin and aligned with the body axes)
    covariance        
6x6 matrix
[m/s^2 rad/s]
[m/s^2 rad/s]^T
Yes The covariance of the noise of a single IMU measurement
    sample_latency    
Real seconds Yes The duration between the "measurement time" (the time at which the measurement occurs) and the "stream time" (the time at which the measurement should be issued in the stream)
    sample_period     
Real seconds Yes The duration between samples
baro_streams Array of Objects No One object for each barometric pressure sensor
    position          
3-vector meters Yes The position in the body frame where barometric pressure is measured
    sample_latency    
Real seconds Yes The duration between the "measurement time" (the time at which the measurement occurs) and the "stream time" (the time at which the measurement should be issued in the stream)
    sample_period     
Real seconds Yes The duration between samples
    variance          
Real pascals^2 Yes The variance of a single barometric pressure measurement
mag_streams Array of Objects No One object for each magnetometer sensor
    covariance        
3x3 matrix tesla^2 Yes The covariance of a single measurement
    orientation       
quaternion Yes The orientation of the magnetometer axes in the body frame, represented as a quaternion that rotates magnetometer-frame vectors into body-frame vectors
    sample_latency    
Real seconds Yes The duration between the "measurement time" (the time at which the measurement occurs) and the "stream time" (the time at which the measurement should be issued in the stream)
    sample_period     
Real seconds Yes The duration between samples
tick_stream Object No Present if TickPackets exist within the stream; necessary if there are no high-rate sensors (e.g. IMU, mag, baro) to convey time
    sample_latency    
Real seconds Yes The duration between the "measurement time" (the time at which the measurement occurs) and the "stream time" (the time at which the measurement should be issued in the stream)
    sample_period     
Real seconds Yes The duration between samples

SpectrumInfo

The optional spectrum_info key in a gnss_stream Object describes GNSS-agnostic information about the downconverted band. It has the following information:

Key Type Unit Required Description
lo_frequency Real Hz Yes RF frequency that 0 Hz in downconverted band corresponds to (= LO frequency)
band_start Real Hz Yes lowest RF frequency captured (= low edge of SAW passband)
band_end Real Hz Yes highest RF frequency captured (= high edge of SAW passband)

Substream

The Objects inside the optional substreams Array in a gnss_stream Object each describe one GNSS signal that is present in the GNSS stream. They have the following information:

Key Type Unit Required Description
axis unit 3-vector No Direction of antenna axis (boresight) in body frame
position 3-vector meters No Position of antenna phase center in body frame
frequency Real Hz Yes Frequency of this GNSS signal in the downconverted band (e.g. 0 Hz for zero-IF downconversion)
system String Yes GNSS signal. Current options: GPS_L1, GPS_L2C, GLO_L1, GLO_L2, GAL_E1B
forward unit 3-vector No Direction of antenna frame x-axis in body frame
correlator_spacing Real samples In cooked/cooked2 streams Spacing between correlator taps
correlator_count Integer In cooked/cooked2 streams Number of correlator taps
correlation_latency Real seconds In cooked/cooked2 streams The duration between the "measurement time" (the time at which the measurement occurs) and the "stream time" (the time at which the measurement should be issued in the stream)
correlator_obeys_configuration_exactly Boolean In cooked/cooked2 streams true if and only if the correlator will immediately and exactly (no rounding/etc.) obey DesiredCorrelatorConfigurations
observation_latency Real seconds In observables streams The duration between the "measurement time" (the time at which the measurement occurs) and the "stream time" (the time at which the measurement should be issued in the stream)

Simulation tutorial

The following is a valid config for a fictional platform with two GPS_L1 antennas spaced 1 meter apart along the body X axis and pointing along the body +Z axis:

{
"max_stream_jitter": 0.1,
"gnss_streams": [{
"i_bits": 2,
"q_bits": 2,
"samples_per_packet": 100000,
"sample_latency": 0,
"sample_period": 1e-7,
"substreams": [{
"axis": [0, 0, 1],
"position": [-0.5, 0, 0],
"frequency": 0,
"system": "GPS_L1",
"forward": [1, 0, 0],
"observation_latency": 0.01
}]
}, {
"i_bits": 2,
"q_bits": 2,
"samples_per_packet": 100000,
"sample_latency": 0,
"sample_period": 1e-7,
"substreams": [{
"axis": [0, 0, 1],
"position": [0.5, 0, 0],
"frequency": 0,
"system": "GPS_L1",
"forward": [1, 0, 0],
"observation_latency": 0.01
}]
}],
"imu": {
"covariance": [[0.01, 0, 0, 0, 0, 0], [0, 0.01, 0, 0, 0, 0], [0, 0, 0.01, 0, 0, 0], [0, 0, 0, 4e-4, 0, 0], [0, 0, 0, 0, 4e-4, 0], [0, 0, 0, 0, 0, 4e-4]],
"sample_latency": 0,
"sample_period": 1e-3
}
}

After saving the above config to a file named configs/dual, we can run the following commands to perform various simulations:

sdgps generate-simple-trajectory --angular-velocity-enu '[1, 0, 0]' ! simulate-raw configs/dual ! plot-sensors

This shows the IMU output while the vehicle is being rotated around its +X axis.

Simulation 1
sdgps generate-simple-trajectory --angular-velocity-enu '[0, 0, 1]' --rate 5 ! \
simulate-observables configs/dual ! \
plot-observables --min-sample-period 0.1 ! \
plot-observables --min-sample-period 0.1 --gnss-stream 1

This shows the observables from both GNSS antennas while the vehicle is being rotated about its +Z axis.

Simulation 2

Sample (from Infix-2)

The following was output by running sdgps print-config ugi2:.

{
"max_stream_jitter": 0.1,
"gnss_streams": [{
"i_bits": 2,
"q_bits": 2,
"samples_per_packet": 516096,
"sample_latency": -7.9984e-4,
"sample_period": 1.6276041666666666e-7,
"spectrum_info": {
"lo_frequency": 1575321600,
"band_start": 1573221600,
"band_end": 1577421600,
"antenna_id": "ANT0",
"antenna_position": [0, 0, 0],
"antenna_axis": [0, 0, 1]
},
"substreams": [{
"axis": [0, 0, 1],
"position": [0, 0, 0],
"frequency": 98400,
"system": "GPS_L1",
"antenna_id": "ANT0",
"correlator_spacing": 1,
"correlator_count": 24,
"correlation_latency": 5e-4,
"correlator_obeys_configuration_exactly": false,
"observation_latency": 0.011
}]
}],
"imu": {
"covariance": [[3e-4, 0, 0, 0, 0, 0], [0, 3e-4, 0, 0, 0, 0], [0, 0, 4.5e-4, 0, 0, 0], [0, 0, 0, 2e-6, 0, 0], [0, 0, 0, 0, 2e-6, 0], [0, 0, 0, 0, 0, 1.5e-6]],
"sample_latency": 0.0052,
"sample_period": 1e-3
},
"baro_streams": [{
"position": [0.00816, 0.00487, -0.0016],
"sample_latency": 0.0089,
"sample_period": 0.01,
"variance": 4
}],
"mag_streams": [{
"covariance": [[4e-13, 0, 0], [0, 4e-13, 0], [0, 0, 4e-13]],
"orientation": {
"w": 1,
"x": 0,
"y": 0,
"z": 0
},
"sample_latency": 0.0177,
"sample_period": 0.02
}],
"time_streams": [{
"name": "USB clock (free-running)",
"sample_latency": 6.000000000000001e-4,
"sample_period": 0.01
}]
}

From this, we can see that the Infix-2 has a barometer, magnetometer, and IMU. In addition, it has a single 2-bit GNSS frontend that can receive the GPS_L1 signal.