Symbian3/PDK/Source/GUID-22DB5009-A552-55F7-97EF-1C454E510782.dita
author Dominic Pinkman <dominic.pinkman@nokia.com>
Fri, 02 Jul 2010 12:51:36 +0100
changeset 11 5072524fcc79
parent 5 f345bda72bc4
child 14 578be2adaf3e
permissions -rw-r--r--
Fixing terminology

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
<!-- This component and the accompanying materials are made available under the terms of the License 
"Eclipse Public License v1.0" which accompanies this distribution, 
and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
<!-- Initial Contributors:
    Nokia Corporation - initial contribution.
Contributors: 
-->
<!DOCTYPE concept
  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
<concept xml:lang="en" id="GUID-22DB5009-A552-55F7-97EF-1C454E510782"><title>Simulation PSY User Guide </title><prolog><metadata><keywords/></metadata></prolog><conbody><p>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. </p> <section><title>Contents</title> <ul><li id="GUID-CF25E210-F1DF-541A-B62C-5A22F5E82A74"><p><xref href="GUID-22DB5009-A552-55F7-97EF-1C454E510782.dita#GUID-22DB5009-A552-55F7-97EF-1C454E510782/GUID-F7315778-D02C-5C71-A4E3-1CB52000F1DA">Introduction</xref>  </p> </li> <li id="GUID-4A26A756-D53C-5A6A-B6FB-36F76B4E333A"><p><xref href="GUID-22DB5009-A552-55F7-97EF-1C454E510782.dita#GUID-22DB5009-A552-55F7-97EF-1C454E510782/GUID-D7E4C82A-4C55-5EBD-AE1C-40F6FAF51970"> Key concepts and terms</xref>  </p> </li> <li id="GUID-D406A424-0EFE-5CBA-872E-9777FF11750A"><p><xref href="GUID-22DB5009-A552-55F7-97EF-1C454E510782.dita#GUID-22DB5009-A552-55F7-97EF-1C454E510782/GUID-D7DFA3B9-AD1C-5C9E-920C-59154970A789">Operating Modes</xref>  </p> </li> <li id="GUID-96853668-9107-50A6-804B-80221B36CE96"><p><xref href="GUID-22DB5009-A552-55F7-97EF-1C454E510782.dita#GUID-22DB5009-A552-55F7-97EF-1C454E510782/GUID-A112E097-F5CB-5303-BEED-600134D2933F">Data Set Modes</xref>  </p> </li> <li id="GUID-794E1EE0-A9C0-52F2-9A51-F310BA425EF5"><p><xref href="GUID-22DB5009-A552-55F7-97EF-1C454E510782.dita#GUID-22DB5009-A552-55F7-97EF-1C454E510782/GUID-7E15F107-DF9A-5A75-AD29-77159C98893F">Configuring the PSY</xref>  </p> </li> <li id="GUID-C4156BF9-93D7-5729-8466-32753C858479"><p><xref href="GUID-22DB5009-A552-55F7-97EF-1C454E510782.dita#GUID-22DB5009-A552-55F7-97EF-1C454E510782/GUID-37FB65B6-D8F9-5904-A078-5E3F0D61C65A">Connecting and retrieving a location</xref>  </p> </li> <li id="GUID-FF74E9CA-549B-5866-939C-A767669EB881"><p><xref href="GUID-22DB5009-A552-55F7-97EF-1C454E510782.dita#GUID-22DB5009-A552-55F7-97EF-1C454E510782/GUID-AF7C2A8F-AC98-5242-99A0-048D729C20E1">Status reporting</xref>  </p> </li> <li id="GUID-B3C54E9F-A0AC-5C29-A920-3A1852C52870"><p><xref href="GUID-22DB5009-A552-55F7-97EF-1C454E510782.dita#GUID-22DB5009-A552-55F7-97EF-1C454E510782/GUID-0BFFF75B-C6FB-577C-AE81-C6D57331C42B">Data file formats</xref>  </p> </li> </ul> </section> <section id="GUID-F7315778-D02C-5C71-A4E3-1CB52000F1DA"><title>Introduction</title> <p>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. </p> <p>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. </p> <p>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. </p> </section> <section id="GUID-D7E4C82A-4C55-5EBD-AE1C-40F6FAF51970"><title>Key concepts and terms</title> <dl><dlentry><dt>NMEA</dt> <dd><p>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. </p> </dd> </dlentry> </dl> </section> <section id="GUID-D7DFA3B9-AD1C-5C9E-920C-59154970A789"><title>Operating Modes</title> <p>You can use Simulation PSY in one of three different Operating Modes: </p> <ul><li id="GUID-6E15BB6B-0526-59B3-854E-D384C67BEDB7"><p>NMEA Mode </p> <p>In NMEA Mode, the PSY reads NMEA sentences from a data file. </p> <p>The PSY operates in NMEA Mode if it can find a data file with a <codeph>.nme</codeph> filename extension containing NMEA sentences. </p> <p>This is the default mode. The PSY uses a default data file called <filepath>default.nme</filepath> if it cannot load your data file. </p> <p>For the behaviour of the PSY in NME Mode see <xref href="GUID-22DB5009-A552-55F7-97EF-1C454E510782.dita#GUID-22DB5009-A552-55F7-97EF-1C454E510782/GUID-0C50ACAE-0DC4-5BF9-ADF3-E0DFD6275D3A">NMEA file format</xref>. </p> </li> <li id="GUID-03FFE8A5-6F13-5560-89AB-47E98201B3D1"><p>Simulated Movement Mode </p> <p>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. </p> <p>The PSY operates in Simulated Movement Mode if it can find a data file with a <codeph>.sps</codeph> filename extension. You must create your own simulated movement data file. </p> <p>For the behaviour of the PSY in Simulated Movement Mode see <xref href="GUID-22DB5009-A552-55F7-97EF-1C454E510782.dita#GUID-22DB5009-A552-55F7-97EF-1C454E510782/GUID-6042D5D0-5F5C-5503-8CEF-FF011F715003">Simulated movement file format</xref>. </p> </li> <li id="GUID-F4FEE15D-5FDA-562F-BBFD-E9BFE8EF08D5"><p>Fixed Data Mode </p> <p>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: </p> <table id="GUID-480B09E4-5ECD-5FC3-A51F-C91EC8115581"><tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/><thead><row><entry>Position data</entry> <entry>Value</entry> </row> </thead> <tbody><row><entry><p>Latitude </p> </entry> <entry><p>0</p> </entry> </row> <row><entry><p>Longitude </p> </entry> <entry><p>0</p> </entry> </row> <row><entry><p>Altitude (WGS 84) </p> </entry> <entry><p>0</p> </entry> </row> <row><entry><p>Horizontal Accuracy </p> </entry> <entry><p>0</p> </entry> </row> <row><entry><p>Vertical Accuracy </p> </entry> <entry><p>0</p> </entry> </row> <row><entry><p>Datum </p> </entry> <entry><p>WGS-84 </p> </entry> </row> <row><entry><p>Time </p> </entry> <entry><p>Current System Time </p> </entry> </row> </tbody> </tgroup> </table> </li> </ul> <p>The data file from which the PSY attempts to load position data is controlled by a setting defined by the <xref href="GUID-45F9389E-F31B-59DA-A4FE-E254EAEB2213.dita">Simulation PSY Settings API</xref>. </p> </section> <section id="GUID-A112E097-F5CB-5303-BEED-600134D2933F"><title>Data Set Modes</title> <p>The Simulation PSY has two Data Set Modes that control what data is returned to multiple client sessions: </p> <ul><li id="GUID-52A8694D-CD37-5B1B-A97D-8A558D46D46A"><p>Independent Data Set Mode </p> <p>In this mode every client session that requests a position from the PSY is treated independently. </p> <p>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. </p> <p>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). </p> </li> <li id="GUID-FDF7CEAE-CD11-572C-878D-7D0C3567040F"><p>Common Data Set Mode </p> <p>In Common Data Set Mode, the Simulation PSY stores the latest position fix, which is shared between all client sessions. </p> <p>Details specific to NMEA Mode and Simulated Movement Mode are as follows: </p> <ul><li id="GUID-75487DCA-2F56-5B8D-B91A-38406FEBEE39"><p>NMEA Mode </p> <p>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. </p> </li> <li id="GUID-6568E568-3D2B-549C-9151-211F81101A3E"><p>Simulated Movement Mode </p> <p>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. </p> <p>When the last client disconnects, the PSY resets the stored time of the first position request. </p> </li> </ul> </li> </ul> <p>For more information about how to configure the Data Set Mode, see <xref href="GUID-45F9389E-F31B-59DA-A4FE-E254EAEB2213.dita">Simulation PSY Settings API</xref>. </p> </section> <section id="GUID-7E15F107-DF9A-5A75-AD29-77159C98893F"><title> Configuring the PSY</title> <p>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 <xref href="GUID-45F9389E-F31B-59DA-A4FE-E254EAEB2213.dita">Simulation PSY Settings API</xref> to tell the PSY which position data file to load. </p> </section> <section id="GUID-37FB65B6-D8F9-5904-A078-5E3F0D61C65A"><title>Connecting and retrieving a location</title> <p>For full information on how to retrieve location updates from the Location Server, see <xref href="GUID-D0318BB6-0B9F-5A1C-AB0B-61BA22D28661.dita">Location Acquisition API</xref>. The information presented here is a summary, with focus on features specific to the Simulation PSY. </p> <p>To get a location from the Simulation PSY, a user must: </p> <ol id="GUID-97E69798-C576-568D-AC85-5D528AF7E4E6"><li id="GUID-76509728-1991-5174-B9B1-C9D4985DD483"><p>Connect to <xref href="GUID-0ADC4654-7F7B-3B53-A2F9-7035670F501B.dita"><apiname>RPositionServer</apiname></xref>. </p> </li> <li id="GUID-12F5DD7F-1F76-55BF-984B-D5C0F6DF463E"><p>Open an <xref href="GUID-1EAEB7EF-0AC7-37C7-B35F-C9B780FFC575.dita"><apiname>RPositioner</apiname></xref> subsession using the Simulation PSY. </p> </li> <li id="GUID-7AF67615-C091-58B1-A1C4-A7AFE8B989B7"><p>Call <xref href="GUID-1EAEB7EF-0AC7-37C7-B35F-C9B780FFC575.dita#GUID-1EAEB7EF-0AC7-37C7-B35F-C9B780FFC575/GUID-321F6046-3551-3ACE-B0A3-26D51FAEB477"><apiname>RPositioner::NotifyPositionUpdate()</apiname></xref>. </p> </li> </ol> <p>The outline code shown below illustrates these steps: </p> <codeblock id="GUID-E71085E4-7CCF-5372-9803-E5609A4BA1A8" xml:space="preserve">
#include &lt;lbs.h&gt;
#include &lt;lbserrors.h&gt;

