This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

GPS timeout and interval (with SUPL A-GPS)

Hi,

OS: Windows 10
Editor: SEGGER Embedded Studio for ARM (Nordic Edition) V5.50c (64-bit)
nrfjprog version: 10.13.0
JLinkARM.dll version: 7.50a
nRF Connect SDK version: 1.6.0
SUPL client library version: v0.7.0
nRF9160 modem firmware version: 1.2.3

I'm having some problems with GPS and SUPL client library on our custom nRF9160 device. I'm using the nRF9160 GPS driver with a periodic GPS search mode and I have a similar gps_controller than Asset Tracker has. I also have PSM enabled.

In purpose, I tested the device inside a building so it won't get a GPS fix and see what the device is doing then. I'm not happy with the results. I see that timeout and interval is not working properly there.

Below is parts of the project configuration, code and also logs from the device.

prj.conf

# GPS
CONFIG_NRF9160_GPS=y
CONFIG_GPS_CONTROL_FIX_CHECK_INTERVAL=1200
CONFIG_GPS_CONTROL_FIX_TRY_TIME=180

# AGPS
CONFIG_AGPS=y
CONFIG_AGPS_SRC_SUPL=y
CONFIG_FPU=y

# Heap and stacks
CONFIG_HEAP_MEM_POOL_SIZE=16384
CONFIG_MAIN_STACK_SIZE=8192
CONFIG_APPLICATION_WORKQUEUE_STACK_SIZE=4096
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=8192
CONFIG_IDLE_STACK_SIZE=2048
CONFIG_NRF_MODEM_LIB_HEAP_SIZE=2048
CONFIG_NRF9160_GPS_THREAD_STACK_SIZE=4608

gps_controller.c

/* GPS search configuration */
struct gps_config gps_cfg = {
	.nav_mode = GPS_NAV_MODE_PERIODIC,
	.power_mode = GPS_POWER_MODE_DISABLED,
	.use_case = GPS_USE_CASE_SINGLE_COLD_START,
	.accuracy = GPS_ACCURACY_NORMAL,
	.timeout = CONFIG_GPS_CONTROL_FIX_TRY_TIME,
	.interval = CONFIG_GPS_CONTROL_FIX_TRY_TIME +
		CONFIG_GPS_CONTROL_FIX_CHECK_INTERVAL,
	.delete_agps_data = false,
	.priority = true,
};

main.c

#if defined(CONFIG_AGPS)
/* Request A-GPS data no more often than every hour (time in milliseconds). */
#define AGPS_UPDATE_PERIOD (60 * 60 * 1000)
static struct gps_agps_request agps_request;
static struct k_work_delayable send_agps_request_work;
#endif /* CONFIG_AGPS */


#if defined(CONFIG_AGPS)
/**@brief Request AGPS data. */
static void send_agps_request(struct k_work *work)
{
	ARG_UNUSED(work);

	int err;
	static int64_t last_request_timestamp;

	if ((last_request_timestamp != 0) &&
	   (k_uptime_get() - last_request_timestamp < AGPS_UPDATE_PERIOD)) {
		LOG_WRN("A-GPS request was sent less than 1 hour ago");
		return;
	}

	LOG_INF("Sending A-GPS request");

	err = gps_agps_request_send(agps_request, GPS_SOCKET_NOT_PROVIDED);
	if (err) {
		LOG_ERR("Failed to request A-GPS data, error: %d", err);
		return;
	}

	last_request_timestamp = k_uptime_get();
}
#endif /* CONFIG_AGPS */


/**@brief Callback for GPS events. */
static void gps_handler(const struct device *dev, struct gps_event *evt)
{
...
	case GPS_EVT_AGPS_DATA_NEEDED:
		LOG_INF("GPS_EVT_AGPS_DATA_NEEDED");
#if defined(CONFIG_AGPS)
		/* Send A-GPS request with short delay to avoid LTE network-
		 * dependent corner-case where the request would not be sent.
		 */
		memcpy(&agps_request, &evt->agps_request, sizeof(agps_request));
		k_work_reschedule_for_queue(&application_work_q,
						&send_agps_request_work,
						K_SECONDS(1));
#endif /* CONFIG_AGPS */
		break;
...
	}
}

