GPS Accuracy Discrepancy: Printed vs. Actual Coordinates on Google Maps

Hello,

I am working on the GNSS application provided in the sdk-nrf at [path: samples/cellular/gnss] and I'm using thing91: nrf9160 board. I have modified the GPS acquisition loop to meet my project requirements, specifically requiring GPS coordinates with an accuracy of up to 5 meters from the reference point.

During testing, I noticed an issue: while the application prints an accuracy of 5 meters after obtaining a GPS fix, the actual distance between the reference point and the acquired GPS coordinates (latitude and longitude), when checked on Google Maps, ranges from 13 meters to 98 meters. This discrepancy poses a significant problem for my use case.

Below is the code snippet we are using to fetch GPS coordinates.

#define STS_AGNSS_FIX_ACCURACY_THD_MTR          (5.0f)
#define STS_AGNSS_ACCURACY_RETRY_TIMEOUT_SEC    (30U)
#define STS_AGNSS_FIX_RETRY_TIMEOUT_SEC         (90U)

int sts_get_gnss_fix(double *latitude, double *longitude)
{
	bool isGNSSFixAvial = false;
	uint16_t fixRetryCntAGNSS = 0U;
	uint16_t agpsSecCnt = 0U;
#if defined(CONFIG_GNSS_SAMPLE_ACCURACY_CHECK)
	uint16_t accuracyRetryCntAGNSS = 0U;
#endif /* CONFIG_GNSS_SAMPLE_ACCURACY_CHECK */

	if (sts_work_queue_init() != 0)
	{
		LOG_ERR("Failed to initialize GNSS work queue");
		return -1;
	}

	if (sts_gnss_init() != 0)
	{
		LOG_ERR("Failed to initialize GNSS");
		return -1;
	}

	if (sts_gnss_start(0U, 1U) != 0)
	{
		LOG_ERR("Failed to start GNSS");
		return -1;
	}
	
    for (;;)
	{
		(void)k_poll(events, 1, K_MSEC(500));

		if (events[0].state == K_POLL_STATE_SEM_AVAILABLE &&
		            k_sem_take(events[0].sem, K_NO_WAIT) == 0)
		{
			/* Display RSRP, RSRQ, SNR values */
			STS_Get_Signal_Values();

			/* New PVT data available */
			sts_print_satellite_stats(&sts_last_pvt);

			if (sts_last_pvt.flags & NRF_MODEM_GNSS_PVT_FLAG_DEADLINE_MISSED)
			{
				printf("GNSS operation blocked by LTE\n");
			}
			
			if (sts_last_pvt.flags & NRF_MODEM_GNSS_PVT_FLAG_NOT_ENOUGH_WINDOW_TIME)
			{
				printf("Insufficient GNSS time windows\n");
			}
			
			if (sts_last_pvt.flags & NRF_MODEM_GNSS_PVT_FLAG_SLEEP_BETWEEN_PVT)
			{
				printf("Sleep period(s) between PVT notifications\n");
			}
			
			agpsSecCnt++;
			printf("-----------------------------------:%d\n", agpsSecCnt);

			if (sts_last_pvt.flags & NRF_MODEM_GNSS_PVT_FLAG_FIX_VALID)
			{
				sts_print_fix_data(&sts_last_pvt);
#if defined(CONFIG_GNSS_SAMPLE_ACCURACY_CHECK)
                accuracyRetryCntAGNSS++;

				if ( ( sts_last_pvt.accuracy <= STS_AGNSS_FIX_ACCURACY_THD_MTR ) || 
                     ( accuracyRetryCntAGNSS == STS_AGNSS_ACCURACY_RETRY_TIMEOUT_SEC ) )
#endif /* CONFIG_GNSS_SAMPLE_ACCURACY_CHECK */
				{
				    *latitude = sts_last_pvt.latitude;
				    *longitude = sts_last_pvt.longitude;
				    isGNSSFixAvial = true;
				    break;
				}
			}
			else
			{
				fixRetryCntAGNSS++;
				printf("Searching [%c]\n", sts_update_indicator[fixRetryCntAGNSS%4]);

				if ( fixRetryCntAGNSS == STS_AGNSS_FIX_RETRY_TIMEOUT_SEC )
				{
				    sts_print_fix_data(&sts_last_pvt);
					isGNSSFixAvial = false;
				    break;
				}
			}

			events[0].state = K_POLL_STATE_NOT_READY;
		}		
	}

    sts_gnss_stop_dInit();

    if ( isGNSSFixAvial )
	{
	    return 0;
	}
	else
	{
		return -1;
	}
}
	
