Advertisement
Queen4

Parsing logs WT 0.1

Jan 9th, 2020
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.37 KB | None | 0 0
  1. #include <string>
  2. #include <ctime>
  3. #include <cstring>
  4. #include <iostream>
  5. #include <fstream>
  6. #include <iomanip>
  7.  
  8. constexpr size_t NumberOfQualityStrings = 9;
  9. constexpr size_t NumberOfSatellitesPerGSVSentencePart = 4;
  10. constexpr size_t MaxNumberOfPartsInSentence = 10;
  11. constexpr size_t MaxTokensInSentence = 64;
  12. constexpr size_t NumberOfFieldsInGGA = 12;
  13.  
  14. std::string QualityString[NumberOfQualityStrings]{ // Типы решения StandAlone
  15.  
  16.     /*0 – нет решения,
  17.     1 – StandAlone,
  18.     2 – DGPS,
  19.     3 – PPS,
  20.     4 – фиксированный RTK,
  21.     5 – не фиксированный RTK,
  22.     6 – использование данных инерциальных систем,
  23.     7 – ручной решения,
  24.     8 – режим симуляции */
  25.     "invalid", "GPS  (SPS)", "DGPS ", "PPS ", "Real Time Kinematic", "Float RTK",
  26.     "estimated (dead reckoning", "Manual input mode", "Simulation mode" };
  27.  
  28. //  Данные GGA
  29. struct GGA {
  30.     // Время последнего появления спутника
  31.     unsigned int TimeInUtcHours{};
  32.     unsigned int TimeInUtcMinutes{};
  33.     unsigned int TimeInUtcSeconds{};
  34.     unsigned int TimeInUtcMilliSeconds{};
  35.     // Широта
  36.     unsigned int lattitudeInDegree{};
  37.     double lattitudeInMinutes{};
  38.     std::string lattitideDirection{};
  39.     // Долгота
  40.     unsigned int longitudeInDegree{};
  41.     double longitudeInMinutes{};
  42.     std::string longitudeDirection{};
  43.     // Типы решения
  44.     unsigned int Quality{};
  45.     std::string QualityString{};
  46.     // Количество отслеживаемых спутников
  47.     unsigned int numberOfTrackedSatellites{};
  48.     // Геометрический фактор, HDOP
  49.     double horizontalDilution{};
  50.     // Высота над уровнем моря в метрах
  51.     double altitude{};
  52.     std::string altitudeDimension{};
  53.     // Высота геоида над эллипсоидом WGS 84
  54.     double goidHight{};
  55.     std::string goidHightDimension{};
  56. };
  57.  
  58. // Подробная информация о спутниках (GSV)
  59. struct SatelliteData {
  60.     std::string satellitePRNnumber{};
  61.     double elevationInDegress{};
  62.     double azimuthInDegrees{};
  63.     double snr{};  // Signal Noise Ratio
  64. };
  65.  
  66. // Часть GSV
  67. struct GSVSentencePart {
  68.     size_t numberOfSentencesForFullData{};
  69.     size_t sentencePartNumber{};
  70.     size_t numberOfSatellitesInView{};
  71.     size_t numberOfSatellitesInThisPart{};
  72.     SatelliteData satelliteData[NumberOfSatellitesPerGSVSentencePart];
  73. };
  74. struct GSV
  75. {
  76.     GSVSentencePart gsvSentencePart[MaxNumberOfPartsInSentence];
  77.     size_t numberOfParts{};
  78. };
  79.  
  80. bool checksumTest(std::string& line) {
  81.     bool result{ false };
  82.     // Проверяем, есть ли в конце контрольная сумма из 2 цифр
  83.     size_t pos{}, checkSumGiven{ std::stoul(line.substr(line.size() - 2), &pos, 16) };
  84.     if (pos == 2){
  85.         // От символа $ до *
  86.         line = line.substr(1, line.size() - 4);
  87.         // Считаем XOR сумму  
  88.         unsigned char calculatedChecksum{ 0U }; for (const unsigned char c : line)  calculatedChecksum ^= c;
  89.         // Проверка
  90.         result = (calculatedChecksum == checkSumGiven);
  91.     }
  92.     return result;
  93. }
  94.  
  95. // Разделяем строку на токены/
  96. size_t splitIntoTokens(std::string& s, std::string(&tokens)[MaxTokensInSentence]) {
  97.     // Число токенов
  98.     size_t numberOfTokens{ 0 };
  99.     // Проверка на контрольную сумму
  100.     if (checksumTest(s)) {
  101.         // Разделяем между запятыми
  102.         for (size_t i{ 0U }, startpos{ 0U }; i < s.size(); ++i) {
  103.             // Если встречаем запятую или конец строки
  104.             if ((s[i] == ',') || (i == (s.size() - 1))) {
  105.                 // Копируем строку
  106.                 tokens[numberOfTokens++] = s.substr(startpos, i - startpos);
  107.                 startpos = i + 1;
  108.             }
  109.         }
  110.     }
  111.     return numberOfTokens;
  112. }
  113.  
  114. GGA convertStringToGGA(std::string& s) {
  115.     GGA gga;
  116.     // Разделяем строку на токены и проверяем
  117.     std::string tokens[MaxTokensInSentence];
  118.     if (splitIntoTokens(s, tokens) > NumberOfFieldsInGGA&& tokens[0] == "GPGGA") {
  119.         gga.TimeInUtcHours = std::stoul(tokens[1].substr(0, 2));
  120.         gga.TimeInUtcMinutes = std::stoul(tokens[1].substr(2, 2));
  121.         gga.TimeInUtcSeconds = std::stoul(tokens[1].substr(4, 2));
  122.         gga.TimeInUtcMilliSeconds = std::stod(tokens[1].substr(6, 2)) * 1000.0;
  123.         gga.lattitudeInDegree = std::stoul(tokens[2].substr(0, 2));
  124.         gga.lattitudeInMinutes = std::stod(tokens[2].substr(2));
  125.         gga.lattitideDirection = tokens[3];
  126.         gga.longitudeInDegree = std::stoul(tokens[4].substr(0, 2));
  127.         gga.longitudeInMinutes = std::stod(tokens[4].substr(2));
  128.         gga.longitudeDirection = tokens[5];
  129.         gga.Quality = std::stoul(tokens[6]);
  130.         gga.QualityString = (gga.Quality < NumberOfQualityStrings) ? QualityString[gga.Quality] : QualityString[0];
  131.         gga.numberOfTrackedSatellites = std::stoul(tokens[7]);
  132.         gga.horizontalDilution = std::stod(tokens[8]);
  133.         gga.altitude = std::stod(tokens[9]);
  134.         gga.altitudeDimension = tokens[10];
  135.         gga.goidHight = std::stod(tokens[11]);
  136.         gga.goidHightDimension = tokens[12];
  137.     }
  138.     return gga;
  139. }
  140.  
  141. GSVSentencePart convertToGSVSentencePart(std::string& s) {
  142.     GSVSentencePart gsvsp;
  143.     // Разделяем строку на токены и проверяем
  144.     std::string tokens[MaxTokensInSentence];
  145.     size_t numberOfCOnvertedTokens = splitIntoTokens(s, tokens);
  146.     if (numberOfCOnvertedTokens > 0 && tokens[0] == "GPGSV") {
  147.         gsvsp.numberOfSentencesForFullData = std::stoul(tokens[1]);
  148.         gsvsp.sentencePartNumber = std::stoul(tokens[2]);
  149.         gsvsp.numberOfSatellitesInView = std::stoul(tokens[3]);
  150.         gsvsp.numberOfSatellitesInThisPart = 0;
  151.         for (size_t currentToken = 4; currentToken < numberOfCOnvertedTokens; currentToken += 4) {
  152.             gsvsp.satelliteData[gsvsp.numberOfSatellitesInThisPart].satellitePRNnumber = tokens[currentToken];
  153.             gsvsp.satelliteData[gsvsp.numberOfSatellitesInThisPart].elevationInDegress = stod(tokens[currentToken + 1]);
  154.             gsvsp.satelliteData[gsvsp.numberOfSatellitesInThisPart].azimuthInDegrees = stod(tokens[currentToken + 2]);
  155.             gsvsp.satelliteData[gsvsp.numberOfSatellitesInThisPart].snr = stod(tokens[currentToken + 3]);
  156.             ++gsvsp.numberOfSatellitesInThisPart;
  157.         }
  158.     }
  159.     return gsvsp;
  160. }
  161. // Считаем время
  162. std::string calculateElapsedTime(const GGA& previousGGA, const GGA& nextGGA) {
  163.     std::tm tmPrevious{}, tmNext{};
  164.     tmPrevious.tm_hour = previousGGA.TimeInUtcHours;
  165.     tmPrevious.tm_min = previousGGA.TimeInUtcMinutes;
  166.     tmPrevious.tm_sec = previousGGA.TimeInUtcSeconds;
  167.     std::time_t previousTime = std::mktime(&tmPrevious);
  168.     tmNext.tm_hour = nextGGA.TimeInUtcHours;
  169.     tmNext.tm_min = nextGGA.TimeInUtcMinutes;
  170.     tmNext.tm_sec = nextGGA.TimeInUtcSeconds;
  171.     std::time_t nextTime = std::mktime(&tmNext);
  172.     float diff = std::difftime(nextTime, previousTime);
  173.     diff = nextGGA.TimeInUtcHours * 3600 - previousGGA.TimeInUtcHours * 3600 +
  174.         nextGGA.TimeInUtcMinutes * 60 - previousGGA.TimeInUtcMinutes * 60 +
  175.         nextGGA.TimeInUtcSeconds - previousGGA.TimeInUtcSeconds +
  176.         1.0 * nextGGA.TimeInUtcMilliSeconds / 1000.0 - 1.0 * previousGGA.TimeInUtcMilliSeconds / 1000.0;
  177.     return std::to_string(diff);
  178. }
  179.  
  180. int main() {
  181.     // Открываем файл, проверяем, открылся ли
  182.     std::ifstream nmeaFile("C:/Users/Ivan/Desktop/log123.txt");
  183.     std::ofstream Outlogs("C:/Users/Ivan/Desktop/outLOG.txt");
  184.     if (nmeaFile) {
  185.         GGA previousGGA;
  186.         GGA nextGGA;
  187.         GGA gga;
  188.         GSV gsv;
  189.         size_t state{ 0 };
  190.         for (std::string line{}; std::getline(nmeaFile, line); ) {
  191.             switch (state) {
  192.  
  193.             case 0:     // Ждем первую строчку с GGA
  194.                 if (line.substr(0, 6) == "$GPGGA") {
  195.  
  196.                     previousGGA = nextGGA;
  197.                     nextGGA = convertStringToGGA(line);
  198.  
  199.                     state = 1;
  200.                     gsv = {};
  201.                 }
  202.                 break;
  203.             case 1: // Ждем строчку с GSV
  204.                 if (line.substr(0, 6) == "$GPGSV") {
  205.                     gsv.gsvSentencePart[gsv.numberOfParts] = convertToGSVSentencePart(line);
  206.                     if (gsv.gsvSentencePart[gsv.numberOfParts].numberOfSentencesForFullData == gsv.gsvSentencePart[gsv.numberOfParts].sentencePartNumber) {
  207.                         state = 0;
  208.                         ++gsv.numberOfParts;
  209.                         // Все данные доступны, выводим что нам нужно
  210.                         // Выводим данные о спутниках
  211.                         size_t counter{ 0 };
  212.                         for (size_t i = 0; i < gsv.numberOfParts; ++i) {
  213.                             for (size_t j = 0; j < gsv.gsvSentencePart[i].numberOfSatellitesInThisPart; j++) {
  214.                                 Outlogs << "Satellite: " << std::setw(2) << ++counter << "  Satellite name: " <<
  215.                                     std::setw(3) << gsv.gsvSentencePart[i].satelliteData[j].satellitePRNnumber <<
  216.                                     "   SNR: " << std::setw(8) << gsv.gsvSentencePart[i].satelliteData[j].snr <<
  217.                                     "  Elapsed time: " << calculateElapsedTime(previousGGA, nextGGA) << " s\n";
  218.                             }
  219.                         }
  220.                         --gsv.numberOfParts;
  221.                     }
  222.                     ++gsv.numberOfParts;
  223.                 }
  224.             case 2: // Ждем строчку с включением
  225.                 if (line.substr(0, 9) == "RE004%on%") {
  226.                     Outlogs << "Time of work: " << gga.TimeInUtcHours << "." << gga.TimeInUtcMinutes << "." << gga.TimeInUtcSeconds << gga.TimeInUtcMilliSeconds << std::endl;
  227.                 }
  228.                 break;
  229.                    
  230.             }
  231.  
  232.            
  233.         }
  234.         nmeaFile.close();
  235.         std::cout << "Success" << std::endl;
  236.     }
  237.     else std::cout << "File is not open" << '\n';
  238.     Outlogs.close();
  239.     return 0;
  240. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement