Skip to content

Commit f27cbca

Browse files
tokangasrlubos
authored andcommitted
lib: location: add support for GNSS high accuracy
Added support for GNSS high accuracy fixes. In high accuracy mode, GNSS is allowed to produce several fixes before the library outputs the location. This typically improves location accuracy, at the expense of increased power consumption. Signed-off-by: Tommi Kangas <[email protected]>
1 parent 3e6701d commit f27cbca

File tree

6 files changed

+49
-10
lines changed

6 files changed

+49
-10
lines changed

doc/nrf/libraries/modem/location.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ Each location method has its own implementation for the location retrieval:
4040
precedence as the transport method of GNSS assistance data.
4141
* Note that acquiring GNSS fix only starts when LTE connection, more specifically Radio Resource Control (RRC) connection, is idle.
4242
Also, if A-GPS is not used and Power Saving Mode (PSM) is enabled, Location library will wait for the modem to enter PSM.
43+
* Selectable location accuracy (low/normal/high).
4344
* Cellular positioning
4445
* :ref:`lte_lc_readme` for getting visible cellular base stations.
4546
* :ref:`lib_multicell_location` for sending cell information to the selected location service and getting the calculated location back to the device.

doc/nrf/releases/release-notes-changelog.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,10 @@ Other libraries
272272
* Removed the :kconfig:`CONFIG_DATE_TIME_IPV6` Kconfig option.
273273
The library now automatically uses IPv6 for NTP when available.
274274

275+
* :ref:`lib_location` library:
276+
277+
* Added support for GNSS high accuracy.
278+
275279
Event Manager
276280
+++++++++++++
277281

include/modem/location.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ enum location_accuracy {
5656
LOCATION_ACCURACY_LOW,
5757
/** Normal accuracy. */
5858
LOCATION_ACCURACY_NORMAL,
59+
/** Try to improve accuracy. Increases power consumption. */
60+
LOCATION_ACCURACY_HIGH,
5961
};
6062

6163
/** Location service. */
@@ -145,8 +147,24 @@ struct location_gnss_config {
145147
*/
146148
uint16_t timeout;
147149

148-
/** Desired accuracy level. */
150+
/** @brief Desired accuracy level.
151+
*
152+
* @details If accuracy is set to LOCATION_ACCURACY_LOW, GNSS relaxes the
153+
* criteria for a qualifying fix and may produce fixes using only three satellites.
154+
*
155+
* If accuracy is set to LOCATION_ACCURACY_HIGH, instead of using the first fix, GNSS is
156+
* allowed to run for a longer time. This typically improves the location accuracy.
157+
*/
149158
enum location_accuracy accuracy;
159+
160+
/**
161+
* @brief The number of fixes GNSS is allowed to produce before the library outputs the
162+
* current location when accuracy is set to LOCATION_ACCURACY_HIGH.
163+
*
164+
* @details If accuracy is set to LOCATION_ACCURACY_NORMAL or LOCATION_ACCURACY_LOW this
165+
* parameter has no effect.
166+
*/
167+
uint8_t num_consecutive_fixes;
150168
};
151169

152170
/** LTE cellular positioning configuration. */

lib/location/location.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ static void location_config_method_defaults_set(
128128
if (method_type == LOCATION_METHOD_GNSS) {
129129
method->gnss.timeout = 120;
130130
method->gnss.accuracy = LOCATION_ACCURACY_NORMAL;
131+
method->gnss.num_consecutive_fixes = 3;
131132
} else if (method_type == LOCATION_METHOD_CELLULAR) {
132133
method->cellular.timeout = 30;
133134
method->cellular.service = LOCATION_SERVICE_ANY;

lib/location/location_core.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ static const struct location_method_api *location_method_api_get(enum location_m
135135

136136
static const char LOCATION_ACCURACY_LOW_STR[] = "low";
137137
static const char LOCATION_ACCURACY_NORMAL_STR[] = "normal";
138+
static const char LOCATION_ACCURACY_HIGH_STR[] = "high";
138139

139140
static const char *location_core_gnss_accuracy_str(enum location_accuracy accuracy)
140141
{
@@ -147,6 +148,9 @@ static const char *location_core_gnss_accuracy_str(enum location_accuracy accura
147148
case LOCATION_ACCURACY_NORMAL:
148149
accuracy_str = LOCATION_ACCURACY_NORMAL_STR;
149150
break;
151+
case LOCATION_ACCURACY_HIGH:
152+
accuracy_str = LOCATION_ACCURACY_HIGH_STR;
153+
break;
150154
default:
151155
__ASSERT_NO_MSG(0);
152156
break;

lib/location/method_gnss.c

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ static struct k_work method_gnss_agps_ext_work;
9292
static void method_gnss_agps_ext_work_fn(struct k_work *item);
9393
#endif
9494

95+
static int fixes_remaining;
96+
9597
#if defined(CONFIG_NRF_CLOUD_PGPS)
9698
static void method_gnss_manage_pgps(struct k_work *work)
9799
{
@@ -582,6 +584,8 @@ static void method_gnss_pvt_work_fn(struct k_work *item)
582584
* in memory and it is not overwritten in case we get an invalid fix.
583585
*/
584586
if (pvt_data.flags & NRF_MODEM_GNSS_PVT_FLAG_FIX_VALID) {
587+
fixes_remaining--;
588+
585589
location_result.method = LOCATION_METHOD_GNSS;
586590
location_result.latitude = pvt_data.latitude;
587591
location_result.longitude = pvt_data.longitude;
@@ -595,9 +599,11 @@ static void method_gnss_pvt_work_fn(struct k_work *item)
595599
location_result.datetime.second = pvt_data.datetime.seconds;
596600
location_result.datetime.ms = pvt_data.datetime.ms;
597601

598-
/* We are done, stop GNSS and publish the fix. */
599-
method_gnss_cancel();
600-
location_core_event_cb(&location_result);
602+
if (fixes_remaining <= 0) {
603+
/* We are done, stop GNSS and publish the fix. */
604+
method_gnss_cancel();
605+
location_core_event_cb(&location_result);
606+
}
601607
}
602608
}
603609

@@ -626,22 +632,27 @@ static void method_gnss_positioning_work_fn(struct k_work *work)
626632
#if defined(CONFIG_NRF_CLOUD_AGPS_ELEVATION_MASK)
627633
err |= nrf_modem_gnss_elevation_threshold_set(CONFIG_NRF_CLOUD_AGPS_ELEVATION_MASK);
628634
#endif
635+
/* By default we take the first fix. */
636+
fixes_remaining = 1;
629637

630-
uint8_t use_case;
638+
uint8_t use_case = NRF_MODEM_GNSS_USE_CASE_MULTIPLE_HOT_START;
631639

632640
switch (gnss_config.accuracy) {
633641
case LOCATION_ACCURACY_LOW:
634-
use_case = NRF_MODEM_GNSS_USE_CASE_MULTIPLE_HOT_START |
635-
NRF_MODEM_GNSS_USE_CASE_LOW_ACCURACY;
636-
err |= nrf_modem_gnss_use_case_set(use_case);
642+
use_case |= NRF_MODEM_GNSS_USE_CASE_LOW_ACCURACY;
637643
break;
638644

639645
case LOCATION_ACCURACY_NORMAL:
640-
use_case = NRF_MODEM_GNSS_USE_CASE_MULTIPLE_HOT_START;
641-
err |= nrf_modem_gnss_use_case_set(use_case);
646+
break;
647+
648+
case LOCATION_ACCURACY_HIGH:
649+
/* In high accuracy mode, use the configured fix count. */
650+
fixes_remaining = gnss_config.num_consecutive_fixes;
642651
break;
643652
}
644653

654+
err |= nrf_modem_gnss_use_case_set(use_case);
655+
645656
if (err) {
646657
LOG_ERR("Failed to configure GNSS");
647658
location_core_event_cb_error();

0 commit comments

Comments
 (0)