...

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, &amp;positionServer);
</codeblock> <p>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. </p> <p><b>Supported class types </b> </p> <p>Simulation PSY supports the following class types: </p> <ul><li id="GUID-5FC2F24A-5EF8-55AB-9C58-543D0A4031DB"><p> <xref href="GUID-D5B2E933-209D-3871-8E27-CC5C8855C745.dita"><apiname>TPositionInfo</apiname></xref>  </p> </li> <li id="GUID-28C29243-9A31-57C1-8909-5184CEB1F8A5"><p> <xref href="GUID-B4CD3637-0FC6-38B8-AE89-C03EEC83C50D.dita"><apiname>TPositionCourseInfo</apiname></xref>  </p> </li> <li id="GUID-AF425A02-5B8C-54C9-A0BA-F5F25F40C97C"><p> <xref href="GUID-54AE0674-C49D-3329-8B77-3A58EFFC03D7.dita"><apiname>TPositionSatelliteInfo</apiname></xref>  </p> </li> <li id="GUID-21F63B24-A60A-5554-AC77-C21A096612E6"><p> <xref href="GUID-C0D87E5C-315E-37E6-829E-73F93E83748E.dita"><apiname>HPositionGenericInfo</apiname></xref>  </p> </li> </ul> <p>The argument to <xref href="GUID-1EAEB7EF-0AC7-37C7-B35F-C9B780FFC575.dita#GUID-1EAEB7EF-0AC7-37C7-B35F-C9B780FFC575/GUID-321F6046-3551-3ACE-B0A3-26D51FAEB477"><apiname>RPositioner::NotifyPositionUpdate()</apiname></xref> must be one of the above classes. </p> <p>Note: <codeph>HPositionGenericInfo</codeph>, <codeph>TPositionCourseInfo</codeph> and <codeph>TPositionSatelliteInfo</codeph> are all derived from <codeph>TPositionInfo</codeph>. </p> <p><b>Returned position data </b> </p> <p>The position data that is returned depends on the PSY operating mode: </p> <ul><li id="GUID-1FC5F983-1E68-5BB5-A32A-E8798C464610"><p>NMEA mode </p> <p>The position data that is returned by the PSY depends on the class of the <xref href="GUID-D5B2E933-209D-3871-8E27-CC5C8855C745.dita"><apiname>TPositionInfo</apiname></xref> derived object reference argument passed by the client in its <codeph>NotifyPositionUpdate()</codeph> call. If you use an <xref href="GUID-C0D87E5C-315E-37E6-829E-73F93E83748E.dita"><apiname>HPositionGenericInfo</apiname></xref>, your client application must set the request fields for each type of required position data. The fields are defined by the enumeration <xref href="GUID-4C6802E9-93DE-3457-9A00-88DCA6B392F3.dita"><apiname>_TPositionFieldId</apiname></xref>. If a field is set, Simulation PSY returns the corresponding position data. </p> <p>Example: If the field <codeph>EPositionFieldNMEASentences</codeph> 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 <codeph>TUint8</codeph>. </p> <p>The first NMEA sentence is stored in the <codeph>EPositionFieldNMEASentencesStart</codeph> field. The second sentence is stored in the <codeph>EPositionFieldNMEASentencesStart+1</codeph> field, and so on. The returned type is <codeph>TDesC8</codeph>. </p> <p>The returned position fix data uses the WGS 84 reference coordinate system. </p> </li> <li id="GUID-787F9233-28C2-5BEB-8854-315B3C73FF6C"><p>Simulated movement mode and fixed data mode </p> <p>Only position data defined by the <xref href="GUID-D5B2E933-209D-3871-8E27-CC5C8855C745.dita"><apiname>TPositionInfo</apiname></xref> member variables is returned. Additional position data defined by classes derived from <codeph>TPositionInfo</codeph> is not returned. </p> <p>The returned position fix data uses the WGS 84 reference coordinate system. </p> </li> </ul> <p>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. </p> <p><b>Supported update options </b> </p> <p>You can set position update options using the Location Acquisition API. See using the <xref href="GUID-F6B5F777-D12F-5913-AECE-047DF8C72F1F.dita">How to Get Location Information</xref> for more background information. </p> <p>Simulation PSY supports the following update options: </p> <ul><li id="GUID-B0BDD3F2-9B29-52AA-8671-71085A19050D"><p> <codeph>TPositionUpdateOptions::SetUpdateTimeOut(TTimeIntervalMicroSeconds
                aTimeOut) </codeph> to specify an update timeout for the request. </p> </li> <li id="GUID-3A25A1B0-B138-5168-ABAF-78CDE18F36C1"><p> <codeph>TPositionUpdateOptions::SetUpdateInterval(TTimeIntervalMicroSeconds
                aInterval)</codeph> to support tracking requests. </p> </li> <li id="GUID-625A4475-51A7-5188-8E03-B0EC25C17922"><p> <codeph>TPositionUpdateOptions::SetAcceptPartialUpdates(TBool
                aPartial) </codeph> to accept partial updates (that is, incomplete updates). </p> <p>Partial updates are only supported in NMEA mode. Partial updates are not supported in simulated movement mode. </p> </li> </ul> <p id="GUID-97FF7B3A-9084-5876-ABC0-BFB5156F6AF0"><b>Error codes</b> </p> <p>When you open a session using <xref href="GUID-1EAEB7EF-0AC7-37C7-B35F-C9B780FFC575.dita#GUID-1EAEB7EF-0AC7-37C7-B35F-C9B780FFC575/GUID-AF3D9B5F-8025-3AFF-A101-82025520EBD6"><apiname>RPositioner::Open()</apiname></xref>, one of the following error codes may be returned: </p> <ul><li id="GUID-AC26A58A-C4E1-5FC2-A82E-26007E823A0D"><p> <codeph>KErrNotFound</codeph>  </p> <p>The Simulation PSY cannot find a file it needs. </p> </li> <li id="GUID-41DA4B39-E9DB-59D7-8488-CFE7D679BBFD"><p> <codeph>KErrCorrupt</codeph>  </p> <p>The syntax of the simulated movement file is incorrect or some required data is missing. </p> </li> <li id="GUID-AA74C98F-8F86-5FE7-A353-7C09643E2DAB"><p> <codeph>KErrNotSupported</codeph>  </p> <p>The extension of the simulation file is recognized: it is neither <codeph>.sps</codeph> or <codeph>.nme</codeph>. </p> </li> </ul> <p>When calling <xref href="GUID-1EAEB7EF-0AC7-37C7-B35F-C9B780FFC575.dita#GUID-1EAEB7EF-0AC7-37C7-B35F-C9B780FFC575/GUID-321F6046-3551-3ACE-B0A3-26D51FAEB477"><apiname>RPositioner::NotifyPositionUpdate()</apiname></xref>, one of following error codes may be set for the <codeph>TRequestStatus</codeph>: </p> <ul><li id="GUID-04C4602E-38E5-5616-A9C7-CBB6B51ADAA1"><p> <codeph>KPositionQualityLoss</codeph>  </p> <p>The configuration for requests is set to fail in the simulated movement mode. </p> </li> <li id="GUID-716ED855-E821-58D3-ABCB-C7BC6450E542"><p> <codeph>KPositionPartialUpdate</codeph>  </p> <p>The NMEA data file is missing some position info and the client has allowed partial updates by calling <codeph>TPositionUpdateOptions::SetAcceptPartialUpdates()</codeph>. </p> </li> <li id="GUID-3C81AB1D-7216-5AD5-BC98-E2F1D1ED7BF5"><p>System wide error codes from <codeph>TLexer</codeph> and <codeph>Math</codeph>. </p> </li> <li id="GUID-F35E2BC9-0BF3-5C13-A713-4A3CDA974D59"><p>Other system wide error codes. </p> </li> </ul> <p>When trying to cancel a position update with <xref href="GUID-1EAEB7EF-0AC7-37C7-B35F-C9B780FFC575.dita#GUID-1EAEB7EF-0AC7-37C7-B35F-C9B780FFC575/GUID-BF6665C5-2FC2-3C0D-8C4C-C46DC39B2027"><apiname>RPositioner::CancelRequest()</apiname></xref>, the PSY will return <codeph>KErrCancel</codeph> to notify that the request was properly cancelled. </p> </section> <section id="GUID-AF7C2A8F-AC98-5242-99A0-048D729C20E1"><title>Status reporting</title> <p>See <xref href="GUID-D0318BB6-0B9F-5A1C-AB0B-61BA22D28661.dita">Location Acquisition API</xref> for information on how to retrieve the PSY status. </p> <p>To get the module status from the Simulation PSY, you first need to connect to <codeph>RPositionServer</codeph> and then open a subsession. </p> <p>The following is an example of how to retrieve the module status from Simulation PSY: </p> <codeblock id="GUID-91F03736-0482-5CAF-9FFD-4DFDB0D625B0" xml:space="preserve">