static void sts_gnss_event_handler(int event)
{
	int retval;

	switch (event) {
	case NRF_MODEM_GNSS_EVT_PVT:
		retval = nrf_modem_gnss_read(&sts_last_pvt, sizeof(sts_last_pvt), NRF_MODEM_GNSS_DATA_PVT);
		if (retval == 0) {
			k_sem_give(&pvt_data_sem);
		}
		break;

	case NRF_MODEM_GNSS_EVT_AGNSS_REQ:
#if !defined(CONFIG_GNSS_SAMPLE_ASSISTANCE_NONE)
		retval = nrf_modem_gnss_read(&sts_last_agnss,
					     sizeof(sts_last_agnss),
					     NRF_MODEM_GNSS_DATA_AGNSS_REQ);
		if (retval == 0) {
			sts_add_element_to_work_queue();
		}
#endif /* !CONFIG_GNSS_SAMPLE_ASSISTANCE_NONE */
		break;

	default:
		break;
	}
}


static void sts_print_fix_data(struct nrf_modem_gnss_pvt_data_frame *pvt_data)
{
	printf("Latitude:       %.06f\n", pvt_data->latitude);
	printf("Longitude:      %.06f\n", pvt_data->longitude);
	printf("Altitude:       %.01f m\n", pvt_data->altitude);
	printf("Accuracy:       %.01f m\n", pvt_data->accuracy);
	printf("Speed:          %.01f m/s\n", pvt_data->speed);
	printf("Speed accuracy: %.01f m/s\n", pvt_data->speed_accuracy);
	printf("Heading:        %.01f deg\n", pvt_data->heading);
	printf("Date:           %04u-%02u-%02u\n",
	       pvt_data->datetime.year,
	       pvt_data->datetime.month,
	       pvt_data->datetime.day);
	printf("Time (UTC):     %02u:%02u:%02u.%03u\n",
	       pvt_data->datetime.hour,
	       pvt_data->datetime.minute,
	       pvt_data->datetime.seconds,
	       pvt_data->datetime.ms);
	printf("PDOP:           %.01f\n", pvt_data->pdop);
	printf("HDOP:           %.01f\n", pvt_data->hdop);
	printf("VDOP:           %.01f\n", pvt_data->vdop);
	printf("TDOP:           %.01f\n", pvt_data->tdop);
}

Kindly please let me know how I can fix this issue.


Best Regards,
Mahima

Parents
  • Hi,

    Can you specify all changes which you made to the samples/cellular/gnss sample?

    Which NCS and modem firmware version do you use?

    During testing, I noticed an issue: while the application prints an accuracy of 5 meters after obtaining a GPS fix, the actual distance between the reference point and the acquired GPS coordinates (latitude and longitude), when checked on Google Maps, ranges from 13 meters to 98 meters. This discrepancy poses a significant problem for my use case.

    Can you provide more detailed information about your use case?

    Best regards,
    Dejan

  • Hi,

    Which NCS and modem firmware version do you use?

    I'm using the NCS v2.6.0 and the Modem Firmware v1.3.5.

    Can you specify all changes which you made to the samples/cellular/gnss sample?

    I have not done any major changes in configurations. I have added the check to stop GPS fetching in cases where the accuracy of 5m is acquired or if time of 180sec is elapsed and still not able to fetch the first fix. 

    			if (sts_last_pvt.flags & NRF_MODEM_GNSS_PVT_FLAG_SLEEP_BETWEEN_PVT)
    			{
    				printf("Sleep period(s) between PVT notifications\n");
    			}
    			
    			agpsSecCnt++;
    			printf("-----------------------------------:%d\n", agpsSecCnt);
    
    			if (sts_last_pvt.flags & NRF_MODEM_GNSS_PVT_FLAG_FIX_VALID)
    			{
    				sts_print_fix_data(&sts_last_pvt);
    #if defined(CONFIG_GNSS_SAMPLE_ACCURACY_CHECK)
                    accuracyRetryCntAGNSS++;
    
    				if ( ( sts_last_pvt.accuracy <= STS_AGNSS_FIX_ACCURACY_THD_MTR ) || 
                         ( accuracyRetryCntAGNSS == STS_AGNSS_ACCURACY_RETRY_TIMEOUT_SEC ) )
    #endif /* CONFIG_GNSS_SAMPLE_ACCURACY_CHECK */
    				{
    				    *latitude = sts_last_pvt.latitude;
    				    *longitude = sts_last_pvt.longitude;
    				    isGNSSFixAvial = true;
    				    break;
    				}
    			}
    			else
    			{
    				fixRetryCntAGNSS++;
    				printf("Searching [%c]\n", sts_update_indicator[fixRetryCntAGNSS%4]);
    
    				if ( fixRetryCntAGNSS == STS_AGNSS_FIX_RETRY_TIMEOUT_SEC )
    				{
    				    sts_print_fix_data(&sts_last_pvt);
    					isGNSSFixAvial = false;
    				    break;
    				}
    			}

    In thingy91: nrf9160 board, I have tested with both external antenna [molex antenna: part number: 2066400001] and onboard antenna. If I don't make any changes in gnss code the behavior is still same in both the cases. The distance between reference and acquired co-ordinates is more then 5m [i.e. 12m to 22m when gnss code is tested multiple times].

    The prj.conf configurations for external antenna are as follows:

    CONFIG_MODEM_ANTENNA_GNSS_EXTERNAL=y
    
    CONFIG_MODEM_ANTENNA_AT_MAGPIO="AT%XMAGPIO=1,1,1,7,1,746,803,2,698,748,2,1710,2200,3,824,894,4,880,960,5,791,849,7,1565,1586"
    
    CONFIG_MODEM_ANTENNA_AT_COEX0="AT%XCOEX0"

    The prj.conf configurations for internal antenna are as follows:

    CONFIG_MODEM_ANTENNA_GNSS_EXTERNAL=n
    
    CONFIG_MODEM_ANTENNA_AT_MAGPIO="AT%XMAGPIO=1,1,1,7,1,746,803,2,698,748,2,1710,2200,3,824,894,4,880,960,5,791,849,7,1565,1586"
    
    CONFIG_MODEM_ANTENNA_AT_COEX0="AT%XCOEX0=1,1,1565,1586"

    Do let me know if you require any further details.

    Regards,

    Mahima