/**@brief Main function. */
void main(void)
{
...
#if defined(CONFIG_AGPS)
	k_work_init_delayable(&send_agps_request_work, send_agps_request);
#endif /* CONFIG_AGPS */
...
}

log

[00:00:24.650,848] [1B][0m<inf> gps_control: GPS config set: Timeout = 180, Interval = 1380[1B][0m
[00:00:24.659,881] [1B][0m<inf> application: Enabling GPS[1B][0m
[00:00:24.665,954] [1B][0m<inf> gps_control: GPS starting in 0 seconds[1B][0m
[00:00:24.673,675] [1B][0m<dbg> nrf9160_gps.enable_gps: GPS mode is enabled[1B][0m
[00:00:24.686,340] [1B][0m<dbg> nrf9160_gps.start: GPS operational[1B][0m
[00:00:24.692,901] [1B][0m<inf> gps_control: GPS started successfully. Searching for satellites 
to get position fix. This may take several minutes.
The device will attempt to get a fix for 180 seconds, 
before the GPS is stopped. It's restarted every 1200 seconds[1B][0m
[00:00:24.718,627] [1B][0m<inf> application: GPS_EVT_SEARCH_STARTED[1B][0m
[00:00:24.725,708] [1B][0m<dbg> nrf9160_gps.gps_thread: A-GPS data update needed[1B][0m
[00:00:24.733,642] [1B][0m<inf> application: GPS_EVT_AGPS_DATA_NEEDED[1B][0m
[00:00:25.693,237] [1B][0m<dbg> nrf9160_gps.gps_thread: Waiting for time window to operate[1B][0m
[00:00:25.702,117] [1B][0m<inf> application: GPS_EVT_OPERATION_BLOCKED[1B][0m
[00:00:25.740,905] [1B][0m<inf> application: Sending A-GPS request[1B][0m
[00:00:25.747,772] [1B][0m<dbg> agps.init_supl: Using GPS driver to input assistance data[1B][0m
[00:00:25.756,622] [1B][0m<inf> agps: SUPL is initialized[1B][0m
[00:00:25.884,735] [1B][0m<dbg> agps.open_supl_socket: ip 142.250.150.192 (c096fa8e) port 7276[1B][0m
[00:00:25.971,160] [1B][0m<inf> agps: Starting SUPL session[1B][0m

[00:00:28.325,286] [1B][0m<dbg> agps.supl_logger: SUPL session finished[1B][0m
[00:00:28.332,366] [1B][0m<inf> agps: SUPL session finished successfully[1B][0m
[00:00:28.339,599] [1B][0m<dbg> net_sock.z_impl_zsock_close: (application_work_q): close: ctx=0x20021200, fd=1[1B][0m
[00:00:35.718,322] [1B][0m<dbg> nrf9160_gps.gps_priority_set: GPS priority enabled[1B][0m
%CESQ: 255,0,255,0
[00]+CSCON: 0
[00][00:00:40.088,928] [1B][0m<dbg> lte_lc.at_handler: +CSCON notification[1B][0m
[00:00:40.096,038] [1B][0m<inf> application: RRC mode: Idle[1B][0m
[00:00:40.152,313] [1B][0m<dbg> nrf9160_gps.gps_thread: GPS has time window to operate[1B][0m
[00:00:40.160,797] [1B][0m<inf> application: GPS_EVT_OPERATION_UNBLOCKED[1B][0m
[00:00:40.168,334] [1B][0m<dbg> nrf9160_gps.print_satellite_stats: Tracking: 0 Using: 0 Unhealthy: 0[1B][0m
[00:00:40.178,222] [1B][0m<dbg> nrf9160_gps.print_satellite_stats: Seconds since last fix 40[1B][0m

[00:03:24.098,236] [1B][0m<dbg> nrf9160_gps.print_satellite_stats: Seconds since last fix 204[1B][0m
[00:03:29.107,727] [1B][0m<inf> application: GPS_EVT_SEARCH_TIMEOUT[1B][0m
[00:03:29.114,685] [1B][0m<inf> application: GPS will try to get fix again after 1200 seconds,
and will try again 2 more times[1B][0m
[00:12:15.414,703] [1B][0m<inf> application: GPS_EVT_SEARCH_STARTED[1B][0m
[00:12:15.421,661] [1B][0m<dbg> nrf9160_gps.print_satellite_stats: Tracking: 0 Using: 0 Unhealthy: 0[1B][0m
[00:12:15.431,549] [1B][0m<dbg> nrf9160_gps.print_satellite_stats: Seconds since last fix 735[1B][0m

[00:26:24.443,939] [1B][0m<dbg> nrf9160_gps.print_satellite_stats: Seconds since last fix 1584[1B][0m
[00:26:29.453,521] [1B][0m<inf> application: GPS_EVT_SEARCH_TIMEOUT[1B][0m
[00:26:29.460,479] [1B][0m<inf> application: GPS will try to get fix again after 1200 seconds,
and will try again 1 more times[1B][0m
[00:37:15.449,981] [1B][0m<inf> application: GPS_EVT_SEARCH_STARTED[1B][0m
[00:37:15.456,939] [1B][0m<dbg> nrf9160_gps.print_satellite_stats: Tracking: 0 Using: 0 Unhealthy: 0[1B][0m
[00:37:15.466,857] [1B][0m<dbg> nrf9160_gps.print_satellite_stats: Seconds since last fix 2235[1B][0m

[00:49:24.476,348] [1B][0m<dbg> nrf9160_gps.print_satellite_stats: Seconds since last fix 2964[1B][0m
[00:49:29.485,961] [1B][0m<inf> application: GPS_EVT_SEARCH_TIMEOUT[1B][0m
[00:49:29.492,919] [1B][0m<inf> application: Disabling GPS[1B][0m
[00:49:29.499,084] [1B][0m<inf> gps_control: GPS stopping in 0 seconds[1B][0m
[00:49:29.506,134] [1B][0m<dbg> nrf9160_gps.stop_gps: Stopping GPS[1B][0m
[00:49:29.521,514] [1B][0m<inf> gps_control: GPS operation was stopped[1B][0m
[00:49:29.528,503] [1B][0m<inf> application: GPS_EVT_SEARCH_STOPPED[1B][0m

I read this ticket and I think that almanac downloads might have something to do with this. But shouldn't it already have ephemerides and almanacs downloaded from SUPL?

Is there any way to avoid those downloads or make timeout and interval working properly?

Or am I doing something wrong on A-GPS request?

It's killing the battery pretty fast when GPS is active for so long.

Regards,
Tero

Parents Reply
  • Hi ,

    After a short testing of the A-GPS sample, I saw the same behavior when using the same timeout and interval values as I do have in my own project. The defaults (timeout 120 and interval 240) worked properly but when I changed the timeout to 180 and the interval to 180+1200 it's failing again.

    I will test that more and try to see what is the thing there that causes that unexpected behavior.

    Is there any maximum values that timeout or interval could be? At least I haven't see any.

Children
  • I'm still finding values which are working.

    But I find something in nrf_socket.h:

    /**@brief Defines the interval between each fix in seconds.
     * @details Allowed values are 0, 1, 10..1800, value 0 denotes single fix.
     *          Default interval is 1 second (continous mode), 0 denotes a single fix.
     * @deprecated since v1.2.0.
     */
    typedef uint16_t nrf_gnss_fix_interval_t;
    
    /**@brief Defines how long (in seconds) the receiver should try to get a fix.
     * @details The default retry wait time is 60 seconds before it gives up.
     *          0 denotes an infinite limit.
     * @deprecated since v1.2.0.
     */
    typedef uint16_t nrf_gnss_fix_retry_t;

    It seems that 1800 seconds should be the maximum allowed value for interval. So my value (180+1200) should be allowed there.

    What those "@deprecated since v1.2.0." lines means? Those should not work anymore or? And what's that version, modem FW or SDK?

    The nRF9160 GPS driver is still using that nrf_gnss_fix_interval_t on its nrf9160_gps_config structure.

    I got to say I'm really confused with this issue.

  • For now, I have tested these:

    /* WORKING 3+3min */
    		.timeout = 180,
    		.interval = 180 + 180,
    
    /* WORKING 3+5min */
    		.timeout = 180,
    		.interval = 180 + 300,
    
    /* WORKING 3+7min */
    		.timeout = 180,
    		.interval = 180 + 420,
    
    /* WORKING 3+8min */
    		.timeout = 180,
    		.interval = 180 + 480,
    
    /* NOT WORKING 3+9min */
    		.timeout = 180,
    		.interval = 180 + 540,
    
    /* NOT WORKING 3+10min */
    		.timeout = 180,
    		.interval = 180 + 600,
    
    /* NOT WORKING 3+15min */
    		.timeout = 180,
    		.interval = 180 + 900,
    
    /* NOT WORKING 3+20min */
    		.timeout = 180,
    		.interval = 180 + 1200,

    I will test more tomorrow.

  • Hi Tero,

    Sorry for the delayed answer. I've talked to our development team regarding the GNSS. 

     

    anicare-tero said:
    What those "@deprecated since v1.2.0." lines means?

     There is a new GNSS API developed to improve usability of the GNSS, and to move away from the GPS driver. This can be used with modem FW 1.2.3, but will improve usability on mfw 1.3.0. Currently, the GPS sample has been updated with this, while there is still ongoing work to introduce more imrprovement.
    https://github.com/nrfconnect/sdk-nrfxlib/blob/100872a0e1052931c4bad505e709a92912d4743b/nrf_modem/include/nrf_modem_gnss.h

    Also, please note that the SUPL library is now available as v 0.7.1

    SUPL client library v0.7.1
    Changelog:
    
    Added soft-float build of the library.
    Fixed cell ID encoding in the sent request, so that the server can determine the location of the device and send a reference location back to the device. The MCC table is used as a fall back in case no reference location is received from the server.
    Reference location is now only injected if it was requested.
    Fixed usage of an IPv6 address as the device ID.
    Removed the dependency to the modem library (modemlib). This version works with both modem and old bsdlib (sdk-nrfxlib/bsdlib) library.

  • Hi ,

    Also, please note that the SUPL library is now available as v 0.7.1
    Just FYI: I updated the SUPL client library to version v0.7.1 and disabled FPU from project configuration.

    Already updated that earlier.

    There is a new GNSS API developed to improve usability of the GNSS, and to move away from the GPS driver.

    So you suggest to stop using the GPS driver and to move to GNSS API? That would need a lot of work.

    Things I can't do now:

    1. Take the master branch of the SDK since we need a confirmed stable SDK as we are already in production.
    2. Use modem FW 1.3.0 since we have still B0 revisions and our devices have modem FW 1.2.3 which is not updatable to 1.3.0.

    I really need this bug to be fixed and it kind of should be for the GPS driver.

    Why is the A-GPS breaking those timeouts and intervals?

  • Hi 

    anicare-tero said:
    Already updated that earlier.

    Yes, that is true. I forgot that detail earlier today.

     

    anicare-tero said:

    So you suggest to stop using the GPS driver and to move to GNSS API? That would need a lot of work.

    No, I'm asking if it helps to use this to test the stability of the GPS. 

     

    anicare-tero said:
    Take the master branch of the SDK since we need a confirmed stable SDK as we are already in production.

     The link I provided to GNSS API in my last comment is from NCS v1.6.1. 

     

    anicare-tero said:
    Use modem FW 1.3.0 since we have still B0 revisions and our devices have modem FW 1.2.3 which is not updatable to 1.3.0.

     That is OK. The new GNSS API should support mfw 1.2.3 as well. Some features are marked to work only with mfw 1.3.0, but the rest should work. 

    Kind regards,
    Øyvind

Related