Position Issue - failed to get heading value

Hi, forum,

I have a trouble with my positioning test.
I can get the 3D location successfully by:

 res = le_pos_Get3DLocation(&latitude, &longitude, &hAccuracy, &altitude, &vAccuracy);
if (res == LE_OK)								//Function succeeded.
	{
	    LE_INFO("Location: latitude=%d, longitude=%d, hAccuracy=%d, altitude = %d,vAccuracy = %d", latitude, longitude, hAccuracy,altitude,vAccuracy);
	}
	else if (res == LE_FAULT)
	{
	    LE_INFO("Failed to get the 3D location's data");
	}
	else if (res == LE_OUT_OF_RANGE)
	{
	    LE_INFO("One of the retrieved parameter is invalid (set to INT32_MAX)");
	}
	else
	{
	    LE_INFO("unknown location error (%d)", res);
	}

however it was failed to get the heading by:

res = le_pos_GetHeading(&heading, &headingAccuracy);
    if (res == LE_OK)								//Function succeeded.
    	{
    		LE_INFO("Check le_pos_GetHeading heading.%u, headingAccuracy.%u", heading, headingAccuracy);
    	}
    	else if (res == LE_FAULT)
    	{
    		LE_INFO("Function failed to get the heading indication.");
    	}
    	else if (res == LE_OUT_OF_RANGE)
    	{
    		LE_INFO("One of the retrieved parameter is invalid (set to INT32_MAX)");
    	}
    	else
    	{
    		LE_INFO("unknown location error (%d)", res);
    	}

I run on the legato,

Logs:
Jan  6 00:04:55 | helloWorld[1679]/helloComponent T=main | helloWorld.c gps_report() 50 | Location: latitude=22780192, longitude=114069832, hAccuracy=19, altitude = 62,vAccuracy = 16
Jan  6 00:04:55 | helloWorld[1679]/framework T=main | le_pos_client.c le_pos_GetHeading() 1144 | Sending message to server and waiting for response : 0 bytes sent
Jan  6 00:04:55 | helloWorld[1679]/helloComponent T=main | helloWorld.c gps_report() 79 | One of the retrieved parameter is invalid (set to INT32_MAX)

How can I fix it?

I have updated the codes, see below reply,

Hi @lumao,

which version of Legato+firmware do you have?

Also please use the preformatted text to include your code otherwise it is very hard to read.

Thanks!

my helloWorld.c

 /**
     *
     * int to string and loading into smsBoby with size.
     * snprintf(smsBody, sizeof(smsBody), "Loc:%d,%d", latitude, longitude);
     * eg latitude = 123456, longitude = 56201, size = 12, the smsBody will loading"Loc:123456,56"
     *
     *
     * */

    #include "legato.h"
    #include"adc.h"
    #include"gpio.h"
    #include"gps.h"

    #include"interfaces.h"

    //Public variable declaration
    int counter =0;		//used for timer counter in second
    le_posCtrl_ActivationRef_t posCtrlRef;

    static le_timer_Ref_t PlayTimer = NULL;
    /*
     *  delete timer
    */
    static void DeleteTimerAndFreePtr(
    		le_timer_Ref_t t
    )
     {
         le_timer_Stop( t );
         free( le_timer_GetContextPtr( t ) );
         le_timer_Delete( t );  // timer ref is now invalid
     }


    void timerCounterHandler(
    		//le_timer_Ref_t timerRef
    )
    {
    	static  bool value = false;

    	//Toggle IOT1_GPIO3
    	gpioPin32Output(value);
    	value=!value;

    	//adc ReadValue
    	readAdc();

    	LE_INFO("1 second increase counter = %d\n Pin21 = %d\n adc0 = %d\n adc1 = %d",counter++,le_gpioPin21_Read(),adcValue[0],adcValue[1]);

    	//GPS report
    	Testle_pos_GetInfo();

    	if(counter > 3)
    		{
    			LE_INFO("Time Out. End.");
    			le_posCtrl_Release(posCtrlRef);
    			DeleteTimerAndFreePtr(PlayTimer);
    			gpioPin32Output(false);
    			exit(EXIT_SUCCESS);
    		}
    }
    static void PlayTimerInit()
    {
        PlayTimer = le_timer_Create("playTimer");
        le_timer_SetHandler(PlayTimer,timerCounterHandler);
        le_timer_SetRepeat(PlayTimer, 0);
        le_timer_SetMsInterval(PlayTimer, 5000);				//5 seconds
        le_timer_Start(PlayTimer);
    }

    //
    COMPONENT_INIT
    {
        LE_INFO("Hello, world.");

        gpiosPinInit();

        posCtrlRef = le_posCtrl_Request();						// Reference to the service activation request (to be used later for releasing the request).

        PlayTimerInit();
    }

