I wrote an OO driver for Teseo-LIV3 GPS module (as used in shabaz ' GPS / Galileo / BeiDou / GLONASS receiver). It knows how to retrieve info from the GPS, in NMEA format. In this series, I'm designing an OO lib to parse the payloads and return the data as objects.
The fourth post touches on some options you have once the data is available in a structured way. I'm going to count how much data we got from the GLONASS and GPS constellations. Using an STL built-in algorithm.
what do you need to know?
- I use Teseo library to retrieve data out of an ST Teseo GPS. The data that we get is a container of GPS data strings
The data in these strings are information on the GPS "brands" (constellations is the term) and their satellites
The data set is called GSV (GNSS Satellites in View). This is not important, but you'll see this term in the code below.
The GPS will return multiple data strings for each constellation. - I use NMEA library to extract (parse) attributes out of those data strings,
and build a container with a C++ object that holds those attributes, for each string - Constellation examples are GPS and GLONASS.
- see all links at the bottom of this post for the Teseo and NMEA libraries used here.
The C++ Standard Template Library (STL) has options to process that structured data. You can filter, search, count, average, group, print ... on the objects and containers. Often by using standard (and already tested for years and years) algorithms.
First a preparation exercise that I showed in previous post: get the GSV data out of the GPS IC, and transfer it into a container of gsv objects:
teseo::teseo gps; std::vector<std::string> replies(NMEA_MAX_REPLIES); // hold GPS replies as data strings // vector size is a suggestion. STL will allocate at least NMEA_MAX_REPLIES uint count; // intentionally uninitialised bool valid; // intentionally uninitialised std::array<nmea::gsv, NMEA_MAX_REPLIES> gsv_set = {}; // hold gsv objects // ... void retrieve_gsv() { // get the GSV data as text strings from the Teseo GPS IC // into container "replies" valid = gps.ask_gsv(replies, count); if (!valid) { return; } // for each string in "replies", parse the attributes, // and fill a gsv object with it in container "gsv_set" unsigned int index = 0; for(auto& r : std::ranges::subrange(replies.begin(), replies.begin() + count)) { valid = nmea::gsv::from_data(r, gsv_set[index]); if (!valid) { break; } index++; } for(auto&& r: std::ranges::subrange(gsv_set.begin() + count, gsv_set.end())) { r = {}; // clean out unused tail of the container } return; } int main() { // ... while (true) { retrieve_gsv(); // ... sleep_ms(1000); } }
You don't need to understand this code snippet to follow along. As long as you get that:
The result is that we have a container of GSV objects. Each object has the data of one GPS gsv data string.
One of the members of the gsv object is the source. The source tells what constellation served the data.
This is that same container in the debugger:
Counting with the STL
Now, let's use a STL algorithm to count how many objects we have in the container for GPS and GLONASS. I'll use the std::count_if()algorithm.
count_if() runs over the container, and only counts if a particular condition is true (in STL lingo: predicate). In my case: the source equals the constellation I want to count.
size_t count_constellations(const nmea::nmea::talker_id source) { size_t i = std::count_if(gsv_set.begin(), gsv_set.end(), [source](const auto& o){ return (o.source == source); }); return i; }
That's one of the functionalities of the STL. Its algorithms work on custom containers, such as my "vector of gps objects". It would also work if I put my objects in a classic C style array.
Here's how I use it:
int main() { size_t count; // intentionally uninitialised while (true) { retrieve_gsv(); count = count_constellations(nmea::nmea::gps); printf("count of gps: %i\r\n", count); count = count_constellations(nmea::nmea::glonass); printf("count of glonass: %i\r\n", count); sleep_ms(1000); } }
Result:
count of gps: 4
count of glonass: 3
That's it.
Except that there are way more algorithms, filters, views, ... available in the STL. Many of those can be useful in this (and your) project.
Link to all posts.