C++实现GNSS/GPS的NMEA数据格式解析类示例

nmea数据具体各字段的含义请参考标准定义,这里给出一个C++实现的例子,环境是Android,本文只解析了几个常用的字段;

本示例的关键方法有split、startswith方法和stringToNumber模版函数

  1. bool GnssNmeaParser::startsWith(const std::string &src, const std::string &str)
  2. {
  3. int srcpos = 0;
  4. int srclen = src.length();
  5. int sublen = str.length();
  6. if (srclen < sublen) {
  7. return false;
  8. }
  9. return (0 == src.compare(srcpos, sublen, str));
  10. }
  11. bool GnssNmeaParser::endsWith(const std::string &src, const std::string &str)
  12. {
  13. int srcpos = 0;
  14. int srclen = src.length();
  15. int sublen = str.length();
  16. if (srclen < sublen) {
  17. return false;
  18. }
  19. srcpos = srclen - sublen;
  20. return (0 == src.compare(srcpos, sublen, str));
  21. }
  1. template <class T>
  2. T stringToNumber(const std::string &sstr)
  3. {
  4. T number {};
  5. std::istringstream iss {};
  6. iss.str(sstr);
  7. iss >> number; /* can auto remove leading 0 */
  8. return number;
  9. }
  1. size_t GnssNmeaParser::split(const std::string &line, const std::string &delim, std::vector<std::string> &vstr)
  2. {
  3. size_t pstart = 0;
  4. size_t phit = 0;
  5. std::string sstr;
  6. size_t length = line.length();
  7. vstr.clear();
  8. for (;pstart <= length;)
  9. {
  10. phit = line.find(delim, pstart);
  11. if (std::string::npos != phit)
  12. {
  13. /* find delim, get substr */
  14. sstr = line.substr(pstart, phit-pstart);
  15. vstr.push_back(sstr);
  16. pstart = phit + delim.size();
  17. } else {
  18. /* not find delim, append remaining str and break */
  19. vstr.push_back(line.substr(pstart));
  20. break;
  21. }
  22. }
  23. return vstr.size();
  24. }

for Android Gnss V1.0

解析.h头文件

  1. #ifndef HAL_GNSS_V1_0_GNSSNMEAPARSER_H
  2. #define HAL_GNSS_V1_0_GNSSNMEAPARSER_H
  3. #include <cstdio>
  4. #include <iostream>
  5. #include <sstream>
  6. #include <bitset>
  7. #include <vector>
  8. #include <map>
  9. #include <queue>
  10. #include <hardware/gps.h>
  11. #define GNSS_NMEA_LINE_SEP "\n"
  12. #define GNSS_NMEA_ELEMENT_SEP ","
  13. #define GNSS_NMEA_PARSER_VERSION "v1.0-20.0716"
  14. #if __GNSS_HAL_DEBUG_ON__
  15. /* Flags that indicate information about the satellite */
  16. typedef uint8_t LocGnssSvFlags;
  17. #define GNSS_SV_FLAGS_NONE 0
  18. #define GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA (1)
  19. #define GNSS_SV_FLAGS_HAS_ALMANAC_DATA (2)
  20. #define GNSS_SV_FLAGS_USED_IN_FIX (4)
  21. //hardware/libhardware/include/hardware/gps.h
  22. typedef int64_t GpsUtcTime;
  23. /**
  24. * Flags that indicate information about the satellite
  25. */
  26. typedef uint8_t GnssSvFlags;
  27. /**
  28. * Constellation type of GnssSvInfo
  29. */
  30. typedef uint8_t GnssConstellationType;
  31. /** Represents a location. */
  32. typedef struct {
  33. /** set to sizeof(GpsLocation) */
  34. size_t size;
  35. /** Contains GpsLocationFlags bits. */
  36. uint16_t flags;
  37. /** Represents latitude in degrees. */
  38. double latitude;
  39. /** Represents longitude in degrees. */
  40. double longitude;
  41. /**
  42. * Represents altitude in meters above the WGS 84 reference ellipsoid.
  43. */
  44. double altitude;
  45. /** Represents speed in meters per second. */
  46. float speed;
  47. /** Represents heading in degrees. */
  48. float bearing;
  49. /** Represents expected accuracy in meters. */
  50. float accuracy;
  51. /** Timestamp for the location fix. */
  52. GpsUtcTime timestamp;
  53. } GpsLocation;
  54. typedef struct {
  55. /** set to sizeof(GnssSvInfo) */
  56. size_t size;
  57. /**
  58. * Pseudo-random number for the SV, or FCN/OSN number for Glonass. The
  59. * distinction is made by looking at constellation field. Values should be
  60. * in the range of:
  61. *
  62. * - GPS: 1-32
  63. * - SBAS: 120-151, 183-192
  64. * - GLONASS: 1-24, the orbital slot number (OSN), if known. Or, if not:
  65. * 93-106, the frequency channel number (FCN) (-7 to +6) offset by + 100
  66. * i.e. report an FCN of -7 as 93, FCN of 0 as 100, and FCN of +6 as 106.
  67. * - QZSS: 193-200
  68. * - Galileo: 1-36
  69. * - Beidou: 1-37
  70. */
  71. int16_t svid;
  72. /**
  73. * Defines the constellation of the given SV. Value should be one of those
  74. * GNSS_CONSTELLATION_* constants
  75. */
  76. GnssConstellationType constellation;
  77. /**
  78. * Carrier-to-noise density in dB-Hz, typically in the range [0, 63].
  79. * It contains the measured C/N0 value for the signal at the antenna port.
  80. *
  81. * This is a mandatory value.
  82. */
  83. float c_n0_dbhz;
  84. /** Elevation of SV in degrees. */
  85. float elevation;
  86. /** Azimuth of SV in degrees. */
  87. float azimuth;
  88. /**
  89. * Contains additional data about the given SV. Value should be one of those
  90. * GNSS_SV_FLAGS_* constants
  91. */
  92. GnssSvFlags flags;
  93. } GnssSvInfo;
  94. /**
  95. * Legacy struct to represents SV information.
  96. * Deprecated, to be removed in the next Android release.
  97. * Use GnssSvInfo instead.
  98. */
  99. typedef struct {
  100. /** set to sizeof(GpsSvInfo) */
  101. size_t size;
  102. /** Pseudo-random number for the SV. */
  103. int prn;
  104. /** Signal to noise ratio. */
  105. float snr;
  106. /** Elevation of SV in degrees. */
  107. float elevation;
  108. /** Azimuth of SV in degrees. */
  109. float azimuth;
  110. } GpsSvInfo;
  111. /**
  112. * Legacy struct to represents SV status.
  113. * Deprecated, to be removed in the next Android release.
  114. * Use GnssSvStatus instead.
  115. */
  116. typedef struct {
  117. /** set to sizeof(GpsSvStatus) */
  118. size_t size;
  119. int num_svs;
  120. GpsSvInfo sv_list[GPS_MAX_SVS];
  121. uint32_t ephemeris_mask;
  122. uint32_t almanac_mask;
  123. uint32_t used_in_fix_mask;
  124. } GpsSvStatus;
  125. typedef struct {
  126. /** set to sizeof(GnssSvStatus) */
  127. size_t size;
  128. /** Number of GPS SVs currently visible, refers to the SVs stored in sv_list */
  129. int num_svs;
  130. /**
  131. * Pointer to an array of SVs information for all GNSS constellations,
  132. * except GPS, which is reported using sv_list
  133. */
  134. GnssSvInfo gnss_sv_list[GNSS_MAX_SVS];
  135. } GnssSvStatus;
  136. #endif
  137. //GGA 定位信息
  138. enum eGNSS_GGA_ITEM_T {
  139. eGGA_Header = 0,
  140. eGGA_UTCTime = 1,
  141. eGGA_Latitude = 2,
  142. eGGA_LatitudeHemi = 3,
  143. eGGA_Longitude = 4,
  144. eGGA_LongitudeHemi = 5,
  145. eGGA_StatusIndicator = 6,
  146. eGGA_SatellitesCount = 7,
  147. eGGA_HDOP = 8,
  148. eGGA_Altitude = 9,
  149. eGGA_AltitudeUnit = 10,
  150. eGGA_GeoidHeight = 11,
  151. eGGA_GeoidHeightUnit = 12,
  152. eGGA_DiffTemporal = 13,
  153. eGGA_DiffStationId = 14,
  154. eGGA_CheckSum = 15,
  155. };
  156. //GLL 定位地理信息
  157. enum eGNSS_GLL_ITEM_T {
  158. eGLL_Header = 0,
  159. eGLL_Latitude = 1,
  160. eGLL_LatitudeHemi = 2,
  161. eGLL_Longitude = 3,
  162. eGLL_LongitudeHemi = 4,
  163. eGLL_UTCTime = 5,
  164. eGLL_FixStatus = 6,
  165. eGLL_PositioningMode = 7, //optional
  166. eGLL_CheckSum = 8,
  167. };
  168. //GSA 当前卫星信息
  169. enum eGNSS_GSA_ITEM_T {
  170. eGSA_Header = 0,
  171. eGSA_Mode = 1,
  172. eGSA_Type = 2,
  173. eGSA_PRN1 = 3,
  174. eGSA_PRN2 = 4,
  175. eGSA_PRN3 = 5,
  176. eGSA_PRN4 = 6,
  177. eGSA_PRN5 = 7,
  178. eGSA_PRN6 = 8,
  179. eGSA_PRN7 = 9,
  180. eGSA_PRN8 = 10,
  181. eGSA_PRN9 = 11,
  182. eGSA_PRN10 = 12,
  183. eGSA_PRN11 = 13,
  184. eGSA_PRN12 = 14,
  185. eGSA_PDOP = 15,
  186. eGSA_HDOP = 16,
  187. eGSA_VDOP = 17,
  188. eGSA_CheckSum = 18,
  189. };
  190. //GSV 可见卫星信息
  191. enum eGNSS_GSV_ITEM_T {
  192. eGSV_Header = 0,
  193. eGSV_ItemCount = 1,
  194. eGSV_ItemSequence = 2,
  195. eGSV_SatellitesCount = 3,
  196. eGSV_PRNCode = 4,
  197. eGSV_SatelliteElevation = 5,
  198. eGSV_SatelliteAzimuth = 6,
  199. eGSV_SignalNoiseRatio = 7,
  200. eGSV_PRNCode2 = 8,
  201. eGSV_SatelliteElevation2 = 9,
  202. eGSV_SatelliteAzimuth2 = 10,
  203. eGSV_SignalNoiseRatio2 = 11,
  204. eGSV_PRNCode3 = 12,
  205. eGSV_SatelliteElevation3 = 13,
  206. eGSV_SatelliteAzimuth3 = 14,
  207. eGSV_SignalNoiseRatio3 = 15,
  208. eGSV_PRNCode4 = 16,
  209. eGSV_SatelliteElevation4 = 17,
  210. eGSV_SatelliteAzimuth4 = 18,
  211. eGSV_SignalNoiseRatio4 = 19,
  212. eGSV_CheckSum = 20,
  213. };
  214. // RMC
  215. enum eGNSS_RMC_ITEM_T {
  216. eRMC_Header = 0,
  217. eRMC_UTCTime = 1,
  218. eRMC_FixStatus = 2,
  219. eRMC_Latitude = 3,
  220. eRMC_LatitudeHemi = 4,
  221. eRMC_Longitude = 5,
  222. eRMC_LongitudeHemi = 6,
  223. eRMC_SpeedKnots = 7,
  224. eRMC_Azimuth = 8,
  225. eRMC_UTCDate = 9,
  226. eRMC_MagneticDeclination = 10,
  227. eRMC_MagneticDeclinationDirection = 11,
  228. eRMC_PositioningMode = 12, //optional
  229. eRMC_CheckSum = 13,
  230. };
  231. //VTG 地面速度信息
  232. enum eGNSS_VTG_ITEM_T {
  233. eVTG_Header = 0,
  234. eVTG_MovementAngle = 1,
  235. eVTG_TrueNorthRef = 2,
  236. eVTG_MovementAngle2 = 3,
  237. eVTG_MagneticNorthRef = 4,
  238. eVTG_HorizontalMoveSpeed = 5,
  239. eVTG_SpeedKnots = 6,
  240. eVTG_HorizontalMoveSpeed2 = 7,
  241. eVTG_SpeedKmh = 8,
  242. eVTG_PositioningMode = 9, //optional
  243. eVTG_CheckSum = 10,
  244. };
  245. //(GGA)GPS定位信息 Global Positioning System Fix Data
  246. //$GPGGA,014434.70,3817.13334637,N,12139.72994196,E,4,07,1.5,6.571,M,8.942,M,0.7,0016*7B
  247. struct XXGGA_Info_T {
  248. double UTCTime; //UTC时间,格式为hhmmss.sss
  249. double Latitude; //纬度,格式为ddmm.mmmm
  250. char LatitudeHemi; //纬度半球,N或S
  251. double Longitude; //经度,格式为dddmm.mmmm
  252. char LongitudeHemi;//经度半球,E或W
  253. uint16_t StatusIndicator;//GPS状态:0初始化,1单点定位,2码差分,3无效PPS,4固定解,5浮点解,6正在估算,7人工输入固定值,8模拟模式,9WAAS差分
  254. size_t SatellitesCount; //使用卫星数量,从00到12
  255. float HDOP; //HDOP-水平精度因子,0.5到99.9,一般认为HDOP越小,质量越好
  256. double Altitude; //椭球高,-9999.9到9999.9米
  257. char AltitudeUnit; //M指单位米
  258. float GeoidHeight; //大地水准面高度异常差值,-9999.9到9999.9米
  259. char GeoidHeightUnit; //M指单位米
  260. int64_t DiffTemporal; //差分GPS数据期限(RTCM SC-104),最后设立RTCM传送的秒数量,如不是差分定位则为空
  261. int16_t DiffStationId;//差分参考基站标号,从0000到1023
  262. //char CheckSum[4]; //从$开始到*之间的所有ASCII码的异或校验
  263. std::bitset<16> BitFlags;
  264. };
  265. //(GLL)定位地理信息 Geographic Position
  266. struct XXGLL_Info_T {
  267. double Latitude; //纬度ddmm.mmmm(度分)格式
  268. char LatitudeHemi; //纬度半球N或S
  269. double Longitude; //经度dddmm.mmmm(度分)格式
  270. char LongitudeHemi;//经度半球E或W
  271. int UTCTimeInt; //UTC时间,hhmmss(时分秒)格式
  272. char FixStatus; //定位状态,A=有效定位,V=无效定位
  273. char PositioningMode; //模式指示,仅NMEA0183 v3.00输出,A=自主定位,D=差分,E=估算,N=数据无效
  274. //char CheckSum[4];
  275. std::bitset<16> BitFlags;
  276. };
  277. //GSA 当前卫星信息 GPS DOP and Active Satellites (GSA)当前卫星信息
  278. #define GSA_INFO_PRN_CNT 12
  279. struct XXGSA_Info_T {
  280. char Mode; //定位模式,A=自动手动2D/3D,M=手动2D/3D
  281. uint16_t Type; //定位类型,1=未定位,2=2D定位,3=3D定位
  282. int PRNList[GSA_INFO_PRN_CNT]; //PRN码-伪随机噪声码,第x信道正在使用的卫星PRN码编号
  283. float PDOP; //accuracy PDOP综合位置精度因子,0.5-99.9
  284. float HDOP; //HDOP水平精度因子0.5-99.9
  285. float VDOP; //VDOP垂直精度因子0.5-99.9
  286. //char CheckSum[4];
  287. std::bitset<32> BitFlags;
  288. };
  289. //(GSV)可见卫星信息 可见卫星信息 GPS Satellites in View
  290. struct XXGSV_Info_T {
  291. uint8_t Ext_constellation; //UNKNOWN==0/GPS==1/SBAS==2/GLONASS==3/QZSS==4/BEIDOU==5/GALILEO==6
  292. size_t ItemCount; //GSV语句的总数
  293. int ItemSequence; //本句GSV的编号
  294. int SatellitesCount; //可见卫星的总数,00~12,前面的0也将被传输
  295. int PRNCode; //PRN码-伪随机噪声码,前面的0也将被传输;GPS:1-32,Beidou:1-37,GLONASS:1-24,Galileo:1-36,...
  296. float SatelliteElevation;//卫星仰角,00~90度,前面的0也将被传输
  297. float SatelliteAzimuth; //卫星方位角,000~359度,前面的0也将被传输
  298. float SignalNoiseRatio; //信噪比,00~99dB,没有跟踪到卫星时为空,前面的0也将被传输
  299. int PRNCode2; //按照每颗卫星进行循环显示,每条GSV语句最多可以显示4颗卫星的信息
  300. float SatelliteElevation2;
  301. float SatelliteAzimuth2;
  302. float SignalNoiseRatio2;
  303. int PRNCode3;
  304. float SatelliteElevation3;
  305. float SatelliteAzimuth3;
  306. float SignalNoiseRatio3;
  307. int PRNCode4;
  308. float SatelliteElevation4;
  309. float SatelliteAzimuth4;
  310. float SignalNoiseRatio4;
  311. //char CheckSum[4];
  312. std::bitset<32> BitFlags;
  313. };
  314. // (RMC)推荐定位信息 Recommended Minimum Specific GPS/TRANSIT Data
  315. //$GPRMC,200808.000,A,3114.4591,N,12118.0993,E,0.82,282.15,191220,,,A*61
  316. struct XXRMC_Info_T {
  317. double UTCTime; //UTC时间,hhmmss.sss格式,格林尼治时间;
  318. char FixStatus; //状态,A=定位,V=未定位;当给GPS复位时为V,不输出速度,角度,时间数据;
  319. double Latitude; //纬度ddmm.mmmm,度分格式
  320. char LatitudeHemi; //纬度N或S
  321. double Longitude; //经度dddmm.mmmm,度分格式
  322. char LongitudeHemi; //经度E或W
  323. float SpeedKnots; //速度,节,Knots
  324. float Azimuth; //方位角,度 Azimuth/bearing
  325. int UTCDate; //UTC日期,DDMMYY格式
  326. float MagneticDeclination; //磁偏角,000-180度
  327. char MagneticDeclinationDirection;//磁偏角方向,E或W
  328. char PositioningMode; //模式指示,仅NMEA0183 v3.00输出,A=自主定位,D=差分,E=估算,N=数据无效
  329. //char CheckSum[4];
  330. std::bitset<16> BitFlags;
  331. };
  332. //(VTG)地面速度信息 Track Made Good and Ground Speed
  333. struct XXVTG_Info_T {
  334. float MovementAngleTN; //以真北为参考基准的地面航向,000~359度,前面的0也将被传输
  335. char TrueNorthRef; //T
  336. float MovementAngleMN; //以磁北为参考基准的地面航向,000~359度,前面的0也将被传输
  337. char MagneticNorthRef; //M
  338. float HorizontalMoveSpeedKn; //地面速率,000.0~999.9节,前面的0也将被传输
  339. char SpeedKnots; //N
  340. float HorizontalMoveSpeedKm; //地面速率,0000.0~1851.8Km/h,前面的0也将被传输
  341. char SpeedKmh; //K
  342. char PositioningMode; //模式指示,仅NMEA0183 v3.00输出,A=自主定位,D=差分,E=估算,N=数据无效
  343. //char CheckSum[4];
  344. std::bitset<16> BitFlags;
  345. };
  346. template <class T>
  347. T stringToNumber(const std::string &sstr)
  348. {
  349. T number {};
  350. std::istringstream iss {};
  351. iss.str(sstr);
  352. iss >> number; /* can auto remove leading 0 */
  353. return number;
  354. }
  355. template <class T>
  356. std::string toString(T &value)
  357. {
  358. std::ostringstream oss {};
  359. oss << value;
  360. return oss.str();
  361. }
  362. template <int BS_MAX_SIZE>
  363. void bitsFlagSet(std::bitset<BS_MAX_SIZE> &bs, size_t pos)
  364. {
  365. bs.set(pos);
  366. }
  367. template <int BS_MAX_SIZE>
  368. void bitsFlagReset(std::bitset<BS_MAX_SIZE> &bs, size_t pos)
  369. {
  370. bs.reset(pos);
  371. }
  372. template <int BS_MAX_SIZE>
  373. void bitsFlagClear(std::bitset<BS_MAX_SIZE> &bs)
  374. {
  375. bs.reset();
  376. }
  377. template <int BS_MAX_SIZE>
  378. bool bitsFlagTest(std::bitset<BS_MAX_SIZE> bs, size_t pos)
  379. {
  380. return bs.test(pos);
  381. }
  382. template <int BS_MAX_SIZE>
  383. std::string bitsFlagToString(std::bitset<BS_MAX_SIZE> &bs)
  384. {
  385. return bs.to_string();
  386. }
  387. class GnssNmeaParser
  388. {
  389. public:
  390. GnssNmeaParser();
  391. ~GnssNmeaParser();
  392. int parse(const std::string &nmea);
  393. int getNmeaLines(std::vector<std::string> &lines);
  394. bool getGnssLocation(GpsLocation &gnssLocation);
  395. bool getGnssSvStatus(GnssSvStatus &gnssSvStatus);
  396. GpsUtcTime getUtcTime();
  397. //bool getGpsSvStatus(GpsSvStatus &gpsSvStatus);
  398. //bool getGpsStatus(GpsStatus &gpsStatus);
  399. private:
  400. int procGGA(XXGGA_Info_T &gga);
  401. int procGLL(XXGLL_Info_T &gll);
  402. int procGSA(std::vector<XXGSA_Info_T> &gsaVect);
  403. int procGSV(std::vector<XXGSV_Info_T> &gsvVect);
  404. int procRMC(XXRMC_Info_T &rmc);
  405. int procVTG(XXVTG_Info_T &vtg);
  406. /* convert latitude(ddmm.mmmm) and longitude(dddmm.mmmm) to degrees */
  407. double latLongToDegree(const double dddmm_mmmm);
  408. int gnssSvFlagUsedInFix(const int svid);
  409. void updateUtcTime(const int ddmmyy, const double hhmmss_sss);
  410. void updateLatLong(const double latitude, const char latHemi, const double longtitude, const char longHemi);
  411. void updateAltitude(const double altitude);
  412. void updateBearing(const float bearing);
  413. void updateMagDec(const float magDec, const char magDecDir);
  414. void updateAccuracy(const float pdop, const float hdop, const float vdop);
  415. void updateSpeed(const float speed);
  416. void updateGnssSvStatus(const std::vector<XXGSV_Info_T> &gsvVectInfoT);
  417. void removeChecksum(std::string &str);
  418. uint8_t getNConstellation(const std::string &nmeaHead);
  419. bool startsWith(const std::string &src, const std::string &str);
  420. bool endsWith(const std::string &src, const std::string &str);
  421. std::string replace(const std::string &raw, const std::string &oldstr, const std::string &newstr);
  422. size_t split(const std::string &line, const std::string &delim, std::vector<std::string> &vstr);
  423. void reset();
  424. std::vector<std::string> m_nmeaLines;
  425. std::string m_nmeaLineSep = GNSS_NMEA_LINE_SEP;
  426. std::string m_nmeaElementSep = GNSS_NMEA_ELEMENT_SEP;
  427. std::vector<std::string> m_nmeaGGAvect;
  428. std::vector<std::string> m_nmeaGLLvect;
  429. std::vector<std::vector<std::string>> m_nmeaGSAvec2d;
  430. std::vector<std::vector<std::string>> m_nmeaGSVvec2d;
  431. std::vector<std::string> m_nmeaRMCvect;
  432. std::vector<std::string> m_nmeaVTGvect;
  433. XXGGA_Info_T m_ggaInfoT;
  434. XXGLL_Info_T m_gllInfoT;
  435. std::vector<XXGSA_Info_T> m_gsaVectInfoT;
  436. std::vector<XXGSV_Info_T> m_gsvVectInfoT;
  437. XXRMC_Info_T m_rmcInfoT;
  438. XXVTG_Info_T m_vtgInfoT;
  439. GpsUtcTime m_gnssUtcTime;
  440. GpsLocation m_gnssLocation;
  441. GnssSvStatus m_gnssSvStatus;
  442. GpsStatus m_gpsStatus;
  443. };
  444. #endif // HAL_GNSS_V1_0_GNSSNMEAPARSER_H

