Last active
July 1, 2022 09:07
-
-
Save ncoder-1/8313815ac387e6757f751dc8960f03d7 to your computer and use it in GitHub Desktop.
example C++17 gpsd program using libgpsmm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Example C++17 gpsd program using libgpsmm | |
// Has no actual purpose other than output some of libgpsmm struct variables of your choosing. | |
// reference declarations: https://fossies.org/dox/gpsd-3.22/index.html | |
// | |
// compiles without warning as follows: | |
// g++ -std=c++17 -Wall -pedantic -pthread $(pkg-config --cflags --libs libgps) gpsd-example.cpp -o gpsd-example | |
// clang++ -std=c++17 -Wall -pedantic -pthread $(pkg-config --cflags --libs libgps) gpsd-example.cpp -o gpsd-example | |
// Free for the taking. | |
// Version 1.84 | |
#include <libgpsmm.h> | |
#include <ctime> | |
#include <iomanip> | |
#include <iostream> | |
#include <sstream> | |
#include <thread> | |
enum TimeFormat { LOCALTIME, UTC, UNIX, ISO_8601 }; | |
auto TimespecToTimeStr(const timespec& gpsd_time, TimeFormat time_format = LOCALTIME) { | |
// example showing different ways of formating GPSD's timespec, depending on requirement | |
std::ostringstream oss; | |
switch (time_format) { | |
case LOCALTIME: { | |
// convert timespec_t into localtime (dd-mm-YY HH:MM:SS) | |
const auto tm = *std::localtime(&gpsd_time.tv_sec); | |
oss << std::put_time(&tm, "%d-%m-%Y %H:%M:%S"); | |
break; | |
} | |
case UTC: { | |
// convert timespec_t into UTC (dd-mm-YY HH:MM:SS) | |
const auto tm = *std::gmtime(&gpsd_time.tv_sec); | |
oss << std::put_time(&tm, "%d-%m-%Y %H:%M:%S"); | |
break; | |
} | |
case UNIX: | |
// returns seconds since the Epoch | |
oss << gpsd_time.tv_sec; | |
break; | |
case ISO_8601: { | |
// convert timespec_t into ISO8601 UTC time (yyyy-MM-dd'T'HH:mm:ss'Z') | |
constexpr size_t kScrSize{128}; | |
std::array<char, kScrSize> scr{}; | |
timespec_to_iso8601(gpsd_time, scr.data(), kScrSize); | |
oss << scr.data(); | |
break; | |
} | |
} | |
return oss.str(); | |
} | |
auto main() -> int { | |
gpsmm gps_rec("localhost", DEFAULT_GPSD_PORT); | |
if (gps_rec.stream(WATCH_ENABLE | WATCH_JSON) == nullptr) { | |
std::cerr << "No GPSD running.\n"; | |
return 1; | |
} | |
constexpr auto kWaitingTime{1000000}; // 1000000 is 1 second | |
for (;;) { | |
if (!gps_rec.waiting(kWaitingTime)) { | |
continue; | |
} | |
struct gps_data_t* gpsd_data; | |
if ((gps_rec.read()) == nullptr) { | |
std::cerr << "GPSD read error.\n"; | |
return 1; | |
} | |
while (((gpsd_data = gps_rec.read()) == nullptr) || (gpsd_data->fix.mode < MODE_2D)) { | |
// Do nothing until fix, block execution for 1 second (busy wait mitigation) | |
std::this_thread::sleep_for(std::chrono::seconds(1)); | |
} | |
const auto latitude{gpsd_data->fix.latitude}; | |
const auto longitude{gpsd_data->fix.longitude}; | |
const auto hdop{gpsd_data->dop.hdop}; | |
const auto vdop{gpsd_data->dop.vdop}; | |
const auto pdop{gpsd_data->dop.pdop}; | |
const auto s_vis{gpsd_data->satellites_visible}; | |
const auto s_used{gpsd_data->satellites_used}; | |
const auto time_str{TimespecToTimeStr(gpsd_data->fix.time, ISO_8601)}; // you can change the 2nd argument to LOCALTIME, UTC, UNIX or ISO8601 | |
std::cout << std::setprecision(8) << std::fixed; // set output to fixed floating point, 8 decimal precision | |
std::cout << time_str << "," << latitude << "," << longitude << "," << hdop << "," << vdop << "," << pdop << "," << s_vis << "," << s_used << '\n'; | |
} | |
} |
@garyv100, they are quite rare now, but this is the one I have: https://www.globalsources.com/gsol/I/PC-PDA/p/sm/1147069913.htm#1147069913
@ncoder-1, Thank you!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@ncoder-1, I tried to lookup GR-8013 USB GPS, but I am coming up w/ all kind of stuff. If you could send me the link - it would be great.
Thanks,
Gary