Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <string>
- #include <ctime>
- #include <cstring>
- #include <iostream>
- #include <fstream>
- #include <iomanip>
- constexpr size_t NumberOfQualityStrings = 9;
- constexpr size_t NumberOfSatellitesPerGSVSentencePart = 4;
- constexpr size_t MaxNumberOfPartsInSentence = 10;
- constexpr size_t MaxTokensInSentence = 64;
- constexpr size_t NumberOfFieldsInGGA = 12;
- std::string QualityString[NumberOfQualityStrings]{ // Типы решения StandAlone
- /*0 – нет решения,
- 1 – StandAlone,
- 2 – DGPS,
- 3 – PPS,
- 4 – фиксированный RTK,
- 5 – не фиксированный RTK,
- 6 – использование данных инерциальных систем,
- 7 – ручной решения,
- 8 – режим симуляции */
- "invalid", "GPS (SPS)", "DGPS ", "PPS ", "Real Time Kinematic", "Float RTK",
- "estimated (dead reckoning", "Manual input mode", "Simulation mode" };
- // Данные GGA
- struct GGA {
- // Время последнего появления спутника
- unsigned int TimeInUtcHours{};
- unsigned int TimeInUtcMinutes{};
- unsigned int TimeInUtcSeconds{};
- unsigned int TimeInUtcMilliSeconds{};
- // Широта
- unsigned int lattitudeInDegree{};
- double lattitudeInMinutes{};
- std::string lattitideDirection{};
- // Долгота
- unsigned int longitudeInDegree{};
- double longitudeInMinutes{};
- std::string longitudeDirection{};
- // Типы решения
- unsigned int Quality{};
- std::string QualityString{};
- // Количество отслеживаемых спутников
- unsigned int numberOfTrackedSatellites{};
- // Геометрический фактор, HDOP
- double horizontalDilution{};
- // Высота над уровнем моря в метрах
- double altitude{};
- std::string altitudeDimension{};
- // Высота геоида над эллипсоидом WGS 84
- double goidHight{};
- std::string goidHightDimension{};
- };
- // Подробная информация о спутниках (GSV)
- struct SatelliteData {
- std::string satellitePRNnumber{};
- double elevationInDegress{};
- double azimuthInDegrees{};
- double snr{}; // Signal Noise Ratio
- };
- // Часть GSV
- struct GSVSentencePart {
- size_t numberOfSentencesForFullData{};
- size_t sentencePartNumber{};
- size_t numberOfSatellitesInView{};
- size_t numberOfSatellitesInThisPart{};
- SatelliteData satelliteData[NumberOfSatellitesPerGSVSentencePart];
- };
- struct GSV
- {
- GSVSentencePart gsvSentencePart[MaxNumberOfPartsInSentence];
- size_t numberOfParts{};
- };
- bool checksumTest(std::string& line) {
- bool result{ false };
- // Проверяем, есть ли в конце контрольная сумма из 2 цифр
- size_t pos{}, checkSumGiven{ std::stoul(line.substr(line.size() - 2), &pos, 16) };
- if (pos == 2){
- // От символа $ до *
- line = line.substr(1, line.size() - 4);
- // Считаем XOR сумму
- unsigned char calculatedChecksum{ 0U }; for (const unsigned char c : line) calculatedChecksum ^= c;
- // Проверка
- result = (calculatedChecksum == checkSumGiven);
- }
- return result;
- }
- // Разделяем строку на токены/
- size_t splitIntoTokens(std::string& s, std::string(&tokens)[MaxTokensInSentence]) {
- // Число токенов
- size_t numberOfTokens{ 0 };
- // Проверка на контрольную сумму
- if (checksumTest(s)) {
- // Разделяем между запятыми
- for (size_t i{ 0U }, startpos{ 0U }; i < s.size(); ++i) {
- // Если встречаем запятую или конец строки
- if ((s[i] == ',') || (i == (s.size() - 1))) {
- // Копируем строку
- tokens[numberOfTokens++] = s.substr(startpos, i - startpos);
- startpos = i + 1;
- }
- }
- }
- return numberOfTokens;
- }
- GGA convertStringToGGA(std::string& s) {
- GGA gga;
- // Разделяем строку на токены и проверяем
- std::string tokens[MaxTokensInSentence];
- if (splitIntoTokens(s, tokens) > NumberOfFieldsInGGA&& tokens[0] == "GPGGA") {
- gga.TimeInUtcHours = std::stoul(tokens[1].substr(0, 2));
- gga.TimeInUtcMinutes = std::stoul(tokens[1].substr(2, 2));
- gga.TimeInUtcSeconds = std::stoul(tokens[1].substr(4, 2));
- gga.TimeInUtcMilliSeconds = std::stod(tokens[1].substr(6, 2)) * 1000.0;
- gga.lattitudeInDegree = std::stoul(tokens[2].substr(0, 2));
- gga.lattitudeInMinutes = std::stod(tokens[2].substr(2));
- gga.lattitideDirection = tokens[3];
- gga.longitudeInDegree = std::stoul(tokens[4].substr(0, 2));
- gga.longitudeInMinutes = std::stod(tokens[4].substr(2));
- gga.longitudeDirection = tokens[5];
- gga.Quality = std::stoul(tokens[6]);
- gga.QualityString = (gga.Quality < NumberOfQualityStrings) ? QualityString[gga.Quality] : QualityString[0];
- gga.numberOfTrackedSatellites = std::stoul(tokens[7]);
- gga.horizontalDilution = std::stod(tokens[8]);
- gga.altitude = std::stod(tokens[9]);
- gga.altitudeDimension = tokens[10];
- gga.goidHight = std::stod(tokens[11]);
- gga.goidHightDimension = tokens[12];
- }
- return gga;
- }
- GSVSentencePart convertToGSVSentencePart(std::string& s) {
- GSVSentencePart gsvsp;
- // Разделяем строку на токены и проверяем
- std::string tokens[MaxTokensInSentence];
- size_t numberOfCOnvertedTokens = splitIntoTokens(s, tokens);
- if (numberOfCOnvertedTokens > 0 && tokens[0] == "GPGSV") {
- gsvsp.numberOfSentencesForFullData = std::stoul(tokens[1]);
- gsvsp.sentencePartNumber = std::stoul(tokens[2]);
- gsvsp.numberOfSatellitesInView = std::stoul(tokens[3]);
- gsvsp.numberOfSatellitesInThisPart = 0;
- for (size_t currentToken = 4; currentToken < numberOfCOnvertedTokens; currentToken += 4) {
- gsvsp.satelliteData[gsvsp.numberOfSatellitesInThisPart].satellitePRNnumber = tokens[currentToken];
- gsvsp.satelliteData[gsvsp.numberOfSatellitesInThisPart].elevationInDegress = stod(tokens[currentToken + 1]);
- gsvsp.satelliteData[gsvsp.numberOfSatellitesInThisPart].azimuthInDegrees = stod(tokens[currentToken + 2]);
- gsvsp.satelliteData[gsvsp.numberOfSatellitesInThisPart].snr = stod(tokens[currentToken + 3]);
- ++gsvsp.numberOfSatellitesInThisPart;
- }
- }
- return gsvsp;
- }
- // Считаем время
- std::string calculateElapsedTime(const GGA& previousGGA, const GGA& nextGGA) {
- std::tm tmPrevious{}, tmNext{};
- tmPrevious.tm_hour = previousGGA.TimeInUtcHours;
- tmPrevious.tm_min = previousGGA.TimeInUtcMinutes;
- tmPrevious.tm_sec = previousGGA.TimeInUtcSeconds;
- std::time_t previousTime = std::mktime(&tmPrevious);
- tmNext.tm_hour = nextGGA.TimeInUtcHours;
- tmNext.tm_min = nextGGA.TimeInUtcMinutes;
- tmNext.tm_sec = nextGGA.TimeInUtcSeconds;
- std::time_t nextTime = std::mktime(&tmNext);
- float diff = std::difftime(nextTime, previousTime);
- diff = nextGGA.TimeInUtcHours * 3600 - previousGGA.TimeInUtcHours * 3600 +
- nextGGA.TimeInUtcMinutes * 60 - previousGGA.TimeInUtcMinutes * 60 +
- nextGGA.TimeInUtcSeconds - previousGGA.TimeInUtcSeconds +
- 1.0 * nextGGA.TimeInUtcMilliSeconds / 1000.0 - 1.0 * previousGGA.TimeInUtcMilliSeconds / 1000.0;
- return std::to_string(diff);
- }
- int main() {
- // Открываем файл, проверяем, открылся ли
- std::ifstream nmeaFile("C:/Users/Ivan/Desktop/log123.txt");
- std::ofstream Outlogs("C:/Users/Ivan/Desktop/outLOG.txt");
- if (nmeaFile) {
- GGA previousGGA;
- GGA nextGGA;
- GGA gga;
- GSV gsv;
- size_t state{ 0 };
- for (std::string line{}; std::getline(nmeaFile, line); ) {
- switch (state) {
- case 0: // Ждем первую строчку с GGA
- if (line.substr(0, 6) == "$GPGGA") {
- previousGGA = nextGGA;
- nextGGA = convertStringToGGA(line);
- state = 1;
- gsv = {};
- }
- break;
- case 1: // Ждем строчку с GSV
- if (line.substr(0, 6) == "$GPGSV") {
- gsv.gsvSentencePart[gsv.numberOfParts] = convertToGSVSentencePart(line);
- if (gsv.gsvSentencePart[gsv.numberOfParts].numberOfSentencesForFullData == gsv.gsvSentencePart[gsv.numberOfParts].sentencePartNumber) {
- state = 0;
- ++gsv.numberOfParts;
- // Все данные доступны, выводим что нам нужно
- // Выводим данные о спутниках
- size_t counter{ 0 };
- for (size_t i = 0; i < gsv.numberOfParts; ++i) {
- for (size_t j = 0; j < gsv.gsvSentencePart[i].numberOfSatellitesInThisPart; j++) {
- Outlogs << "Satellite: " << std::setw(2) << ++counter << " Satellite name: " <<
- std::setw(3) << gsv.gsvSentencePart[i].satelliteData[j].satellitePRNnumber <<
- " SNR: " << std::setw(8) << gsv.gsvSentencePart[i].satelliteData[j].snr <<
- " Elapsed time: " << calculateElapsedTime(previousGGA, nextGGA) << " s\n";
- }
- }
- --gsv.numberOfParts;
- }
- ++gsv.numberOfParts;
- }
- case 2: // Ждем строчку с включением
- if (line.substr(0, 9) == "RE004%on%") {
- Outlogs << "Time of work: " << gga.TimeInUtcHours << "." << gga.TimeInUtcMinutes << "." << gga.TimeInUtcSeconds << gga.TimeInUtcMilliSeconds << std::endl;
- }
- break;
- }
- }
- nmeaFile.close();
- std::cout << "Success" << std::endl;
- }
- else std::cout << "File is not open" << '\n';
- Outlogs.close();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement