Simulation PSY User Guide

This guide describes how to use the Simulation PSY. It is intended for application developers and device creators. The Simulation PSY allows applications to be tested with an emulator and on hardware without using an implementation PSY.

Introduction

You usually want to test your applications during development. By using Simulation PSY, your Location Based Services enabled application can receive simulated position updates when under test in the Windows emulator and on target devices. The Simulation PSY does not use real hardware to obtain position updates.

Simulation PSY can read position data from a file of your choice. You can configure the PSY to return the same data for every position request from your application or to simulate device movement in a specific direction.

Simulation PSY makes it easy to simulate position updates from different locations around the world. You can test your application's behaviour in unusual locations, such as at the poles and along the zero longitude meridian. You can also use the PSY to test your application's behaviour when the accuracy of position updates changes and under error conditions.

Key concepts and terms

NMEA

In this context, an abbreviation of the NMEA (National Maritime Electronics Association) 0183 standard. This defines an electrical and data exchange protocol for marine electronic devices (including GPS receivers). NMEA is a protocol commonly used by Bluetooth GPS devices. Simulation PSY can read data from a file that contains data in NMEA format.

Operating Modes

You can use Simulation PSY in one of three different Operating Modes:

  • NMEA Mode

    In NMEA Mode, the PSY reads NMEA sentences from a data file.

    The PSY operates in NMEA Mode if it can find a data file with a .nme filename extension containing NMEA sentences.

    This is the default mode. The PSY uses a default data file called default.nme if it cannot load your data file.

    For the behaviour of the PSY in NME Mode see NMEA file format.

  • Simulated Movement Mode

    In Simulated Movement Mode, the PSY reads data from a file that simulates mobile device movement in a specified direction at a specified speed. This is useful to test applications that use tracking: those that require periodic position updates.

    The PSY operates in Simulated Movement Mode if it can find a data file with a .sps filename extension. You must create your own simulated movement data file.

    For the behaviour of the PSY in Simulated Movement Mode see Simulated movement file format.

  • Fixed Data Mode

    The PSY returns a fixed set of basic position data if it cannot find a data file. The values returned are shown in the following table:

    Position data Value

    Latitude

    0

    Longitude

    0

    Altitude (WGS 84)

    0

    Horizontal Accuracy

    0

    Vertical Accuracy

    0

    Datum

    WGS-84

    Time

    Current System Time

The data file from which the PSY attempts to load position data is controlled by a setting defined by the Simulation PSY Settings API.

Data Set Modes

The Simulation PSY has two Data Set Modes that control what data is returned to multiple client sessions:

  • Independent Data Set Mode

    In this mode every client session that requests a position from the PSY is treated independently.

    This means that for each position request by a client session, the next returned position is relative to the last position returned to that client session. The PSY does not consider the last position returned to any other open client session. This applies for both NMEA Mode and Simulated Movement Mode.

    This behaviour is acceptable for many applications, but may cause problems if your client application opens more than one session and needs to receive related position data from both sessions. The Common Data Set Mode addresses this use-case (see below).

  • Common Data Set Mode

    In Common Data Set Mode, the Simulation PSY stores the latest position fix, which is shared between all client sessions.

    Details specific to NMEA Mode and Simulated Movement Mode are as follows:

    • NMEA Mode

      When the first client requests a position, the PSY starts to read NMEA sentences from the data file at a rate of one per second. Reading continues until the last client disconnects. When any client requests a position update, it receives a the latest, shared position fix.

    • Simulated Movement Mode

      When the first client requests a position, the PSY stores the time of the request and returns a position update. When another client requests a position, it is calculated relative to the time of the first request. This means that the two returned positions are related, with the second being further along the course specified in the simulated data file.

      When the last client disconnects, the PSY resets the stored time of the first position request.

For more information about how to configure the Data Set Mode, see Simulation PSY Settings API.

Configuring the PSY

You can control the data that the Simulation PSY returns. To do this, put the data in a file (NMEA data or Simulated Movement data) and tell the PSY where to find it. Use the Simulation PSY Settings API to tell the PSY which position data file to load.

Connecting and retrieving a location

For full information on how to retrieve location updates from the Location Server, see Location Acquisition API. The information presented here is a summary, with focus on features specific to the Simulation PSY.

To get a location from the Simulation PSY, a user must:

  1. Connect to RPositionServer.

  2. Open an RPositioner subsession using the Simulation PSY.

  3. Call RPositioner::NotifyPositionUpdate().

The outline code shown below illustrates these steps:


#include <lbs.h>
#include <lbserrors.h>

...