my gps.c:

    //gps module -- position sample
    #include"gps.h"

    //--------------------------------------------------------------------------------------------------
    /**
     * Test: Get position Fix info.
     *
     */
    //--------------------------------------------------------------------------------------------------
    void Testle_pos_GetInfo()
    {
    	gpsStruct_e gpsStruct;

        LE_ASSERT((le_pos_GetFixState(&gpsStruct.fixState) == LE_OK));
        LE_INFO("position fix state %d",gpsStruct.fixState);

        gpsStruct.res= le_pos_Get2DLocation(&gpsStruct.latitude, &gpsStruct.longitude, &gpsStruct.hAccuracy);
        LE_INFO("le_pos_Get2DLocation %s" , (gpsStruct.res==LE_OK)?"OK":(gpsStruct.res==LE_OUT_OF_RANGE)?"parameter(s) out of range":"ERROR");
        LE_ASSERT((gpsStruct.res ==LE_OK)||(gpsStruct.res == LE_OUT_OF_RANGE));
        LE_INFO("Check le_pos_Get2DLocation latitude.%d, longitude.%d, hAccuracy.%d" ,
        		gpsStruct.latitude,gpsStruct.longitude,gpsStruct.hAccuracy);

        gpsStruct.res= le_pos_Get3DLocation(&gpsStruct.latitude, &gpsStruct.longitude, &gpsStruct.hAccuracy, &gpsStruct.altitude, &gpsStruct.vAccuracy);
        LE_INFO("le_pos_Get3DLocation %s" , (gpsStruct.res==LE_OK)?"OK":(gpsStruct.res==LE_OUT_OF_RANGE)?"parameter(s) out of range":"ERROR");
        LE_ASSERT((gpsStruct.res ==LE_OK)||(gpsStruct.res == LE_OUT_OF_RANGE));
        LE_INFO("Check le_pos_Get3DLocation latitude.%d, longitude.%d, hAccuracy.%d, altitude.%d" ", vAccuracy.%d" ,
        		gpsStruct.latitude, gpsStruct.longitude, gpsStruct.hAccuracy, gpsStruct.altitude, gpsStruct.vAccuracy);

        gpsStruct.res= le_pos_GetDate(&gpsStruct.year, &gpsStruct.month, &gpsStruct.day);
        LE_INFO("le_pos_GetDate %s" , (gpsStruct.res==LE_OK)?"OK":(gpsStruct.res==LE_OUT_OF_RANGE)?"parameter(s) out of range":"ERROR");
        LE_ASSERT((gpsStruct.res ==LE_OK)||(gpsStruct.res == LE_OUT_OF_RANGE));
        LE_INFO("Check le_pos_GetDate year.%d, month.%d, day.%d" ,
        		gpsStruct.year, gpsStruct.month,gpsStruct. day);

        gpsStruct.res= le_pos_GetTime(&gpsStruct.hours, &gpsStruct.minutes, &gpsStruct.seconds, &gpsStruct.milliseconds);
        LE_INFO("le_pos_GetTime %s" , (gpsStruct.res==LE_OK)?"OK":(gpsStruct.res==LE_OUT_OF_RANGE)?"parameter(s) out of range":"ERROR");
        LE_ASSERT((gpsStruct.res ==LE_OK)||(gpsStruct.res == LE_OUT_OF_RANGE));
        LE_INFO("Check le_pos_GetTime hours.%d, minutes.%d, seconds.%d, milliseconds.%d" ,
        		gpsStruct.hours, gpsStruct.minutes, gpsStruct.seconds, gpsStruct.milliseconds);

        gpsStruct. res= le_pos_GetMotion(&gpsStruct.hSpeed, &gpsStruct.hSpeedAccuracy, &gpsStruct.vSpeed, &gpsStruct.vSpeedAccuracy);
        LE_INFO("le_pos_GetMotion %s"  , (gpsStruct.res==LE_OK)?"OK":(gpsStruct.res==LE_OUT_OF_RANGE)?"parameter(s) out of range":"ERROR");
        LE_ASSERT((gpsStruct.res ==LE_OK)||(gpsStruct.res == LE_OUT_OF_RANGE));
        LE_INFO("Check le_pos_GetMotion hSpeed.%u, hSpeedAccuracy.%u, vSpeed.%d, vSpeedAccuracy.%d",
        		gpsStruct.hSpeed, gpsStruct.hSpeedAccuracy, gpsStruct.vSpeed, gpsStruct.vSpeedAccuracy);

        gpsStruct.res= le_pos_GetHeading(&gpsStruct.heading, &gpsStruct.headingAccuracy);
        LE_INFO("le_pos_GetHeading %s" , (gpsStruct.res==LE_OK)?"OK":(gpsStruct.res==LE_OUT_OF_RANGE)?"parameter(s) out of range":"ERROR");
        LE_ASSERT((gpsStruct.res ==LE_OK)||(gpsStruct.res == LE_OUT_OF_RANGE));
        LE_INFO("Check le_pos_GetHeading heading.%u, headingAccuracy.%u" ,
        		gpsStruct. heading, gpsStruct.headingAccuracy);

        gpsStruct.res= le_pos_GetDirection(&gpsStruct.direction, &gpsStruct.directionAccuracy);
        LE_INFO("le_pos_GetDirection %s" , (gpsStruct.res==LE_OK)?"OK":(gpsStruct.res==LE_OUT_OF_RANGE)?"parameter(s) out of range":"ERROR");
        LE_ASSERT((gpsStruct.res ==LE_OK)||(gpsStruct.res == LE_OUT_OF_RANGE));
        LE_INFO("Check le_pos_GetDirection direction.%u, directionAccuracy.%u" ,
        		gpsStruct. direction, gpsStruct.directionAccuracy);
    }

