u-blox / ubxlib

Portable C libraries which provide APIs to build applications with u-blox products and services. Delivered as add-on to existing microcontroller and RTOS SDKs.
Apache License 2.0
287 stars 82 forks source link

API for fetching current GNSS status #166

Closed arnoutdekimo closed 6 months ago

arnoutdekimo commented 7 months ago

Hi,

I might be overlooking something, but I didn't immediately find an API to do the following. Ideally I'd like to:

The first two I can do with uGnssPosGetStreamedStart. But the callback does not periodically tell me how many sats are in view, it just says -1 until there is a lock.

Is there a simple way to do so with the current API's?

Sorry if I overlooked it,

Kind regards, Arnout

RobMeades commented 7 months ago

Unfortunately I don't think the number of satellites field is populated by the GNSS device unless it has actually achieved a solution; from the receiver manual:

image

Below is a log of the body of the UBX-NAV-PVT messages, from a cold start, taken from one of our tests. I've highlighted the numSV column in red: you can see that it remains zero until the very last message, which is where a fix has been achieved, whereupon it jumps to 8, the number of satellites employed in the solution.

image

arnoutdekimo commented 7 months ago

Interesting. Have you tried the u-center2 application? With it, directly connecting to an M10S device over UART, it sends UBX/NMEA messages and is able show the received signal strengths of all sats even before the fix.

image image

Hence, I thought it might be easy to get this info as well through ubxlib. But I guess not:)

RobMeades commented 7 months ago

I've never used uCenter myself but, looking at your screen shot, I'd guess that the NMEA messages might include a "number of satellites in view" field.

We chose to stick with just UBX messages in ubxlib 'cos they are so much easier to parse and you need to ask for less stuff to get what you want, but actually I do have a query open at the moment with the POS guys to ask how one gets general quality information from the GNSS device, what message to read to get an idea of what the device can see, in order to help elektron314 with issue #155; this kind of thing might give you what you want also.

I will prod them for a response again.

RobMeades commented 7 months ago

Actually, just browsing the manual, maybe what you would find useful is UBX-NAV-SAT:

image

You could configure the GNSS device to send this message to you at the same rate as UBX-NAV-PVT with code something like this (this code not compiled, just intended to point you in the right direction):

// Callback for asynchronous message reception.
static void callback(uDeviceHandle_t devHandle, const uGnssMessageId_t *pMessageId,
                     int32_t errorCodeOrLength, void *pCallbackParam)
{
    char *pBuffer = (char *) pCallbackParam;
    int32_t length;

    (void) pMessageId;

    if (errorCodeOrLength >= 0) {
        // Read the message into our buffer and print it
        length = uGnssMsgReceiveCallbackRead(devHandle, pBuffer, errorCodeOrLength);
        if (length >= 0) {
            printf("%.*s", length, pBuffer);
        } else {
            printf("Empty or bad message received.\n");
        }
    }
}

...and in your main code:

// Enough room for the UBX-NAV-SAT message, which has a body of length 456 bytes,
// if we assume 40 satellites max
char *pBuffer = (char *) pUPortMalloc(456);
uGnssMessageId_t messageId = {0};

// Configure the GNSS device to send UBX-NAV-SAT to us once an epoch [second]
U_GNSS_CFG_SET_VAL_RAM(devHandle, MSGOUT_UBX_NAV_SAT_I2C_U1, 1);
messageId.type = U_GNSS_PROTOCOL_UBX;
messageId.id.ubx =  0x0135; // message class/ID of UBX-NAV-SAT.

// We give the message receiver pBuffer so that it can read messages into it
int32_t handle = uGnssMsgReceiveStart(devHandle, &messageId, callback, pBuffer);
if (handle >= 0) {
    // Wait a while for some messages to arrive
    uPortTaskBlock(5000);
    // Stop the message receiver(s) once more
    uGnssMsgReceiveStopAll(devHandle);
} else {
    printf("Unable to start message receiver!\n");
}
arnoutdekimo commented 7 months ago

Turn's out, what I wanted to do, isn't that hard. Just a few AT commands, thanks to the FAE's comments:

AT+UGPRF=1 <= Enables the TXD_GNSS output AT+UGPS=1,5,511 <= Enable the GPS AT+UGGSV=1 <= Enabled the NMEA output of sats in view message AT+UGGGA=1 <= Position NMEA messages AT+UGGLL=1 <= Position NMEA messages

When on the EVB, setting the correct switches, one can then use the USB interface to use one interface for AT, and the other for GNSS parsing:

image

And this is already sent before we have a lock. This is pretty useful for debugging

And btw, for configuration, it is possible to use the ucenter program to gerneate the ubx message codes, and then input these into at+ugubx="" commands.

image

RobMeades commented 7 months ago

Interesting: not a use-case I had considered before, but you're right that being able to direct things out of the alternative serial port is useful.

Do you think this is something that you would need to do through ubxlib (i.e. does ubxlib need to support configuring this kind of stuff, not that it necessarily needs to do anything with the output of the second UART/NMEA), or would you only be doing this on the bench, with tools like uCenter and mCenter?

arnoutdekimo commented 7 months ago

Well, to be honest, I am actually bypassing ubxlib for setting up the GPS AT commands. (I am still using the at parser which works great, and using just parts of the lib works great too due to its modularity) The library is a bit too complex for my usecase (I started trying to use calls like uCellLocSetSystem, uCellLocSetServer, uCellLocSetAssistNowOnline, but eventually reverted to just executing the AT command I wanted myself, since the relevant flags are set in alot of places otherwise) Same with the alternative GNSS output interface - I can just parse that serial interface myself if I wanted to, although I'll probably just execute some AT+SGGEV? commands myself and parse though over the regular UART interface. Having the ucenter tool to visualize is pretty useful though, so I thought I'd share that info

RobMeades commented 7 months ago

Very sensible, that's what we would expect.

It usually depends upon the level of competence/confidence in embedded C, and debugging embedded C, something which you certainly have no problem with.

I was wondering if it was worth implementing something as a kind of "helping hand" but, to give a useful helping hand without adding "fat" to ubxlib, ends up being relatively application/situation specific; I think it is best left to the customer/developer, with your helpful comments here to guide them :-).

RobMeades commented 6 months ago

Hi Arnout: I think this one has run its course, am going to close it; please feel free to re-open it, or open another issue, if you think there's more to discuss.