#include &lt;lbs.h&gt;
#include &lt;lbserrors.h&gt;

...

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, &amp;positionServer); // positioner and positionServer
</codeblock> <p>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: </p> <table id="GUID-B4F7B45D-D1E8-5120-B7AE-0B4A3EAE4D3F"><tgroup cols="3"><colspec colname="col0"/><colspec colname="col1"/><colspec colname="col2"/><thead><row><entry>Module Status</entry> <entry>Event Group</entry> <entry>Comment</entry> </row> </thead> <tbody><row><entry><p> <xref href="GUID-F8376F62-46F2-3E7C-9536-920DB6FC6039.dita#GUID-F8376F62-46F2-3E7C-9536-920DB6FC6039/GUID-B2A06538-8FA6-36A4-A954-C824B04AB7A6"><apiname> TPositionModuleStatus::EDeviceError </apiname></xref>  </p> </entry> <entry><p>Device Status </p> </entry> <entry><p>Reported if a data file cannot be found or is corrupt. </p> </entry> </row> <row><entry><p> <xref href="GUID-F8376F62-46F2-3E7C-9536-920DB6FC6039.dita#GUID-F8376F62-46F2-3E7C-9536-920DB6FC6039/GUID-22AD998E-5DF9-328B-8C46-17EA4C144DA5"><apiname> TPositionModuleStatus::EDeviceInactive</apiname></xref>  </p> </entry> <entry><p>Device Status </p> </entry> <entry><p>Reported when Simulation PSY is unloaded. </p> </entry> </row> <row><entry><p> <xref href="GUID-F8376F62-46F2-3E7C-9536-920DB6FC6039.dita#GUID-F8376F62-46F2-3E7C-9536-920DB6FC6039/GUID-01F7CDB2-A069-315D-9450-E86AA580AB07"><apiname>TPositionModuleStatus::EDeviceReady</apiname></xref>  </p> </entry> <entry><p>Device Status </p> </entry> <entry><p>Reported when Simulation PSY is online and ready to retrieve position information. </p> </entry> </row> <row><entry><p> <xref href="GUID-F8376F62-46F2-3E7C-9536-920DB6FC6039.dita#GUID-F8376F62-46F2-3E7C-9536-920DB6FC6039/GUID-8EAB44F9-DD0E-3247-9434-2461751F0C1C"><apiname> TPositionModuleStatus::EDataQualityUnknown</apiname></xref>  </p> </entry> <entry><p>Data Quality Status </p> </entry> <entry><p>Reported when Simulation PSY is unloaded. </p> </entry> </row> <row><entry><p> <xref href="GUID-15215686-5693-3317-8F66-1D265F5D5B76.dita"><apiname>TPositionModuleStatus:EDataQualityNormal</apiname></xref>  </p> </entry> <entry><p>Data Quality Status </p> </entry> <entry><p>Reported when Simulation PSY is online and ready to retrieve position information. </p> </entry> </row> </tbody> </tgroup> </table> </section> <section id="GUID-0BFFF75B-C6FB-577C-AE81-C6D57331C42B"><title>Data file formats</title> <p id="GUID-0C50ACAE-0DC4-5BF9-ADF3-E0DFD6275D3A"><b>NMEA file format</b> </p> <p>Simulation PSY can read data files that contain NMEA sentences based on <xref scope="external" href="http://www.nmea.org">NMEA 0183 version 2.1</xref>. The NMEA file is in 7-bit ASCII format. All lines end with the character ’\n’. The NMEA sentences are case sensitive. </p> <p>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. </p> <p>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. </p> <p>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. </p> <p>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 <xref href="GUID-54AE0674-C49D-3329-8B77-3A58EFFC03D7.dita"><apiname>TPositionSatelliteInfo</apiname></xref> or <xref href="GUID-C0D87E5C-315E-37E6-829E-73F93E83748E.dita"><apiname>HPositionGenericInfo</apiname></xref>. If the object is an instance of <codeph>HPositionGenericInfo</codeph>, the satellite time is stored only if it is a requested field. System time is set in the base class <codeph>TPositionInfo</codeph> for each position update. </p> <p>The following table shows: </p> <ul><li id="GUID-55DD5765-DC70-5593-9837-92BA69275E5E"><p>The supported NMEA sentences. </p> </li> <li id="GUID-BD59A9D8-AB48-5861-A3FE-5E4FF65670CE"><p>The position data in each NMEA sentence. </p> </li> <li id="GUID-1DA441B4-0DC1-5E10-A2CB-84C7AD2DEF54"><p>The object class(es) that can be passed as an argument in <xref href="GUID-1EAEB7EF-0AC7-37C7-B35F-C9B780FFC575.dita#GUID-1EAEB7EF-0AC7-37C7-B35F-C9B780FFC575/GUID-321F6046-3551-3ACE-B0A3-26D51FAEB477"><apiname>RPositioner::NotifyPositionUpdate()</apiname></xref> to get the position data. </p> <p>Note: All NMEA sentences read from the data file are included in <codeph>HPositionGenericInfo</codeph> if <codeph>EPositionFieldNMEASentences</codeph> is set as a requested field. </p> </li> </ul> <table id="GUID-A5462BB8-C7EF-553E-94D6-BC92A9165B56"><tgroup cols="4"><colspec colname="col0"/><colspec colname="col1"/><colspec colname="col2"/><colspec colname="col3"/><thead><row><entry>NMEA sentence</entry> <entry>Position data in the sentence</entry> <entry>TPositionInfo-derived class types that return this data</entry> <entry>Comments</entry> </row> </thead> <tbody><row><entry><p>GGA </p> </entry> <entry><p>Latitude </p> </entry> <entry><p> <xref href="GUID-D5B2E933-209D-3871-8E27-CC5C8855C745.dita"><apiname>TPositionInfo</apiname></xref>  </p> </entry> <entry/></row> <row><entry><p>Longitude </p> </entry> <entry><p> <codeph>TPositionInfo</codeph>  </p> </entry> <entry/></row> <row><entry><p>Altitude (WGS-84) </p> </entry> <entry><p> <codeph>TPositionInfo</codeph>  </p> </entry> <entry><p>Calculated as mean sea level altitude plus geoidal separation. </p> </entry> </row> <row><entry><p>Geoidal separation </p> </entry> <entry><p> <xref href="GUID-C0D87E5C-315E-37E6-829E-73F93E83748E.dita"><apiname>HPositionGenericInfo</apiname></xref>  </p> </entry> <entry/></row> <row><entry><p>Altitude (above sea level) </p> </entry> <entry><p> <codeph>HPositionGenericInfo</codeph>  </p> </entry> <entry><p>Taken directly from GGA. </p> </entry> </row> <row><entry><p>RMC </p> </entry> <entry><p>Satellite time </p> </entry> <entry><p> <xref href="GUID-54AE0674-C49D-3329-8B77-3A58EFFC03D7.dita"><apiname>TPositionSatelliteInfo</apiname></xref>, <codeph>HPositionGenericInfo</codeph>  </p> </entry> <entry/></row> <row><entry><p>True course </p> </entry> <entry><p> <xref href="GUID-B4CD3637-0FC6-38B8-AE89-C03EEC83C50D.dita"><apiname>TPositionCourseInfo</apiname></xref>, <codeph>HPositionGenericInfo</codeph>  </p> </entry> <entry/></row> <row><entry><p>Speed </p> </entry> <entry><p> <codeph>TPositionCourseInfo</codeph>, <codeph>HPositionGenericInfo</codeph>  </p> </entry> <entry/></row> <row><entry><p>Magnetic course </p> </entry> <entry><p> <codeph>HPositionGenericInfo</codeph>  </p> </entry> <entry><p>Calculated as true course + magnetic variation. </p> </entry> </row> <row><entry><p>GSA </p> </entry> <entry><p>Number of used satellites </p> </entry> <entry><p> <codeph>TPositionSatelliteInfo</codeph>, <codeph>HPositionGenericInfo</codeph>  </p> </entry> <entry><p>Number of satellites used in the position fix. </p> </entry> </row> <row><entry><p>PRN (for each satellite) </p> </entry> <entry><p> <codeph>TPositionSatelliteInfo</codeph>  </p> </entry> <entry/></row> <row><entry><p>HDOP </p> </entry> <entry><p> <codeph>TPositionSatelliteInfo</codeph>  </p> </entry> <entry/></row> <row><entry><p>VDOP </p> </entry> <entry><p> <codeph>TPositionSatelliteInfo</codeph>  </p> </entry> <entry/></row> <row><entry><p>PDOP </p> </entry> <entry><p> <codeph>HPositionGenericInfo</codeph>  </p> </entry> <entry><p>If PDOP is not present in the sentence, it is calculated as SQRT(HDOP^2 + VDOP^2). </p> </entry> </row> <row><entry><p>Horizontal accuracy </p> </entry> <entry><p> <codeph>TPositionInfo</codeph>  </p> </entry> <entry><p>Calculated as HDOP * UERE where UERE is 10m. </p> </entry> </row> <row><entry><p>Vertical accuracy </p> </entry> <entry><p> <codeph>TPositionInfo</codeph>  </p> </entry> <entry><p>If fix is in 3D mode, it is calculated as 1.5 * HDOP * UERE where UERE is 10m. </p> </entry> </row> <row><entry><p>GSV </p> </entry> <entry><p>Number of satellites in view </p> </entry> <entry><p> <codeph>TPositionSatelliteInfo</codeph>, <codeph>HPositionGenericInfo</codeph>  </p> </entry> <entry><p>Calculated total number of satellites from GSV sentences. </p> <p>In <codeph>TPositionSatelliteInfo</codeph>, this value indicates how many satellites this information is based on. </p> <p>The number of satellites in view cannot be set explicitly in the data file. </p> </entry> </row> <row><entry><p>Elevation </p> </entry> <entry><p> <codeph>TPositionSatelliteInfo</codeph>  </p> </entry> <entry/></row> <row><entry><p>Azimuth </p> </entry> <entry><p> <codeph>TPositionSatelliteInfo</codeph>  </p> </entry> <entry/></row> <row><entry><p>Signal strength </p> </entry> <entry><p> <codeph>TPositionSatelliteInfo</codeph>  </p> </entry> <entry/></row> <row><entry><p>All </p> </entry> <entry><p>Raw NMEA data </p> </entry> <entry><p> <codeph>HPositionGenericInfo</codeph>  </p> </entry> <entry/></row> </tbody> </tgroup> </table> <p>The following is an example of valid NMEA file content: </p> <codeblock id="GUID-4E426504-DA60-5761-9EE1-F9FB443781AB" xml:space="preserve">
$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
</codeblock> <p> <b>The PSY obtains a simulated position fix after parsing the GLL, GGA, RMC and GSA sentences.</b>  </p> <p>Latitude, longitude, altitude and position accuracy are parsed from the GGA sentence. </p> <p>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. </p> <codeblock id="GUID-F91FC61F-5682-5721-859A-5D163F3786C7" xml:space="preserve">...
$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
...</codeblock> <p>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. </p> <codeblock id="GUID-447A6BC7-F968-5967-B694-AC1A2586E888" xml:space="preserve">...
$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
...</codeblock> <p>The following is an example of incorrect NMEA file content: </p> <codeblock id="GUID-E3B49C5E-763C-5571-A8EF-6BA08887F17B" xml:space="preserve">
$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
</codeblock> <p>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. </p> <p>The Simulation PSY supports NMEA sentences from the following GPS devices: </p> <ul><li id="GUID-7AB5B011-2F55-56E8-93BC-C5471D0BF2ED"><p>Garmin: </p> <ul><li id="GUID-D7045587-3BE5-5C66-9348-B10D4B53A2FE"><p>eTrex – basic </p> </li> <li id="GUID-C9FE128A-C7EA-5842-8A34-3CD3C6AF13A4"><p>eTrex – Legend </p> </li> <li id="GUID-F2EC44E6-8F73-58EA-8533-F4245859F146"><p>III plus </p> </li> <li id="GUID-929CE1B0-A10E-5186-B4E7-54DF28A70FD6"><p>12 cx </p> </li> </ul> </li> <li id="GUID-259CF69F-B839-524B-85C2-6E0FAE7EC1FB"><p>Magellan: </p> <ul><li id="GUID-950034D1-AF25-5E9C-B0CD-BEFEC79875A6"><p>GPS 315 </p> </li> <li id="GUID-063CB474-6699-5A35-8D8B-3B19851F36F9"><p>Meridian Gold </p> </li> <li id="GUID-02AC6F79-7B0A-55D4-891B-B99C5C3A6DFA"><p>Tracker </p> </li> </ul> </li> </ul> <p id="GUID-6042D5D0-5F5C-5503-8CEF-FF011F715003"><b>Simulated movement file format</b> </p> <p>The Simulation PSY operates in Simulated Movement Mode if it can find a data file with the filename extension <codeph>.sps</codeph>. </p> <p>A simulated movement data file has the following format: </p> <codeblock id="GUID-5741C5CF-600D-55DF-825E-43456089AFC8" xml:space="preserve">
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};
</codeblock> <p>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. </p> <p><b>Key-value pairs </b> </p> <p>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. </p> <p>No comments are allowed in the data file. </p> <p>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: </p> <table id="GUID-23B0E1A4-F931-5FF1-A04A-4FFB2807851B"><tgroup cols="5"><colspec colname="col0"/><colspec colname="col1"/><colspec colname="col2"/><colspec colname="col3"/><colspec colname="col4"/><thead><row><entry>Key</entry> <entry>Data type</entry> <entry>Value type</entry> <entry>Value range</entry> <entry>Example values, delimited by ;</entry> </row> </thead> <tbody><row><entry><p> <codeph>Horizontal accuracy</codeph>  </p> </entry> <entry><p>meter (m) </p> </entry> <entry><p>Float </p> </entry> <entry><p>&gt;= 0 </p> </entry> <entry><p>23.56; 56 </p> </entry> </row> <row><entry><p> <codeph>Vertical accuracy</codeph>  </p> </entry> <entry><p>meter (m) </p> </entry> <entry><p>Float </p> </entry> <entry><p>&gt;= 0 </p> </entry> <entry><p>30.89899; 12 </p> </entry> </row> <row><entry><p> <codeph>TimeToFix min</codeph>  </p> </entry> <entry><p>seconds (s) </p> </entry> <entry><p>Integer </p> </entry> <entry><p>&gt;= 0 </p> </entry> <entry><p>0; 2 </p> </entry> </row> <row><entry><p> <codeph>TimeToFix max</codeph>  </p> </entry> <entry><p>seconds (s) </p> </entry> <entry><p>Integer </p> </entry> <entry><p>&gt;= 0 </p> </entry> <entry><p>4; 5 </p> </entry> </row> <row><entry><p> <codeph>Powerup time</codeph>  </p> </entry> <entry><p>seconds (s) </p> </entry> <entry><p>Integer </p> </entry> <entry><p>&gt;= 0 </p> </entry> <entry><p>3; 6 </p> </entry> </row> <row><entry><p>Longitude </p> </entry> <entry><p>degrees </p> </entry> <entry><p>Float </p> </entry> <entry><p>[-180, 180) </p> </entry> <entry><p>-179.686; -180; 180; 0; </p> </entry> </row> <row><entry><p>Latitude </p> </entry> <entry><p>degrees </p> </entry> <entry><p>Float </p> </entry> <entry><p>(-90, 90) </p> </entry> <entry><p>51.568; -90; 90; 0 </p> </entry> </row> <row><entry><p>Speed </p> </entry> <entry><p>meters per second (m/s) </p> </entry> <entry><p>Integer </p> </entry> <entry><p>&gt;= 0 </p> </entry> <entry><p>0; 5 </p> </entry> </row> <row><entry><p>Course </p> </entry> <entry><p>degrees </p> </entry> <entry><p>Integer </p> </entry> <entry><p>(0, 360) </p> </entry> <entry><p>78; 0; 360 </p> </entry> </row> <row><entry><p>Deterministic | Random </p> </entry> <entry><p>error simulation mode </p> </entry> <entry><p>Integer </p> </entry> <entry><p>&gt;= 0 </p> </entry> <entry><p>0; 3; 5 </p> </entry> </row> </tbody> </tgroup> </table> <p>Simulation PSY calculates position updates based on the starting <codeph>Latitude</codeph> and <codeph>Longitude</codeph> values, together with the <codeph>Speed</codeph> and <codeph>Course</codeph>. </p> <p>If <codeph>Speed</codeph> &gt; 0, a new position fix is calculated and returned for each position update. </p> <p>The <codeph>Course</codeph> value is the direction of the simulated movement in degrees (0 and 360 = North, 90 = East, 180 = South and 270 = West). </p> <p><b>Error simulation mode </b> </p> <p>The error simulation mode key specifies how errors are simulated. </p> <p>There are two possible error simulation modes : <codeph>Deterministic</codeph> and <codeph>Random</codeph>: </p> <ul><li id="GUID-37B8EED3-EC3A-5D3B-A14A-21CB64FE47F3"><p> <codeph>Deterministic</codeph>  </p> <p>Positioning fails at the specified frequency value. </p> <p>Example: <codeph>Deterministic = 3</codeph> means that every third position request fails. </p> </li> <li id="GUID-739A6514-6B3A-5192-891A-A11912E4382F"><p> <codeph>Random</codeph>  </p> <p> <codeph>Random</codeph> means that positioning fails intermittently, but with the specified mean frequency. </p> <p> <codeph>Example: Random = 3</codeph> means that out of a 'large' number of requests, on avaerage one third of them will fail. </p> </li> </ul> <p>For both modes, a failure means that the error code <codeph>KPositionQualityLoss</codeph> is set for the client's <codeph>TRequestStatus</codeph> object. </p> <p>Note: To turn off error simulation, set <codeph>Deterministic =
             0</codeph> in your data file. </p> <p><b>Position accuracy calculations </b> </p> <p>A base horizontal and vertical accuracy are specified by the values for <codeph>Horizontal Accuracy</codeph> and <codeph>Vertical Accuracy</codeph> in the data file. </p> <p>For each new position fix generated by the PSY, the specified <codeph>Horizontal Accuracy</codeph> value is multiplied by a randomly generated value. This adjusted accuracy is added as “error” to the calculated position's longitude and latitude. </p> <p>The altitude coordinate starts at 0 meters in the WGS-84 datum. For each new position fix, the specified <codeph>Vertical Accuracy</codeph> value is multiplied by a random generated value. The adjusted accuracy is added as an "error" to the calculated position's altitude. </p> <p>If the syntax of the file is incorrect or some of the settings are missing, the system wide error code <codeph>KErrCorrupt</codeph> is returned by Simulation PSY. This error code is returned when a client opens a positioning subsession by calling <xref href="GUID-1EAEB7EF-0AC7-37C7-B35F-C9B780FFC575.dita#GUID-1EAEB7EF-0AC7-37C7-B35F-C9B780FFC575/GUID-AF3D9B5F-8025-3AFF-A101-82025520EBD6"><apiname>RPositioner::Open()</apiname></xref>. </p> <p>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 <codeph>.sps</codeph> file with the following content: </p> <codeblock id="GUID-FF9927BB-4A90-5A11-B21B-9098B1D5A2AE" xml:space="preserve">
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;
</codeblock> <p>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 <codeph>Powerup time</codeph> value is added (in this case 3 seconds). </p> </section> </conbody><related-links><link href="GUID-45F9389E-F31B-59DA-A4FE-E254EAEB2213.dita"><linktext>Simulation
                PSY Settings API</linktext> </link> <link href="GUID-1A9BA6A1-C6BB-5196-B2D8-355A78B79AE3.dita"><linktext>Simulation
                PSY Overview</linktext> </link> </related-links></concept>