PyMaemo/Using Location API
(→Location methods) |
(→GPSDevice and GPSDeviceFix) |
||
(6 intermediate revisions not shown) | |||
Line 11: | Line 11: | ||
import location | import location | ||
</source> | </source> | ||
- | Liblocation has two public <code>GObject</code>s. <code>GPSDControl</code. is used for starting and stopping of location services, setting location method and interval, and listening for errors. <code>GPSDevice</code> has information about device status and contains the actual fix when one exists. The two <code>GObjects</code> are initiated as follows. | + | Liblocation has two public <code>GObject</code>s. <code>GPSDControl</code>. is used for starting and stopping of location services, setting location method and interval, and listening for errors. <code>GPSDevice</code> has information about device status and contains the actual fix when one exists. The two <code>GObjects</code> are initiated as follows. |
<source lang="python"> | <source lang="python"> | ||
control = location.GPSDControl.get_default() | control = location.GPSDControl.get_default() | ||
device = location.GPSDevice() | device = location.GPSDevice() | ||
</source> | </source> | ||
+ | |||
== Location methods == | == Location methods == | ||
Line 26: | Line 27: | ||
* <code>location.METHOD_AGNSS</code> (Assisted Global Navigation Satellite System) - A method for using GPS receiver with assistance data from external location server. A SIM card and a network connection is needed for AGNSS method. If no network connection or SIM card is available, this equals to GNSS. | * <code>location.METHOD_AGNSS</code> (Assisted Global Navigation Satellite System) - A method for using GPS receiver with assistance data from external location server. A SIM card and a network connection is needed for AGNSS method. If no network connection or SIM card is available, this equals to GNSS. | ||
- | Location resources are shared between applications, and applications can request different location methods. Fixes for all requested methods are sent for all applications listening to <code>GPSDevice</code>'s "changed" signal, therefore application should judge whether fix it is receiving, is one that it needs. See [[#GPSDevice and GPSDeviceFix|GPSDeviceFix]] section for discussion. | + | Location resources are shared between applications, and applications can request different location methods. Fixes for all requested methods are sent for all applications listening to <code>GPSDevice</code>'s "<code>changed</code>" signal, therefore application should judge whether fix it is receiving, is one that it needs. See [[#GPSDevice and GPSDeviceFix|GPSDeviceFix]] section for discussion. |
If device is set for bluetooth GPS from control panel, it can used for locationing via USER_SELECTED, AGNSS and GNSS methods. In this case AGNSS and GNSS do not differ, because assistance server cannot be utilized. | If device is set for bluetooth GPS from control panel, it can used for locationing via USER_SELECTED, AGNSS and GNSS methods. In this case AGNSS and GNSS do not differ, because assistance server cannot be utilized. | ||
Line 44: | Line 45: | ||
Here is table that summarizes differences between the methods. Accuracy refers to horizontal accuracy of the fix. | Here is table that summarizes differences between the methods. Accuracy refers to horizontal accuracy of the fix. | ||
- | {| class="wikitable" | + | {| class="wikitable" |
+ | |+ Available location methods | ||
+ | |- | ||
! Method !! Typical accuracy !! Requires SIM !! Requires network !! Drains battery | ! Method !! Typical accuracy !! Requires SIM !! Requires network !! Drains battery | ||
|- | |- | ||
- | | CWP || | + | | CWP || 1 - 1000 km || Yes || No || No |
|- | |- | ||
- | | ACWP || | + | | ACWP || 1 - 10 km || Yes || Yes || No |
|- | |- | ||
- | | GNSS || | + | | GNSS || 5 - 100 m || No || No || Yes |
|- | |- | ||
- | | AGNSS || | + | | AGNSS || 5 - 100 m || Yes || Yes || Yes |
|} | |} | ||
Line 66: | Line 69: | ||
== GPSDevice and GPSDeviceFix == | == GPSDevice and GPSDeviceFix == | ||
- | <code>GPSDevice</code> object has the following attributes ('''FIXME:''' currently "satellites" and "cell_info" attributes are not supported in Python): | + | <code>GPSDevice</code> object has the following attributes ('''FIXME:''' currently "<code>satellites</code>" and "<code>cell_info</code>" attributes are not supported in Python): |
- | *online: Whether there is a connection to the hardware | + | *<code>online</code>: Whether there is a connection to the hardware |
- | *status: Status of the device | + | *<code>status</code>: Status of the device |
- | *fix: Tuple containing actual fix data (latitude, longitude, etc) | + | *<code>fix</code>: Tuple containing actual fix data (latitude, longitude, etc) |
- | *satellites_in_view: Number of satellites in view | + | *<code>satellites_in_view</code>: Number of satellites in view |
- | *satellites_in_use: Number of satellites in use | + | *<code>satellites_in_use</code>: Number of satellites in use |
- | *satellites: Tuple containing information about satellites | + | *<code>satellites</code>: Tuple containing information about satellites |
- | *cell_info: Tuple containing information about cell the device is connected to | + | *<code>cell_info</code>: Tuple containing information about cell the device is connected to |
- | The most useful attribute is naturally the "fix" tuple which contains position and movement of the device and accuracies for them. The available information is listed below (in the order they appear on the tuple). In parenthesis there is a identifier which can be bitwisely anded with the "fields" value, to see whether corresponding tuple value is set. | + | The most useful attribute is naturally the "<code>fix</code>" tuple which contains position and movement of the device and accuracies for them. The available information is listed below (in the order they appear on the tuple). In parenthesis there is a identifier which can be bitwisely anded with the "fields" value, to see whether corresponding tuple value is set. |
- | *mode: The mode of the fix | + | *<code>mode</code>: The mode of the fix |
- | *fields: A bitfield representing which items of this tuple contain valid data | + | *<code>fields</code>: A bitfield representing which items of this tuple contain valid data |
- | *time: The timestamp of the update (<code>location.GPS_DEVICE_TIME_SET</code>) | + | *<code>time</code>: The timestamp of the update (<code>location.GPS_DEVICE_TIME_SET</code>) |
- | *ept: Time accuracy | + | *<code>ept</code>: Time accuracy |
- | *latitude: Fix latitude (<code>location.GPS_DEVICE_LATLONG_SET</code>) | + | *<code>latitude</code>: Fix latitude (<code>location.GPS_DEVICE_LATLONG_SET</code>) |
- | *longitude: Fix longitude (<code>location.GPS_DEVICE_LATLONG_SET</code>) | + | *<code>longitude</code>: Fix longitude (<code>location.GPS_DEVICE_LATLONG_SET</code>) |
- | *eph: Horizontal position accuracy | + | *<code>eph</code>: Horizontal position accuracy |
- | *altitude: Fix altitude in meters (<code>location.GPS_DEVICE_ALTITUDE_SET</code>) | + | *<code>altitude</code>: Fix altitude in meters (<code>location.GPS_DEVICE_ALTITUDE_SET</code>) |
- | *double epv: Vertical position accuracy | + | *double <code>epv</code>: Vertical position accuracy |
- | *track: Direction of motion in degrees (<code>location.GPS_DEVICE_TRACK_SET</code>) | + | *<code>track</code>: Direction of motion in degrees (<code>location.GPS_DEVICE_TRACK_SET</code>) |
- | *epd: Track accuracy | + | *<code>epd</code>: Track accuracy |
- | *speed: Current speed in km/h (<code>location.GPS_DEVICE_SPEED_SET</code>) | + | *<code>speed</code>: Current speed in km/h (<code>location.GPS_DEVICE_SPEED_SET</code>) |
- | *eps: Speed accuracy | + | *<code>eps</code>: Speed accuracy |
- | *climb: Current rate of climb in m/s (<code>location.GPS_DEVICE_CLIMB_SET</code>) | + | *<code>climb</code>: Current rate of climb in m/s (<code>location.GPS_DEVICE_CLIMB_SET</code>) |
- | *epc: Climb accuracy | + | *<code>epc</code>: Climb accuracy |
- | An application receiving a fix cannot know if the fix is a result from location method it requested. Therefore application should study whether fix is accurate enough to satisfy application's needs. This can be done by inspecting "eph" field, which is fix's horizontal accuracy in centimeters. Typical values for horizontal accuracies can be seen in the location methods table. If accuracy is not known, it has a value of NaN. | + | An application receiving a fix cannot know if the fix is a result from location method it requested. Therefore application should study whether fix is accurate enough to satisfy application's needs. This can be done by inspecting "<code>eph</code>" field, which is fix's horizontal accuracy in centimeters. Typical values for horizontal accuracies can be seen in the location methods table. If accuracy is not known, it has a value of NaN. |
== Liblocation signals and callbacks == | == Liblocation signals and callbacks == | ||
Line 136: | Line 139: | ||
print "Satellites in view: %d, in use: %d" % (device.satellites_in_view, device.satellites_in_use) | print "Satellites in view: %d, in use: %d" % (device.satellites_in_view, device.satellites_in_use) | ||
</source> | </source> | ||
- | Liblocation sends a "changed" signal also after locationing is started or stopped, in which case a last known fix is sent if such exists. Application can differentiate these fixes from real ones by inspecting <code>device.status</code> attribute which equals <code>location.GPS_DEVICE_STATUS_NO_FIX</code> if the fix is not real. | + | Liblocation sends a "<code>changed</code>" signal also after locationing is started or stopped, in which case a last known fix is sent if such exists. Application can differentiate these fixes from real ones by inspecting <code>device.status</code> attribute which equals <code>location.GPS_DEVICE_STATUS_NO_FIX</code> if the fix is not real. |
== Starting and stopping locationing == | == Starting and stopping locationing == | ||
Line 165: | Line 168: | ||
if device.fix[1] & location.GPS_DEVICE_LATLONG_SET: | if device.fix[1] & location.GPS_DEVICE_LATLONG_SET: | ||
print "lat = %f, long = %f" % device.fix[4:6] | print "lat = %f, long = %f" % device.fix[4:6] | ||
- | data.stop() | + | # data.stop() commented out to allow continuous loop for a reliable fix - press ctrl c to break the loop, or program your own way of exiting) |
def on_stop(control, data): | def on_stop(control, data): |
Latest revision as of 17:14, 22 February 2017
Location framework provides a library called liblocation which is used for developing location-aware applications in Fremantle. Liblocation supports internal GPS, network based methods and external bluetooth GPS.
Contents |
[edit] Using liblocation from Python
To start implementing applications using liblocation API on Python, you need to install python-location:
[sbox-FREMANTLE_X86: ~] > apt-get install python-location
Then, on your Python scripts, import the location module:
import location
Liblocation has two public GObject
s. GPSDControl
. is used for starting and stopping of location services, setting location method and interval, and listening for errors. GPSDevice
has information about device status and contains the actual fix when one exists. The two GObjects
are initiated as follows.
control = location.GPSDControl.get_default() device = location.GPSDevice()
[edit] Location methods
Liblocation supports the following location methods which are defined in the location
module:
-
location.METHOD_USER_SELECTED
- Liblocation will choose the best possible location method based on location settings in control panel. You can think of it as asking all the methods CWP+ACWP+GNSS+AGNSS. Choose this method if you don't have any special needs. -
location.METHOD_CWP
(Complementary Wireless Positioning) - This method provides either coordinates for center of current country with horizontal accuracy equalling radius of the country (MCC fix), or coordinates based on currently used GSM base station. Latter is used if such information exists in device's cache, which is updated when ACWP method is used. SIM card is needed for CWP method. -
location.METHOD_ACWP
(Assisted Complementary Wireless Positioning) - A method where device is located based on cellular base station to which device is registered to. SIM card and a network connection is needed for ACWP method. If no network connection is available, this equals to CWP. Application might receive MCC fixes before base station information from external location server is fetched and as a fallback if e.g. network is temporary unavailable. -
location.METHOD_GNSS
(Global Navigation Satellite System) - A method for using GPS receiver. Typically time for the first fix is significantly longer than with AGNSS. Neither SIM card nor network connection is needed for GNSS method, and GNSS can even be used in offline mode. -
location.METHOD_AGNSS
(Assisted Global Navigation Satellite System) - A method for using GPS receiver with assistance data from external location server. A SIM card and a network connection is needed for AGNSS method. If no network connection or SIM card is available, this equals to GNSS.
Location resources are shared between applications, and applications can request different location methods. Fixes for all requested methods are sent for all applications listening to GPSDevice
's "changed
" signal, therefore application should judge whether fix it is receiving, is one that it needs. See GPSDeviceFix section for discussion.
If device is set for bluetooth GPS from control panel, it can used for locationing via USER_SELECTED, AGNSS and GNSS methods. In this case AGNSS and GNSS do not differ, because assistance server cannot be utilized.
Device caches cell information for ACWP and satellite information for AGNSS. Hence if a non-assisted location method is used immediately after it's assisted counterpart, it will probably work as the assisted one.
Location method is set as GPSDControl
's "preferred-method" property. Several methods can be given by bitwise or'ing the method identifiers:
control.set_properties(preferred_method=location.METHOD_GNSS|location.METHOD_AGNSS)
ACWP and AGNSS methods require network positioning and GNSS and AGNSS require GPS to be enabled in location settings. If requirements for asked methods are not enabled when starting location, user is prompted a dialog to enable them. After that all the possible preferred-methods are started. If there is any, an error to application is signalled.
USER_SELECTED method makes expection to dialog rule. Albeit it uses all of the methods: CWP+ACWP+GNSS+AGNSS, dialog is shown only if both networking and gps are disabled.
If user changes location settings during location session, then used location method is modified to best available accordingly, and error signalled if none is available.
Here is table that summarizes differences between the methods. Accuracy refers to horizontal accuracy of the fix.
Method | Typical accuracy | Requires SIM | Requires network | Drains battery |
---|---|---|---|---|
CWP | 1 - 1000 km | Yes | No | No |
ACWP | 1 - 10 km | Yes | Yes | No |
GNSS | 5 - 100 m | No | No | Yes |
AGNSS | 5 - 100 m | Yes | Yes | Yes |
[edit] Location intervals
Liblocation supports a default interval (equals to one second) and intervals of 1, 2, 5, 10, 20, 30, 60 and 120 seconds between fixes. Due to performance and power consumption reasons, all the intervals provide fixes only if position of the device has changed. Therefore the interval reflects more how often device checks for coordinate changes, than the actual interval between fixes. Nature of GPS fixes being constantly changing guarantees that GPS fixes are provided with requested interval. However, if there are several applications using different intervals, then the used interval is the minimum of intervals requested by all applications.
Location interval is set as GPSDControl
's "preferred-interval" property:
control.set_properties(preferred_interval=location.INTERVAL_60S)
[edit] GPSDevice and GPSDeviceFix
GPSDevice
object has the following attributes (FIXME: currently "satellites
" and "cell_info
" attributes are not supported in Python):
online
: Whether there is a connection to the hardwarestatus
: Status of the devicefix
: Tuple containing actual fix data (latitude, longitude, etc)satellites_in_view
: Number of satellites in viewsatellites_in_use
: Number of satellites in usesatellites
: Tuple containing information about satellitescell_info
: Tuple containing information about cell the device is connected to
The most useful attribute is naturally the "fix
" tuple which contains position and movement of the device and accuracies for them. The available information is listed below (in the order they appear on the tuple). In parenthesis there is a identifier which can be bitwisely anded with the "fields" value, to see whether corresponding tuple value is set.
mode
: The mode of the fixfields
: A bitfield representing which items of this tuple contain valid datatime
: The timestamp of the update (location.GPS_DEVICE_TIME_SET
)ept
: Time accuracylatitude
: Fix latitude (location.GPS_DEVICE_LATLONG_SET
)longitude
: Fix longitude (location.GPS_DEVICE_LATLONG_SET
)eph
: Horizontal position accuracyaltitude
: Fix altitude in meters (location.GPS_DEVICE_ALTITUDE_SET
)- double
epv
: Vertical position accuracy track
: Direction of motion in degrees (location.GPS_DEVICE_TRACK_SET
)epd
: Track accuracyspeed
: Current speed in km/h (location.GPS_DEVICE_SPEED_SET
)eps
: Speed accuracyclimb
: Current rate of climb in m/s (location.GPS_DEVICE_CLIMB_SET
)epc
: Climb accuracy
An application receiving a fix cannot know if the fix is a result from location method it requested. Therefore application should study whether fix is accurate enough to satisfy application's needs. This can be done by inspecting "eph
" field, which is fix's horizontal accuracy in centimeters. Typical values for horizontal accuracies can be seen in the location methods table. If accuracy is not known, it has a value of NaN.
[edit] Liblocation signals and callbacks
The most useful signal in liblocation is GPSDevice
's "changed" signal, which is emitted everytime a new fix is received. GPSDControl
has an "error-verbose" signal which is emitted in case of an error. There is also a legacy signal "error", which doesn't give a reason for error.
You can connect to these signals in the usual way:
control.connect("error-verbose", on_error, user_data) device.connect("changed", on_changed, user_data)
Below are examples for these signals' callbacks.
def on_error(control, error, user_data): if error == location.ERROR_USER_REJECTED_DIALOG: print "User didn't enable requested methods" elif error == location.ERROR_USER_REJECTED_SETTINGS: print "User changed settings, which disabled location" elif error == location.ERROR_BT_GPS_NOT_AVAILABLE: print "Problems with BT GPS" elif error == location.ERROR_METHOD_NOT_ALLOWED_IN_OFFLINE_MODE: print "Requested method is not allowed in offline mode" elif error == location.ERROR_SYSTEM: print "System error" def on_changed(device, user_data): if not device: return if device.fix: if device.fix[1] & location.GPS_DEVICE_LATLONG_SET: print "lat = %f, long = %f" % device.fix[4:6] if device.fix[1] & location.GPS_DEVICE_ALTITUDE_SET: print "alt = %f" % device.fix[7] print "horizontal accuracy: %f meters" % (device.fix[6] / 100) # FIXME: not supported yet in Python #if device.cell_info: # if device.cell_info[0] & location.GSM_CELL_INFO_SET: # print "Mobile Country Code GSM: %d" % device.cell_info[1][0] # if device.cell_info[0] & location.WCDMA_CELL_INFO_SET: # print "Mobile Country Code WCDMA: %d" % device.cell_info[2][0] print "Satellites in view: %d, in use: %d" % (device.satellites_in_view, device.satellites_in_use)
Liblocation sends a "changed
" signal also after locationing is started or stopped, in which case a last known fix is sent if such exists. Application can differentiate these fixes from real ones by inspecting device.status
attribute which equals location.GPS_DEVICE_STATUS_NO_FIX
if the fix is not real.
[edit] Starting and stopping locationing
Finally after everything above has been done, locationing can be started.
control.start()
If the chosen location method violates control panel location settings, then a dialog is shown to user. Dialogs ask user to enable necessary services. On user's refusal an error to application is sent. If no error is seen, fixes should be coming after a while. When locationing is no longer needed, it can be stopped.
control.stop()
[edit] Complete example
Here is a complete standalone example using liblocation. It starts location services after program is started, then when first fix arrives, prints it, stops services, and shutdowns.
import location import gobject def on_error(control, error, data): print "location error: %d... quitting" % error data.quit() def on_changed(device, data): if not device: return if device.fix: if device.fix[1] & location.GPS_DEVICE_LATLONG_SET: print "lat = %f, long = %f" % device.fix[4:6] # data.stop() commented out to allow continuous loop for a reliable fix - press ctrl c to break the loop, or program your own way of exiting) def on_stop(control, data): print "quitting" data.quit() def start_location(data): data.start() return False loop = gobject.MainLoop() control = location.GPSDControl.get_default() device = location.GPSDevice() control.set_properties(preferred_method=location.METHOD_USER_SELECTED, preferred_interval=location.INTERVAL_DEFAULT) control.connect("error-verbose", on_error, loop) device.connect("changed", on_changed, control) control.connect("gpsd-stopped", on_stop, loop) gobject.idle_add(start_location, control) loop.run()
You can run this example with the following command:
run-standalone.sh python2.5 test.py
Important: do not name your script "location.py". Otherwise, Python will try to import it as a module, instead of the correct "location" module, and you will get errors like:
Traceback (most recent call last): File "location.py", line 1, in <module> import location File "/home/user/location.py", line 25, in <module> control = location.GPSDControl.get_default() AttributeError: 'module' object has no attribute 'GPSDControl'
- This page was last modified on 22 February 2017, at 17:14.
- This page has been accessed 37,618 times.