const TInt KSimPSYImplUid = 0x101F7A81;

TPositionInfo posInfo;
TRequestStatus status;
RPositionServer positionServer;
RPositioner positioner;

// Connect to the Location Server

User::LeaveIfError(positionServer.Connect());
CleanupClosePushL(positionServer);

// Open a subsession using the Simulation PSY UID explicitly.
// Alternatively, the subsession can be opened by the Default PSY by calling positioner.Open(positionServer).

User::LeaveIfError(positioner.Open(positionServer, TUid::Uid(KSimPSYImplUid)));
CleanupClosePushL(positioner);

// Set the requester information

User::LeaveIfError(positioner.SetRequestor(CRequestor::ERequestorService,
  CRequestor::EFormatUrl, _L("http://www.example.com")));

// Request the position

positioner.NotifyPositionUpdate(posInfo, status);
User::WaitForRequest(status);

// Use the returned posInfo

...

// Clean up positioner and positionServer

CleanupStack::PopAndDestroy(2, &positionServer);

Note: It may be necessary to enable the Simulation PSY on your device by using some kind of Location Settings UI before it can be used by your applications.

Supported class types

Simulation PSY supports the following class types:

The argument to RPositioner::NotifyPositionUpdate() must be one of the above classes.

Note: HPositionGenericInfo, TPositionCourseInfo and TPositionSatelliteInfo are all derived from TPositionInfo.

Returned position data

The position data that is returned depends on the PSY operating mode:

  • NMEA mode

    The position data that is returned by the PSY depends on the class of the TPositionInfo derived object reference argument passed by the client in its NotifyPositionUpdate() call. If you use an HPositionGenericInfo, your client application must set the request fields for each type of required position data. The fields are defined by the enumeration _TPositionFieldId. If a field is set, Simulation PSY returns the corresponding position data.

    Example: If the field EPositionFieldNMEASentences is set as requested the number of NMEA sentences that describe the position fix are stored in it by the PSY. The returned type is TUint8.

    The first NMEA sentence is stored in the EPositionFieldNMEASentencesStart field. The second sentence is stored in the EPositionFieldNMEASentencesStart+1 field, and so on. The returned type is TDesC8.

    The returned position fix data uses the WGS 84 reference coordinate system.

  • Simulated movement mode and fixed data mode

    Only position data defined by the TPositionInfo member variables is returned. Additional position data defined by classes derived from TPositionInfo is not returned.

    The returned position fix data uses the WGS 84 reference coordinate system.

Note: In independent data set mode, two clients can read from the PSY configuration file and/or the data file at the same time. The outputs of the two sessions are completely independent of each other.

Supported update options

You can set position update options using the Location Acquisition API. See using the How to Get Location Information for more background information.

Simulation PSY supports the following update options:

  • TPositionUpdateOptions::SetUpdateTimeOut(TTimeIntervalMicroSeconds aTimeOut) to specify an update timeout for the request.

  • TPositionUpdateOptions::SetUpdateInterval(TTimeIntervalMicroSeconds aInterval) to support tracking requests.

  • TPositionUpdateOptions::SetAcceptPartialUpdates(TBool aPartial) to accept partial updates (that is, incomplete updates).

    Partial updates are only supported in NMEA mode. Partial updates are not supported in simulated movement mode.

Error codes

When you open a session using RPositioner::Open(), one of the following error codes may be returned:

  • KErrNotFound

    The Simulation PSY cannot find a file it needs.

  • KErrCorrupt

    The syntax of the simulated movement file is incorrect or some required data is missing.

  • KErrNotSupported

    The extension of the simulation file is recognized: it is neither .sps or .nme.

When calling RPositioner::NotifyPositionUpdate(), one of following error codes may be set for the TRequestStatus:

  • KPositionQualityLoss

    The configuration for requests is set to fail in the simulated movement mode.

  • KPositionPartialUpdate

    The NMEA data file is missing some position info and the client has allowed partial updates by calling TPositionUpdateOptions::SetAcceptPartialUpdates().

  • System wide error codes from TLexer and Math.

  • Other system wide error codes.

When trying to cancel a position update with RPositioner::CancelRequest(), the PSY will return KErrCancel to notify that the request was properly cancelled.

Status reporting

See Location Acquisition API for information on how to retrieve the PSY status.

To get the module status from the Simulation PSY, you first need to connect to RPositionServer and then open a subsession.

The following is an example of how to retrieve the module status from Simulation PSY:


#include <lbs.h>
#include <lbserrors.h>

...

