Getting Started
The SatGen Scenario API provides a complete programmatic interface for creating, configuring, and running GNSS (Global Navigation Satellite System) signal simulations. It allows you to generate simulated satellite signals for testing GNSS receivers without requiring physical satellite visibility.
Prerequisites
- SatGen 4 must be installed — the API DLLs are loaded from the SatGen 4 installation directory
- A valid SatGen 4 licence must be available (hardware dongle)
- .NET 10.0 or later runtime
- For real-time output: a LabSat device connected and accessible (LabSat Real-Time via USB, or LabSat 4 via Ethernet)
- For file output: no additional hardware is required
Quick Start
using SatGen.ScenarioAPI;
// Create a scenario starting at a specific UTC time
using var scenario = new Scenario(DateTime.UtcNow, AttenuationDB: -3);
// Set a static position (latitude, longitude, altitude in metres, duration in seconds)
scenario.TrajectoryFromStaticPoint(51.5074, -0.1278, 100, 600);
// Stream GPS L1 in real time to a LabSat 4 over Ethernet
scenario.SetOutputToLabSat4Realtime("172.16.20.14",
RealTimeOutputMode.UserTime,
new[] { SignalType.GpsL1CA },
Quantization.TwelveBit,
new LabSat4RealtimeOutputOptions { SatCountLimitMode = SatCountLimitMode.Automatic });
// Run the simulation
scenario.StartSimulation();
scenario.MonitorSimulationProgress(TimeSpan.FromSeconds(1));
Typical Workflow
Scenario with a simulation start time and optional attenuation.ManualAlmanacFile() — useful for reproducing a known scenario or working offline. By default the latest almanacs are downloaded automatically.AddSatelliteTimelineChange() to be applied at fixed elapsed times during the run. Must be scheduled before StartSimulation().Scenario Class
A typical workflow involves:
- Create a new
Scenarioinstance with a simulation start time - Optionally configure dynamics using
SetDynamicsorSetCustomDynamics - Define a trajectory (e.g.
TrajectoryFromStaticPoint,TrajectoryFromRoute,TrajectoryFromKMLFile, etc.) - Configure the output device and signals (e.g.
SetOutputToLabSatFile,SetOutputToLabSatRealtime, etc.) - Start the simulation with
StartSimulation - Monitor progress using
MonitorSimulationProgressor by pollingSimulationPercentCompleteandIsRunning - End the simulation with
EndSimulationor wait for it to complete, then dispose the instance
This class implements IDisposable and should be disposed when no longer needed to release internal resources
such as the simulation engine, almanac services, and output handlers.
public class Scenario : IDisposable
Constructor
public Scenario(DateTime startUTCDateTime, double attenuationDB = -3, double elevationMaskDeg = 5)
The simulation start time is truncated to the nearest whole second, as SatGen requires simulations to begin on a second boundary.
| Parameter | Description |
|---|---|
startUTCDateTime | The UTC date and time at which the simulation should begin. This determines the satellite constellation positions via the almanac data, so it should be set to a realistic date/time for accurate results. Sub-second precision is discarded. |
attenuationDB | The global signal attenuation level in decibels (dB), used to add artificial noise to the simulated signal. Valid range is -15.0 to 0.0. A value of 0.0 disables attenuation entirely. Default is -3 dB, which provides a realistic noise floor for most testing scenarios. |
elevationMaskDeg | The elevation mask angle in degrees. Satellites below this elevation angle (relative to the horizon) will be excluded from the simulation. Valid range is -90 to 90 degrees. Default is 5 degrees, which filters out low-elevation satellites that typically have degraded signal quality. |
Example:
// Basic usage:
var simulationDateTime = new DateTime(2026, 1, 1, 12, 0, 0);
using var scenario = new Scenario(simulationDateTime);
// Full usage with all parameters:
var simulationDateTime = new DateTime(2026, 1, 1, 12, 0, 0);
using var scenario = new Scenario(simulationDateTime, attenuationDB: -3, elevationMaskDeg: 5);
Properties
| Property | Type | Description |
|---|---|---|
BufferUnderrunCount | int | Gets the number of buffer underruns that have occurred during the current real-time simulation.
A buffer underrun happens when the host computer cannot generate simulated signal data fast enough
to keep up with the real-time output rate. Each underrun may cause a brief gap in the output signal.
This property is only meaningful when the output is set to a LabSat Real-Time device. For file-based output, this will always return 0. |
AutomaticSatCountLimit | int | Gets the current automatic satellite count limit during a real-time simulation.
When Automatic is enabled, this value represents the maximum number of
satellites being simulated. It starts at the initial value (default 999 = unlimited) and is automatically
reduced each time a buffer underrun occurs, shedding satellites to reduce CPU load.
This property reflects the live value during a running simulation, or the configured initial value when not running. |
IsReady | bool | Gets a value indicating whether the simulation is currently in a preparing or ready state, waiting for input data before it can begin generating output.
This is particularly relevant for real-time simulations using an external input source (e.g. LabSat or RS232 serial), where the simulation enters a ready state while waiting for the first trajectory data to arrive. For SatGen-generated trajectories, this state is typically brief as the data is already available. |
IsRunning | bool | Gets a value indicating whether the simulation is currently running and actively generating output data.
This property becomes |
SimulationStartTime | DateTime | Gets the accurate UTC start time of the simulation.
Before |
OutputFilePath | string | Gets the full path of the output file that the simulation is writing to.
For file-based simulations (e.g. LabSat3 is a special case: it places its output in a subfolder named after the file stem and
numbers each chunk, so a supplied path of For real-time simulations (e.g. |
SimulationSecondsFromStart | double | Gets the number of seconds that have been simulated since the simulation started.
This value is the simulated time, not wall-clock time - for file-based output the simulation
can advance faster than real time.
Updated periodically by the simulation engine; consumers can either poll this property or
subscribe to |
SimulationPercentComplete | double | Gets the completion progress of the current simulation as a percentage from 0.0 to 100.0.
For file-based simulations with a known duration this represents the proportion of the
trajectory that has been processed. On natural completion this reaches exactly |
SimulationError | string | Gets the error message if an error has occurred during the simulation.
Returns Empty if no error has occurred.
Common error conditions include: failure to initialise the simulation engine, inability to open the output port, LabSat device not found, or invalid output file path. Check this property when a simulation appears to have stopped unexpectedly. |
InputConnectionStatus | InputConnectionStatus | Gets the connection status of the external trajectory input source.
This is only relevant for real-time simulations that receive trajectory data from an external source:
None. |
CurrentStatus | SimulationStatus | Gets the current lifecycle status of the simulation. Mirrors the most recent Status
value carried by the SimulationStatusChanged event, so a consumer that subscribes
to the event after the simulation has already started (or finished) can recover the current state.
Defaults to |
Scenario
public void LoadSatGenFile(string satGenFilePath)
This method is useful when you have a pre-configured scenario created in the SatGen desktop application that you
want to replay programmatically. Because the scenario file already supplies a full configuration, calling any of
the SetOutputTo* methods (and other scenario configuration calls) is optional. Any settings applied
beforeLoadSatGenFile are overwritten by the file's contents, while any settings applied
after the call layer on top of the loaded configuration.
| Parameter | Description |
|---|---|
satGenFilePath | The full absolute path to the SatGen scenario file (.sgen) to load.
Example: @"C:\Scenarios\MyTest.sgen" |
FileLoadException: Thrown if the scenario file could not be loaded (e.g. file not found, corrupt, or invalid format).Example:
scenario.LoadSatGenFile(@"C:\SatGen\Scenarios\example.sgen");
Almanacs
public void ManualAlmanacFile(ConstellationType constellation, string almanacFilePath)
By default, the API automatically downloads the latest almanac data from the Racelogic almanac server for each constellation. Use this method when you need to use a specific almanac file, for example:
- Reproducing a specific test scenario with known satellite positions
- Testing in an environment without internet access
- Using custom or modified almanac data
| Parameter | Description |
|---|---|
constellation | The GNSS constellation to set the manual almanac for (e.g. ConstellationType.GPS, ConstellationType.Galileo, etc.). |
almanacFilePath | The full absolute path to the almanac file. The required file format depends on the constellation type (e.g. YUMA for GPS, XML for Galileo). |
Example:
// Call once per constellation in use:
scenario.ManualAlmanacFile(ConstellationType.GPS, @"C:\Almanacs\gps.alm");
Dynamics
public void SetDynamics(Dynamics dynamics)
This affects how the trajectory is generated when using route-based trajectories. For imported trajectories (NMEA, VBOX, CSV), the dynamics profile does not modify the imported data.
| Parameter | Description |
|---|---|
dynamics | The pre-defined dynamics profile to apply. Options include:
|
Example:
scenario.SetDynamics(Dynamics.Car);
public void SetCustomDynamics(CustomDynamicsOptions dynamicsParams)
SetDynamics) do not match your test requirements.
All acceleration values are specified in g-force units and jerk values in g/s. These limits constrain how the simulated vehicle accelerates, decelerates, and corners when following a route trajectory.
| Parameter | Description |
|---|---|
dynamicsParams | A CustomDynamicsOptions instance containing all nine dynamics parameters:
horizontal velocity (km/h), longitudinal acceleration/deceleration (g), lateral acceleration (g),
vertical acceleration (g), and their corresponding jerk values (g/s). |
Example:
scenario.SetCustomDynamics(new CustomDynamicsOptions(
horizontalVelocity: 200, // km/h
longitudinalAcceleration: 0.5, // g
longitudinalDeceleration: 0.8, // g
lateralAcceleration: 0.4, // g
verticalAcceleration: 0.1, // g
longitudinalAccelerationJerk: 0.5, // g/s
longitudinalDecelerationJerk: 0.8, // g/s
lateralJerk: 0.3, // g/s
verticalJerk: 0.1)); // g/s
Trajectory
public void TrajectoryFromStaticPoint(double latitudeDecDegrees, double longitudeDecDegrees, double altitudeMetres, int durationInSeconds)
- Testing receiver cold/warm start behaviour at a known location
- Evaluating receiver accuracy in a static environment
- Validating signal acquisition and tracking performance
| Parameter | Description |
|---|---|
latitudeDecDegrees | The latitude of the static position in decimal degrees (e.g. 51.5074 for London). Valid range: -90.0 to 90.0. |
longitudeDecDegrees | The longitude of the static position in decimal degrees (e.g. -0.1278 for London). Valid range: -180.0 to 180.0. |
altitudeMetres | The altitude of the static position above the WGS84 ellipsoid in metres (e.g. 0.0 for sea level). |
durationInSeconds | The total duration of the static simulation in seconds. Must be a positive integer. |
Example:
scenario.TrajectoryFromStaticPoint(
latitudeDecDegrees: 51.9831552,
longitudeDecDegrees: -0.999424,
altitudeMetres: 100,
durationInSeconds: 600);
public void TrajectoryFromRoute(RoutingMode routingMode, IReadOnlyList<RouteWaypoint> routeWaypoints)
Each RouteWaypoint defines a geographic position along with optional speed and cornering parameters.
The routing mode determines how the path between waypoints is calculated (e.g. road driving, straight line, rail, etc.).
| Parameter | Description |
|---|---|
routingMode | The method used to calculate the path between waypoints. Common values include road-based routing for driving simulations, or straight-line for direct point-to-point paths. |
routeWaypoints | An ordered list of waypoints that define the route. At least two waypoints are required to create a moving trajectory. Each waypoint specifies a latitude, longitude, altitude, target speed, and apex distance limit. |
Example:
// Basic usage:
var waypoints = new[]
{
new RouteWaypoint(51.9831552, -0.999424, 100),
new RouteWaypoint(51.9900000, -0.990000, 100),
};
scenario.TrajectoryFromRoute(RoutingMode.Road, waypoints);
// Full usage with all waypoint properties set:
var fullWaypoints = new[]
{
new RouteWaypoint(51.9831552, -0.999424, 100)
{
TargetSpeedKilometersPerHour = 50,
ApexDistanceLimitMetres = 5,
},
new RouteWaypoint(51.9900000, -0.990000, 100)
{
TargetSpeedKilometersPerHour = 80,
ApexDistanceLimitMetres = 20,
},
new RouteWaypoint(51.9950000, -0.980000, 110)
{
TargetSpeedKilometersPerHour = 60,
ApexDistanceLimitMetres = 10,
},
};
scenario.TrajectoryFromRoute(RoutingMode.Road, fullWaypoints);
public void TrajectoryFromScript(string satgenFilePath, ScriptTrajectoryOptions? trajectoryOptions = null)
The script is extracted from the first script entry in the specified .sgen file and parsed to
generate a complete trajectory. If the script contains errors, they are collected and thrown
as an AggregateException.
| Parameter | Description |
|---|---|
satgenFilePath | The full absolute path to the SatGen file (.sgen) containing the script trajectory definition. |
trajectoryOptions | Optional configuration for the script trajectory. If null, default options are used (10 Hz output data rate).
Use this to override the output data rate for the generated trajectory. |
InvalidDataException: Thrown if the .sgen file cannot be deserialized into a valid SatGen scenario (e.g. corrupt file or invalid JSON).AggregateException: Thrown if the script contains one or more parsing errors. Each inner exception is a ScriptParseException
whose Message includes the line number, and whose Line
property exposes the line number directly.Example:
// Basic usage:
scenario.TrajectoryFromScript(@"C:\SatGen\Scenarios\example.sgen");
// Full usage with all options set:
scenario.TrajectoryFromScript(
@"C:\SatGen\Scenarios\example.sgen",
new ScriptTrajectoryOptions
{
OutputDataRate = OutputDataRate._10Hz,
});
public void TrajectoryFromKMLFile(string kmlFilePath, KMLTrajectoryOptions? trajectoryOptions = null)
The KML file should contain a LineString or path element defining the trajectory coordinates. The route can optionally be repeated multiple times and the height values can be interpreted as stop times.
| Parameter | Description |
|---|---|
kmlFilePath | The full absolute path to the KML file containing the route definition. |
trajectoryOptions | Optional configuration for the KML trajectory. If null, default options are used
(no repeat, height as altitude, 100 km/h target speed, 10m apex distance limit). |
Example:
// Basic usage:
scenario.TrajectoryFromKMLFile(@"C:\Data\KML\route.kml");
// Full usage with all options set:
scenario.TrajectoryFromKMLFile(
@"C:\Data\KML\route.kml",
new KMLTrajectoryOptions
{
RepeatCount = 2,
UseHeightAsStopTime = false,
TargetSpeedKilometersPerHour = 80,
ApexDistanceLimitMetres = 15,
});
public void TrajectoryFromNMEAFile(string nmeaFilePath, NMEAFileTrajectoryOptions? trajectoryOptions = null)
Supported NMEA sentence types include GGA (position), RMC (position + velocity), and VTG (velocity/course). The gravitational model determines how altitude values from the NMEA data are interpreted.
| Parameter | Description |
|---|---|
nmeaFilePath | The full absolute path to the NMEA log file (.nmea or .txt). |
trajectoryOptions | Optional configuration for the NMEA trajectory. If null, default options are used
(WGS84 gravitational model, use RMC/VTG ground speed). |
Example:
// Basic usage:
scenario.TrajectoryFromNMEAFile(@"C:\Data\NMEA\drive.nmea");
// Full usage with all options set:
scenario.TrajectoryFromNMEAFile(
@"C:\Data\NMEA\drive.nmea",
new NMEAFileTrajectoryOptions
{
GravitationalModel = GravitationalModel.WGS84,
Options = NmeaTrajectoryOptions.UseRmcVtgGroundSpeed,
});
public void TrajectoryFromVBOXFile(string vboxFilePath, GravitationalModel gravitationalModel = GravitationalModel.WGS84)
| Parameter | Description |
|---|---|
vboxFilePath | The full absolute path to the VBOX data file (.vbo). |
gravitationalModel | The gravitational model (altitude datum) used to interpret altitude values from the VBOX file.
Default is WGS84 (WGS84 ellipsoid height).
Use EGM96 if the VBOX data contains geoid-referenced altitudes. |
Example:
// Basic usage:
scenario.TrajectoryFromVBOXFile(@"C:\Data\VBOX\drive.vbo");
// Full usage with all parameters set:
scenario.TrajectoryFromVBOXFile(
@"C:\Data\VBOX\drive.vbo",
gravitationalModel: GravitationalModel.EGM96);
public void TrajectoryFromCSVFile(string csvFilePath, char delimiter = ',', bool isInRadians = false)
This is a flexible import format that can be used with data exported from various tools and systems. The coordinate format (degrees or radians) and field delimiter can be configured.
| Parameter | Description |
|---|---|
csvFilePath | The full absolute path to the CSV file containing trajectory position data. |
delimiter | The character used to separate fields in the CSV file. Default is a comma (',').
Use '\t' for tab-separated files or ';' for semicolon-separated files. |
isInRadians | Set to true if the latitude and longitude values in the CSV file are in radians.
Set to false (default) if they are in decimal degrees. |
Example:
// Basic usage:
scenario.TrajectoryFromCSVFile(@"C:\Data\CSV\trajectory.csv");
// Full usage with all parameters set:
scenario.TrajectoryFromCSVFile(
@"C:\Data\CSV\trajectory.csv",
delimiter: ';',
isInRadians: true);
Output
public void SetOutputToLabSatFile(string outputDirectory, string outputName, LabSatFileOutputMode outputMode, IReadOnlyList<SignalType> signals, Quantization quantization = Quantization.OneBit)
The output format determines the file structure and is tied to the target LabSat hardware:
LabSat1- Generates a .bin file for LabSat 1 devicesLabSat2- Generates a .ls2 file for LabSat 2 devicesLabSat3- Generates a .ls3 file for LabSat 3 devicesLabSat3WB- Generates a .LS3W file for LabSat 3 Wideband devicesLabSat4- Generates a .LS4 file for LabSat 4 devices
| Parameter | Description |
|---|---|
outputDirectory | The directory where the output should be written. May be absolute (e.g. @"C:\Output")
or relative (resolved against the simulation's working directory). Note that some LabSat
formats create a sub-directory here named after and place
their output files inside it. |
outputName | The base name for the output (without an extension, and without a directory component). The extension appropriate to the selected is added automatically (.bin, .ls2, .ls3, .LS3W, or .LS4); any extension you include here will be stripped. |
outputMode | The LabSat file format to use, which determines the target playback device. |
signals | A list of GNSS signal types to include in the output (e.g. SignalType.GpsL1CA, SignalType.GalE1).
The available signals depend on the selected output mode and quantization level. |
quantization | The bit depth for each signal sample. Higher quantization provides better signal quality but requires
more bandwidth and storage. Default is OneBit. |
NotSupportedException: Thrown if the specified output mode is not supported.Example:
var signals = new[] { SignalType.GpsL1CA, SignalType.GpsL2P };
// Basic usage:
scenario.SetOutputToLabSatFile(
@"C:\SatGen\Output",
"scenario",
LabSatFileOutputMode.LabSat3,
signals);
// Full usage with all parameters set:
scenario.SetOutputToLabSatFile(
@"C:\SatGen\Output",
"scenario",
LabSatFileOutputMode.LabSat4,
signals,
Quantization.TwelveBit);
public void SetOutputToLabSatRealtime(RealTimeOutputMode outputMode, IReadOnlyList<SignalType> signals, Quantization quantization = Quantization.OneBit, LabSatRealtimeOutputOptions? options = null)
Quantization guidance:
- Use 2-bit quantization for single-frequency output (e.g. GPS only, GPS+GAL, BDS only)
- Use 1-bit quantization for dual-frequency output (e.g. GPS+GLO, GPS+BDS, GPS+GAL+GLO)
| Parameter | Description |
|---|---|
outputMode | The timing mode for the real-time output:
|
signals | A list of GNSS signal types to include in the real-time output. |
quantization | The bit depth for each signal sample. Default is OneBit. |
options | Optional configuration for real-time output, including satellite count limiting.
If null, defaults are used (automatic satellite count limiting enabled). |
Example:
var signals = new[] { SignalType.GpsL1CA };
// Basic usage:
scenario.SetOutputToLabSatRealtime(
RealTimeOutputMode.UserTime,
signals);
// Full usage with all parameters and all option properties set:
scenario.SetOutputToLabSatRealtime(
RealTimeOutputMode.UserTime,
signals,
Quantization.TwelveBit,
new LabSatRealtimeOutputOptions
{
SatCountLimitMode = SatCountLimitMode.Automatic,
AutoModeInitialSatsCount = 12,
});
public void SetOutputToLabSat4Realtime(string labSat4IPAddress, RealTimeOutputMode outputMode, IReadOnlyList<SignalType> signals, Quantization quantization = Quantization.OneBit, LabSat4RealtimeOutputOptions? options = null)
| Parameter | Description |
|---|---|
labSat4IPAddress | The IP address of the LabSat 4 RT device on the network (e.g. "192.168.1.100").
Use FindAvailableLabSat4RealTimeDevices to discover available devices. |
outputMode | The timing mode for the real-time output (UserTime, CurrentTime, or NMEATime). |
signals | A list of GNSS signal types to include in the real-time output. |
quantization | The bit depth for each signal sample. Default is OneBit. |
options | Optional configuration for real-time output, including satellite count limiting.
If null, defaults are used. |
Example:
var labSatIPAddress = "192.168.1.100";
var signals = new[] { SignalType.GpsL1CA, SignalType.GpsL2P };
// Basic usage:
scenario.SetOutputToLabSat4Realtime(
labSatIPAddress,
RealTimeOutputMode.UserTime,
signals);
// Full usage with all parameters and all option properties set:
scenario.SetOutputToLabSat4Realtime(
labSatIPAddress,
RealTimeOutputMode.UserTime,
signals,
Quantization.TwelveBit,
new LabSat4RealtimeOutputOptions
{
SatCountLimitMode = SatCountLimitMode.Automatic,
AutoModeInitialSatsCount = 12,
});
public void SetOutputToLabSat4RealtimePlus(string labSat4IPAddress, RealTimeOutputMode outputMode, IReadOnlyList<SignalType> signals, Quantization quantization = Quantization.TwoBit, LabSat4RealtimePlusOutputOptions? options = null)
This overload configures the trajectory input to come from the LabSat device itself over Ethernet. Use the other overload if you need to receive trajectory data over an RS232 serial connection instead.
| Parameter | Description |
|---|---|
labSat4IPAddress | The IP address of the LabSat 4 RT+ device on the network (e.g. "192.168.1.100").
Use FindAvailableLabSat4RealTimeDevices to discover available devices. |
outputMode | The timing mode for the real-time output (UserTime, CurrentTime, or NMEATime). |
signals | A list of GNSS signal types to include in the real-time output. |
quantization | The bit depth for each signal sample. Default is TwoBit for RT+ devices. |
options | Optional configuration for RT+ output, including satellite count limiting and buffer mode.
If null, defaults are used. |
Example:
var labSatIPAddress = "192.168.1.100";
var signals = new[] { SignalType.GpsL1CA, SignalType.GpsL2P };
// Basic usage:
scenario.SetOutputToLabSat4RealtimePlus(
labSatIPAddress,
RealTimeOutputMode.UserTime,
signals);
// Full usage with all parameters and all option properties set:
scenario.SetOutputToLabSat4RealtimePlus(
labSatIPAddress,
RealTimeOutputMode.UserTime,
signals,
Quantization.TwelveBit,
new LabSat4RealtimePlusOutputOptions
{
BufferMode = BufferMode._40ms,
SatCountLimitMode = SatCountLimitMode.Automatic,
AutoModeInitialSatsCount = 12,
});
public void SetOutputToLabSat4RealtimePlus(string labSat4IPAddress, string comPort, int baudRate, RealTimeOutputMode outputMode, IReadOnlyList<SignalType> signals, Quantization quantization = Quantization.TwoBit, LabSat4RealtimePlusOutputOptions? options = null)
Use this when the NMEA position data comes from an external device (e.g. a GNSS receiver) connected to the host computer's serial port, and the LabSat 4 RT+ is used purely for signal output.
| Parameter | Description |
|---|---|
labSat4IPAddress | The IP address of the LabSat 4 RT+ device on the network (e.g. "192.168.1.100"). |
comPort | The COM port name for the RS232 serial input (e.g. "COM3"). This is the port connected to the
device providing live NMEA trajectory data. |
baudRate | The baud rate for the RS232 serial connection (e.g. 4800, 9600, 115200). Must match the sending device's configuration. |
outputMode | The timing mode for the real-time output (UserTime, CurrentTime, or NMEATime). |
signals | A list of GNSS signal types to include in the real-time output. |
quantization | The bit depth for each signal sample. Default is TwoBit for RT+ devices. |
options | Optional configuration for RT+ output, including satellite count limiting and buffer mode.
If null, defaults are used. |
Example:
var labSatIPAddress = "192.168.1.100";
var signals = new[] { SignalType.GpsL1CA, SignalType.GpsL2P };
// Basic usage:
scenario.SetOutputToLabSat4RealtimePlus(
labSatIPAddress,
comPort: "COM3",
baudRate: 115200,
RealTimeOutputMode.UserTime,
signals);
// Full usage with all parameters and all option properties set:
scenario.SetOutputToLabSat4RealtimePlus(
labSatIPAddress,
comPort: "COM3",
baudRate: 115200,
RealTimeOutputMode.UserTime,
signals,
Quantization.TwelveBit,
new LabSat4RealtimePlusOutputOptions
{
BufferMode = BufferMode._40ms,
SatCountLimitMode = SatCountLimitMode.Automatic,
AutoModeInitialSatsCount = 12,
});
public async Task<(string IPAddress, string SerialNumber, bool IsReady)[]> FindAvailableLabSat4RealTimeDevices()
Use the returned IP address with SetOutputToLabSat4Realtime or SetOutputToLabSat4RealtimePlus
to configure the output target. The IsReady flag indicates whether the device is available and not
currently in use by another application.
IPAddress- The network IP address of the discovered deviceSerialNumber- The unique serial number of the deviceIsReady- Whether the device is available for use (not currently running a simulation)
Example:
var devices = await scenario.FindAvailableLabSat4RealTimeDevices();
foreach (var device in devices)
{
Console.WriteLine($"{device.SerialNumber} @ {device.IPAddress} (ready: {device.IsReady})");
}
Timeline
public void AddSatelliteTimelineChange(double elapsedTimeSeconds, ConstellationType constellation, int prn, bool enabled, double attenuationDB = 0)
Multiple changes can be scheduled at the same elapsed time by calling this method repeatedly. If a change for the same constellation/PRN already exists at the same elapsed time, the existing values are overwritten by the new ones.
This method must be called before StartSimulation. Changes added after the simulation
has started will not take effect, because the timeline is snapshotted when the simulation begins.
For reactive control of a running real-time simulation (e.g. responding to user input or external
events), use SetSatelliteEnabled and SetSatelliteSignalGainDB instead.
| Parameter | Description |
|---|---|
elapsedTimeSeconds | The elapsed time (in seconds, from the start of the simulation) at which the change should be applied. Values are rounded to the nearest 0.1 s by the timeline service. |
constellation | The GNSS constellation that the satellite belongs to (e.g. ConstellationType.GPS). |
prn | The PRN (Pseudo-Random Noise) number identifying the satellite within its constellation. Valid range: 1-50. |
enabled | Whether the satellite should be enabled (transmitting) after this change is applied. |
attenuationDB | The signal attenuation in decibels (dB) to apply to the satellite. 0 dB = nominal level, negative values weaken the signal. The value is rounded to the nearest integer internally. |
Example:
// Basic usage - 30 seconds in, disable GPS PRN 7 to simulate a satellite outage:
scenario.AddSatelliteTimelineChange(
elapsedTimeSeconds: 30,
ConstellationType.GPS,
prn: 7,
enabled: false);
// Full usage - 60 seconds in, partially attenuate GPS PRN 12 by 6 dB:
scenario.AddSatelliteTimelineChange(
elapsedTimeSeconds: 60,
ConstellationType.GPS,
prn: 12,
enabled: true,
attenuationDB: -6);
public void ClearSatelliteTimeline()
Example:
scenario.ClearSatelliteTimeline();
Satellite Control
public Satellite[] GetSatellitesInRealTimeSimulation(ConstellationType constellation)
Important: This method can only be called while a real-time simulation is actively running.
Calling it before starting a simulation, during a file-based simulation, or after the simulation
has ended will throw a NotSupportedException.
Use this to inspect which satellites are currently visible and their signal levels, for example to identify satellites that could be disabled or attenuated for interference testing.
| Parameter | Description |
|---|---|
constellation | The GNSS constellation to query (e.g. ConstellationType.GPS, ConstellationType.Galileo,
ConstellationType.GLONASS, ConstellationType.BeiDou). |
Satellite objects representing all visible satellites for the specified constellation.
Each satellite includes its constellation type, PRN number, enabled/disabled state, and current attenuation in dB.NotSupportedException: Thrown if a LabSat Real-Time simulation is not currently running.Example:
var gpsSats = scenario.GetSatellitesInRealTimeSimulation(ConstellationType.GPS);
public void SetSatelliteSignalGainDB(ConstellationType constellation, int prn, double signalGainDB)
The gain value is applied relative to the original (nominal) signal level. A value of 0 dB means no change. Negative values attenuate the signal (weaker), and the value is rounded to the nearest integer and clamped to the valid range internally.
Important: This method can only be called while a real-time simulation is actively running.
Use this for reactive, real-time control (e.g. responding to user input or external events). For changes
that should occur at known points in the simulation, use AddSatelliteTimelineChange instead -
timeline changes also work with file-based output.
| Parameter | Description |
|---|---|
constellation | The GNSS constellation the satellite belongs to (e.g. ConstellationType.GPS). |
prn | The PRN (Pseudo-Random Noise) number identifying the satellite. Valid range: 1-50. |
signalGainDB | The signal gain adjustment in decibels (dB). 0 dB = original level, negative values = attenuated. |
NotSupportedException: Thrown if a LabSat Real-Time simulation is not currently running.Example:
// Attenuate GPS satellite PRN 5 by 10 dB
scenario.SetSatelliteSignalGainDB(ConstellationType.GPS, prn: 5, signalGainDB: -10);
public void SetSatelliteEnabled(ConstellationType constellation, int prn, bool enabled)
Restriction: Satellites cannot be manually enabled when Automatic is active,
as the automatic algorithm manages satellite availability to prevent CPU overload. You can still disable satellites
in automatic mode, but enabling them requires switching to None or
Manual.
Important: This method can only be called while a real-time simulation is actively running.
Use this for reactive, real-time control (e.g. responding to user input or external events). For changes
that should occur at known points in the simulation, use AddSatelliteTimelineChange instead -
timeline changes also work with file-based output and are not blocked by Automatic.
| Parameter | Description |
|---|---|
constellation | The GNSS constellation the satellite belongs to (e.g. ConstellationType.GPS). |
prn | The PRN (Pseudo-Random Noise) number identifying the satellite. Valid range: 1-50. |
enabled | Set to true to enable the satellite, or false to disable it. |
NotSupportedException: Thrown if a LabSat Real-Time simulation is not currently running, or if attempting to enable a satellite
while Automatic is active.Example:
// Disable GPS satellite PRN 12
scenario.SetSatelliteEnabled(ConstellationType.GPS, prn: 12, enabled: false);
public bool SetLabSat4ChannelAttenuation(LabSat4Channel channel, int attenuation)
Important: A LabSat 4 RT or RT+ simulation must be actively running. Calling this method when no
simulation is running, or when the active output is not a LabSat 4 RT/RT+ device, will throw a
NotSupportedException.
| Parameter | Description |
|---|---|
channel | The LabSat 4 output channel to adjust. The channel must be active in the current channel plan. |
attenuation | The signal level in dB. Valid range: -69 to +20 (matching the LabSat 4 front panel range). Values outside this range are clamped by the device. |
true if the device accepted the change, false if the underlying replayer rejected it (e.g. the channel is not active).NotSupportedException: Thrown if a LabSat 4 RT or RT+ simulation is not currently running.Example:
scenario.SetLabSat4ChannelAttenuation(LabSat4Channel.A, attenuation: 6);
Simulation
public void StartSimulation()
Before calling this method, you must have:
- Set a trajectory (e.g.
TrajectoryFromStaticPoint,TrajectoryFromRoute, etc.) unless a real-time input source is in use - Configured the output (e.g.
SetOutputToLabSatFile,SetOutputToLabSatRealtime, etc.)
After starting the simulation, you can monitor progress in two ways:
- Call
MonitorSimulationProgressto block and receive periodic updates (recommended for console applications) - Poll the
IsRunning,SimulationPercentComplete,SimulationSecondsFromStart, andSimulationErrorproperties manually - Subscribe to the
SimulationStatusChangedevent for push-style updates (recommended for GUI applications)
- Configures the input parameters based on the selected input mode (SatGen, LabSat, or RS232)
- Sets up the active input source for trajectory data
- Subscribes to output events for progress, errors, and completion notifications
- Downloads any required almanac updates (if auto-almanac mode is enabled)
- Starts the output engine, which begins generating signal data
Example:
scenario.StartSimulation();
public void MonitorSimulationProgress(TimeSpan interval, Action? onInterval = null)
EndSimulation.
The method handles different input modes:
- User-defined trajectory: Waits up to 90 seconds for the simulation to reach the running state before timing out
- real-time trajectory input: Displays a waiting message while the simulation is in the ready state, then monitors once data starts flowing
An optional callback action can be provided to execute custom logic at each polling interval (e.g. logging progress, adjusting satellite levels, or checking external conditions).
| Parameter | Description |
|---|---|
interval | The time interval between progress updates. For example, TimeSpan.FromSeconds(1) to check every second.
Shorter intervals provide more responsive monitoring but consume more CPU. |
onInterval | An optional callback action that is invoked at each polling interval while the simulation is running.
Use this to perform custom per-interval logic such as logging SimulationPercentComplete,
adjusting satellite signal levels, or checking external stop conditions. Can be null. |
Example:
// Basic usage:
scenario.MonitorSimulationProgress(TimeSpan.FromSeconds(1));
// Full usage with a progress callback:
scenario.MonitorSimulationProgress(TimeSpan.FromSeconds(1), () =>
{
if (scenario.IsRunning)
{
Console.Write($"\r{scenario.SimulationPercentComplete:F1}% underruns: {scenario.BufferUnderrunCount} ");
}
});
public void EndSimulation()
Scenario instance is disposed and cannot be reused. Create a new Scenario
instance to run another simulation.
For file-based simulations, any partially written output file will remain on disk up to the point the simulation was stopped. For real-time simulations, signal output ceases immediately.
Example:
scenario.EndSimulation();
public string GetSimulationSummary()
Example:
Console.WriteLine(scenario.GetSimulationSummary());
public string GetChannelPlan()
SatGen may automatically reduce quantization when the requested signal configuration exceeds the bandwidth constraints of the selected output device. This method reflects any such adjustments.
Example:
Console.WriteLine(scenario.GetChannelPlan());
Enumerations
The following enumerations are used to configure various aspects of the API.
but
ConstellationType
| Member | Description |
|---|---|
Gps | The GPS constellation (United States). |
Glonass | The GLONASS constellation (Russia). |
BeiDou | The BeiDou (BDS) constellation (China). |
Galileo | The Galileo constellation (European Union). |
Navic | The NavIC (IRNSS) constellation (India). |
Sbas | The SBAS (Satellite-Based Augmentation System) constellation. |
Dynamics
The dynamics profile controls how the vehicle moves along a route trajectory. For example, a Car
profile will limit the vehicle to normal road speeds with moderate cornering forces, while a RaceCar
profile allows much higher speeds and lateral forces typical of motorsport testing.
For full control over individual motion parameters, use SetCustomDynamics with a
CustomDynamicsOptions instance instead.
| Member | Description |
|---|---|
Car | Standard car dynamics. Suitable for simulating normal road driving with moderate speeds, comfortable acceleration/braking, and typical cornering forces. This is the most commonly used profile for automotive GNSS receiver testing. |
RaceCar | Race car dynamics. Simulates high-performance motorsport driving with high top speeds, aggressive acceleration and braking, and high lateral g-forces during cornering. Use this for testing GNSS receivers under extreme dynamic conditions. |
Train | Train dynamics. Simulates railway vehicle motion with constrained lateral movement, gentle acceleration and deceleration profiles, and moderate top speeds. Suitable for rail-based positioning system testing. |
Pedestrian | Pedestrian dynamics. Simulates walking-speed movement with very low acceleration limits and low maximum velocity. Suitable for testing personal navigation devices and pedestrian tracking applications. |
GravitationalModel
| Member | Description |
|---|---|
WGS84 | WGS84 ellipsoid. Altitudes are interpreted as height above the WGS84 reference ellipsoid. |
EGM84 | EGM84 geoid over WGS84 ellipsoid. |
EGM96 | EGM96 geoid over WGS84 ellipsoid (mean sea level approximation). |
EGM2008 | EGM2008 geoid over WGS84 ellipsoid. |
NMEA | Use the geoid separation reported in the NMEA file itself. |
InputConnectionStatus
InputConnectionStatus property and indicates
whether the external device providing live NMEA trajectory data is actively sending data.
This enum is only relevant when using a LabSat or RS232 serial input for real-time trajectory data.
For simulations using SatGen's built-in trajectory generation (static point, route, KML, NMEA file, etc.),
the status will always be None.
| Member | Description |
|---|---|
None | No external input source is being used, or the input source does not have a connection status. This is the default status for simulations that use SatGen-generated trajectories. |
Connected | The external input source is connected and actively sending trajectory data to the simulation. The simulation is receiving and processing NMEA position updates from the input device. |
Disconnected | The external input source has stopped sending data. This may indicate a cable disconnection, the sending device has been powered off, or a communication failure. The simulation will continue running but will not receive updated trajectory data until the connection is restored. |
LabSat4Channel
SetLabSat4ChannelAttenuation. The available channels correspond to the
physical RF outputs on the LabSat 4 unit; the number of usable channels for a given simulation
depends on the signal selection and quantization (see the LabSat 4 channel plan documentation).| Member | Description |
|---|---|
A | Channel A. |
B | Channel B. |
C | Channel C. |
LabSatFileOutputMode
SetOutputToLabSatFile.
Each format corresponds to a specific LabSat hardware model and determines the file structure, extension, and
supported signal/quantization combinations.
The generated file can be loaded onto the corresponding LabSat device for playback, which will broadcast the simulated GNSS signals via its RF output for testing GNSS receivers.
| Member | Description |
|---|---|
LabSat1 | LabSat 1 file format (.bin). Supports a single GNSS frequency band with 1-bit or 2-bit quantization. Compatible with LabSat 1 hardware for playback. |
LabSat2 | LabSat 2 file format (.ls2). Supports a single GNSS frequency band with 1-bit or 2-bit quantization. Compatible with LabSat 2 hardware for playback. |
LabSat3 | LabSat 3 file format (.ls3). Supports up to three GNSS frequency bands with 1-bit or 2-bit quantization. Compatible with LabSat 3 hardware for playback. This is the most commonly used file format. |
LabSat4 | LabSat 4 file format (.LS4). Supports the full LabSat 4 channel and signal capabilities for offline recording. Compatible with LabSat 4 hardware for playback. |
LabSat3WB | LabSat 3 Wideband file format (.LS3W). Supports wideband signal recording with up to 3-bit quantization and higher bandwidth per channel. Compatible with LabSat 3 Wideband hardware for playback. Required for wideband signals such as GPS L5 or Galileo E5. |
NmeaTrajectoryOptions
| Member | Description |
|---|---|
None | Default behaviour. Speed is derived from successive position fixes. |
UseRmcVtgGroundSpeed | Read the ground speed from RMC or VTG sentences (where present) and use that speed instead of the position-derived value. This typically reduces velocity noise in the simulated trajectory. |
OutputDataRate
Used with OutputDataRate when creating trajectories via
TrajectoryFromScript.
| Member | Description |
|---|---|
_1Hz | 1 position update per second. Lowest resolution, suitable for slow-moving or static scenarios. |
_2Hz | 2 position updates per second. |
_4Hz | 4 position updates per second. |
_5Hz | 5 position updates per second. |
_10Hz | 10 position updates per second. Default rate - provides a good balance between resolution and performance. |
_20Hz | 20 position updates per second. Suitable for moderate-speed vehicle testing. |
_25Hz | 25 position updates per second. |
_50Hz | 50 position updates per second. Suitable for high-speed vehicle testing with fine trajectory detail. |
_100Hz | 100 position updates per second. Highest resolution, suitable for high-dynamics motorsport or aerospace scenarios. |
Quantization
The choice of quantization depends on the target LabSat hardware and the desired signal fidelity. Higher bit depths produce more accurate signals but increase the data rate, which may limit the number of simultaneous signals or constellations that can be simulated:
OneBit- Lowest fidelity, but allows the maximum number of simultaneous signalsTwoBit- Standard quality, recommended for most testing scenariosThreeBit- Enhanced quality for LabSat 3 Wideband devicesFourBittoTwelveBit- High-fidelity modes for LabSat 4 devices
| Member | Description |
|---|---|
OneBit | 1-bit quantization. Each sample is represented by a single bit indicating positive or negative.
For LabSat 2 and LabSat 3: 1 = value is greater than 0.0, 0 = value is zero or negative. For LabSat 3 Wideband: 0 = value is greater than 0.0, 1 = value is zero or negative (inverted logic). Provides the lowest data rate, allowing the maximum number of simultaneous signals. Use 1-bit quantization for multi-frequency/multi-constellation output on LabSat RT devices. |
TwoBit | 2-bit quantization. Each sample is represented by 2 bits providing sign and magnitude information.
For LabSat 2 and LabSat 3: Uses "Unsigned Binary" format where the MSB represents the sign (1 = positive, 0 = zero/negative) and the LSB represents the magnitude relative to the signal range centre. For LabSat 3 Wideband: Uses "Two's Complement" format where the MSB represents the sign (0 = positive, 1 = zero/negative) and the LSB represents the magnitude. Recommended for single-frequency output on LabSat RT devices. Default for LabSat 4 RT+ devices. |
ThreeBit | 3-bit quantization. Each sample uses 3 bits in Two's Complement format (LabSat 3 Wideband only). The MSB represents the sign (0 = positive, 1 = zero/negative) and the two LSBs represent the magnitude. Provides improved signal fidelity over 2-bit for wideband signal simulations. |
FourBit | 4-bit quantization. Available on LabSat 4 devices. Provides enhanced signal resolution with 16 discrete amplitude levels per sample, enabling more accurate signal representation for receiver testing. |
EightBit | 8-bit quantization. Available on LabSat 4 devices. Provides high-fidelity signal representation with 256 discrete amplitude levels per sample. Suitable for advanced receiver testing requiring precise signal level control and realistic noise floor modelling. |
TwelveBit | 12-bit quantization. Available on LabSat 4 devices. Provides the highest signal fidelity with 4096 discrete amplitude levels per sample. Use this for laboratory-grade testing where maximum signal accuracy is required, at the cost of the highest data rate. |
RealTimeOutputMode
The time mode is specified when configuring a real-time output target using
SetOutputToLabSatRealtime, SetOutputToLabSat4Realtime,
or SetOutputToLabSat4RealtimePlus.
| Member | Description |
|---|---|
UserTime | Uses the user-defined simulation start time (specified in the Scenario constructor) as the
time reference for satellite positions and signal timing. The simulation runs in real-time from this
specified start point. This is the most common mode for controlled, repeatable testing. |
CurrentTime | Uses the current system clock (real-world wall-clock time) as the time reference. Satellite positions are calculated based on the actual current time, producing signals that match what a real receiver would see at this moment. Useful for live testing where time-accurate satellite positions are needed. |
NMEATime | Uses the user-defined simulation date combined with the time extracted from the incoming NMEA data stream. The date comes from the scenario's start time, but the time-of-day advances based on the NMEA sentences received from the external input source. This mode is only applicable when using a LabSat or RS232 external input source for trajectory data. |
RoutingMode
TrajectoryFromRoute.| Member | Description |
|---|---|
StraightLine | A direct, point-to-point straight line between two waypoints. |
Road | A route that follows mapped roads between waypoints. |
Rail | A route that follows mapped railway lines between waypoints. |
Walking | A route that follows mapped walking paths between waypoints. |
Custom | A custom route defined manually by an explicit set of positions. |
SatCountLimitMode
Configure this via SatCountLimitMode when setting up
a real-time output with SetOutputToLabSatRealtime,
SetOutputToLabSat4Realtime, or SetOutputToLabSat4RealtimePlus.
| Member | Description |
|---|---|
None | No limits are imposed on the number of simulated satellites. All visible satellites will be simulated regardless of CPU load. Use this only when you are confident that the host computer has sufficient processing power, or when the full satellite constellation is required for testing. |
Automatic | The system automatically manages the satellite count to prevent CPU overload. It starts with the
initial count (configured via AutoModeInitialSatsCount)
and automatically reduces the number of simulated satellites each time a buffer underrun occurs.
This is the recommended mode for most real-time simulations as it self-tunes to the host computer's capability. |
Manual | The user manually selects which satellites are simulated using SetSatelliteEnabled.
No automatic adjustment is performed. This gives full control over the satellite constellation but
requires the user to manage CPU load manually by enabling/disabling individual satellites. |
SignalType
Each output method (SetOutputToLabSatFile, SetOutputToLabSatRealtime,
SetOutputToLabSat4Realtime, SetOutputToLabSat4RealtimePlus)
takes a list of SignalType values to determine which signals are generated. Each enabled
signal adds CPU load, so only enable the signals required by the receiver under test.
| Member | Description |
|---|---|
GpsL1CA | The GPS L1 C/A civilian signal. |
GpsL1C | The GPS L1 C civilian signal. |
GpsL1P | The GPS L1 P military signal (using the public unencrypted P-Code). |
GpsL1M | The GPS L1 M military signal (SatGen generates just noise with spectral characteristics matching the real L1M signal). |
GpsL2C | The GPS L2 C civilian signal. |
GpsL2P | The GPS L2 P military signal (using the public unencrypted P-Code). |
GpsL2M | The GPS L2 M military signal (SatGen generates just noise with spectral characteristics matching the real L2M signal). |
GpsL5 | The GPS L5 (I+Q) civilian signal. |
GlonassL1OF | The GLONASS L1 OF civilian signal (FDMA). |
GlonassL2OF | The GLONASS L2 OF civilian signal (FDMA). |
BeiDouB1I | The BeiDou B1I civilian signal. |
BeiDouB2I | The BeiDou B2I civilian signal. |
BeiDouB3I | The BeiDou B3I civilian signal. |
BeiDouB1C | The BeiDou B1C civilian signal (data + pilot). |
BeiDouB2a | The BeiDou B2a civilian signal (data + pilot). |
BeiDouB2bI | The BeiDou B2b I civilian signal. |
GalileoE1BC | The composite Galileo E1B/E1C (data + pilot) civilian signal. |
GalileoE5a | The Galileo E5a civilian signal (data + pilot). |
GalileoE5b | The Galileo E5b civilian signal (data + pilot). |
GalileoE6BC | The Galileo E6B/E6C (data + pilot) commercial signal. |
NavicL5SPS | The NavIC L5 SPS civilian signal. |
NavicSSPS | The NavIC S-band SPS civilian signal. |
SbasL1 | The SBAS L1 civilian signal. |
SimulationStatus
CurrentStatus
property and carried in SimulationStatusEventArgs when the
SimulationStatusChanged event fires.| Member | Description |
|---|---|
Running | The simulation has not yet been started, or is currently running.
SimulationStatusChanged fires with this status periodically as the simulation
progresses; consumers typically use these events to update progress displays. |
Completed | The simulation finished successfully and produced its full output. When the
SimulationStatusChanged event fires with this status,
SimulationPercentComplete is guaranteed to be exactly
100.0. After this event fires the consumer should unsubscribe and call
EndSimulation. This status will not be reported if the simulation was
stopped manually via EndSimulation before reaching the natural end. |
Failed | The simulation stopped due to an error. The error message is provided in
ErrorMessage (and also in the
SimulationError property). After this event fires the simulation cannot
continue; the consumer should unsubscribe and call EndSimulation. |
Parameter Classes
These classes are used to provide optional configuration when calling API methods.
BaseLabSatOutputOptions
The input mode determines where the simulation receives its trajectory data from:
- SatGen (default) - Trajectory is generated by SatGen from a static point, route, or imported file
- LabSat - Trajectory comes from the LabSat device itself over Ethernet (RT+ only)
- RS232 - Trajectory comes from an external GNSS receiver via RS232 serial port (RT+ only)
BaseLabSatRealtimeOutputOptions
Inherits from: BaseLabSatOutputOptions
Real-time simulations are more CPU-intensive than file-based output because the signal data must be generated and streamed at the exact rate the LabSat hardware requires. If the host computer cannot keep up, buffer underruns occur, causing brief gaps in the output signal.
| Property | Type | Description |
|---|---|---|
SatCountLimitMode | SatCountLimitMode | Gets or sets the satellite count limiting strategy used to manage CPU load during the simulation.
|
AutoModeInitialSatsCount | int | Gets or sets the initial maximum number of satellites to simulate when SatCountLimitMode
is set to Automatic. The actual number of satellites simulated will
be reduced each time the host machine is unable to keep up (i.e. on each buffer underrun).
Set this to 999 (default) to start with no initial limit, allowing the automatic algorithm to find the optimal satellite count for your hardware. Set to a lower value (e.g. 12) to start with a conservative limit if you know your hardware has limited processing capacity. Default value: 999 (effectively unlimited - all visible satellites are simulated initially). |
CustomDynamicsOptions
SetCustomDynamics.
These parameters control the maximum speed, acceleration, deceleration, lateral forces, and jerk limits
of the simulated vehicle when following a route trajectory.
Use this when the pre-defined dynamics profiles (Dynamics) do not match your
specific testing requirements. All nine parameters must be provided to fully define the vehicle's motion capabilities.
Units:
- Velocity: kilometres per hour (km/h)
- Acceleration: g-force (g), where 1g = 9.81 m/s^2
- Jerk: g per second (g/s) - the rate of change of acceleration
public CustomDynamicsOptions(double horizontalVelocity, double longitudinalAcceleration, double longitudinalDeceleration, double lateralAcceleration, double verticalAcceleration, double longitudinalAccelerationJerk, double longitudinalDecelerationJerk, double lateralJerk, double verticalJerk)
| Parameter | Description |
|---|---|
horizontalVelocity | The maximum horizontal velocity in kilometres per hour (km/h). This is the top speed the simulated vehicle can reach on a straight road. |
longitudinalAcceleration | The maximum forward acceleration in g-force units (g). Controls how quickly the vehicle can speed up. |
longitudinalDeceleration | The maximum braking deceleration in g-force units (g). Controls how quickly the vehicle can slow down. |
lateralAcceleration | The maximum lateral (cornering) acceleration in g-force units (g). Controls how aggressively the vehicle can corner. |
verticalAcceleration | The maximum vertical acceleration in g-force units (g). Controls altitude change rate for 3D trajectories. |
longitudinalAccelerationJerk | The rate of change of forward acceleration in g per second (g/s). Controls the smoothness of acceleration onset. |
longitudinalDecelerationJerk | The rate of change of braking deceleration in g per second (g/s). Controls the smoothness of braking onset. |
lateralJerk | The rate of change of lateral acceleration in g per second (g/s). Controls the smoothness of cornering transitions. |
verticalJerk | The rate of change of vertical acceleration in g per second (g/s). Controls the smoothness of altitude change transitions. |
KMLTrajectoryOptions
TrajectoryFromKMLFile. KML files are commonly created using Google Earth
or other mapping tools to define geographic paths and routes.
These options control how the KML data is interpreted and processed into a SatGen trajectory, including route repetition, height interpretation, vehicle speed, and cornering behaviour.
public KMLTrajectoryOptions()
| Property | Type | Description |
|---|---|---|
RepeatCount | int | Gets or sets the number of times the KML route should be repeated after the initial traversal.
A value of 0 means the route is driven once (no repeats). A value of 1 means the route is driven twice, etc.
Useful for creating longer simulations from a short route, for example driving around a test track multiple times. The vehicle will seamlessly transition from the end of the route back to the start. Default value: 0 (no repeats - the route is driven once). |
UseHeightAsStopTime | bool | Gets or sets a value indicating whether the altitude/height value for each KML coordinate should be
interpreted as a stop time (delay in seconds) at that position rather than an actual altitude.
When set to When set to false (height values represent altitude in metres). |
TargetSpeedKilometersPerHour | double | Gets or sets the target speed in kilometres per hour (km/h) for the simulated vehicle along the KML route. The actual speed achieved depends on the configured dynamics profile, which imposes acceleration, deceleration, and cornering limits. Default value: 100 km/h. |
ApexDistanceLimitMetres | double | Gets or sets the maximum allowed distance in metres between each route position and the apex of the
curve when the vehicle rounds a corner. Smaller values produce tighter corners; larger values produce
smoother, wider curves. See ApexDistanceLimitMetres for more detail. Default value: 10 metres. |
LabSat4RealtimeOutputOptions
Inherits from: BaseLabSatRealtimeOutputOptions
SetOutputToLabSat4Realtime.
The LabSat 4 RT connects over Ethernet and supports higher bandwidth configurations than earlier models.
This class inherits all real-time output settings from BaseLabSatRealtimeOutputOptions,
including satellite count limiting options. It exists as a dedicated type to allow LabSat 4-specific
options to be added in future API versions.
public LabSat4RealtimeOutputOptions()
BaseLabSatRealtimeOutputOptions (automatic satellite count limiting enabled).LabSat4RealtimePlusOutputOptions
Inherits from: LabSat4RealtimeOutputOptions
SetOutputToLabSat4RealtimePlus.
The LabSat 4 RT+ extends the standard RT with support for real-time trajectory input, allowing the simulation
to follow a live position feed from an external source (LabSat Ethernet or RS232 serial).
Inherits all LabSat 4 RT options from LabSat4RealtimeOutputOptions (and satellite count limiting
from LabSatRealtimeOutputOptions in turn), and adds a BufferMode setting that
controls the output buffering strategy.
public LabSat4RealtimePlusOutputOptions()
| Property | Type | Description |
|---|---|---|
BufferMode | BufferMode | Gets or sets the output buffer mode for the LabSat 4 RT+ device. The buffer mode controls the size
of the signal data buffer used between the simulation engine and the LabSat hardware.
A larger buffer provides more resilience against brief CPU load spikes but introduces additional latency between trajectory changes and the corresponding signal output. A smaller buffer reduces latency but is more sensitive to CPU load variations. Default value:_40ms (40 milliseconds of buffered data). |
LabSatFileOutputOptions
Inherits from: BaseLabSatOutputOptions
SetOutputToLabSatFile.
This class currently inherits all settings from BaseLabSatOutputOptions without adding
any file-specific options. It exists as a dedicated type to allow file-specific options to be added
in future API versions without breaking the existing method signatures.
public LabSatFileOutputOptions()
LabSatRealtimeOutputOptions
Inherits from: BaseLabSatRealtimeOutputOptions
SetOutputToLabSatRealtime.
Extends the base output options with real-time-specific settings for managing satellite count limits
to prevent CPU overload during live signal generation.
This class inherits all real-time output settings from BaseLabSatRealtimeOutputOptions,
including satellite count limiting options. It exists as a dedicated type to allow LabSat-specific
options to be added in future API versions.
public LabSatRealtimeOutputOptions()
BaseLabSatRealtimeOutputOptions (automatic satellite count limiting enabled).NMEAFileTrajectoryOptions
TrajectoryFromNMEAFile.
NMEA files contain standardised position and velocity sentences logged from a real GNSS receiver.
These options control how the NMEA data is interpreted, including the altitude datum (gravitational model) and which NMEA sentence types are used for speed information.
public NMEAFileTrajectoryOptions()
| Property | Type | Description |
|---|---|---|
GravitationalModel | GravitationalModel | Gets or sets the gravitational model (altitude datum) used to interpret altitude values from the NMEA data.
WGS84 (WGS84 ellipsoid height). |
Options | NmeaTrajectoryOptions | Gets or sets the NMEA trajectory processing options, which control how speed and course information
is extracted from the NMEA sentences.
The default option ( UseRmcVtgGroundSpeed. |
RouteWaypoint
TrajectoryFromRoute to define
a multi-point route that the simulation engine will follow.
Each waypoint specifies a location (latitude, longitude, altitude) and optional driving parameters that control how the simulated vehicle approaches and rounds the corner at this point:
TargetSpeedKilometersPerHour- The desired speed when approaching this waypointApexDistanceLimitMetres- How tightly the vehicle should corner at this point
public RouteWaypoint(double latitudeDecDegrees, double longitudeDecDegrees, double altitudeMetres)
| Parameter | Description |
|---|---|
latitudeDecDegrees | The latitude of the waypoint in decimal degrees (e.g. 51.5074 for London). Valid range: -90.0 to 90.0. |
longitudeDecDegrees | The longitude of the waypoint in decimal degrees (e.g. -0.1278 for London). Valid range: -180.0 to 180.0. |
altitudeMetres | The altitude of the waypoint above the WGS84 ellipsoid in metres (e.g. 0.0 for sea level). |
| Property | Type | Description |
|---|---|---|
TargetSpeedKilometersPerHour | double | Gets or sets the target speed in kilometres per hour (km/h) that the simulated vehicle should aim to
reach when travelling towards this waypoint. The actual speed achieved depends on the configured
dynamics profile (SetDynamics or SetCustomDynamics),
which imposes acceleration and deceleration limits. Default value: 100 km/h. |
ApexDistanceLimitMetres | double | Gets or sets the maximum allowed distance in metres between this waypoint and the apex of the curve
when the simulated vehicle rounds the corner at this point. A smaller value produces tighter corners
(closer to the waypoint) while a larger value allows the vehicle to take a wider, smoother line.
This parameter controls the trade-off between route accuracy (staying close to the defined waypoints) and driving realism (smooth, natural cornering). For sharp turns at intersections, use a smaller value (e.g. 5m). For highway curves, a larger value (e.g. 50m) produces more natural results. Default value: 10 metres. |
Satellite
Instances of this class are returned by GetSatellitesInRealTimeSimulation and represent
a snapshot of the satellite's state at the time of the call. The satellite's enabled state can be modified
using SetSatelliteEnabled, and its signal gain can be adjusted using
SetSatelliteSignalGainDB.
| Property | Type | Description |
|---|---|---|
Constellation | ConstellationType | Gets the GNSS constellation that this satellite belongs to (e.g. GPS, Galileo, GLONASS, BeiDou, QZSS, NavIC/IRNSS, SBAS). |
Prn | int | Gets the PRN (Pseudo-Random Noise) number that uniquely identifies this satellite within its constellation.
For GPS, this is the SVN/PRN number (1-32). For GLONASS, this is the slot number. For Galileo and BeiDou, this is the satellite vehicle number. Valid range: 1-50. |
Enabled | bool | Gets a value indicating whether this satellite is currently enabled in the simulation.
Enabled satellites contribute GNSS signals to the output; disabled satellites are excluded.
Use |
Attenuation | double | Gets the current signal attenuation level of this satellite in decibels (dB).
A value of 0 dB represents the nominal (full-strength) signal level. Negative values indicate
the signal has been attenuated (weakened).
Use |
ScenarioParams
Scenario instance,
including the simulation start time, signal attenuation level, and satellite elevation mask.
Note: This class is from an earlier API version. The current Scenario
constructor accepts these parameters directly rather than through this class.
public ScenarioParams(DateTime startUTCDateTime)
| Parameter | Description |
|---|---|
startUTCDateTime | The UTC date and time at which the simulation should begin. This determines the satellite constellation positions via almanac data. Sub-second precision will be truncated when applied to the scenario. |
| Property | Type | Description |
|---|---|---|
AttenuationDB | double | Gets or sets the global signal attenuation level in decibels (dB), which adds artificial noise
to the simulated GNSS signals to model real-world signal degradation.
A value of 0.0 disables attenuation entirely (clean signal). More negative values apply stronger attenuation, producing a weaker, noisier signal that better represents real-world conditions. Valid range: -15.0 to 0.0 dB. Default value: -3.0 dB (provides a realistic noise floor for most testing scenarios). |
ElevationMaskDeg | double | Gets or sets the elevation mask angle in degrees. Satellites below this angle relative to the
horizon at the simulated position will be excluded from the simulation.
Low-elevation satellites typically have weaker, more distorted signals due to longer atmospheric path lengths. Setting an appropriate elevation mask improves simulation realism by excluding satellites that a real receiver would struggle to track. Valid range: -90 to 90 degrees. Default value: 5 degrees (excludes satellites within 5 degrees of the horizon). |
ScriptTrajectoryOptions
TrajectoryFromScript.
Scripts define complex trajectories using the SatGen scripting language, which supports commands for straight-line motion, turns, altitude changes, and speed profiles. This options class allows you to configure how the trajectory is generated from the parsed script.
public ScriptTrajectoryOptions()
| Property | Type | Description |
|---|---|---|
OutputDataRate | OutputDataRate | Gets or sets the output data rate for the generated trajectory. This determines how many position
samples per second are calculated from the script commands. Higher rates produce smoother trajectories
with finer time resolution, but require more processing.
For most testing scenarios, the default of 10 Hz provides sufficient resolution. Increase to 50 Hz or 100 Hz for high-dynamics scenarios (e.g. motorsport or aerospace) where sub-100ms position changes are significant. Default value:_10Hz (10 position samples per second). |
SimulationStatusEventArgs
Inherits from: EventArgs
SimulationStatusChanged event. Provides a snapshot
of the simulation's progress and lifecycle status at the moment the event was raised.
The same event args type is used for all status transitions; the Status property
indicates which transition occurred:
Running- fires periodically as the simulation progresses.Completed- fires once when the simulation finishes naturally;SimulationPercentCompleteis guaranteed to be exactly100.0.Failed- fires once when an error stops the simulation;ErrorMessagecontains a description of the error.
| Property | Type | Description |
|---|---|---|
Status | SimulationStatus | The current lifecycle status of the simulation at the moment the event was raised. |
SimulationTimeFromStart | TimeSpan | How far the simulation has progressed from its start time, measured in simulated (not wall-clock) time. For file-based simulations this can advance faster than real time. |
SimulatedDateTime | DateTime | The UTC date/time currently being simulated. Equivalent to
SimulationStartTime + SimulationTimeFromStart. |
SimulationPercentComplete | double | Completion percentage of the simulation, from 0.0 to 100.0. When Status is
Completed this value is exactly 100.0; for
Failed it carries the last known progress at the time of error. |
ErrorMessage | string | A human-readable description of the error that stopped the simulation, populated only when
Status is Failed. For other statuses this is
Empty. |
Complete Example
Below is a complete working example demonstrating a full integration.
// ===================================================================================================
// SatGen 4 API Code Sample
// ===================================================================================================
// A starting point for integrating the SatGen Scenario API into your own application. The code below
// demonstrates the minimal steps required to configure and run a GNSS simulation: the active calls
// produce a static-point trajectory streamed in real time to a LabSat 4, but every section can be
// swapped for one of the alternatives described in the comments.
//
// For the full list of methods, parameters, and supported values, see API-Documentation.html
// (generated alongside this sample on build).
//
// Prerequisites:
// - SatGen 4 must be installed (the API DLLs are loaded from the SatGen 4 install directory)
// - A valid SatGen 4 licence must be available (hardware dongle)
// - For real-time output only: a LabSat Real-Time or LabSat 4 device connected and accessible
// (file output does not require any LabSat hardware)
//
// Startup parameters (optional):
// SatGen4APICodeSamples.exe [LabSat4IPAddress] [SimulationDateTime]
// Example: SatGen4APICodeSamples.exe 192.168.1.100 "01 Jan 2026 12:00:00"
// ===================================================================================================
using SatGen.ScenarioAPI;
internal static class Program
{
private static void Main(string[] args)
{
// -- CONFIGURATION -----------------------------------------------------------------------
// Default LabSat 4 IP address - change this to match your device, or pass as a startup parameter.
var labSatIPAddress = "192.168.1.100";
// Simulation start date/time in UTC. Satellite constellation positions are calculated from this
// time, so use a recent date for realistic satellite geometry. Sub-second precision is discarded.
var simulationDateTime = new DateTime(2026, 01, 01, 12, 00, 00);
// Allow overriding configuration via startup parameters
if (args.Length >= 1)
{
labSatIPAddress = args[0];
}
if (args.Length >= 2 && DateTime.TryParse(args[1], out var startupParamSimulationDateTime))
{
simulationDateTime = startupParamSimulationDateTime;
}
try
{
// -- SCENARIO CREATION ---------------------------------------------------------------
// The Scenario is the root object representing a simulation run. Its constructor takes
// the simulation start time and an optional attenuationDB value, which adds artificial
// noise to the output signal (equivalent to the 'Attenuation' box on the Output tab in
// SatGen 4; typical values range from -10 to 0 dB).
using var scenario = new Scenario(simulationDateTime, attenuationDB: -3);
// -- ALMANACS (optional) -------------------------------------------------------------
// By default the API downloads the latest almanac for each constellation from the
// Racelogic almanac server. If you need to reproduce a known scenario or work offline,
// a local almanac file can be supplied per constellation via ManualAlmanacFile().
// -- SIGNALS -------------------------------------------------------------------------
// Defines which GNSS signals are simulated. Each enabled signal adds CPU load, so only
// enable what your receiver under test requires. See API-Documentation.html (SignalType)
// for the full list of supported signals across all constellations.
var signals = new[]
{
SignalType.GpsL1CA,
SignalType.GpsL2C,
};
// -- DYNAMICS (optional) -------------------------------------------------------------
// The dynamics profile constrains how the simulated vehicle accelerates, decelerates,
// and corners. It only applies to route-style trajectories (waypoints, KML, etc.);
// imported trajectories (NMEA, VBOX, CSV) carry their own motion data.
//
// SetDynamics() selects a built-in preset (Car, RaceCar, Train, Pedestrian, ...) and
// SetCustomDynamics() lets you specify exact velocity, acceleration, and jerk limits.
// -- TRAJECTORY ----------------------------------------------------------------------
// Defines where and how the simulated receiver moves. Many trajectory types are
// available - static point, route waypoints, KML, NMEA, VBOX, CSV, and full
// .sgen scenarios - each exposed as a TrajectoryFrom... method. See API-Documentation.html
// for the full list and per-method options.
scenario.TrajectoryFromStaticPoint(
latitudeDecDegrees: 51.9831552,
longitudeDecDegrees: -0.999424,
altitudeMetres: 100,
durationInSeconds: 600);
// -- DEVICE DISCOVERY (optional) -----------------------------------------------------
// FindAvailableLabSat4RealTimeDevices() returns the LabSat 4 devices discovered on the
// network, including each device's IP address, serial number, and ready state. Useful
// when the IP address is not known in advance.
// -- OUTPUT --------------------------------------------------------------------------
// Configures where the simulated signals are sent. Real-time targets (LabSat 1/2/3,
// LabSat 4, LabSat 4 RT+) and file outputs (LS2 / LS3 / LS3W / LS4) are all supported,
// each exposed as a SetOutputTo... method. See API-Documentation.html for the full list.
//
// Quantization controls signal fidelity: higher bit depths produce more accurate signals
// but increase the data rate, which may limit the number of simultaneous signals.
//
// SatCountLimitMode controls CPU load management for real-time outputs. Automatic
// (recommended) starts with the maximum number of satellites and reduces if the CPU is
// overloaded; the alternatives let you simulate all visible satellites or manage them
// manually via SetSatelliteEnabled().
scenario.SetOutputToLabSat4Realtime(
labSatIPAddress,
RealTimeOutputMode.UserTime,
signals,
Quantization.TwelveBit,
new LabSat4RealtimeOutputOptions { SatCountLimitMode = SatCountLimitMode.Automatic });
// -- TIMELINE EVENTS (optional) ------------------------------------------------------
// Schedule satellite changes to be applied automatically as the simulation progresses.
// Each AddSatelliteTimelineChange() call queues a change at a specified elapsed time;
// when the simulation reaches that time, the satellite's enabled state and attenuation
// are updated. Useful for repeatable test cases such as driving through a tunnel,
// simulating a satellite outage, or staging a gradual signal degradation.
// ClearSatelliteTimeline() removes every previously scheduled change.
//
// IMPORTANT: schedule changes BEFORE calling StartSimulation. The timeline is snapshotted
// when the simulation begins; subsequent additions will not take effect on the running run.
// -- INSPECT THE CONFIGURATION (optional) --------------------------------------------
// Before starting the simulation, you can inspect what the engine has decided to do:
// GetSimulationSummary() reports the start time, trajectory, output, and signals;
// GetChannelPlan() reports the RF channels, sample rate, bandwidth, and quantization.
// -- SIMULATION ----------------------------------------------------------------------
// Starts the simulation. The API will print the configuration summary, almanac status,
// and channel plan to the console before the simulation begins.
scenario.StartSimulation();
// Track the simulation start time so we can display the total duration when it finishes
var simulationStartTime = DateTime.Now;
// MonitorSimulationProgress blocks until the simulation ends (either the trajectory
// duration elapses, or EndSimulation() is called from another thread). The optional
// callback runs on each interval tick - useful for printing progress or reacting to
// simulation state.
scenario.MonitorSimulationProgress(TimeSpan.FromSeconds(1),
() =>
{
if (scenario.IsRunning)
{
// Format elapsed time and build a progress bar for visual feedback
var elapsed = TimeSpan.FromSeconds(scenario.SimulationSecondsFromStart);
var percent = scenario.SimulationPercentComplete;
int barWidth = 20;
int filled = (int)(percent / 100 * barWidth);
string bar = new string('#', filled) + new string('-', barWidth - filled);
Console.Write($"\r [{bar}] {percent,5:F1}% Elapsed: {elapsed:hh\\:mm\\:ss} Underruns: {scenario.BufferUnderrunCount} ");
// -- RUNTIME CONTROL (optional) -----------------------------------------
// While a real-time simulation is running, several methods can adjust the
// output and constellation on the fly:
// - GetSatellitesInRealTimeSimulation(), SetSatelliteEnabled(), and
// SetSatelliteSignalGainDB() inspect and control individual satellites
// (useful for stress-testing receiver behaviour under degraded
// constellations).
// - SetLabSat4ChannelAttenuation() adjusts the RF output level of an
// entire LabSat 4 channel - the API equivalent of the LabSat 4 front-
// panel up/down buttons.
//
// IMPORTANT: this callback fires on every interval tick. Calling any of
// these methods directly here will re-apply the change on every tick,
// which is rarely what you want. Guard one-shot changes with a flag or an
// elapsed-time check - for example, apply the change the first time
// scenario.SimulationSecondsFromStart crosses a threshold.
//
// IMPORTANT: these calls are only valid for real-time outputs. On a file
// output they throw.
//
// For changes that should happen at fixed times, the TIMELINE EVENTS
// section above is usually a better fit - the engine handles the timing.
}
else if (scenario.IsReady)
{
Console.Write("\r Waiting for trajectory data... ");
}
});
// Print the final simulation summary
var totalDuration = DateTime.Now - simulationStartTime;
Console.WriteLine();
Console.WriteLine();
Console.WriteLine($" Simulation complete. Total time: {totalDuration:hh\\:mm\\:ss}");
scenario.EndSimulation();
}
catch (Exception ex)
{
// ex.Message is fully formatted by the API for every exception type it throws, including
// the AggregateException used to report multiple script-parser errors - no special handling
// is needed here. Advanced consumers can catch a more specific type (e.g. AggregateException)
// and inspect InnerExceptions if they need to react to individual errors programmatically.
Console.WriteLine();
Console.WriteLine($" ERROR: {ex.Message}");
}
}
}