Reply
  • Hi,

    Which NCS and modem firmware version do you use?

    I'm using the NCS v2.6.0 and the Modem Firmware v1.3.5.

    Can you specify all changes which you made to the samples/cellular/gnss sample?

    I have not done any major changes in configurations. I have added the check to stop GPS fetching in cases where the accuracy of 5m is acquired or if time of 180sec is elapsed and still not able to fetch the first fix. 

    			if (sts_last_pvt.flags & NRF_MODEM_GNSS_PVT_FLAG_SLEEP_BETWEEN_PVT)
    			{
    				printf("Sleep period(s) between PVT notifications\n");
    			}
    			
    			agpsSecCnt++;
    			printf("-----------------------------------:%d\n", agpsSecCnt);
    
    			if (sts_last_pvt.flags & NRF_MODEM_GNSS_PVT_FLAG_FIX_VALID)
    			{
    				sts_print_fix_data(&sts_last_pvt);
    #if defined(CONFIG_GNSS_SAMPLE_ACCURACY_CHECK)
                    accuracyRetryCntAGNSS++;
    
    				if ( ( sts_last_pvt.accuracy <= STS_AGNSS_FIX_ACCURACY_THD_MTR ) || 
                         ( accuracyRetryCntAGNSS == STS_AGNSS_ACCURACY_RETRY_TIMEOUT_SEC ) )
    #endif /* CONFIG_GNSS_SAMPLE_ACCURACY_CHECK */
    				{
    				    *latitude = sts_last_pvt.latitude;
    				    *longitude = sts_last_pvt.longitude;
    				    isGNSSFixAvial = true;
    				    break;
    				}
    			}
    			else
    			{
    				fixRetryCntAGNSS++;
    				printf("Searching [%c]\n", sts_update_indicator[fixRetryCntAGNSS%4]);
    
    				if ( fixRetryCntAGNSS == STS_AGNSS_FIX_RETRY_TIMEOUT_SEC )
    				{
    				    sts_print_fix_data(&sts_last_pvt);
    					isGNSSFixAvial = false;
    				    break;
    				}
    			}

    In thingy91: nrf9160 board, I have tested with both external antenna [molex antenna: part number: 2066400001] and onboard antenna. If I don't make any changes in gnss code the behavior is still same in both the cases. The distance between reference and acquired co-ordinates is more then 5m [i.e. 12m to 22m when gnss code is tested multiple times].

    The prj.conf configurations for external antenna are as follows:

    CONFIG_MODEM_ANTENNA_GNSS_EXTERNAL=y
    
    CONFIG_MODEM_ANTENNA_AT_MAGPIO="AT%XMAGPIO=1,1,1,7,1,746,803,2,698,748,2,1710,2200,3,824,894,4,880,960,5,791,849,7,1565,1586"
    
    CONFIG_MODEM_ANTENNA_AT_COEX0="AT%XCOEX0"

    The prj.conf configurations for internal antenna are as follows:

    CONFIG_MODEM_ANTENNA_GNSS_EXTERNAL=n
    
    CONFIG_MODEM_ANTENNA_AT_MAGPIO="AT%XMAGPIO=1,1,1,7,1,746,803,2,698,748,2,1710,2200,3,824,894,4,880,960,5,791,849,7,1565,1586"
    
    CONFIG_MODEM_ANTENNA_AT_COEX0="AT%XCOEX0=1,1,1565,1586"

    Do let me know if you require any further details.

    Regards,

    Mahima

Children
No Data
Related