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.
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.
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.
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:
The data file from which the PSY attempts to load position data is controlled by a setting defined by the Simulation PSY Settings API.
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.
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.
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:
Connect to RPositionServer.
Open an RPositioner subsession using the Simulation PSY.
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.
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.
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 |
---|---|---|
Device Status |
Reported if a data file cannot be found or is corrupt. |
|
Device Status |
Reported when Simulation PSY is unloaded. |
|
Device Status |
Reported when Simulation PSY is online and ready to retrieve position information. |
|
Data Quality Status |
Reported when Simulation PSY is unloaded. |
|
Data Quality Status |
Reported when Simulation PSY is online and ready to retrieve position information. |
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 |
||
Longitude |
TPositionInfo |
||
Altitude (WGS-84) |
TPositionInfo |
Calculated as mean sea level altitude plus geoidal separation. |
|
Geoidal separation |
|||
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:
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).
Copyright ©2010 Nokia Corporation and/or its subsidiary(-ies).
All rights
reserved. Unless otherwise stated, these materials are provided under the terms of the Eclipse Public License
v1.0.