解析.cpp实现文件

  1. #include <log/log.h>
  2. #include "GnssNmeaParser.h"
  3. #ifdef LOG_TAG
  4. #undef LOG_TAG
  5. #endif
  6. #define LOG_TAG "GnssNmeaParserV1.0"
  7. GnssNmeaParser::GnssNmeaParser()
  8. {
  9. m_nmeaLineSep = GNSS_NMEA_LINE_SEP;
  10. m_nmeaElementSep = GNSS_NMEA_ELEMENT_SEP;
  11. ALOGI("GnssNmeaParser created. %s", GNSS_NMEA_PARSER_VERSION);
  12. reset();
  13. }
  14. GnssNmeaParser::~GnssNmeaParser()
  15. {
  16. reset();
  17. }
  18. int GnssNmeaParser::parse(const std::string &nmea)
  19. {
  20. reset();
  21. int gpCount = 0;
  22. if (0 == nmea.size()) {
  23. return 0;
  24. }
  25. (void)split(nmea, m_nmeaLineSep, m_nmeaLines);
  26. std::vector<std::string>::iterator vsit;
  27. std::vector<std::string> nmeaGSAvect;
  28. std::vector<std::string> nmeaGSVvect;
  29. std::string line;
  30. for (vsit = m_nmeaLines.begin(); vsit != m_nmeaLines.end(); vsit++) {
  31. line = *vsit;
  32. if (line.size() <= 6) {
  33. //$GPxxx
  34. continue;
  35. }
  36. removeChecksum(line);
  37. gpCount += 1;
  38. if (startsWith(line, "$GPGGA")) { //GGA
  39. (void)split(line, m_nmeaElementSep, m_nmeaGGAvect);
  40. } else if (startsWith(line, "$GLGGA")) {
  41. (void)split(line, m_nmeaElementSep, m_nmeaGGAvect);
  42. } else if (startsWith(line, "$BDGGA")) {
  43. (void)split(line, m_nmeaElementSep, m_nmeaGGAvect);
  44. } else if (startsWith(line, "$GNGGA")) {
  45. (void)split(line, m_nmeaElementSep, m_nmeaGGAvect);
  46. }
  47. else if (startsWith(line, "$GPGLL")) { //GLL
  48. (void)split(line, m_nmeaElementSep, m_nmeaGLLvect);
  49. } else if (startsWith(line, "$GLGLL")) {
  50. (void)split(line, m_nmeaElementSep, m_nmeaGLLvect);
  51. } else if (startsWith(line, "$BDGLL")) {
  52. (void)split(line, m_nmeaElementSep, m_nmeaGLLvect);
  53. } else if (startsWith(line, "$GNGLL")) {
  54. (void)split(line, m_nmeaElementSep, m_nmeaGLLvect);
  55. }
  56. else if (startsWith(line, "$GPGSA")) { //GSA
  57. // may contain multi-line
  58. (void)split(line, m_nmeaElementSep, nmeaGSAvect);
  59. m_nmeaGSAvec2d.push_back(nmeaGSAvect);
  60. } else if (startsWith(line, "$GLGSA")) {
  61. (void)split(line, m_nmeaElementSep, nmeaGSAvect);
  62. m_nmeaGSAvec2d.push_back(nmeaGSAvect);
  63. } else if (startsWith(line, "$BDGSA")) {
  64. (void)split(line, m_nmeaElementSep, nmeaGSAvect);
  65. m_nmeaGSAvec2d.push_back(nmeaGSAvect);
  66. } else if (startsWith(line, "$GNGSA")) {
  67. (void)split(line, m_nmeaElementSep, nmeaGSAvect);
  68. m_nmeaGSAvec2d.push_back(nmeaGSAvect);
  69. }
  70. else if (startsWith(line, "$GPGSV")) { //GSV
  71. // may contain multi-line
  72. (void)split(line, m_nmeaElementSep, nmeaGSVvect);
  73. m_nmeaGSVvec2d.push_back(nmeaGSVvect);
  74. } else if (startsWith(line, "$GLGSV")) {
  75. (void)split(line, m_nmeaElementSep, nmeaGSVvect);
  76. m_nmeaGSVvec2d.push_back(nmeaGSVvect);
  77. } else if (startsWith(line, "$BDGSV")) {
  78. (void)split(line, m_nmeaElementSep, nmeaGSVvect);
  79. m_nmeaGSVvec2d.push_back(nmeaGSVvect);
  80. }
  81. else if (startsWith(line, "$GPRMC")) { //RMC
  82. (void)split(line, m_nmeaElementSep, m_nmeaRMCvect);
  83. } else if (startsWith(line, "$GLRMC")) {
  84. (void)split(line, m_nmeaElementSep, m_nmeaRMCvect);
  85. } else if (startsWith(line, "$BDRMC")) {
  86. (void)split(line, m_nmeaElementSep, m_nmeaRMCvect);
  87. } else if (startsWith(line, "$GNRMC")) {
  88. (void)split(line, m_nmeaElementSep, m_nmeaRMCvect);
  89. }
  90. else if (startsWith(line, "$GPVTG")) { //VTG
  91. (void)split(line, m_nmeaElementSep, m_nmeaVTGvect);
  92. } else if (startsWith(line, "$GLVTG")) {
  93. (void)split(line, m_nmeaElementSep, m_nmeaVTGvect);
  94. } else if (startsWith(line, "$BDVTG")) {
  95. (void)split(line, m_nmeaElementSep, m_nmeaVTGvect);
  96. } else if (startsWith(line, "$GNVTG")) {
  97. (void)split(line, m_nmeaElementSep, m_nmeaVTGvect);
  98. }
  99. else {
  100. ALOGD("unkown line:%s", line.c_str());
  101. }
  102. }
  103. (void)procGGA(m_ggaInfoT);
  104. (void)procGLL(m_gllInfoT);
  105. (void)procGSA(m_gsaVectInfoT);
  106. (void)procGSV(m_gsvVectInfoT);
  107. (void)procRMC(m_rmcInfoT);
  108. (void)procVTG(m_vtgInfoT);
  109. m_gnssLocation.size = sizeof(m_gnssLocation);
  110. m_gnssSvStatus.size = sizeof(m_gnssSvStatus);
  111. return gpCount;
  112. }
  113. int GnssNmeaParser::getNmeaLines(std::vector<std::string> &lines)
  114. {
  115. std::vector<std::string>::iterator vsit;
  116. for (vsit = m_nmeaLines.begin(); vsit != m_nmeaLines.end(); vsit++) {
  117. lines.push_back(*vsit+m_nmeaLineSep);
  118. }
  119. return lines.size();
  120. }
  121. int GnssNmeaParser::procGGA(XXGGA_Info_T &gga)
  122. {
  123. size_t vecSize = m_nmeaGGAvect.size();
  124. if (vecSize != eGGA_CheckSum) {
  125. ALOGD("%s invalid vector size:%zu, expected(%d)",
  126. __func__, vecSize, eGGA_CheckSum);
  127. return 0;
  128. }
  129. bitsFlagClear<16>(gga.BitFlags);
  130. for (int i = 1; i < (int)vecSize; i++)
  131. {
  132. if (m_nmeaGGAvect[i].length() != 0)
  133. {
  134. bitsFlagSet<16>(gga.BitFlags, i);
  135. }
  136. }
  137. gga.UTCTime = stringToNumber<double>(m_nmeaGGAvect[eGGA_UTCTime]);
  138. gga.Latitude = stringToNumber<double>(m_nmeaGGAvect[eGGA_Latitude]);
  139. gga.LatitudeHemi = stringToNumber<char>(m_nmeaGGAvect[eGGA_LatitudeHemi]);
  140. gga.Longitude = stringToNumber<double>(m_nmeaGGAvect[eGGA_Longitude]);
  141. gga.LongitudeHemi = stringToNumber<char>(m_nmeaGGAvect[eGGA_LongitudeHemi]);
  142. gga.StatusIndicator = stringToNumber<uint16_t>(m_nmeaGGAvect[eGGA_StatusIndicator]);
  143. gga.SatellitesCount = stringToNumber<size_t>(m_nmeaGGAvect[eGGA_SatellitesCount]);
  144. gga.HDOP = stringToNumber<float>(m_nmeaGGAvect[eGGA_HDOP]);
  145. gga.Altitude = stringToNumber<double>(m_nmeaGGAvect[eGGA_Altitude]);
  146. gga.AltitudeUnit = stringToNumber<char>(m_nmeaGGAvect[eGGA_AltitudeUnit]);
  147. gga.GeoidHeight = stringToNumber<float>(m_nmeaGGAvect[eGGA_GeoidHeight]);
  148. gga.GeoidHeightUnit = stringToNumber<char>(m_nmeaGGAvect[eGGA_GeoidHeightUnit]);
  149. gga.DiffTemporal = stringToNumber<long>(m_nmeaGGAvect[eGGA_DiffTemporal]);
  150. gga.DiffStationId = stringToNumber<int>(m_nmeaGGAvect[eGGA_DiffStationId]);
  151. m_gpsStatus.size = sizeof(m_gpsStatus);
  152. if (gga.StatusIndicator != 0) {
  153. updateLatLong(gga.Latitude, gga.LatitudeHemi, gga.Longitude, gga.LongitudeHemi);
  154. updateAltitude(gga.Altitude);
  155. updateAccuracy(0.0f, gga.HDOP, 0.0f);
  156. }
  157. return m_nmeaGGAvect.size();
  158. }
  159. int GnssNmeaParser::procGLL(XXGLL_Info_T &gll)
  160. {
  161. size_t vecSize = m_nmeaGLLvect.size();
  162. if ((vecSize != eGLL_CheckSum)
  163. && (vecSize != eGLL_CheckSum-1)) {
  164. //PositioningMode is optional, only NMEA0183 v3.00 can provide PositioningMode
  165. ALOGD("%s invalid vector size:%zu, expected(%d/%d)",
  166. __func__, vecSize, eGLL_CheckSum, eGLL_CheckSum-1);
  167. return 0;
  168. }
  169. bitsFlagClear<16>(gll.BitFlags);
  170. for (int i = 1; i < (int)vecSize; i++)
  171. {
  172. if (m_nmeaGLLvect[i].length() != 0)
  173. {
  174. bitsFlagSet<16>(gll.BitFlags, i);
  175. }
  176. }
  177. gll.Latitude = stringToNumber<double>(m_nmeaGLLvect[eGLL_Latitude]);
  178. gll.LatitudeHemi = stringToNumber<char>(m_nmeaGLLvect[eGLL_LatitudeHemi]);
  179. gll.Longitude = stringToNumber<double>(m_nmeaGLLvect[eGLL_Longitude]);
  180. gll.LongitudeHemi = stringToNumber<char>(m_nmeaGLLvect[eGLL_LongitudeHemi]);
  181. gll.UTCTimeInt = stringToNumber<int>(m_nmeaGLLvect[eGLL_UTCTime]);
  182. gll.FixStatus = stringToNumber<char>(m_nmeaGLLvect[eGLL_FixStatus]);
  183. if (vecSize == eGLL_CheckSum) {
  184. gll.PositioningMode = stringToNumber<char>(m_nmeaGLLvect[eGLL_PositioningMode]);//optional
  185. }
  186. if ((gll.FixStatus == 'A') && (gll.PositioningMode != 'N')) {
  187. updateLatLong(gll.Latitude, gll.LatitudeHemi, gll.Longitude, gll.LongitudeHemi);
  188. }
  189. return m_nmeaGLLvect.size();
  190. }
  191. int GnssNmeaParser::procGSA(std::vector<XXGSA_Info_T> &gsaVect)
  192. {
  193. if (m_nmeaGSAvec2d.size() == 0) {
  194. ALOGD("%s invalid vector size:%zu", __func__, m_nmeaGSAvec2d.size());
  195. return 0;
  196. }
  197. std::vector<std::vector<std::string>>::iterator vvsit;
  198. std::vector<std::string> nmeaGSAvect {};
  199. XXGSA_Info_T gsa {};
  200. int prnSn = 0;
  201. size_t vecSize = 0;
  202. std::string nmeaHeader;
  203. for (vvsit = m_nmeaGSAvec2d.begin(); vvsit != m_nmeaGSAvec2d.end(); vvsit++) {
  204. nmeaGSAvect = *vvsit;
  205. (void)memset((void *)&gsa, 0, sizeof(gsa));
  206. bitsFlagClear<32>(gsa.BitFlags);
  207. vecSize = nmeaGSAvect.size();
  208. if (vecSize != eGSA_CheckSum) {
  209. ALOGI("%s invalid vector size:%zu, expected(%d)",
  210. __func__, vecSize, eGSA_CheckSum);
  211. continue;
  212. }
  213. for (int i = 1; i < (int)vecSize; i++)
  214. {
  215. if (nmeaGSAvect[i].length() != 0)
  216. {
  217. bitsFlagSet<32>(gsa.BitFlags, i);
  218. }
  219. }
  220. nmeaHeader = (nmeaGSAvect[eGSA_Header]);
  221. gsa.Mode = stringToNumber<char>(nmeaGSAvect[eGSA_Mode]);
  222. gsa.Type = stringToNumber<uint16_t>(nmeaGSAvect[eGSA_Type]);
  223. for (prnSn = 0; prnSn < GSA_INFO_PRN_CNT; prnSn++) {
  224. gsa.PRNList[prnSn] = stringToNumber<int>(nmeaGSAvect[eGSA_PRN1+prnSn]);;
  225. }
  226. gsa.PDOP = stringToNumber<int>(nmeaGSAvect[eGSA_PDOP]);
  227. gsa.HDOP = stringToNumber<int>(nmeaGSAvect[eGSA_HDOP]);
  228. gsa.VDOP = stringToNumber<int>(nmeaGSAvect[eGSA_VDOP]);
  229. gsaVect.push_back(gsa);
  230. if ((gsa.Type <= 1)) {
  231. ALOGD("%s Positioning Mode is %hu(1-untargeted,2-2D,3-3D)", __func__, gsa.Type);
  232. } else {
  233. updateAccuracy(gsa.PDOP, gsa.HDOP, gsa.VDOP);
  234. }
  235. }
  236. return m_nmeaGSAvec2d.size();
  237. }
  238. int GnssNmeaParser::procGSV(std::vector<XXGSV_Info_T> &gsvVect)
  239. {
  240. if (m_nmeaGSVvec2d.size() == 0) {
  241. ALOGD("%s invalid vector size:%zu", __func__, m_nmeaGSVvec2d.size());
  242. return 0;
  243. }
  244. std::vector<std::vector<std::string>>::iterator vvsit;
  245. std::vector<std::string> nmeaGSVvect {};
  246. XXGSV_Info_T gsv {};
  247. std::string nmeaHeader;
  248. size_t vecSize = 0;
  249. for (vvsit = m_nmeaGSVvec2d.begin(); vvsit != m_nmeaGSVvec2d.end(); vvsit++) {
  250. nmeaGSVvect = *vvsit;
  251. (void)memset((void *)&gsv, 0, sizeof(gsv));
  252. bitsFlagClear<32>(gsv.BitFlags);
  253. vecSize = nmeaGSVvect.size();
  254. if ((0 != (vecSize % 4)) || (vecSize < eGSV_PRNCode)) {
  255. ALOGI("%s invalid vector size:%zu, expected(8/12/16/20)", __func__, vecSize);
  256. continue;
  257. }
  258. for (int i = 1; i < (int)vecSize; i++)
  259. {
  260. if (nmeaGSVvect[i].length() != 0)
  261. {
  262. bitsFlagSet<32>(gsv.BitFlags, i);
  263. }
  264. }
  265. nmeaHeader = nmeaGSVvect[eGSV_Header];
  266. gsv.Ext_constellation = getNConstellation(nmeaHeader);
  267. gsv.ItemCount = stringToNumber<size_t>(nmeaGSVvect[eGSV_ItemCount]);
  268. gsv.ItemSequence = stringToNumber<int>(nmeaGSVvect[eGSV_ItemSequence]);
  269. gsv.SatellitesCount = stringToNumber<int>(nmeaGSVvect[eGSV_SatellitesCount]);
  270. /* gsv slices count maybe 8/12/16/20 */
  271. if (vecSize >= eGSV_PRNCode2) {
  272. gsv.PRNCode = stringToNumber<int>(nmeaGSVvect[eGSV_PRNCode]);
  273. gsv.SatelliteElevation = stringToNumber<float>(nmeaGSVvect[eGSV_SatelliteElevation]);
  274. gsv.SatelliteAzimuth = stringToNumber<float>(nmeaGSVvect[eGSV_SatelliteAzimuth]);
  275. gsv.SignalNoiseRatio = stringToNumber<float>(nmeaGSVvect[eGSV_SignalNoiseRatio]);
  276. }
  277. if (vecSize >= eGSV_PRNCode3) {
  278. gsv.PRNCode2 = stringToNumber<int>(nmeaGSVvect[eGSV_PRNCode2]);
  279. gsv.SatelliteElevation2 = stringToNumber<float>(nmeaGSVvect[eGSV_SatelliteElevation2]);
  280. gsv.SatelliteAzimuth2 = stringToNumber<float>(nmeaGSVvect[eGSV_SatelliteAzimuth2]);
  281. gsv.SignalNoiseRatio2 = stringToNumber<float>(nmeaGSVvect[eGSV_SignalNoiseRatio2]);
  282. }
  283. if (vecSize >= eGSV_PRNCode4) {
  284. gsv.PRNCode3 = stringToNumber<int>(nmeaGSVvect[eGSV_PRNCode3]);
  285. gsv.SatelliteElevation3 = stringToNumber<float>(nmeaGSVvect[eGSV_SatelliteElevation3]);
  286. gsv.SatelliteAzimuth3 = stringToNumber<float>(nmeaGSVvect[eGSV_SatelliteAzimuth3]);
  287. gsv.SignalNoiseRatio3 = stringToNumber<float>(nmeaGSVvect[eGSV_SignalNoiseRatio3]);
  288. }
  289. if (vecSize == eGSV_CheckSum) {
  290. gsv.PRNCode4 = stringToNumber<int>(nmeaGSVvect[eGSV_PRNCode4]);
  291. gsv.SatelliteElevation4 = stringToNumber<float>(nmeaGSVvect[eGSV_SatelliteElevation4]);
  292. gsv.SatelliteAzimuth4 = stringToNumber<float>(nmeaGSVvect[eGSV_SatelliteAzimuth4]);
  293. gsv.SignalNoiseRatio4 = stringToNumber<float>(nmeaGSVvect[eGSV_SignalNoiseRatio4]);
  294. }
  295. gsvVect.push_back(gsv);
  296. }
  297. updateGnssSvStatus(gsvVect);
  298. return m_nmeaGSVvec2d.size();
  299. }
  300. int GnssNmeaParser::procRMC(XXRMC_Info_T &rmc)
  301. {
  302. size_t vecSize = m_nmeaRMCvect.size();
  303. if ((vecSize != eRMC_CheckSum)
  304. && (vecSize != eRMC_CheckSum-1)) {
  305. //PositioningMode is optional, only NMEA0183 v3.00 can provide PositioningMode
  306. ALOGD("%s invalid vector size:%zu, expected(%d/%d)",
  307. __func__, vecSize, eRMC_CheckSum, eRMC_CheckSum-1);
  308. return 0;
  309. }
  310. bitsFlagClear<16>(rmc.BitFlags);
  311. for (int i = 1; i < (int)vecSize; i++)
  312. {
  313. if (m_nmeaRMCvect[i].length() != 0)
  314. {
  315. bitsFlagSet<16>(rmc.BitFlags, i);
  316. }
  317. }
  318. rmc.UTCTime = stringToNumber<double>(m_nmeaRMCvect[eRMC_UTCTime]);
  319. rmc.FixStatus = stringToNumber<char>(m_nmeaRMCvect[eRMC_FixStatus]);
  320. rmc.Latitude = stringToNumber<double>(m_nmeaRMCvect[eRMC_Latitude]);
  321. rmc.LatitudeHemi = stringToNumber<char>(m_nmeaRMCvect[eRMC_LatitudeHemi]);
  322. rmc.Longitude = stringToNumber<double>(m_nmeaRMCvect[eRMC_Longitude]);
  323. rmc.LongitudeHemi = stringToNumber<char>(m_nmeaRMCvect[eRMC_LongitudeHemi]);
  324. rmc.SpeedKnots = stringToNumber<float>(m_nmeaRMCvect[eRMC_SpeedKnots]);
  325. rmc.Azimuth = stringToNumber<float>(m_nmeaRMCvect[eRMC_Azimuth]);
  326. rmc.UTCDate = stringToNumber<int>(m_nmeaRMCvect[eRMC_UTCDate]);
  327. rmc.MagneticDeclination = stringToNumber<float>(m_nmeaRMCvect[eRMC_MagneticDeclination]);
  328. rmc.MagneticDeclinationDirection = stringToNumber<char>(m_nmeaRMCvect[eRMC_MagneticDeclinationDirection]);
  329. if (vecSize == eRMC_CheckSum) {
  330. rmc.PositioningMode = stringToNumber<char>(m_nmeaRMCvect[eRMC_PositioningMode]);//optional
  331. }
  332. if (rmc.FixStatus == 'A') {
  333. updateUtcTime(rmc.UTCDate, rmc.UTCTime);
  334. updateLatLong(rmc.Latitude, rmc.LatitudeHemi, rmc.Longitude, rmc.LongitudeHemi);
  335. updateBearing(rmc.Azimuth);
  336. updateSpeed((1.852f * rmc.SpeedKnots / 3.6f));
  337. updateMagDec(rmc.MagneticDeclination, rmc.MagneticDeclinationDirection);
  338. } else if (rmc.FixStatus == 'V') {
  339. ALOGW("%s FixStatus is V(A-targeted,V-untargeted)", __func__);
  340. // UTCDate and UTCTime may be empty
  341. //updateUtcTime(rmc.UTCDate, rmc.UTCTime);
  342. updateLatLong(rmc.Latitude, rmc.LatitudeHemi, rmc.Longitude, rmc.LongitudeHemi);
  343. //updateBearing(rmc.Azimuth);
  344. } else {
  345. //invalid data
  346. ALOGD("%s invalid FixStatus(%c)", __func__, rmc.FixStatus);
  347. }
  348. return m_nmeaRMCvect.size();
  349. }
  350. int GnssNmeaParser::procVTG(XXVTG_Info_T &vtg)
  351. {
  352. size_t vecSize = m_nmeaVTGvect.size();
  353. if ((vecSize != eVTG_CheckSum)
  354. && (vecSize != eVTG_CheckSum-1)) {
  355. //PositioningMode is optional, only NMEA0183 v3.00 can provide PositioningMode
  356. ALOGD("%s invalid vector size:%zu, expected(%d/%d)",
  357. __func__, vecSize, eVTG_CheckSum, eVTG_CheckSum-1);
  358. return 0;
  359. }
  360. bitsFlagClear<16>(vtg.BitFlags);
  361. for (int i = 1; i < (int)vecSize; i++)
  362. {
  363. if (m_nmeaVTGvect[i].length() != 0)
  364. {
  365. bitsFlagSet<16>(vtg.BitFlags, i);
  366. }
  367. }
  368. vtg.MovementAngleTN = stringToNumber<float>(m_nmeaVTGvect[eVTG_MovementAngle]);
  369. vtg.TrueNorthRef = stringToNumber<char>(m_nmeaVTGvect[eVTG_TrueNorthRef]);
  370. vtg.MovementAngleMN = stringToNumber<float>(m_nmeaVTGvect[eVTG_MovementAngle2]);
  371. vtg.MagneticNorthRef = stringToNumber<char>(m_nmeaVTGvect[eVTG_MagneticNorthRef]);
  372. vtg.HorizontalMoveSpeedKn = stringToNumber<float>(m_nmeaVTGvect[eVTG_HorizontalMoveSpeed]);
  373. vtg.SpeedKnots = stringToNumber<char>(m_nmeaVTGvect[eVTG_SpeedKnots]);
  374. vtg.HorizontalMoveSpeedKm = stringToNumber<float>(m_nmeaVTGvect[eVTG_HorizontalMoveSpeed2]);
  375. vtg.SpeedKmh = stringToNumber<char>(m_nmeaVTGvect[eVTG_SpeedKmh]);
  376. if (vecSize == eVTG_CheckSum) {
  377. vtg.PositioningMode = stringToNumber<char>(m_nmeaVTGvect[eVTG_PositioningMode]);//optional
  378. }
  379. if ((vtg.PositioningMode == 'A') || (vtg.PositioningMode == 'D')) {
  380. updateSpeed(vtg.HorizontalMoveSpeedKm/3.6f);
  381. }
  382. return m_nmeaVTGvect.size();
  383. }
  384. void GnssNmeaParser::updateUtcTime(const int ddmmyy, const double hhmmss_sss)
  385. {
  386. //get utc diff
  387. time_t time_now = time(NULL);
  388. struct tm tm_local {};
  389. struct tm tm_utc {};
  390. long time_local_sec = 0;
  391. long time_utc_sec = 0;
  392. long utc_diff_sec = 0;
  393. //get fixed time
  394. struct tm tm_gnss {};
  395. time_t time_fixed = 0;
  396. int utc_year = 0;
  397. int utc_month = 0;
  398. int utc_day = 0;
  399. int utc_hour = 0;
  400. int utc_minute = 0;
  401. int utc_seconds = 0;
  402. int hhmmss = (int)hhmmss_sss;
  403. int milliseconds = 0;
  404. gmtime_r(&time_now, &tm_utc);
  405. localtime_r(&time_now, &tm_local);
  406. time_local_sec = tm_local.tm_sec +
  407. 60*(tm_local.tm_min +
  408. 60*(tm_local.tm_hour +
  409. 24*(tm_local.tm_yday +
  410. 365*tm_local.tm_year)));
  411. time_utc_sec = tm_utc.tm_sec +
  412. 60*(tm_utc.tm_min +
  413. 60*(tm_utc.tm_hour +
  414. 24*(tm_utc.tm_yday +
  415. 365*tm_utc.tm_year)));
  416. utc_diff_sec = time_local_sec - time_utc_sec;
  417. utc_day = (ddmmyy / 100) / 100;
  418. utc_month = (ddmmyy / 100) % 100;
  419. utc_year = (ddmmyy % 100) + 2000;
  420. utc_hour = ((hhmmss / 100) / 100);
  421. utc_minute = ((hhmmss / 100) % 100);
  422. utc_seconds = (hhmmss % 100);
  423. //milliseconds = (int)((hhmmss_sss - hhmmss) * 1000); //will less precise
  424. milliseconds = (int)((hhmmss_sss * 1000) - (hhmmss * 1000)); //Improve accuracy
  425. tm_gnss.tm_hour = utc_hour;
  426. tm_gnss.tm_min = utc_minute;
  427. tm_gnss.tm_sec = utc_seconds;
  428. tm_gnss.tm_year = utc_year - 1900;
  429. tm_gnss.tm_mon = utc_month - 1;
  430. tm_gnss.tm_mday = utc_day;
  431. tm_gnss.tm_isdst = -1;
  432. time_fixed = mktime(&tm_gnss) + utc_diff_sec;
  433. m_gnssUtcTime = (long long)time_fixed * 1000 + milliseconds;
  434. m_gnssLocation.timestamp = m_gnssUtcTime;
  435. if ((0 == ddmmyy) || (0 == hhmmss)) {
  436. ALOGW("%s invalid UTCDate=%d, UTCTime=%d", __func__, ddmmyy, hhmmss);
  437. //use local stored utc time
  438. time_fixed = mktime(&tm_utc) + utc_diff_sec;
  439. m_gnssUtcTime = (long long)time_fixed * 1000;
  440. m_gnssLocation.timestamp = m_gnssUtcTime;
  441. }
  442. }
  443. void GnssNmeaParser::updateLatLong(const double latitude, const char latHemi, const double longtitude, const char longHemi)
  444. {
  445. double lat = latitude;
  446. double lon = longtitude;
  447. if (latHemi == 'S') {
  448. lat = -lat;
  449. }
  450. if (longHemi == 'W') {
  451. lon = -lon;
  452. }
  453. m_gnssLocation.flags |= GPS_LOCATION_HAS_LAT_LONG;
  454. m_gnssLocation.latitude = latLongToDegree(lat);
  455. m_gnssLocation.longitude = latLongToDegree(lon);
  456. }
  457. void GnssNmeaParser::updateAltitude(const double altitude)
  458. {
  459. double alt = altitude;
  460. m_gnssLocation.flags |= GPS_LOCATION_HAS_ALTITUDE;
  461. m_gnssLocation.altitude = alt;
  462. }
  463. void GnssNmeaParser::updateBearing(const float bearing)
  464. {
  465. float bea = bearing;
  466. m_gnssLocation.flags |= GPS_LOCATION_HAS_BEARING;
  467. m_gnssLocation.bearing = bea;
  468. }
  469. void GnssNmeaParser::updateMagDec(const float magDec, const char magDecDir)
  470. {
  471. (void)magDec;
  472. (void)magDecDir;
  473. }
  474. void GnssNmeaParser::updateAccuracy(const float pdop, const float hdop, const float vdop)
  475. {
  476. /* GSA HDOP */
  477. (void)pdop;
  478. (void)vdop;
  479. if ((0.1f <= hdop)) {
  480. m_gnssLocation.flags |= GPS_LOCATION_HAS_HORIZONTAL_ACCURACY;
  481. m_gnssLocation.accuracy = hdop;
  482. }
  483. }
  484. void GnssNmeaParser::updateSpeed(const float speed)
  485. {
  486. float velocity = speed;
  487. m_gnssLocation.flags |= GPS_LOCATION_HAS_SPEED;
  488. m_gnssLocation.speed = velocity;
  489. }
  490. void GnssNmeaParser::updateGnssSvStatus(const std::vector<XXGSV_Info_T> &gsvVectInfoT)
  491. {
  492. std::vector<XXGSV_Info_T>::const_iterator vit;
  493. int itemsCount = 0;
  494. int itemSequence = 0;
  495. int sateSeq = 0;
  496. m_gnssSvStatus.size = sizeof(m_gnssSvStatus);
  497. m_gnssSvStatus.num_svs = 0;
  498. for (vit = gsvVectInfoT.begin(); vit != gsvVectInfoT.end(); vit++) {
  499. itemsCount = vit->ItemCount;
  500. itemSequence = vit->ItemSequence;
  501. if ((sateSeq+3) > (GNSS_MAX_SVS-1)) {
  502. /* preventing arrays from out of bounds */
  503. ALOGW(" gnssSvStatus num more than GNSS_MAX_SVS:%d", GNSS_MAX_SVS);
  504. break;
  505. }
  506. //m_gnssSvStatus.gnss_sv_list[sateSeq].size = sizeof(GnssSvInfo);
  507. m_gnssSvStatus.gnss_sv_list[sateSeq].svid = vit->PRNCode;
  508. m_gnssSvStatus.gnss_sv_list[sateSeq].elevation = vit->SatelliteElevation;
  509. m_gnssSvStatus.gnss_sv_list[sateSeq].azimuth = vit->SatelliteAzimuth;
  510. m_gnssSvStatus.gnss_sv_list[sateSeq].c_n0_dbhz = vit->SignalNoiseRatio;
  511. m_gnssSvStatus.gnss_sv_list[sateSeq].flags = 0;
  512. if (bitsFlagTest<32>((*vit).BitFlags, eGSV_SignalNoiseRatio)) {
  513. //m_gnssSvStatus.gnss_sv_list[sateSeq].flags |= GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY;
  514. }
  515. m_gnssSvStatus.gnss_sv_list[sateSeq].constellation = vit->Ext_constellation;
  516. if (vit->PRNCode > 0) {
  517. /* check and set flag whether available satellite */
  518. m_gnssSvStatus.gnss_sv_list[sateSeq].flags |= gnssSvFlagUsedInFix(vit->PRNCode);
  519. /* increase visible satellites count */
  520. sateSeq += 1;
  521. }
  522. //m_gnssSvStatus.gnss_sv_list[sateSeq].size = sizeof(GnssSvInfo);
  523. m_gnssSvStatus.gnss_sv_list[sateSeq].svid = vit->PRNCode2;
  524. m_gnssSvStatus.gnss_sv_list[sateSeq].elevation = vit->SatelliteElevation2;
  525. m_gnssSvStatus.gnss_sv_list[sateSeq].azimuth = vit->SatelliteAzimuth2;
  526. m_gnssSvStatus.gnss_sv_list[sateSeq].c_n0_dbhz = vit->SignalNoiseRatio2;
  527. m_gnssSvStatus.gnss_sv_list[sateSeq].flags = 0;
  528. if ( bitsFlagTest<32>(vit->BitFlags, eGSV_SignalNoiseRatio2) ) {
  529. //m_gnssSvStatus.gnss_sv_list[sateSeq].flags |= GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY;
  530. }
  531. m_gnssSvStatus.gnss_sv_list[sateSeq].constellation = vit->Ext_constellation;
  532. if (vit->PRNCode2 > 0) {
  533. m_gnssSvStatus.gnss_sv_list[sateSeq].flags |= gnssSvFlagUsedInFix(vit->PRNCode2);
  534. sateSeq += 1;
  535. }
  536. //m_gnssSvStatus.gnss_sv_list[sateSeq].size = sizeof(GnssSvInfo);
  537. m_gnssSvStatus.gnss_sv_list[sateSeq].svid = vit->PRNCode3;
  538. m_gnssSvStatus.gnss_sv_list[sateSeq].elevation = vit->SatelliteElevation3;
  539. m_gnssSvStatus.gnss_sv_list[sateSeq].azimuth = vit->SatelliteAzimuth3;
  540. m_gnssSvStatus.gnss_sv_list[sateSeq].c_n0_dbhz = vit->SignalNoiseRatio3;
  541. m_gnssSvStatus.gnss_sv_list[sateSeq].flags = 0;
  542. if (bitsFlagTest<32>(vit->BitFlags, eGSV_SignalNoiseRatio3)) {
  543. //m_gnssSvStatus.gnss_sv_list[sateSeq].flags |= GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY;
  544. }
  545. m_gnssSvStatus.gnss_sv_list[sateSeq].constellation = vit->Ext_constellation;
  546. if (vit->PRNCode3 > 0) {
  547. m_gnssSvStatus.gnss_sv_list[sateSeq].flags |= gnssSvFlagUsedInFix(vit->PRNCode3);
  548. sateSeq += 1;
  549. }
  550. //m_gnssSvStatus.gnss_sv_list[sateSeq].size = sizeof(GnssSvInfo);
  551. m_gnssSvStatus.gnss_sv_list[sateSeq].svid = vit->PRNCode4;
  552. m_gnssSvStatus.gnss_sv_list[sateSeq].elevation = vit->SatelliteElevation4;
  553. m_gnssSvStatus.gnss_sv_list[sateSeq].azimuth = vit->SatelliteAzimuth4;
  554. m_gnssSvStatus.gnss_sv_list[sateSeq].c_n0_dbhz = vit->SignalNoiseRatio4;
  555. m_gnssSvStatus.gnss_sv_list[sateSeq].flags = 0;
  556. if (bitsFlagTest<32>(vit->BitFlags, eGSV_SignalNoiseRatio4)) {
  557. //m_gnssSvStatus.gnss_sv_list[sateSeq].flags |= GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY;
  558. }
  559. m_gnssSvStatus.gnss_sv_list[sateSeq].constellation = vit->Ext_constellation;
  560. if (vit->PRNCode4 > 0) {
  561. m_gnssSvStatus.gnss_sv_list[sateSeq].flags |= gnssSvFlagUsedInFix(vit->PRNCode4);
  562. sateSeq += 1;
  563. }
  564. }
  565. m_gnssSvStatus.num_svs = sateSeq;
  566. }
  567. double GnssNmeaParser::latLongToDegree(const double dddmm_mmmm)
  568. {
  569. // eg.: 12031.0902 -> 120.51817(120+(31.0902/60.0=0.51817))
  570. int ddd = (int)(dddmm_mmmm/100);
  571. double mm_mmmm = dddmm_mmmm - (ddd*100.0);
  572. double ddd_xxx = ddd + (mm_mmmm / 60.0);
  573. return ddd_xxx;
  574. }
  575. int GnssNmeaParser::gnssSvFlagUsedInFix(const int svid) {
  576. int fixed = 0;
  577. int prnSn = 0;
  578. std::vector<XXGSA_Info_T>::iterator gsaIt;
  579. for (gsaIt = m_gsaVectInfoT.begin(); gsaIt != m_gsaVectInfoT.end(); gsaIt++) {
  580. for (prnSn = 0; prnSn < GSA_INFO_PRN_CNT; prnSn++) {
  581. if (svid == gsaIt->PRNList[prnSn]) {
  582. fixed = GNSS_SV_FLAGS_USED_IN_FIX;
  583. break;
  584. }
  585. }
  586. }
  587. return fixed;
  588. }
  589. bool GnssNmeaParser::getGnssLocation(GpsLocation &gnssLocation)
  590. {
  591. (void)memcpy(&gnssLocation, &m_gnssLocation, sizeof(m_gnssLocation));
  592. return true;
  593. }
  594. bool GnssNmeaParser::getGnssSvStatus(GnssSvStatus &gnssSvStatus)
  595. {
  596. #if 1
  597. int numSv = m_gnssSvStatus.num_svs;
  598. ALOGD("getGnssSvStatus size:%zu, num_svs:%d", m_gnssSvStatus.size, m_gnssSvStatus.num_svs);
  599. for(int tmp = 0; tmp < numSv; tmp++)
  600. {
  601. ALOGD("getGnssSvStatus (id=%d,elevation=%f,azimuth=%f,dbhz=%f,CX=%d,svFlag=0x%x)",
  602. m_gnssSvStatus.gnss_sv_list[tmp].svid,
  603. m_gnssSvStatus.gnss_sv_list[tmp].elevation,
  604. m_gnssSvStatus.gnss_sv_list[tmp].azimuth,
  605. m_gnssSvStatus.gnss_sv_list[tmp].c_n0_dbhz,
  606. (int)m_gnssSvStatus.gnss_sv_list[tmp].constellation,
  607. (int)m_gnssSvStatus.gnss_sv_list[tmp].flags);
  608. }
  609. #endif
  610. (void)memcpy(&gnssSvStatus, &m_gnssSvStatus, sizeof(gnssSvStatus));
  611. return true;
  612. }
  613. GpsUtcTime GnssNmeaParser::getUtcTime()
  614. {
  615. return m_gnssUtcTime;
  616. }
  617. void GnssNmeaParser::reset()
  618. {
  619. m_nmeaLines.clear();
  620. m_nmeaGGAvect.clear();
  621. m_nmeaGLLvect.clear();
  622. m_nmeaGSAvec2d.clear();
  623. m_nmeaGSVvec2d.clear();
  624. m_nmeaRMCvect.clear();
  625. m_nmeaVTGvect.clear();
  626. m_gnssUtcTime = 0;
  627. (void)memset(&m_ggaInfoT, 0, sizeof(m_ggaInfoT));
  628. (void)memset(&m_gllInfoT, 0, sizeof(m_gllInfoT));
  629. m_gsaVectInfoT.clear();
  630. m_gsvVectInfoT.clear();
  631. (void)memset(&m_rmcInfoT, 0, sizeof(m_rmcInfoT));
  632. (void)memset(&m_vtgInfoT, 0, sizeof(m_vtgInfoT));
  633. (void)memset(&m_gnssLocation, 0, sizeof(m_gnssLocation));
  634. (void)memset(&m_gnssSvStatus, 0, sizeof(m_gnssSvStatus));
  635. }
  636. void GnssNmeaParser::removeChecksum(std::string &str)
  637. {
  638. // get rid of checksum at the end of the sentecne
  639. // remove chars after *
  640. size_t phit = 0;
  641. phit = str.find("*");
  642. if (std::string::npos != phit)
  643. {
  644. str.erase(phit);
  645. }
  646. }
  647. uint8_t GnssNmeaParser::getNConstellation(const std::string &nmeaHead)
  648. {
  649. uint8_t constellation = GNSS_CONSTELLATION_UNKNOWN;
  650. if (startsWith(nmeaHead, "$GP")) {
  651. constellation = GNSS_CONSTELLATION_GPS;
  652. } else if (startsWith(nmeaHead, "$GL")) {
  653. constellation = GNSS_CONSTELLATION_GLONASS;
  654. } else if (startsWith(nmeaHead, "$BD")) {
  655. constellation = GNSS_CONSTELLATION_BEIDOU;
  656. } else {
  657. constellation = GNSS_CONSTELLATION_UNKNOWN;
  658. }
  659. return constellation;
  660. }
  661. bool GnssNmeaParser::startsWith(const std::string &src, const std::string &str)
  662. {
  663. int srcpos = 0;
  664. int srclen = src.length();
  665. int sublen = str.length();
  666. if (srclen < sublen) {
  667. return false;
  668. }
  669. return (0 == src.compare(srcpos, sublen, str));
  670. }
  671. bool GnssNmeaParser::endsWith(const std::string &src, const std::string &str)
  672. {
  673. int srcpos = 0;
  674. int srclen = src.length();
  675. int sublen = str.length();
  676. if (srclen < sublen) {
  677. return false;
  678. }
  679. srcpos = srclen - sublen;
  680. return (0 == src.compare(srcpos, sublen, str));
  681. }
  682. std::string GnssNmeaParser::replace(const std::string &raw, const std::string &oldstr, const std::string &newstr) {
  683. std::string res_string = raw;
  684. size_t startpos = 0;
  685. size_t retpos = 0;
  686. while (std::string::npos != (retpos = res_string.find(oldstr, startpos)))
  687. {
  688. if (oldstr.size() == newstr.size()) {
  689. (void)res_string.replace(retpos, oldstr.size(), newstr);
  690. } else {
  691. (void)res_string.erase(retpos, oldstr.size());
  692. (void)res_string.insert(retpos, newstr);
  693. }
  694. startpos = retpos + oldstr.size();
  695. }
  696. return res_string;
  697. }
  698. size_t GnssNmeaParser::split(const std::string &line, const std::string &delim, std::vector<std::string> &vstr)
  699. {
  700. size_t pstart = 0;
  701. size_t phit = 0;
  702. std::string sstr;
  703. size_t length = line.length();
  704. vstr.clear();
  705. for (;pstart <= length;)
  706. {
  707. phit = line.find(delim, pstart);
  708. if (std::string::npos != phit)
  709. {
  710. /* find delim, get substr */
  711. sstr = line.substr(pstart, phit-pstart);
  712. vstr.push_back(sstr);
  713. pstart = phit + delim.size();
  714. } else {
  715. /* not find delim, append remaining str and break */
  716. vstr.push_back(line.substr(pstart));
  717. break;
  718. }
  719. }
  720. return vstr.size();
  721. }