TPositionModuleStatus moduleStatus;
TPositionModuleStatusEvent moduleEvent;
TRequestStatus status;
RPositionServer positionServer;
RPositioner positioner;

const TPositionModuleId KSimulationPSYUid = {0x101f7a81};

User::LeaveIfError(positionServer.Connect());
CleanupClosePushL(positionServer);

// Asynchronous module status
moduleEvent.SetRequestedEvents(TPositionModuleStatusEvent::EEventAll);
positionServer.NotifyModuleStatusEvent(moduleEvent, status, KSimulationPSYUid);

TInt err = positioner.Open(positionServer, KSimulationPSYUid);
// Variable err could be checked
CleanupClosePushL(positioner);
User::WaitForRequest(status);

moduleEvent.GetModuleStatus(moduleStatus);
TPositionModuleStatus::TDeviceStatus deviceStatus 
    = moduleStatus.DeviceStatus();
TPositionModuleStatus::TDataQualityStatus qualityStatus
    = moduleStatus.DataQualityStatus();

// Do something with moduleStatus, deviceStatus, qualityStatus

// Synchronous module status
User::LeaveIfError(positionServer.GetModuleStatus(moduleStatus,
    KSimulationPSYUid));

deviceStatus = moduleStatus.DeviceStatus();
qualityStatus = moduleStatus.DataQualityStatus();

// Do something with moduleStatus, deviceStatus, qualityStatus

CleanupStack::PopAndDestroy(2, &positionServer); // positioner and positionServer

Simulation PSY reports module status changes during its life cycle. Module status changes are reported only when Simulation PSY is opened and closed. Status changes are not reported during location requests. The following module statuses are reported:

Module Status Event Group Comment

TPositionModuleStatus::EDeviceError

Device Status

Reported if a data file cannot be found or is corrupt.

TPositionModuleStatus::EDeviceInactive

Device Status

Reported when Simulation PSY is unloaded.

TPositionModuleStatus::EDeviceReady

Device Status

Reported when Simulation PSY is online and ready to retrieve position information.

TPositionModuleStatus::EDataQualityUnknown

Data Quality Status

Reported when Simulation PSY is unloaded.

TPositionModuleStatus:EDataQualityNormal

Data Quality Status

Reported when Simulation PSY is online and ready to retrieve position information.

Data file formats

NMEA file format

Simulation PSY can read data files that contain NMEA sentences based on NMEA 0183 version 2.1. The NMEA file is in 7-bit ASCII format. All lines end with the character ’\n’. The NMEA sentences are case sensitive.

Simulation PSY parses position information from the NMEA sentences GGA, RMC, GSA and GSV. Data from other NMEA sentences are not parsed. The NMEA sentences GLL, GGA, GSA and RMC are required to make a position update.

When a required NMEA sentence is read for the second time, parsing of the NMEA data stops and Simulation PSY checks whether all required sentences have been read. Reading of NMEA sentences continues if there are required sentences which are still unread.

When the end of the data file is reached, Simulation PSY begins reading the file again, starting from the beginning. The parser is reset, which means that all of the required NMEA sentences must be read again before a position update can be returned.

Satellite time is read from the RMC sentence. It is stored in the position object passed from the client if it is an instance of TPositionSatelliteInfo or HPositionGenericInfo. If the object is an instance of HPositionGenericInfo, the satellite time is stored only if it is a requested field. System time is set in the base class TPositionInfo for each position update.

The following table shows:

  • The supported NMEA sentences.

  • The position data in each NMEA sentence.

  • The object class(es) that can be passed as an argument in RPositioner::NotifyPositionUpdate() to get the position data.

    Note: All NMEA sentences read from the data file are included in HPositionGenericInfo if EPositionFieldNMEASentences is set as a requested field.

NMEA sentence Position data in the sentence TPositionInfo-derived class types that return this data Comments

GGA

Latitude

TPositionInfo

 

Longitude

TPositionInfo

 

Altitude (WGS-84)

TPositionInfo

Calculated as mean sea level altitude plus geoidal separation.

Geoidal separation

HPositionGenericInfo

 

Altitude (above sea level)

HPositionGenericInfo

Taken directly from GGA.

RMC

Satellite time

TPositionSatelliteInfo, HPositionGenericInfo

 

True course

TPositionCourseInfo, HPositionGenericInfo

 

Speed

TPositionCourseInfo, HPositionGenericInfo

 

Magnetic course

HPositionGenericInfo

Calculated as true course + magnetic variation.

GSA

Number of used satellites

TPositionSatelliteInfo, HPositionGenericInfo

Number of satellites used in the position fix.

PRN (for each satellite)

TPositionSatelliteInfo

 

HDOP

TPositionSatelliteInfo

 

VDOP

TPositionSatelliteInfo

 

PDOP

HPositionGenericInfo

If PDOP is not present in the sentence, it is calculated as SQRT(HDOP^2 + VDOP^2).

Horizontal accuracy

TPositionInfo

Calculated as HDOP * UERE where UERE is 10m.

Vertical accuracy

TPositionInfo

If fix is in 3D mode, it is calculated as 1.5 * HDOP * UERE where UERE is 10m.

GSV

Number of satellites in view

TPositionSatelliteInfo, HPositionGenericInfo

Calculated total number of satellites from GSV sentences.

In TPositionSatelliteInfo, this value indicates how many satellites this information is based on.

The number of satellites in view cannot be set explicitly in the data file.

Elevation

TPositionSatelliteInfo

 

Azimuth

TPositionSatelliteInfo

 

Signal strength

TPositionSatelliteInfo

 

All

Raw NMEA data

HPositionGenericInfo

 

The following is an example of valid NMEA file content:


$GPGSV,3,2,12,24,32,051,,22,21,292,,01,20,315,,14,20,321,*71
$GPGSV,3,3,12,05,19,134,,13,18,348,,17,14,180,,10,10,110,*7F
$GPGLL,6459.8757,N,01433.8547,E,091931.375,A*3E
$GPGGA,091931.38,6459.8757,N,01433.8547,E,1,04,2.0,-0034,M,,,,*3D
$GPRMB,A,0.21,L,SIM003,SIM001,6500.0900,N,01433.8589,E,000.2,00..,000.0,V*18
$GPRMC,091931.38,A,6459.8757,N,01433.8547,E,21.7,177.3,200302,02.,E*6F
$GPAPB,A,A,0.2,L,N,,,87.6,M,SIM001,358.1,M,,,*16
$GPGSA,A,3,01,02,03,04,,,,,,,,,1.0,2.0,3.0*34

The PSY obtains a simulated position fix after parsing the GLL, GGA, RMC and GSA sentences.

Latitude, longitude, altitude and position accuracy are parsed from the GGA sentence.

In the following example file content, latitude is parsed from “6459.8757,N”. Longitude is parsed from “01433.8547,E”. Altitude is parsed from “-0034”, and the value “2.0” is used for calculating horizontal and vertical accuracy.

...
$GPGLL,6459.8757,N,01433.8547,E,091931.375,A*3E
$GPGSV,3,1,12,06,53,095,,30,52,150,,15,51,090,,25,37,230,*7F
$GPGSV,3,2,12,24,32,051,,22,21,292,,01,20,315,,14,20,321,*71
$GPGGA,091931.38,6459.8757,N,01433.8547,E,1,04,2.0,-0034,M,,,,*3D
$GPRMB,A,0.21,L,SIM003,SIM001,6500.0900,N,01433.8589,E,000.2,00..,000.0,V*18
$GPRMC,091931.38,A,6459.8757,N,01433.8547,E,21.7,177.3,200302,02.,E*6F
$GPAPB,A,A,0.2,L,N,,,87.6,M,SIM001,358.1,M,,,*16
$GPGSA,A,3,01,02,03,04,,,,,,,,,1.0,2.0,3.0*34
...

The first line in the following content starts with a GLL sentence which has already been parsed. The other three sentences required for calculating position information, i.e. GGA, RMC and GSA, have also been parsed. Hence a second position fix is obtained from the parsed sentences.

...
$GPGLL,6459.8757,N,01433.8547,E,091931.375,A*3E
$GPGSV,3,1,12,06,53,095,,30,52,150,,15,51,090,,25,37,230,*7F
$GPGSV,3,2,12,24,32,051,,22,21,292,,01,20,315,,14,20,321,*71
...

The following is an example of incorrect NMEA file content:


$GPGSV,3,2,12,24,32,051,,22,21,292,,01,20,315,,14,20,321,*71
$GPGSV,3,3,12,05,19,134,,13,18,348,,17,14,180,,10,10,110,*7F
$GPGLL,6459.8757,N,01433.8547,E,091931.375,A*3E
$GPGGA,091931.38,6459.8757,N,01433.8547,E,1,04,2.0,-0034,M,,,,*3D
$GPRMB,A,0.21,L,SIM003,SIM001,6500.0900,N,01433.8589,E,000.2,00..,000.0,V*18
$GPRMC,091931.38,A,6459.8757,N,01433.8547,E,21.7,177.3,200302,02.,E*6F
$GPGGA,091931.38,6434.8744,N,01343.8637,E,1,04,2.0,-0032,M,,,,*3D

This file content is incorrect because a second GGA sentence is read before the next required GSA sentence. The Simulation PSY continues reading NMEA sentences to try to read a correct fix.

The Simulation PSY supports NMEA sentences from the following GPS devices:

  • Garmin:

    • eTrex – basic

    • eTrex – Legend

    • III plus

    • 12 cx

  • Magellan:

    • GPS 315

    • Meridian Gold

    • Tracker

Simulated movement file format

The Simulation PSY operates in Simulated Movement Mode if it can find a data file with the filename extension .sps.

A simulated movement data file has the following format:


Horizontal accuracy={float};
Vertical accuracy={float};
TimeToFix min={integer};
TimeToFix max={integer}; 
Powerup time={integer};
Longitude={float};
Latitude={float};
Speed={float};
Course={float};
[Deterministic|Random]={integer};

The data file must be in 7-bit ASCII format. All lines must end with the end of line character ‘\n‘. The data file text is case insensitive. The data file is opened and read when a subsession that uses the Simulation PSY is opened by the Location Server.

Key-value pairs

The file content consists of key-value pairs. Keys and values are separated by the "=" character. The keys must include the spaces as shown above. Each key-value pair is terminated by a semicolon character (;). It is legal to have spaces before and after the "=" character and before the terminating semicolon.

No comments are allowed in the data file.

Any ordering of the key-value pairs is valid, but all of the key-value pairs (shown in the example above and in the following table) must exist in the file:

Key Data type Value type Value range Example values, delimited by ;

Horizontal accuracy

meter (m)

Float

>= 0

23.56; 56

Vertical accuracy

meter (m)

Float

>= 0

30.89899; 12

TimeToFix min

seconds (s)

Integer

>= 0

0; 2

TimeToFix max

seconds (s)

Integer

>= 0

4; 5

Powerup time

seconds (s)

Integer

>= 0

3; 6

Longitude

degrees

Float

[-180, 180)

-179.686; -180; 180; 0;

Latitude

degrees

Float

(-90, 90)

51.568; -90; 90; 0

Speed

meters per second (m/s)

Integer

>= 0

0; 5

Course

degrees

Integer

(0, 360)

78; 0; 360

Deterministic | Random

error simulation mode

Integer

>= 0

0; 3; 5

Simulation PSY calculates position updates based on the starting Latitude and Longitude values, together with the Speed and Course.

If Speed > 0, a new position fix is calculated and returned for each position update.

The Course value is the direction of the simulated movement in degrees (0 and 360 = North, 90 = East, 180 = South and 270 = West).

Error simulation mode

The error simulation mode key specifies how errors are simulated.

There are two possible error simulation modes : Deterministic and Random:

  • Deterministic

    Positioning fails at the specified frequency value.

    Example: Deterministic = 3 means that every third position request fails.

  • Random

    Random means that positioning fails intermittently, but with the specified mean frequency.

    Example: Random = 3 means that out of a 'large' number of requests, on avaerage one third of them will fail.

For both modes, a failure means that the error code KPositionQualityLoss is set for the client's TRequestStatus object.

Note: To turn off error simulation, set Deterministic = 0 in your data file.

Position accuracy calculations

A base horizontal and vertical accuracy are specified by the values for Horizontal Accuracy and Vertical Accuracy in the data file.

For each new position fix generated by the PSY, the specified Horizontal Accuracy value is multiplied by a randomly generated value. This adjusted accuracy is added as “error” to the calculated position's longitude and latitude.

The altitude coordinate starts at 0 meters in the WGS-84 datum. For each new position fix, the specified Vertical Accuracy value is multiplied by a random generated value. The adjusted accuracy is added as an "error" to the calculated position's altitude.

If the syntax of the file is incorrect or some of the settings are missing, the system wide error code KErrCorrupt is returned by Simulation PSY. This error code is returned when a client opens a positioning subsession by calling RPositioner::Open().

Example: To simulate the positions of a car that is driving at 20 m/s (72 km/h) due North (with a simulated request failure for every seventh location request) create a .sps file with the following content:


Horizontal accuracy=20;
Vertical accuracy=30;
TimeToFix min=2;
TimeToFix max=7; 
Powerup time=3;
Longitude=11.34;
Latitude=57.11;
Speed=20;
Course=0;
Deterministic=7;

When the PSY receives a location request, it generates its next position update at some time between 2 and 7 seconds from the time the request was received. The exception to this is for the first position request, when an additional delay specified by the Powerup time value is added (in this case 3 seconds).