my gps.h

        #ifndef __GPS_H
        #define __GPS_H
        #include "legato.h"
        #include"interfaces.h"

        typedef struct
        {
        	int32_t           latitude;
        	int32_t           longitude;
        	int32_t           altitude;
        	int32_t           hAccuracy;
        	int32_t           vAccuracy;
        	uint32_t          hSpeed;
        	uint32_t          hSpeedAccuracy;
        	int32_t           vSpeed;
        	int32_t           vSpeedAccuracy;
        	uint32_t          heading;
        	uint32_t          headingAccuracy;
        	uint32_t          direction;
        	uint32_t          directionAccuracy;
        	uint16_t          year;
        	uint16_t          month;
        	uint16_t          day;
        	uint16_t          hours;
        	uint16_t          minutes;
        	uint16_t          seconds;
        	uint16_t          milliseconds;
        	le_pos_FixState_t fixState;
        	le_result_t       res;
        }gpsStruct_e;


    void Testle_pos_GetInfo();

    #endif

my legato version:

    root@swi-mdm9x15:~# legato version
    16.10.1_a6a25fbda05738774857dccb9fd76a99_modified
    root@swi-mdm9x15:~# cm info
    Device:     WP8548
    IMEI:       35xxx706004xxxx
    FSN:        LL6xx30010xxxx
    Firmware:   SWI9X15Y_07.11.22.00 r33729 CARMD-EV-FRMWR1 2017/01/11 18:04:06
    Bootloader: SWI9X15Y_07.11.22.00 r33729 CARMD-EV-FRMWR1 2017/01/11 18:04:06
    priIdPn:    9906xxx
    priIdRev:   01.00
    skuId:      110xxx3
    root@swi-mdm9x15:~# 

<a class=“attachment"href=”//cdck-file-uploads-global.s3.dualstack.us-west-2.amazonaws.com/business5/uploads/legato1/original/1X/209986047d157110f18434b95710b8df3fb39e28">log-20170615 (45.4 KB)

And it seems ok by using the command line:

    root@swi-mdm9x15:~# microcom -E /dev/ttyAT
    at
    OK
    AT!GPSLOC?
    Lat: 22 Deg 46 Min 48.68 Sec N  (0x0040CC07)
    Lon: 114 Deg 4 Min 11.99 Sec E  (0x0144773D)
    Time: 2017 06 15 3 01:20:15 (GPS) 
    LocUncAngle: 78.7 deg  LocUncA: 4 m  LocUncP: 2 m  HEPE: 4.472 m
    2D Fix 
    Altitude: 45 m  LocUncVe: 8.0 m
    Heading: 58.0 deg  VelHoriz: 0.0 m/s  VelVert: 0 m/s


OK

CoRfr,

screenshot:

Can you help me?

Hi @lumao,

it doesn’t look like an issue on your side.
An issue has been created and I will update you when we have an idea of what’s happening.

Thanks!

CoRfr,

Understood. Thanks.

Regards!

@CoRfr Hey thanks for highlighting the issue. I am facing the same problem. I was wondering if this issue has been solved?

Could you try to use le_gnss_GetDirection instead? It is that the ‘heading’ information as returned from the GNSS engine is made available as the ‘direction’.

The le_pos_GetHeading() function gets the last updated heading value in degrees and its associated accuracy value:

Heading in degrees, ranges from 0 to 359, 0 being True North. Heading is the direction that the vehicle or person is facing.
The le_pos_GetDirection() function gets the last updated direction value in degrees and its associated accuracy value:

Direction in degrees, ranges from 0 to 359, 0 being True North. Direction of movement is the direction that the vehicle or person is actually moving.

I tried using the le_pos_GetDirection and it works. But after reading the documentation, I could not understand the exact difference between le_pos_GetDirection and le_pos_GetHeading. @CoRfr can you explain?

Hi @virajpadte,

I think the important differences to note are these:

le_pos_GetHeading()

Heading is the direction that the vehicle or person is facing.

le_pos_GetDirection()

Direction of movement is the direction that the vehicle or person is actually moving.

Imagine travelling on a train while sitting in a backwards-facing seat (le_pos_GetHeading()) while the train is travelling in the opposite direction (le_pos_GetDirection()).