for Android Gnss V1.1

  1. #ifndef HAL_GNSS_V1_0_GNSSNMEAPARSER_H
  2. #define HAL_GNSS_V1_0_GNSSNMEAPARSER_H
  3. #include <cstdio>
  4. #include <iostream>
  5. #include <sstream>
  6. #include <bitset>
  7. #include <vector>
  8. #include <map>
  9. #include <queue>
  10. //#include <hardware/gps.h>
  11. #include <android/hardware/gnss/1.1/IGnss.h>
  12. #define GNSS_NMEA_LINE_SEP "\n"
  13. #define GNSS_NMEA_ELEMENT_SEP ","
  14. #define GNSS_NMEA_PARSER_VERSION "v1.0-20.0716"
  15. using GnssSvFlags = ::android::hardware::gnss::V1_0::IGnssCallback::GnssSvFlags;
  16. using GnssStatusValue = ::android::hardware::gnss::V1_0::IGnssCallback::GnssStatusValue;
  17. using GnssLocationFlags = android::hardware::gnss::V1_0::GnssLocationFlags;
  18. using GnssMax = ::android::hardware::gnss::V1_0::GnssMax;
  19. using GnssLocation = ::android::hardware::gnss::V1_0::GnssLocation;
  20. using GnssConstellationType = ::android::hardware::gnss::V1_0::GnssConstellationType;
  21. using GnssSvInfo = ::android::hardware::gnss::V1_0::IGnssCallback::GnssSvInfo;
  22. using GnssSvStatus = ::android::hardware::gnss::V1_0::IGnssCallback::GnssSvStatus;
  23. using GnssUtcTime = ::android::hardware::gnss::V1_0::GnssUtcTime;
  24. using GnssAidingData = ::android::hardware::gnss::V1_0::IGnss::GnssAidingData;
  25. using GnssPositionMode = ::android::hardware::gnss::V1_0::IGnss::GnssPositionMode;
  26. using GnssPositionRecurrence = ::android::hardware::gnss::V1_0::IGnss::GnssPositionRecurrence;
  27. //GGA 定位信息
  28. enum eGNSS_GGA_ITEM_T {
  29. eGGA_Header = 0,
  30. eGGA_UTCTime = 1,
  31. eGGA_Latitude = 2,
  32. eGGA_LatitudeHemi = 3,
  33. eGGA_Longitude = 4,
  34. eGGA_LongitudeHemi = 5,
  35. eGGA_StatusIndicator = 6,
  36. eGGA_SatellitesCount = 7,
  37. eGGA_HDOP = 8,
  38. eGGA_Altitude = 9,
  39. eGGA_AltitudeUnit = 10,
  40. eGGA_GeoidHeight = 11,
  41. eGGA_GeoidHeightUnit = 12,
  42. eGGA_DiffTemporal = 13,
  43. eGGA_DiffStationId = 14,
  44. eGGA_CheckSum = 15,
  45. };
  46. //GLL 定位地理信息
  47. enum eGNSS_GLL_ITEM_T {
  48. eGLL_Header = 0,
  49. eGLL_Latitude = 1,
  50. eGLL_LatitudeHemi = 2,
  51. eGLL_Longitude = 3,
  52. eGLL_LongitudeHemi = 4,
  53. eGLL_UTCTime = 5,
  54. eGLL_FixStatus = 6,
  55. eGLL_PositioningMode = 7, //optional
  56. eGLL_CheckSum = 8,
  57. };
  58. //GSA 当前卫星信息
  59. enum eGNSS_GSA_ITEM_T {
  60. eGSA_Header = 0,
  61. eGSA_Mode = 1,
  62. eGSA_Type = 2,
  63. eGSA_PRN1 = 3,
  64. eGSA_PRN2 = 4,
  65. eGSA_PRN3 = 5,
  66. eGSA_PRN4 = 6,
  67. eGSA_PRN5 = 7,
  68. eGSA_PRN6 = 8,
  69. eGSA_PRN7 = 9,
  70. eGSA_PRN8 = 10,
  71. eGSA_PRN9 = 11,
  72. eGSA_PRN10 = 12,
  73. eGSA_PRN11 = 13,
  74. eGSA_PRN12 = 14,
  75. eGSA_PDOP = 15,
  76. eGSA_HDOP = 16,
  77. eGSA_VDOP = 17,
  78. eGSA_CheckSum = 18,
  79. };
  80. //GSV 可见卫星信息
  81. enum eGNSS_GSV_ITEM_T {
  82. eGSV_Header = 0,
  83. eGSV_ItemCount = 1,
  84. eGSV_ItemSequence = 2,
  85. eGSV_SatellitesCount = 3,
  86. eGSV_PRNCode = 4,
  87. eGSV_SatelliteElevation = 5,
  88. eGSV_SatelliteAzimuth = 6,
  89. eGSV_SignalNoiseRatio = 7,
  90. eGSV_PRNCode2 = 8,
  91. eGSV_SatelliteElevation2 = 9,
  92. eGSV_SatelliteAzimuth2 = 10,
  93. eGSV_SignalNoiseRatio2 = 11,
  94. eGSV_PRNCode3 = 12,
  95. eGSV_SatelliteElevation3 = 13,
  96. eGSV_SatelliteAzimuth3 = 14,
  97. eGSV_SignalNoiseRatio3 = 15,
  98. eGSV_PRNCode4 = 16,
  99. eGSV_SatelliteElevation4 = 17,
  100. eGSV_SatelliteAzimuth4 = 18,
  101. eGSV_SignalNoiseRatio4 = 19,
  102. eGSV_CheckSum = 20,
  103. };
  104. // RMC
  105. enum eGNSS_RMC_ITEM_T {
  106. eRMC_Header = 0,
  107. eRMC_UTCTime = 1,
  108. eRMC_FixStatus = 2,
  109. eRMC_Latitude = 3,
  110. eRMC_LatitudeHemi = 4,
  111. eRMC_Longitude = 5,
  112. eRMC_LongitudeHemi = 6,
  113. eRMC_SpeedKnots = 7,
  114. eRMC_Azimuth = 8,
  115. eRMC_UTCDate = 9,
  116. eRMC_MagneticDeclination = 10,
  117. eRMC_MagneticDeclinationDirection = 11,
  118. eRMC_PositioningMode = 12, //optional
  119. eRMC_CheckSum = 13,
  120. };
  121. //VTG 地面速度信息
  122. enum eGNSS_VTG_ITEM_T {
  123. eVTG_Header = 0,
  124. eVTG_MovementAngle = 1,
  125. eVTG_TrueNorthRef = 2,
  126. eVTG_MovementAngle2 = 3,
  127. eVTG_MagneticNorthRef = 4,
  128. eVTG_HorizontalMoveSpeed = 5,
  129. eVTG_SpeedKnots = 6,
  130. eVTG_HorizontalMoveSpeed2 = 7,
  131. eVTG_SpeedKmh = 8,
  132. eVTG_PositioningMode = 9, //optional
  133. eVTG_CheckSum = 10,
  134. };
  135. //(GGA)GPS定位信息 Global Positioning System Fix Data
  136. //$GPGGA,014434.70,3817.13334637,N,12139.72994196,E,4,07,1.5,6.571,M,8.942,M,0.7,0016*7B
  137. struct XXGGA_Info_T {
  138. double UTCTime; //UTC时间,格式为hhmmss.sss
  139. double Latitude; //纬度,格式为ddmm.mmmm
  140. char LatitudeHemi; //纬度半球,N或S
  141. double Longitude; //经度,格式为dddmm.mmmm
  142. char LongitudeHemi;//经度半球,E或W
  143. uint16_t StatusIndicator;//GPS状态:0初始化,1单点定位,2码差分,3无效PPS,4固定解,5浮点解,6正在估算,7人工输入固定值,8模拟模式,9WAAS差分
  144. size_t SatellitesCount; //使用卫星数量,从00到12
  145. float HDOP; //HDOP-水平精度因子,0.5到99.9,一般认为HDOP越小,质量越好
  146. double Altitude; //椭球高,-9999.9到9999.9米
  147. char AltitudeUnit; //M指单位米
  148. float GeoidHeight; //大地水准面高度异常差值,-9999.9到9999.9米
  149. char GeoidHeightUnit; //M指单位米
  150. int64_t DiffTemporal; //差分GPS数据期限(RTCM SC-104),最后设立RTCM传送的秒数量,如不是差分定位则为空
  151. int16_t DiffStationId;//差分参考基站标号,从0000到1023
  152. //char CheckSum[4]; //从$开始到*之间的所有ASCII码的异或校验
  153. std::bitset<16> BitFlags;
  154. };
  155. //(GLL)定位地理信息 Geographic Position
  156. struct XXGLL_Info_T {
  157. double Latitude; //纬度ddmm.mmmm(度分)格式
  158. char LatitudeHemi; //纬度半球N或S
  159. double Longitude; //经度dddmm.mmmm(度分)格式
  160. char LongitudeHemi;//经度半球E或W
  161. int UTCTimeInt; //UTC时间,hhmmss(时分秒)格式
  162. char FixStatus; //定位状态,A=有效定位,V=无效定位
  163. char PositioningMode; //模式指示,仅NMEA0183 v3.00输出,A=自主定位,D=差分,E=估算,N=数据无效
  164. //char CheckSum[4];
  165. std::bitset<16> BitFlags;
  166. };
  167. //GSA 当前卫星信息 GPS DOP and Active Satellites (GSA)当前卫星信息
  168. #define GSA_INFO_PRN_CNT 12
  169. struct XXGSA_Info_T {
  170. char Mode; //定位模式,A=自动手动2D/3D,M=手动2D/3D
  171. uint16_t Type; //定位类型,1=未定位,2=2D定位,3=3D定位
  172. int PRNList[GSA_INFO_PRN_CNT]; //PRN码-伪随机噪声码,第x信道正在使用的卫星PRN码编号
  173. float PDOP; //accuracy PDOP综合位置精度因子,0.5-99.9
  174. float HDOP; //HDOP水平精度因子0.5-99.9
  175. float VDOP; //VDOP垂直精度因子0.5-99.9
  176. //char CheckSum[4];
  177. std::bitset<32> BitFlags;
  178. };
  179. //(GSV)可见卫星信息 可见卫星信息 GPS Satellites in View
  180. struct XXGSV_Info_T {
  181. uint8_t Ext_constellation; //UNKNOWN==0/GPS==1/SBAS==2/GLONASS==3/QZSS==4/BEIDOU==5/GALILEO==6
  182. size_t ItemCount; //GSV语句的总数
  183. int ItemSequence; //本句GSV的编号
  184. int SatellitesCount; //可见卫星的总数,00~12,前面的0也将被传输
  185. int PRNCode; //PRN码-伪随机噪声码,前面的0也将被传输;GPS:1-32,Beidou:1-37,GLONASS:1-24,Galileo:1-36,...
  186. float SatelliteElevation;//卫星仰角,00~90度,前面的0也将被传输
  187. float SatelliteAzimuth; //卫星方位角,000~359度,前面的0也将被传输
  188. float SignalNoiseRatio; //信噪比,00~99dB,没有跟踪到卫星时为空,前面的0也将被传输
  189. int PRNCode2; //按照每颗卫星进行循环显示,每条GSV语句最多可以显示4颗卫星的信息
  190. float SatelliteElevation2;
  191. float SatelliteAzimuth2;
  192. float SignalNoiseRatio2;
  193. int PRNCode3;
  194. float SatelliteElevation3;
  195. float SatelliteAzimuth3;
  196. float SignalNoiseRatio3;
  197. int PRNCode4;
  198. float SatelliteElevation4;
  199. float SatelliteAzimuth4;
  200. float SignalNoiseRatio4;
  201. //char CheckSum[4];
  202. std::bitset<32> BitFlags;
  203. };
  204. // (RMC)推荐定位信息 Recommended Minimum Specific GPS/TRANSIT Data
  205. //$GPRMC,200808.000,A,3114.4591,N,12118.0993,E,0.82,282.15,191220,,,A*61
  206. struct XXRMC_Info_T {
  207. double UTCTime; //UTC时间,hhmmss.sss格式,格林尼治时间;
  208. char FixStatus; //状态,A=定位,V=未定位;当给GPS复位时为V,不输出速度,角度,时间数据;
  209. double Latitude; //纬度ddmm.mmmm,度分格式
  210. char LatitudeHemi; //纬度N或S
  211. double Longitude; //经度dddmm.mmmm,度分格式
  212. char LongitudeHemi; //经度E或W
  213. float SpeedKnots; //速度,节,Knots
  214. float Azimuth; //方位角,度 Azimuth/bearing
  215. int UTCDate; //UTC日期,DDMMYY格式
  216. float MagneticDeclination; //磁偏角,000-180度
  217. char MagneticDeclinationDirection;//磁偏角方向,E或W
  218. char PositioningMode; //模式指示,仅NMEA0183 v3.00输出,A=自主定位,D=差分,E=估算,N=数据无效
  219. //char CheckSum[4];
  220. std::bitset<16> BitFlags;
  221. };
  222. //(VTG)地面速度信息 Track Made Good and Ground Speed
  223. struct XXVTG_Info_T {
  224. float MovementAngleTN; //以真北为参考基准的地面航向,000~359度,前面的0也将被传输
  225. char TrueNorthRef; //T
  226. float MovementAngleMN; //以磁北为参考基准的地面航向,000~359度,前面的0也将被传输
  227. char MagneticNorthRef; //M
  228. float HorizontalMoveSpeedKn; //地面速率,000.0~999.9节,前面的0也将被传输
  229. char SpeedKnots; //N
  230. float HorizontalMoveSpeedKm; //地面速率,0000.0~1851.8Km/h,前面的0也将被传输
  231. char SpeedKmh; //K
  232. char PositioningMode; //模式指示,仅NMEA0183 v3.00输出,A=自主定位,D=差分,E=估算,N=数据无效
  233. //char CheckSum[4];
  234. std::bitset<16> BitFlags;
  235. };
  236. template <class T>
  237. T stringToNumber(const std::string &sstr)
  238. {
  239. T number {};
  240. std::istringstream iss {};
  241. iss.str(sstr);
  242. iss >> number; /* can auto remove leading 0 */
  243. return number;
  244. }
  245. template <class T>
  246. std::string toString(T &value)
  247. {
  248. std::ostringstream oss {};
  249. oss << value;
  250. return oss.str();
  251. }
  252. template <int BS_MAX_SIZE>
  253. void bitsFlagSet(std::bitset<BS_MAX_SIZE> &bs, size_t pos)
  254. {
  255. bs.set(pos);
  256. }
  257. template <int BS_MAX_SIZE>
  258. void bitsFlagReset(std::bitset<BS_MAX_SIZE> &bs, size_t pos)
  259. {
  260. bs.reset(pos);
  261. }
  262. template <int BS_MAX_SIZE>
  263. void bitsFlagClear(std::bitset<BS_MAX_SIZE> &bs)
  264. {
  265. bs.reset();
  266. }
  267. template <int BS_MAX_SIZE>
  268. bool bitsFlagTest(std::bitset<BS_MAX_SIZE> bs, size_t pos)
  269. {
  270. return bs.test(pos);
  271. }
  272. template <int BS_MAX_SIZE>
  273. std::string bitsFlagToString(std::bitset<BS_MAX_SIZE> &bs)
  274. {
  275. return bs.to_string();
  276. }
  277. class GnssNmeaParser
  278. {
  279. public:
  280. GnssNmeaParser();
  281. ~GnssNmeaParser();
  282. int parse(const std::string &nmea);
  283. int getNmeaLines(std::vector<std::string> &lines);
  284. bool getGnssLocation(GnssLocation &gnssLocation);
  285. bool getGnssSvStatus(GnssSvStatus &gnssSvStatus);
  286. GnssUtcTime getUtcTime();
  287. private:
  288. int procGGA(XXGGA_Info_T &gga);
  289. int procGLL(XXGLL_Info_T &gll);
  290. int procGSA(std::vector<XXGSA_Info_T> &gsaVect);
  291. int procGSV(std::vector<XXGSV_Info_T> &gsvVect);
  292. int procRMC(XXRMC_Info_T &rmc);
  293. int procVTG(XXVTG_Info_T &vtg);
  294. /* convert latitude(ddmm.mmmm) and longitude(dddmm.mmmm) to degrees */
  295. double latLongToDegree(const double dddmm_mmmm);
  296. int gnssSvFlagUsedInFix(const int svid);
  297. void updateUtcTime(const int ddmmyy, const double hhmmss_sss);
  298. void updateLatLong(const double latitude, const char latHemi, const double longtitude, const char longHemi);
  299. void updateAltitude(const double altitude);
  300. void updateBearing(const float bearing);
  301. void updateMagDec(const float magDec, const char magDecDir);
  302. void updateAccuracy(const float pdop, const float hdop, const float vdop);
  303. void updateSpeed(const float speed);
  304. void updateGnssSvStatus(const std::vector<XXGSV_Info_T> &gsvVectInfoT);
  305. void removeChecksum(std::string &str);
  306. uint8_t getNConstellation(const std::string &nmeaHead);
  307. bool startsWith(const std::string &src, const std::string &str);
  308. bool endsWith(const std::string &src, const std::string &str);
  309. std::string replace(const std::string &raw, const std::string &oldstr, const std::string &newstr);
  310. size_t split(const std::string &line, const std::string &delim, std::vector<std::string> &vstr);
  311. void reset();
  312. std::vector<std::string> m_nmeaLines;
  313. std::string m_nmeaLineSep = GNSS_NMEA_LINE_SEP;
  314. std::string m_nmeaElementSep = GNSS_NMEA_ELEMENT_SEP;
  315. std::vector<std::string> m_nmeaGGAvect;
  316. std::vector<std::string> m_nmeaGLLvect;
  317. std::vector<std::vector<std::string>> m_nmeaGSAvec2d;
  318. std::vector<std::vector<std::string>> m_nmeaGSVvec2d;
  319. std::vector<std::string> m_nmeaRMCvect;
  320. std::vector<std::string> m_nmeaVTGvect;
  321. XXGGA_Info_T m_ggaInfoT;
  322. XXGLL_Info_T m_gllInfoT;
  323. std::vector<XXGSA_Info_T> m_gsaVectInfoT;
  324. std::vector<XXGSV_Info_T> m_gsvVectInfoT;
  325. XXRMC_Info_T m_rmcInfoT;
  326. XXVTG_Info_T m_vtgInfoT;
  327. GnssUtcTime m_gnssUtcTime;
  328. GnssLocation m_gnssLocation;
  329. GnssSvStatus m_gnssSvStatus;
  330. //GnssStatusValue m_gnssStatus;
  331. };
  332. #endif // HAL_GNSS_V1_0_GNSSNMEAPARSER_H
  1. #include <log/log.h>
  2. #include "GnssNmeaParser.h"
  3. #ifdef LOG_TAG
  4. #undef LOG_TAG
  5. #endif
  6. #define LOG_TAG "GnssNmeaParserV1.1"
  7. GnssNmeaParser::GnssNmeaParser()
  8. {
  9. m_nmeaLineSep = GNSS_NMEA_LINE_SEP;
  10. m_nmeaElementSep = GNSS_NMEA_ELEMENT_SEP;
  11. ALOGI("GnssNmeaParser created. %s", GNSS_NMEA_PARSER_VERSION);
  12. reset();
  13. }
  14. GnssNmeaParser::~GnssNmeaParser()
  15. {
  16. reset();
  17. }
  18. int GnssNmeaParser::parse(const std::string &nmea)
  19. {
  20. reset();
  21. int gpCount = 0;
  22. if (0 == nmea.size()) {
  23. return 0;
  24. }
  25. (void)split(nmea, m_nmeaLineSep, m_nmeaLines);
  26. std::vector<std::string>::iterator vsit;
  27. std::vector<std::string> nmeaGSAvect;
  28. std::vector<std::string> nmeaGSVvect;
  29. std::string line;
  30. for (vsit = m_nmeaLines.begin(); vsit != m_nmeaLines.end(); vsit++) {
  31. line = *vsit;
  32. if (line.size() <= 6) {
  33. //$GPxxx
  34. continue;
  35. }
  36. removeChecksum(line);
  37. gpCount += 1;
  38. if (startsWith(line, "$GPGGA")) { //GGA
  39. (void)split(line, m_nmeaElementSep, m_nmeaGGAvect);
  40. } else if (startsWith(line, "$GLGGA")) {
  41. (void)split(line, m_nmeaElementSep, m_nmeaGGAvect);
  42. } else if (startsWith(line, "$BDGGA")) {
  43. (void)split(line, m_nmeaElementSep, m_nmeaGGAvect);
  44. } else if (startsWith(line, "$GNGGA")) {
  45. (void)split(line, m_nmeaElementSep, m_nmeaGGAvect);
  46. }
  47. else if (startsWith(line, "$GPGLL")) { //GLL
  48. (void)split(line, m_nmeaElementSep, m_nmeaGLLvect);
  49. } else if (startsWith(line, "$GLGLL")) {
  50. (void)split(line, m_nmeaElementSep, m_nmeaGLLvect);
  51. } else if (startsWith(line, "$BDGLL")) {
  52. (void)split(line, m_nmeaElementSep, m_nmeaGLLvect);
  53. } else if (startsWith(line, "$GNGLL")) {
  54. (void)split(line, m_nmeaElementSep, m_nmeaGLLvect);
  55. }
  56. else if (startsWith(line, "$GPGSA")) { //GSA
  57. // may contain multi-line
  58. (void)split(line, m_nmeaElementSep, nmeaGSAvect);
  59. m_nmeaGSAvec2d.push_back(nmeaGSAvect);
  60. } else if (startsWith(line, "$GLGSA")) {
  61. (void)split(line, m_nmeaElementSep, nmeaGSAvect);
  62. m_nmeaGSAvec2d.push_back(nmeaGSAvect);
  63. } else if (startsWith(line, "$BDGSA")) {
  64. (void)split(line, m_nmeaElementSep, nmeaGSAvect);
  65. m_nmeaGSAvec2d.push_back(nmeaGSAvect);
  66. } else if (startsWith(line, "$GNGSA")) {
  67. (void)split(line, m_nmeaElementSep, nmeaGSAvect);
  68. m_nmeaGSAvec2d.push_back(nmeaGSAvect);
  69. }
  70. else if (startsWith(line, "$GPGSV")) { //GSV
  71. // may contain multi-line
  72. (void)split(line, m_nmeaElementSep, nmeaGSVvect);
  73. m_nmeaGSVvec2d.push_back(nmeaGSVvect);
  74. } else if (startsWith(line, "$GLGSV")) {
  75. (void)split(line, m_nmeaElementSep, nmeaGSVvect);
  76. m_nmeaGSVvec2d.push_back(nmeaGSVvect);
  77. } else if (startsWith(line, "$BDGSV")) {
  78. (void)split(line, m_nmeaElementSep, nmeaGSVvect);
  79. m_nmeaGSVvec2d.push_back(nmeaGSVvect);
  80. }
  81. else if (startsWith(line, "$GPRMC")) { //RMC
  82. (void)split(line, m_nmeaElementSep, m_nmeaRMCvect);
  83. } else if (startsWith(line, "$GLRMC")) {
  84. (void)split(line, m_nmeaElementSep, m_nmeaRMCvect);
  85. } else if (startsWith(line, "$BDRMC")) {
  86. (void)split(line, m_nmeaElementSep, m_nmeaRMCvect);
  87. } else if (startsWith(line, "$GNRMC")) {
  88. (void)split(line, m_nmeaElementSep, m_nmeaRMCvect);
  89. }
  90. else if (startsWith(line, "$GPVTG")) { //VTG
  91. (void)split(line, m_nmeaElementSep, m_nmeaVTGvect);
  92. } else if (startsWith(line, "$GLVTG")) {
  93. (void)split(line, m_nmeaElementSep, m_nmeaVTGvect);
  94. } else if (startsWith(line, "$BDVTG")) {
  95. (void)split(line, m_nmeaElementSep, m_nmeaVTGvect);
  96. } else if (startsWith(line, "$GNVTG")) {
  97. (void)split(line, m_nmeaElementSep, m_nmeaVTGvect);
  98. }
  99. else {
  100. ALOGD("unkown line:%s", line.c_str());
  101. }
  102. }
  103. (void)procGGA(m_ggaInfoT);
  104. (void)procGLL(m_gllInfoT);
  105. (void)procGSA(m_gsaVectInfoT);
  106. (void)procGSV(m_gsvVectInfoT);
  107. (void)procRMC(m_rmcInfoT);
  108. (void)procVTG(m_vtgInfoT);
  109. return gpCount;
  110. }
  111. int GnssNmeaParser::getNmeaLines(std::vector<std::string> &lines)
  112. {
  113. std::vector<std::string>::iterator vsit;
  114. for (vsit = m_nmeaLines.begin(); vsit != m_nmeaLines.end(); vsit++) {
  115. lines.push_back(*vsit+m_nmeaLineSep);
  116. }
  117. return lines.size();
  118. }
  119. int GnssNmeaParser::procGGA(XXGGA_Info_T &gga)
  120. {
  121. size_t vecSize = m_nmeaGGAvect.size();
  122. if (vecSize != eGGA_CheckSum) {
  123. ALOGD("%s invalid vector size:%zu, expected(%d)",
  124. __func__, vecSize, eGGA_CheckSum);
  125. return 0;
  126. }
  127. bitsFlagClear<16>(gga.BitFlags);
  128. for (int i = 1; i < (int)vecSize; i++)
  129. {
  130. if (m_nmeaGGAvect[i].length() != 0)
  131. {
  132. bitsFlagSet<16>(gga.BitFlags, i);
  133. }
  134. }
  135. gga.UTCTime = stringToNumber<double>(m_nmeaGGAvect[eGGA_UTCTime]);
  136. gga.Latitude = stringToNumber<double>(m_nmeaGGAvect[eGGA_Latitude]);
  137. gga.LatitudeHemi = stringToNumber<char>(m_nmeaGGAvect[eGGA_LatitudeHemi]);
  138. gga.Longitude = stringToNumber<double>(m_nmeaGGAvect[eGGA_Longitude]);
  139. gga.LongitudeHemi = stringToNumber<char>(m_nmeaGGAvect[eGGA_LongitudeHemi]);
  140. gga.StatusIndicator = stringToNumber<uint16_t>(m_nmeaGGAvect[eGGA_StatusIndicator]);
  141. gga.SatellitesCount = stringToNumber<size_t>(m_nmeaGGAvect[eGGA_SatellitesCount]);
  142. gga.HDOP = stringToNumber<float>(m_nmeaGGAvect[eGGA_HDOP]);
  143. gga.Altitude = stringToNumber<double>(m_nmeaGGAvect[eGGA_Altitude]);
  144. gga.AltitudeUnit = stringToNumber<char>(m_nmeaGGAvect[eGGA_AltitudeUnit]);
  145. gga.GeoidHeight = stringToNumber<float>(m_nmeaGGAvect[eGGA_GeoidHeight]);
  146. gga.GeoidHeightUnit = stringToNumber<char>(m_nmeaGGAvect[eGGA_GeoidHeightUnit]);
  147. gga.DiffTemporal = stringToNumber<long>(m_nmeaGGAvect[eGGA_DiffTemporal]);
  148. gga.DiffStationId = stringToNumber<int>(m_nmeaGGAvect[eGGA_DiffStationId]);
  149. if (gga.StatusIndicator != 0) {
  150. updateLatLong(gga.Latitude, gga.LatitudeHemi, gga.Longitude, gga.LongitudeHemi);
  151. updateAltitude(gga.Altitude);
  152. updateAccuracy(0.0f, gga.HDOP, 0.0f);
  153. }
  154. return m_nmeaGGAvect.size();
  155. }
  156. int GnssNmeaParser::procGLL(XXGLL_Info_T &gll)
  157. {
  158. size_t vecSize = m_nmeaGLLvect.size();
  159. if ((vecSize != eGLL_CheckSum)
  160. && (vecSize != eGLL_CheckSum-1)) {
  161. //PositioningMode is optional, only NMEA0183 v3.00 can provide PositioningMode
  162. ALOGD("%s invalid vector size:%zu, expected(%d/%d)",
  163. __func__, vecSize, eGLL_CheckSum, eGLL_CheckSum-1);
  164. return 0;
  165. }
  166. bitsFlagClear<16>(gll.BitFlags);
  167. for (int i = 1; i < (int)vecSize; i++)
  168. {
  169. if (m_nmeaGLLvect[i].length() != 0)
  170. {
  171. bitsFlagSet<16>(gll.BitFlags, i);
  172. }
  173. }
  174. gll.Latitude = stringToNumber<double>(m_nmeaGLLvect[eGLL_Latitude]);
  175. gll.LatitudeHemi = stringToNumber<char>(m_nmeaGLLvect[eGLL_LatitudeHemi]);
  176. gll.Longitude = stringToNumber<double>(m_nmeaGLLvect[eGLL_Longitude]);
  177. gll.LongitudeHemi = stringToNumber<char>(m_nmeaGLLvect[eGLL_LongitudeHemi]);
  178. gll.UTCTimeInt = stringToNumber<int>(m_nmeaGLLvect[eGLL_UTCTime]);
  179. gll.FixStatus = stringToNumber<char>(m_nmeaGLLvect[eGLL_FixStatus]);
  180. if (vecSize == eGLL_CheckSum) {
  181. gll.PositioningMode = stringToNumber<char>(m_nmeaGLLvect[eGLL_PositioningMode]);//optional
  182. }
  183. if ((gll.FixStatus == 'A') && (gll.PositioningMode != 'N')) {
  184. updateLatLong(gll.Latitude, gll.LatitudeHemi, gll.Longitude, gll.LongitudeHemi);
  185. }
  186. return m_nmeaGLLvect.size();
  187. }
  188. int GnssNmeaParser::procGSA(std::vector<XXGSA_Info_T> &gsaVect)
  189. {
  190. if (m_nmeaGSAvec2d.size() == 0) {
  191. ALOGD("%s invalid vector size:%zu", __func__, m_nmeaGSAvec2d.size());
  192. return 0;
  193. }
  194. std::vector<std::vector<std::string>>::iterator vvsit;
  195. std::vector<std::string> nmeaGSAvect {};
  196. XXGSA_Info_T gsa {};
  197. int prnSn = 0;
  198. size_t vecSize = 0;
  199. std::string nmeaHeader;
  200. for (vvsit = m_nmeaGSAvec2d.begin(); vvsit != m_nmeaGSAvec2d.end(); vvsit++) {
  201. nmeaGSAvect = *vvsit;
  202. (void)memset((void *)&gsa, 0, sizeof(gsa));
  203. bitsFlagClear<32>(gsa.BitFlags);
  204. vecSize = nmeaGSAvect.size();
  205. if (vecSize != eGSA_CheckSum) {
  206. ALOGI("%s invalid vector size:%zu, expected(%d)",
  207. __func__, vecSize, eGSA_CheckSum);
  208. continue;
  209. }
  210. for (int i = 1; i < (int)vecSize; i++)
  211. {
  212. if (nmeaGSAvect[i].length() != 0)
  213. {
  214. bitsFlagSet<32>(gsa.BitFlags, i);
  215. }
  216. }
  217. nmeaHeader = (nmeaGSAvect[eGSA_Header]);
  218. gsa.Mode = stringToNumber<char>(nmeaGSAvect[eGSA_Mode]);
  219. gsa.Type = stringToNumber<uint16_t>(nmeaGSAvect[eGSA_Type]);
  220. for (prnSn = 0; prnSn < GSA_INFO_PRN_CNT; prnSn++) {
  221. gsa.PRNList[prnSn] = stringToNumber<int>(nmeaGSAvect[eGSA_PRN1+prnSn]);;
  222. }
  223. gsa.PDOP = stringToNumber<int>(nmeaGSAvect[eGSA_PDOP]);
  224. gsa.HDOP = stringToNumber<int>(nmeaGSAvect[eGSA_HDOP]);
  225. gsa.VDOP = stringToNumber<int>(nmeaGSAvect[eGSA_VDOP]);
  226. gsaVect.push_back(gsa);
  227. if ((gsa.Type <= 1)) {
  228. ALOGD("%s Positioning Mode is %hu(1-untargeted,2-2D,3-3D)", __func__, gsa.Type);
  229. } else {
  230. updateAccuracy(gsa.PDOP, gsa.HDOP, gsa.VDOP);
  231. }
  232. }
  233. return m_nmeaGSAvec2d.size();
  234. }
  235. int GnssNmeaParser::procGSV(std::vector<XXGSV_Info_T> &gsvVect)
  236. {
  237. if (m_nmeaGSVvec2d.size() == 0) {
  238. ALOGD("%s invalid vector size:%zu", __func__, m_nmeaGSVvec2d.size());
  239. return 0;
  240. }
  241. std::vector<std::vector<std::string>>::iterator vvsit;
  242. std::vector<std::string> nmeaGSVvect {};
  243. XXGSV_Info_T gsv {};
  244. std::string nmeaHeader;
  245. size_t vecSize = 0;
  246. for (vvsit = m_nmeaGSVvec2d.begin(); vvsit != m_nmeaGSVvec2d.end(); vvsit++) {
  247. nmeaGSVvect = *vvsit;
  248. (void)memset((void *)&gsv, 0, sizeof(gsv));
  249. bitsFlagClear<32>(gsv.BitFlags);
  250. vecSize = nmeaGSVvect.size();
  251. if ((0 != (vecSize % 4)) || (vecSize < eGSV_PRNCode)) {
  252. ALOGI("%s invalid vector size:%zu, expected(8/12/16/20)", __func__, vecSize);
  253. continue;
  254. }
  255. for (int i = 1; i < (int)vecSize; i++)
  256. {
  257. if (nmeaGSVvect[i].length() != 0)
  258. {
  259. bitsFlagSet<32>(gsv.BitFlags, i);
  260. }
  261. }
  262. nmeaHeader = nmeaGSVvect[eGSV_Header];
  263. gsv.Ext_constellation = getNConstellation(nmeaHeader);
  264. gsv.ItemCount = stringToNumber<size_t>(nmeaGSVvect[eGSV_ItemCount]);
  265. gsv.ItemSequence = stringToNumber<int>(nmeaGSVvect[eGSV_ItemSequence]);
  266. gsv.SatellitesCount = stringToNumber<int>(nmeaGSVvect[eGSV_SatellitesCount]);
  267. /* gsv slices count maybe 8/12/16/20 */
  268. if (vecSize >= eGSV_PRNCode2) {
  269. gsv.PRNCode = stringToNumber<int>(nmeaGSVvect[eGSV_PRNCode]);
  270. gsv.SatelliteElevation = stringToNumber<float>(nmeaGSVvect[eGSV_SatelliteElevation]);
  271. gsv.SatelliteAzimuth = stringToNumber<float>(nmeaGSVvect[eGSV_SatelliteAzimuth]);
  272. gsv.SignalNoiseRatio = stringToNumber<float>(nmeaGSVvect[eGSV_SignalNoiseRatio]);
  273. }
  274. if (vecSize >= eGSV_PRNCode3) {
  275. gsv.PRNCode2 = stringToNumber<int>(nmeaGSVvect[eGSV_PRNCode2]);
  276. gsv.SatelliteElevation2 = stringToNumber<float>(nmeaGSVvect[eGSV_SatelliteElevation2]);
  277. gsv.SatelliteAzimuth2 = stringToNumber<float>(nmeaGSVvect[eGSV_SatelliteAzimuth2]);
  278. gsv.SignalNoiseRatio2 = stringToNumber<float>(nmeaGSVvect[eGSV_SignalNoiseRatio2]);
  279. }
  280. if (vecSize >= eGSV_PRNCode4) {
  281. gsv.PRNCode3 = stringToNumber<int>(nmeaGSVvect[eGSV_PRNCode3]);
  282. gsv.SatelliteElevation3 = stringToNumber<float>(nmeaGSVvect[eGSV_SatelliteElevation3]);
  283. gsv.SatelliteAzimuth3 = stringToNumber<float>(nmeaGSVvect[eGSV_SatelliteAzimuth3]);
  284. gsv.SignalNoiseRatio3 = stringToNumber<float>(nmeaGSVvect[eGSV_SignalNoiseRatio3]);
  285. }
  286. if (vecSize == eGSV_CheckSum) {
  287. gsv.PRNCode4 = stringToNumber<int>(nmeaGSVvect[eGSV_PRNCode4]);
  288. gsv.SatelliteElevation4 = stringToNumber<float>(nmeaGSVvect[eGSV_SatelliteElevation4]);
  289. gsv.SatelliteAzimuth4 = stringToNumber<float>(nmeaGSVvect[eGSV_SatelliteAzimuth4]);
  290. gsv.SignalNoiseRatio4 = stringToNumber<float>(nmeaGSVvect[eGSV_SignalNoiseRatio4]);
  291. }
  292. gsvVect.push_back(gsv);
  293. }
  294. updateGnssSvStatus(gsvVect);
  295. return m_nmeaGSVvec2d.size();
  296. }
  297. int GnssNmeaParser::procRMC(XXRMC_Info_T &rmc)
  298. {
  299. size_t vecSize = m_nmeaRMCvect.size();
  300. if ((vecSize != eRMC_CheckSum)
  301. && (vecSize != eRMC_CheckSum-1)) {
  302. //PositioningMode is optional, only NMEA0183 v3.00 can provide PositioningMode
  303. ALOGD("%s invalid vector size:%zu, expected(%d/%d)",
  304. __func__, vecSize, eRMC_CheckSum, eRMC_CheckSum-1);
  305. return 0;
  306. }
  307. bitsFlagClear<16>(rmc.BitFlags);
  308. for (int i = 1; i < (int)vecSize; i++)
  309. {
  310. if (m_nmeaRMCvect[i].length() != 0)
  311. {
  312. bitsFlagSet<16>(rmc.BitFlags, i);
  313. }
  314. }
  315. rmc.UTCTime = stringToNumber<double>(m_nmeaRMCvect[eRMC_UTCTime]);
  316. rmc.FixStatus = stringToNumber<char>(m_nmeaRMCvect[eRMC_FixStatus]);
  317. rmc.Latitude = stringToNumber<double>(m_nmeaRMCvect[eRMC_Latitude]);
  318. rmc.LatitudeHemi = stringToNumber<char>(m_nmeaRMCvect[eRMC_LatitudeHemi]);
  319. rmc.Longitude = stringToNumber<double>(m_nmeaRMCvect[eRMC_Longitude]);
  320. rmc.LongitudeHemi = stringToNumber<char>(m_nmeaRMCvect[eRMC_LongitudeHemi]);
  321. rmc.SpeedKnots = stringToNumber<float>(m_nmeaRMCvect[eRMC_SpeedKnots]);
  322. rmc.Azimuth = stringToNumber<float>(m_nmeaRMCvect[eRMC_Azimuth]);
  323. rmc.UTCDate = stringToNumber<int>(m_nmeaRMCvect[eRMC_UTCDate]);
  324. rmc.MagneticDeclination = stringToNumber<float>(m_nmeaRMCvect[eRMC_MagneticDeclination]);
  325. rmc.MagneticDeclinationDirection = stringToNumber<char>(m_nmeaRMCvect[eRMC_MagneticDeclinationDirection]);
  326. if (vecSize == eRMC_CheckSum) {
  327. rmc.PositioningMode = stringToNumber<char>(m_nmeaRMCvect[eRMC_PositioningMode]);//optional
  328. }
  329. if (rmc.FixStatus == 'A') {
  330. updateUtcTime(rmc.UTCDate, rmc.UTCTime);
  331. updateLatLong(rmc.Latitude, rmc.LatitudeHemi, rmc.Longitude, rmc.LongitudeHemi);
  332. updateBearing(rmc.Azimuth);
  333. updateSpeed((1.852f * rmc.SpeedKnots / 3.6f));
  334. updateMagDec(rmc.MagneticDeclination, rmc.MagneticDeclinationDirection);
  335. } else if (rmc.FixStatus == 'V') {
  336. ALOGW("%s FixStatus is V(A-targeted,V-untargeted)", __func__);
  337. // UTCDate and UTCTime may be empty
  338. //updateUtcTime(rmc.UTCDate, rmc.UTCTime);
  339. updateLatLong(rmc.Latitude, rmc.LatitudeHemi, rmc.Longitude, rmc.LongitudeHemi);
  340. //updateBearing(rmc.Azimuth);
  341. } else {
  342. //invalid data
  343. ALOGD("%s invalid FixStatus(%c)", __func__, rmc.FixStatus);
  344. }
  345. return m_nmeaRMCvect.size();
  346. }
  347. int GnssNmeaParser::procVTG(XXVTG_Info_T &vtg)
  348. {
  349. size_t vecSize = m_nmeaVTGvect.size();
  350. if ((vecSize != eVTG_CheckSum)
  351. && (vecSize != eVTG_CheckSum-1)) {
  352. //PositioningMode is optional, only NMEA0183 v3.00 can provide PositioningMode
  353. ALOGD("%s invalid vector size:%zu, expected(%d/%d)",
  354. __func__, vecSize, eVTG_CheckSum, eVTG_CheckSum-1);
  355. return 0;
  356. }
  357. bitsFlagClear<16>(vtg.BitFlags);
  358. for (int i = 1; i < (int)vecSize; i++)
  359. {
  360. if (m_nmeaVTGvect[i].length() != 0)
  361. {
  362. bitsFlagSet<16>(vtg.BitFlags, i);
  363. }
  364. }
  365. vtg.MovementAngleTN = stringToNumber<float>(m_nmeaVTGvect[eVTG_MovementAngle]);
  366. vtg.TrueNorthRef = stringToNumber<char>(m_nmeaVTGvect[eVTG_TrueNorthRef]);
  367. vtg.MovementAngleMN = stringToNumber<float>(m_nmeaVTGvect[eVTG_MovementAngle2]);
  368. vtg.MagneticNorthRef = stringToNumber<char>(m_nmeaVTGvect[eVTG_MagneticNorthRef]);
  369. vtg.HorizontalMoveSpeedKn = stringToNumber<float>(m_nmeaVTGvect[eVTG_HorizontalMoveSpeed]);
  370. vtg.SpeedKnots = stringToNumber<char>(m_nmeaVTGvect[eVTG_SpeedKnots]);
  371. vtg.HorizontalMoveSpeedKm = stringToNumber<float>(m_nmeaVTGvect[eVTG_HorizontalMoveSpeed2]);
  372. vtg.SpeedKmh = stringToNumber<char>(m_nmeaVTGvect[eVTG_SpeedKmh]);
  373. if (vecSize == eVTG_CheckSum) {
  374. vtg.PositioningMode = stringToNumber<char>(m_nmeaVTGvect[eVTG_PositioningMode]);//optional
  375. }
  376. if ((vtg.PositioningMode == 'A') || (vtg.PositioningMode == 'D')) {
  377. updateSpeed(vtg.HorizontalMoveSpeedKm/3.6f);
  378. }
  379. return m_nmeaVTGvect.size();
  380. }
  381. void GnssNmeaParser::updateUtcTime(const int ddmmyy, const double hhmmss_sss)
  382. {
  383. //get utc diff
  384. time_t time_now = time(NULL);
  385. struct tm tm_local {};
  386. struct tm tm_utc {};
  387. long time_local_sec = 0;
  388. long time_utc_sec = 0;
  389. long utc_diff_sec = 0;
  390. //get fixed time
  391. struct tm tm_gnss {};
  392. time_t time_fixed = 0;
  393. int utc_year = 0;
  394. int utc_month = 0;
  395. int utc_day = 0;
  396. int utc_hour = 0;
  397. int utc_minute = 0;
  398. int utc_seconds = 0;
  399. int hhmmss = (int)hhmmss_sss;
  400. int milliseconds = 0;
  401. gmtime_r(&time_now, &tm_utc);
  402. localtime_r(&time_now, &tm_local);
  403. time_local_sec = tm_local.tm_sec +
  404. 60*(tm_local.tm_min +
  405. 60*(tm_local.tm_hour +
  406. 24*(tm_local.tm_yday +
  407. 365*tm_local.tm_year)));
  408. time_utc_sec = tm_utc.tm_sec +
  409. 60*(tm_utc.tm_min +
  410. 60*(tm_utc.tm_hour +
  411. 24*(tm_utc.tm_yday +
  412. 365*tm_utc.tm_year)));
  413. utc_diff_sec = time_local_sec - time_utc_sec;
  414. utc_day = (ddmmyy / 100) / 100;
  415. utc_month = (ddmmyy / 100) % 100;
  416. utc_year = (ddmmyy % 100) + 2000;
  417. utc_hour = ((hhmmss / 100) / 100);
  418. utc_minute = ((hhmmss / 100) % 100);
  419. utc_seconds = (hhmmss % 100);
  420. //milliseconds = (int)((hhmmss_sss - hhmmss) * 1000); //will less precise
  421. milliseconds = (int)((hhmmss_sss * 1000) - (hhmmss * 1000)); //Improve accuracy
  422. tm_gnss.tm_hour = utc_hour;
  423. tm_gnss.tm_min = utc_minute;
  424. tm_gnss.tm_sec = utc_seconds;
  425. tm_gnss.tm_year = utc_year - 1900;
  426. tm_gnss.tm_mon = utc_month - 1;
  427. tm_gnss.tm_mday = utc_day;
  428. tm_gnss.tm_isdst = -1;
  429. time_fixed = mktime(&tm_gnss) + utc_diff_sec;
  430. m_gnssUtcTime = (long long)time_fixed * 1000 + milliseconds;
  431. m_gnssLocation.timestamp = m_gnssUtcTime;
  432. if ((0 == ddmmyy) || (0 == hhmmss)) {
  433. ALOGW("%s invalid UTCDate=%d, UTCTime=%d", __func__, ddmmyy, hhmmss);
  434. //use local stored utc time
  435. time_fixed = mktime(&tm_utc) + utc_diff_sec;
  436. m_gnssUtcTime = (long long)time_fixed * 1000;
  437. m_gnssLocation.timestamp = m_gnssUtcTime;
  438. }
  439. }
  440. void GnssNmeaParser::updateLatLong(const double latitude, const char latHemi, const double longtitude, const char longHemi)
  441. {
  442. double lat = latitude;
  443. double lon = longtitude;
  444. if (latHemi == 'S') {
  445. lat = -lat;
  446. }
  447. if (longHemi == 'W') {
  448. lon = -lon;
  449. }
  450. m_gnssLocation.gnssLocationFlags |= GnssLocationFlags::HAS_LAT_LONG;
  451. m_gnssLocation.latitudeDegrees = latLongToDegree(lat);
  452. m_gnssLocation.longitudeDegrees = latLongToDegree(lon);
  453. }
  454. void GnssNmeaParser::updateAltitude(const double altitude)
  455. {
  456. double alt = altitude;
  457. m_gnssLocation.gnssLocationFlags |= GnssLocationFlags::HAS_ALTITUDE;
  458. m_gnssLocation.altitudeMeters = alt;
  459. }
  460. void GnssNmeaParser::updateBearing(const float bearing)
  461. {
  462. float bea = bearing;
  463. m_gnssLocation.gnssLocationFlags |= GnssLocationFlags::HAS_BEARING;
  464. m_gnssLocation.bearingDegrees = bea;
  465. }
  466. void GnssNmeaParser::updateMagDec(const float magDec, const char magDecDir)
  467. {
  468. (void)magDec;
  469. (void)magDecDir;
  470. }
  471. void GnssNmeaParser::updateAccuracy(const float pdop, const float hdop, const float vdop)
  472. {
  473. /* GSA HDOP */
  474. (void)pdop;
  475. (void)vdop;
  476. if ((0.1f <= hdop)) {
  477. m_gnssLocation.gnssLocationFlags |= GnssLocationFlags::HAS_HORIZONTAL_ACCURACY;
  478. m_gnssLocation.horizontalAccuracyMeters = hdop;
  479. }
  480. if ((0.1f <= vdop)) {
  481. m_gnssLocation.gnssLocationFlags |= GnssLocationFlags::HAS_VERTICAL_ACCURACY;
  482. m_gnssLocation.verticalAccuracyMeters = vdop;
  483. }
  484. }
  485. void GnssNmeaParser::updateSpeed(const float speed)
  486. {
  487. float velocity = speed;
  488. m_gnssLocation.gnssLocationFlags |= GnssLocationFlags::HAS_SPEED;
  489. m_gnssLocation.speedMetersPerSec = velocity;
  490. }
  491. void GnssNmeaParser::updateGnssSvStatus(const std::vector<XXGSV_Info_T> &gsvVectInfoT)
  492. {
  493. std::vector<XXGSV_Info_T>::const_iterator vit;
  494. int itemsCount = 0;
  495. int itemSequence = 0;
  496. int sateSeq = 0;
  497. m_gnssSvStatus.numSvs = 0;
  498. for (vit = gsvVectInfoT.begin(); vit != gsvVectInfoT.end(); vit++) {
  499. itemsCount = vit->ItemCount;
  500. itemSequence = vit->ItemSequence;
  501. if ((sateSeq+3) > ((int)GnssMax::SVS_COUNT)-1) {
  502. /* preventing arrays from out of bounds */
  503. ALOGW("gnssSvStatus num more than SVS_COUNT:%d", GnssMax::SVS_COUNT);
  504. break;
  505. }
  506. m_gnssSvStatus.gnssSvList[sateSeq].svid = vit->PRNCode;
  507. m_gnssSvStatus.gnssSvList[sateSeq].elevationDegrees = vit->SatelliteElevation;
  508. m_gnssSvStatus.gnssSvList[sateSeq].azimuthDegrees = vit->SatelliteAzimuth;
  509. m_gnssSvStatus.gnssSvList[sateSeq].cN0Dbhz = vit->SignalNoiseRatio;
  510. m_gnssSvStatus.gnssSvList[sateSeq].svFlag = 0;
  511. if (bitsFlagTest<32>((*vit).BitFlags, eGSV_SignalNoiseRatio)) {
  512. //m_gnssSvStatus.gnssSvList[sateSeq].svFlag |= GnssSvFlags:HAS_CARRIER_FREQUENCY;
  513. }
  514. m_gnssSvStatus.gnssSvList[sateSeq].constellation = (GnssConstellationType)vit->Ext_constellation;
  515. if (vit->PRNCode > 0) {
  516. /* check and set flag whether available satellite */
  517. m_gnssSvStatus.gnssSvList[sateSeq].svFlag |= gnssSvFlagUsedInFix(vit->PRNCode);
  518. /* increase visible satellites count */
  519. sateSeq += 1;
  520. }
  521. m_gnssSvStatus.gnssSvList[sateSeq].svid = vit->PRNCode2;
  522. m_gnssSvStatus.gnssSvList[sateSeq].elevationDegrees = vit->SatelliteElevation2;
  523. m_gnssSvStatus.gnssSvList[sateSeq].azimuthDegrees = vit->SatelliteAzimuth2;
  524. m_gnssSvStatus.gnssSvList[sateSeq].cN0Dbhz = vit->SignalNoiseRatio2;
  525. m_gnssSvStatus.gnssSvList[sateSeq].svFlag = 0;
  526. if ( bitsFlagTest<32>(vit->BitFlags, eGSV_SignalNoiseRatio2) ) {
  527. //m_gnssSvStatus.gnssSvList[sateSeq].svFlag |= GnssSvFlags:HAS_CARRIER_FREQUENCY;
  528. }
  529. m_gnssSvStatus.gnssSvList[sateSeq].constellation = (GnssConstellationType)vit->Ext_constellation;
  530. if (vit->PRNCode2 > 0) {
  531. m_gnssSvStatus.gnssSvList[sateSeq].svFlag |= gnssSvFlagUsedInFix(vit->PRNCode2);
  532. sateSeq += 1;
  533. }
  534. m_gnssSvStatus.gnssSvList[sateSeq].svid = vit->PRNCode3;
  535. m_gnssSvStatus.gnssSvList[sateSeq].elevationDegrees = vit->SatelliteElevation3;
  536. m_gnssSvStatus.gnssSvList[sateSeq].azimuthDegrees = vit->SatelliteAzimuth3;
  537. m_gnssSvStatus.gnssSvList[sateSeq].cN0Dbhz = vit->SignalNoiseRatio3;
  538. m_gnssSvStatus.gnssSvList[sateSeq].svFlag = 0;
  539. if (bitsFlagTest<32>(vit->BitFlags, eGSV_SignalNoiseRatio3)) {
  540. //m_gnssSvStatus.gnssSvList[sateSeq].svFlag |= GnssSvFlags:HAS_CARRIER_FREQUENCY;
  541. }
  542. m_gnssSvStatus.gnssSvList[sateSeq].constellation = (GnssConstellationType)vit->Ext_constellation;
  543. if (vit->PRNCode3 > 0) {
  544. m_gnssSvStatus.gnssSvList[sateSeq].svFlag |= gnssSvFlagUsedInFix(vit->PRNCode3);
  545. sateSeq += 1;
  546. }
  547. m_gnssSvStatus.gnssSvList[sateSeq].svid = vit->PRNCode4;
  548. m_gnssSvStatus.gnssSvList[sateSeq].elevationDegrees = vit->SatelliteElevation4;
  549. m_gnssSvStatus.gnssSvList[sateSeq].azimuthDegrees = vit->SatelliteAzimuth4;
  550. m_gnssSvStatus.gnssSvList[sateSeq].cN0Dbhz = vit->SignalNoiseRatio4;
  551. m_gnssSvStatus.gnssSvList[sateSeq].svFlag = 0;
  552. if (bitsFlagTest<32>(vit->BitFlags, eGSV_SignalNoiseRatio4)) {
  553. //m_gnssSvStatus.gnssSvList[sateSeq].svFlag |= GnssSvFlags:HAS_CARRIER_FREQUENCY;
  554. }
  555. m_gnssSvStatus.gnssSvList[sateSeq].constellation = (GnssConstellationType)vit->Ext_constellation;
  556. if (vit->PRNCode4 > 0) {
  557. m_gnssSvStatus.gnssSvList[sateSeq].svFlag |= gnssSvFlagUsedInFix(vit->PRNCode4);
  558. sateSeq += 1;
  559. }
  560. }
  561. m_gnssSvStatus.numSvs = sateSeq;
  562. }
  563. double GnssNmeaParser::latLongToDegree(const double dddmm_mmmm)
  564. {
  565. // eg.: 12031.0902 -> 120.51817(120+(31.0902/60.0=0.51817))
  566. int ddd = (int)(dddmm_mmmm/100);
  567. double mm_mmmm = dddmm_mmmm - (ddd*100.0);
  568. double ddd_xxx = ddd + (mm_mmmm / 60.0);
  569. return ddd_xxx;
  570. }
  571. int GnssNmeaParser::gnssSvFlagUsedInFix(const int svid) {
  572. int fixed = 0;
  573. int prnSn = 0;
  574. std::vector<XXGSA_Info_T>::iterator gsaIt;
  575. for (gsaIt = m_gsaVectInfoT.begin(); gsaIt != m_gsaVectInfoT.end(); gsaIt++) {
  576. for (prnSn = 0; prnSn < GSA_INFO_PRN_CNT; prnSn++) {
  577. if (svid == gsaIt->PRNList[prnSn]) {
  578. fixed = (int)GnssSvFlags::USED_IN_FIX;
  579. break;
  580. }
  581. }
  582. }
  583. return fixed;
  584. }
  585. bool GnssNmeaParser::getGnssLocation(GnssLocation &gnssLocation)
  586. {
  587. (void)memcpy(&gnssLocation, &m_gnssLocation, sizeof(m_gnssLocation));
  588. return true;
  589. }
  590. bool GnssNmeaParser::getGnssSvStatus(GnssSvStatus &gnssSvStatus)
  591. {
  592. #if 1
  593. int numSv = m_gnssSvStatus.numSvs;
  594. ALOGD("getGnssSvStatus numSvs:%d", m_gnssSvStatus.numSvs);
  595. for(int tmp = 0; tmp < numSv; tmp++)
  596. {
  597. ALOGD("getGnssSvStatus (svid=%d,elevation=%f,azimuth=%f,dbhz=%f,CX=%d,svFlag=0x%x)",
  598. m_gnssSvStatus.gnssSvList[tmp].svid,
  599. m_gnssSvStatus.gnssSvList[tmp].elevationDegrees,
  600. m_gnssSvStatus.gnssSvList[tmp].azimuthDegrees,
  601. m_gnssSvStatus.gnssSvList[tmp].cN0Dbhz,
  602. (int)m_gnssSvStatus.gnssSvList[tmp].constellation,
  603. (int)m_gnssSvStatus.gnssSvList[tmp].svFlag);
  604. }
  605. #endif
  606. (void)memcpy(&gnssSvStatus, &m_gnssSvStatus, sizeof(gnssSvStatus));
  607. return true;
  608. }
  609. GnssUtcTime GnssNmeaParser::getUtcTime()
  610. {
  611. return m_gnssUtcTime;
  612. }
  613. void GnssNmeaParser::reset()
  614. {
  615. m_nmeaLines.clear();
  616. m_nmeaGGAvect.clear();
  617. m_nmeaGLLvect.clear();
  618. m_nmeaGSAvec2d.clear();
  619. m_nmeaGSVvec2d.clear();
  620. m_nmeaRMCvect.clear();
  621. m_nmeaVTGvect.clear();
  622. m_gnssUtcTime = 0;
  623. (void)memset(&m_ggaInfoT, 0, sizeof(m_ggaInfoT));
  624. (void)memset(&m_gllInfoT, 0, sizeof(m_gllInfoT));
  625. m_gsaVectInfoT.clear();
  626. m_gsvVectInfoT.clear();
  627. (void)memset(&m_rmcInfoT, 0, sizeof(m_rmcInfoT));
  628. (void)memset(&m_vtgInfoT, 0, sizeof(m_vtgInfoT));
  629. (void)memset(&m_gnssLocation, 0, sizeof(m_gnssLocation));
  630. (void)memset(&m_gnssSvStatus, 0, sizeof(m_gnssSvStatus));
  631. }
  632. void GnssNmeaParser::removeChecksum(std::string &str)
  633. {
  634. // get rid of checksum at the end of the sentecne
  635. // remove chars after *
  636. size_t phit = 0;
  637. phit = str.find("*");
  638. if (std::string::npos != phit)
  639. {
  640. str.erase(phit);
  641. }
  642. }
  643. uint8_t GnssNmeaParser::getNConstellation(const std::string &nmeaHead)
  644. {
  645. uint8_t constellation = (uint8_t)GnssConstellationType::UNKNOWN;
  646. if (startsWith(nmeaHead, "$GP")) {
  647. constellation = (uint8_t)GnssConstellationType::GPS;
  648. } else if (startsWith(nmeaHead, "$GL")) {
  649. constellation = (uint8_t)GnssConstellationType::GLONASS;
  650. } else if (startsWith(nmeaHead, "$BD")) {
  651. constellation = (uint8_t)GnssConstellationType::BEIDOU;
  652. } else {
  653. constellation = (uint8_t)GnssConstellationType::UNKNOWN;
  654. }
  655. return constellation;
  656. }
  657. bool GnssNmeaParser::startsWith(const std::string &src, const std::string &str)
  658. {
  659. int srcpos = 0;
  660. int srclen = src.length();
  661. int sublen = str.length();
  662. if (srclen < sublen) {
  663. return false;
  664. }
  665. return (0 == src.compare(srcpos, sublen, str));
  666. }
  667. bool GnssNmeaParser::endsWith(const std::string &src, const std::string &str)
  668. {
  669. int srcpos = 0;
  670. int srclen = src.length();
  671. int sublen = str.length();
  672. if (srclen < sublen) {
  673. return false;
  674. }
  675. srcpos = srclen - sublen;
  676. return (0 == src.compare(srcpos, sublen, str));
  677. }
  678. std::string GnssNmeaParser::replace(const std::string &raw, const std::string &oldstr, const std::string &newstr) {
  679. std::string res_string = raw;
  680. size_t startpos = 0;
  681. size_t retpos = 0;
  682. while (std::string::npos != (retpos = res_string.find(oldstr, startpos)))
  683. {
  684. if (oldstr.size() == newstr.size()) {
  685. (void)res_string.replace(retpos, oldstr.size(), newstr);
  686. } else {
  687. (void)res_string.erase(retpos, oldstr.size());
  688. (void)res_string.insert(retpos, newstr);
  689. }
  690. startpos = retpos + oldstr.size();
  691. }
  692. return res_string;
  693. }
  694. size_t GnssNmeaParser::split(const std::string &line, const std::string &delim, std::vector<std::string> &vstr)
  695. {
  696. size_t pstart = 0;
  697. size_t phit = 0;
  698. std::string sstr;
  699. size_t length = line.length();
  700. vstr.clear();
  701. for (;pstart <= length;)
  702. {
  703. phit = line.find(delim, pstart);
  704. if (std::string::npos != phit)
  705. {
  706. /* find delim, get substr */
  707. sstr = line.substr(pstart, phit-pstart);
  708. vstr.push_back(sstr);
  709. pstart = phit + delim.size();
  710. } else {
  711. /* not find delim, append remaining str and break */
  712. vstr.push_back(line.substr(pstart));
  713. break;
  714. }
  715. }
  716. return vstr.size();
  717. }

 

posted @ 2023-07-20 18:13  SymPny  阅读(543)  评论(0编辑  收藏  举报