luat_lib_libgnss.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  1. /*
  2. @module libgnss
  3. @summary NMEA数据处理
  4. @version 1.0
  5. @date 2020.07.03
  6. @demo libgnss
  7. */
  8. #include "luat_base.h"
  9. #include "luat_msgbus.h"
  10. #include "luat_malloc.h"
  11. #include "luat_uart.h"
  12. #define LUAT_LOG_TAG "luat.gnss"
  13. #include "luat_log.h"
  14. #include "minmea.h"
  15. typedef struct luat_libgnss
  16. {
  17. uint8_t debug;
  18. uint8_t prev_fixed;
  19. // int lua_ref;
  20. struct minmea_sentence_rmc frame_rmc;
  21. struct minmea_sentence_gga frame_gga;
  22. struct minmea_sentence_gll frame_gll;
  23. struct minmea_sentence_gst frame_gst;
  24. struct minmea_sentence_gsv frame_gsv[3];
  25. struct minmea_sentence_vtg frame_vtg;
  26. struct minmea_sentence_gsa frame_gsa;
  27. struct minmea_sentence_zda frame_zda;
  28. } luat_libgnss_t;
  29. static luat_libgnss_t *gnss = NULL;
  30. static luat_libgnss_t *gnsstmp = NULL;
  31. static int luat_libgnss_init(lua_State *L) {
  32. if (gnss == NULL) {
  33. gnss = luat_heap_malloc(sizeof(luat_libgnss_t));
  34. if (gnss == NULL) {
  35. LLOGW("out of memory for libgnss data parse");
  36. return 0;
  37. }
  38. gnsstmp = luat_heap_malloc(sizeof(luat_libgnss_t));
  39. if (gnsstmp == NULL) {
  40. luat_heap_free(gnss);
  41. LLOGW("out of memory for libgnss data parse");
  42. return 0;
  43. }
  44. // gnss->lua_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  45. memset(gnss, 0, sizeof(luat_libgnss_t));
  46. memset(gnsstmp, 0, sizeof(luat_libgnss_t));
  47. }
  48. lua_pushboolean(L, 1);
  49. return 1;
  50. }
  51. static int parse_nmea(const char* line, lua_State *L) {
  52. // $GNRMC,080313.00,A,2324.40756,N,11313.86184,E,0.284,,010720,,,A*68
  53. //if (gnss != NULL && gnss->debug)
  54. // LLOGD("GNSS [%s]", line);
  55. if (gnss == NULL && luat_libgnss_init(L)) {
  56. return 0;
  57. }
  58. switch (minmea_sentence_id(line, false)) {
  59. case MINMEA_SENTENCE_RMC: {
  60. if (minmea_parse_rmc(&(gnsstmp->frame_rmc), line)) {
  61. if (gnsstmp->frame_rmc.valid) {
  62. memcpy(&(gnss->frame_rmc), &gnsstmp->frame_rmc, sizeof(struct minmea_sentence_rmc));
  63. }
  64. else {
  65. gnss->frame_rmc.valid = 0;
  66. if (gnsstmp->frame_rmc.date.year > 0) {
  67. memcpy(&(gnss->frame_rmc.date), &(gnsstmp->frame_rmc.date), sizeof(struct minmea_date));
  68. }
  69. if (gnsstmp->frame_rmc.time.hours > 0) {
  70. memcpy(&(gnss->frame_rmc.time), &(gnsstmp->frame_rmc.time), sizeof(struct minmea_time));
  71. }
  72. }
  73. //memcpy(&(gnss->frame_rmc), &frame_rmc, sizeof(struct minmea_sentence_rmc));
  74. //LLOGD("RMC %s", line);
  75. //LLOGD("RMC isFix(%d) Lat(%ld) Lng(%ld)", gnss->frame_rmc.valid, gnss->frame_rmc.latitude.value, gnss->frame_rmc.longitude.value);
  76. // if (prev_gnss_fixed != gnss->frame_rmc.valid) {
  77. // lua_getglobal(L, "sys_pub");
  78. // if (lua_isfunction(L, -1)) {
  79. // lua_pushliteral(L, "GPS_STATE");
  80. // lua_pushstring(L, gnss->frame_rmc.valid ? "LOCATION_SUCCESS" : "LOCATION_FAIL");
  81. // lua_call(L, 2, 0);
  82. // }
  83. // else {
  84. // lua_pop(L, 1);
  85. // }
  86. // prev_gnss_fixed = gnss->frame_rmc.valid;
  87. // }
  88. }
  89. } break;
  90. case MINMEA_SENTENCE_GGA: {
  91. //struct minmea_sentence_gga frame_gga;
  92. if (minmea_parse_gga(&gnsstmp->frame_gga, line)) {
  93. memcpy(&(gnss->frame_gga), &gnsstmp->frame_gga, sizeof(struct minmea_sentence_gga));
  94. //LLOGD("$GGA: fix quality: %d", frame_gga.fix_quality);
  95. }
  96. } break;
  97. case MINMEA_SENTENCE_GSA: {
  98. if (minmea_parse_gsa(&(gnss->frame_gsa), line)) {
  99. }
  100. } break;
  101. case MINMEA_SENTENCE_GLL: {
  102. if (minmea_parse_gll(&(gnss->frame_gll), line)) {
  103. // memcpy(&(gnss->frame_gll), &frame_gll, sizeof(struct minmea_sentence_gsa));
  104. }
  105. } break;
  106. // case MINMEA_SENTENCE_GST: {
  107. // if (minmea_parse_gst(&gnsstmp->frame_gst, line)) {
  108. // memcpy(&(gnss->frame_gst), &gnsstmp->frame_gst, sizeof(struct minmea_sentence_gst));
  109. // }
  110. // } break;
  111. case MINMEA_SENTENCE_GSV: {
  112. if (minmea_parse_gsv(&gnsstmp->frame_gsv[0], line)) {
  113. switch (gnsstmp->frame_gsv[0].msg_nr)
  114. {
  115. case 1:
  116. memset(&(gnss->frame_gsv), 0, sizeof(struct minmea_sentence_gsv) * 3);
  117. case 2:
  118. case 3:
  119. memcpy(&(gnss->frame_gsv[gnsstmp->frame_gsv[0].msg_nr - 1]), &gnsstmp->frame_gsv, sizeof(struct minmea_sentence_gsv));
  120. break;
  121. default:
  122. break;
  123. }
  124. // LLOGD("$GSV: message %d of %d", frame_gsv.msg_nr, frame_gsv.total_msgs);
  125. // LLOGD("$GSV: sattelites in view: %d", frame_gsv.total_sats);
  126. // for (int i = 0; i < 4; i++)
  127. // LLOGD("$GSV: sat nr %d, elevation: %d, azimuth: %d, snr: %d dbm",
  128. // frame_gsv.sats[i].nr,
  129. // frame_gsv.sats[i].elevation,
  130. // frame_gsv.sats[i].azimuth,
  131. // frame_gsv.sats[i].snr);
  132. }
  133. } break;
  134. case MINMEA_SENTENCE_VTG: {
  135. //struct minmea_sentence_vtg frame_vtg;
  136. if (minmea_parse_vtg(&(gnsstmp->frame_vtg), line)) {
  137. memcpy(&(gnss->frame_vtg), &gnsstmp->frame_vtg, sizeof(struct minmea_sentence_vtg));
  138. //--------------------------------------
  139. // 暂时不发GPS_MSG_REPORT
  140. // lua_getglobal(L, "sys_pub");
  141. // if (lua_isfunction(L, -1)) {
  142. // lua_pushstring(L, "GPS_MSG_REPORT");
  143. // lua_call(L, 1, 0);
  144. // }
  145. // else {
  146. // lua_pop(L, 1);
  147. // }
  148. //--------------------------------------
  149. }
  150. } break;
  151. case MINMEA_SENTENCE_ZDA: {
  152. if (minmea_parse_zda(&(gnsstmp->frame_zda), line)) {
  153. memcpy(&(gnss->frame_zda), &gnsstmp->frame_zda, sizeof(struct minmea_sentence_zda));
  154. }
  155. } break;
  156. default:
  157. break;
  158. }
  159. return 0;
  160. }
  161. /**
  162. 处理nmea数据
  163. @api libgnss.parse(str)
  164. @string 原始nmea数据
  165. @usage
  166. -- 解析nmea
  167. libgnss.parse(indata)
  168. log.info("nmea", json.encode(libgnss.getRmc()))
  169. */
  170. static int l_libgnss_parse(lua_State *L) {
  171. size_t len = 0;
  172. const char* str = luaL_checklstring(L, 1, &len);
  173. if (len == 0) {
  174. return 0;
  175. }
  176. char buff[85] = {0}; // nmea 最大长度82,含换行符
  177. char *ptr = (char*)str;
  178. size_t prev = 0;
  179. for (size_t i = 1; i < len; i++)
  180. {
  181. if (*(ptr + i) == 0x0A) {
  182. if (i - prev > 10 && i - prev < 82) {
  183. memcpy(buff, ptr + prev, i - prev - 1);
  184. if (buff[0] == '$') {
  185. buff[i - prev - 1] = 0; // 确保结束符存在
  186. parse_nmea((const char*)buff, L);
  187. }
  188. }
  189. i ++;
  190. prev = i;
  191. }
  192. }
  193. return 0;
  194. }
  195. /**
  196. 当前是否已经定位成功
  197. @api libgnss.isFix()
  198. @return boolean 定位成功与否
  199. @usage
  200. -- 解析nmea
  201. libgnss.parse(indata)
  202. log.info("nmea", "isFix", libgnss.isFix())
  203. */
  204. static int l_libgnss_is_fix(lua_State *L) {
  205. if (gnss == NULL) {
  206. lua_pushboolean(L, 0);
  207. }
  208. else
  209. lua_pushboolean(L, gnss->frame_rmc.valid != 0 ? 1 : 0);
  210. return 1;
  211. }
  212. /**
  213. 获取位置信息
  214. @api libgnss.getIntLocation()
  215. @return int lat数据, 格式为 ddmmmmmmm
  216. @return int lng数据, 格式为 ddmmmmmmm
  217. @return int speed数据
  218. @usage
  219. -- 解析nmea
  220. libgnss.parse(indata)
  221. log.info("nmea", "loc", libgnss.getIntLocation())
  222. */
  223. static int l_libgnss_get_int_location(lua_State *L) {
  224. if (gnss != NULL && gnss->frame_rmc.valid) {
  225. lua_pushinteger(L, minmea_tofloat(&(gnss->frame_rmc.latitude)));
  226. lua_pushinteger(L, minmea_tofloat(&(gnss->frame_rmc.longitude)));
  227. lua_pushinteger(L, gnss->frame_rmc.speed.value);
  228. } else {
  229. lua_pushinteger(L, 0);
  230. lua_pushinteger(L, 0);
  231. lua_pushinteger(L, 0);
  232. }
  233. return 3;
  234. }
  235. /**
  236. 获取原始RMC位置信息
  237. @api libgnss.getRmc()
  238. @return table 原始rmc数据
  239. @usage
  240. -- 解析nmea
  241. libgnss.parse(indata)
  242. log.info("nmea", "rmc", json.encode(libgnss.getRmc()))
  243. */
  244. static int l_libgnss_get_rmc(lua_State *L) {
  245. lua_createtable(L, 0, 12);
  246. if (gnss != NULL) {
  247. lua_pushliteral(L, "valid");
  248. lua_pushboolean(L, gnss->frame_rmc.valid);
  249. lua_settable(L, -3);
  250. lua_pushliteral(L, "lat");
  251. lua_pushnumber(L, minmea_tofloat(&(gnss->frame_rmc.latitude)));
  252. lua_settable(L, -3);
  253. lua_pushliteral(L, "lng");
  254. lua_pushnumber(L, minmea_tofloat(&(gnss->frame_rmc.longitude)));
  255. lua_settable(L, -3);
  256. lua_pushliteral(L, "speed");
  257. lua_pushinteger(L, gnss->frame_rmc.speed.value);
  258. lua_settable(L, -3);
  259. lua_pushliteral(L, "course");
  260. lua_pushinteger(L, gnss->frame_rmc.course.value);
  261. lua_settable(L, -3);
  262. lua_pushliteral(L, "variation");
  263. lua_pushinteger(L, gnss->frame_rmc.variation.value);
  264. lua_settable(L, -3);
  265. lua_pushliteral(L, "year");
  266. lua_pushinteger(L, gnss->frame_rmc.date.year + 2000);
  267. lua_settable(L, -3);
  268. lua_pushliteral(L, "month");
  269. lua_pushinteger(L, gnss->frame_rmc.date.month);
  270. lua_settable(L, -3);
  271. lua_pushliteral(L, "day");
  272. lua_pushinteger(L, gnss->frame_rmc.date.day);
  273. lua_settable(L, -3);
  274. lua_pushliteral(L, "hour");
  275. lua_pushinteger(L, gnss->frame_rmc.time.hours);
  276. lua_settable(L, -3);
  277. lua_pushliteral(L, "min");
  278. lua_pushinteger(L, gnss->frame_rmc.time.minutes);
  279. lua_settable(L, -3);
  280. lua_pushliteral(L, "sec");
  281. lua_pushinteger(L, gnss->frame_rmc.time.seconds);
  282. lua_settable(L, -3);
  283. }
  284. return 1;
  285. }
  286. /**
  287. 获取原始GSV信息
  288. @api libgnss.getGsv()
  289. @return table 原始GSV数据
  290. @usage
  291. -- 解析nmea
  292. libgnss.parse(indata)
  293. log.info("nmea", "gsv", json.encode(libgnss.getGsv()))
  294. */
  295. static int l_libgnss_get_gsv(lua_State *L) {
  296. lua_createtable(L, 0, 2);
  297. if (gnss != NULL) {
  298. int count = 1;
  299. lua_pushliteral(L, "total_sats");
  300. lua_pushinteger(L, gnss->frame_gsv[0].total_sats);
  301. lua_settable(L, -3);
  302. lua_pushliteral(L, "sats");
  303. lua_createtable(L, 12, 0);
  304. for (size_t i = 0; i < gnss->frame_gsv[0].msg_nr; i++)
  305. {
  306. for (size_t j = 0; j < 4; j++)
  307. {
  308. if (gnss->frame_gsv[i].sats[j].snr) {
  309. lua_pushinteger(L, count++);
  310. lua_createtable(L, 0, 3);
  311. lua_pushliteral(L, "snr");
  312. lua_pushinteger(L, gnss->frame_gsv[i].sats[j].snr);
  313. lua_settable(L, -3);
  314. lua_pushliteral(L, "elevation");
  315. lua_pushinteger(L, gnss->frame_gsv[i].sats[j].elevation);
  316. lua_settable(L, -3);
  317. lua_pushliteral(L, "azimuth");
  318. lua_pushinteger(L, gnss->frame_gsv[i].sats[j].azimuth);
  319. lua_settable(L, -3);
  320. lua_settable(L, -3);
  321. }
  322. }
  323. }
  324. lua_settable(L, -3);
  325. }
  326. return 1;
  327. }
  328. /**
  329. 获取原始GSA信息
  330. @api libgnss.getGsa()
  331. @return table 原始GSA数据
  332. @usage
  333. -- 解析nmea
  334. libgnss.parse(indata)
  335. log.info("nmea", "gsa", json.encode(libgnss.getGsa()))
  336. */
  337. static int l_libgnss_get_gsa(lua_State *L) {
  338. lua_createtable(L, 0, 10);
  339. //lua_pushliteral(L, "mode");
  340. //lua_pushlstring(L, gnss ? &(gnss->frame_gsa.mode) : "N", 1);
  341. //lua_settable(L, -3);
  342. lua_pushliteral(L, "fix_type");
  343. lua_pushinteger(L, gnss ? gnss->frame_gsa.fix_type : 0);
  344. lua_settable(L, -3);
  345. lua_pushliteral(L, "pdop");
  346. lua_pushinteger(L, gnss ? gnss->frame_gsa.pdop.value : 0);
  347. lua_settable(L, -3);
  348. lua_pushliteral(L, "hdop");
  349. lua_pushinteger(L, gnss ? gnss->frame_gsa.hdop.value : 0);
  350. lua_settable(L, -3);
  351. lua_pushliteral(L, "vdop");
  352. lua_pushinteger(L, gnss ? gnss->frame_gsa.vdop.value : 0);
  353. lua_settable(L, -3);
  354. lua_pushliteral(L, "sats");
  355. lua_createtable(L, 12, 0);
  356. if (gnss != NULL) {
  357. for (size_t i = 0; i < 12; i++) {
  358. if (gnss->frame_gsa.sats[i] == 0) break;
  359. lua_pushinteger(L, i + 1);
  360. lua_pushinteger(L, gnss->frame_gsa.sats[i]);
  361. lua_settable(L, -3);
  362. }
  363. }
  364. lua_settable(L, -3);
  365. return 1;
  366. }
  367. /**
  368. 获取原始VTA位置信息
  369. @api libgnss.getVtg()
  370. @return table 原始VTA数据
  371. @usage
  372. -- 解析nmea
  373. libgnss.parse(indata)
  374. log.info("nmea", "vtg", json.encode(libgnss.getVtg()))
  375. */
  376. static int l_libgnss_get_vtg(lua_State *L) {
  377. lua_createtable(L, 0, 10);
  378. //lua_pushliteral(L, "faa_mode");
  379. //lua_pushlstring(L, gnss ? &(gnss->frame_vtg.faa_mode) : 'N', 1);
  380. //lua_settable(L, -3);
  381. lua_pushliteral(L, "true_track_degrees");
  382. lua_pushinteger(L, gnss ? gnss->frame_vtg.true_track_degrees.value : 0);
  383. lua_settable(L, -3);
  384. lua_pushliteral(L, "magnetic_track_degrees");
  385. lua_pushinteger(L, gnss ? gnss->frame_vtg.magnetic_track_degrees.value : 0);
  386. lua_settable(L, -3);
  387. lua_pushliteral(L, "speed_knots");
  388. lua_pushinteger(L, gnss ? gnss->frame_vtg.speed_knots.value : 0);
  389. lua_settable(L, -3);
  390. lua_pushliteral(L, "speed_kph");
  391. lua_pushinteger(L, gnss ? gnss->frame_vtg.speed_kph.value : 0);
  392. lua_settable(L, -3);
  393. return 1;
  394. }
  395. /**
  396. 获取原始ZDA时间和日期信息
  397. @api libgnss.getZda()
  398. @return table 原始zda数据
  399. @usage
  400. -- 解析nmea
  401. libgnss.parse(indata)
  402. log.info("nmea", "zda", json.encode(libgnss.getZda()))
  403. */
  404. static int l_libgnss_get_zda(lua_State *L) {
  405. lua_createtable(L, 0, 9);
  406. if (gnss != NULL) {
  407. lua_pushliteral(L, "hour_offset");
  408. lua_pushinteger(L, gnss->frame_zda.hour_offset);
  409. lua_settable(L, -3);
  410. lua_pushliteral(L, "minute_offset");
  411. lua_pushinteger(L, gnss->frame_zda.minute_offset);
  412. lua_settable(L, -3);
  413. lua_pushliteral(L, "year");
  414. lua_pushinteger(L, gnss->frame_zda.date.year + 2000);
  415. lua_settable(L, -3);
  416. lua_pushliteral(L, "month");
  417. lua_pushinteger(L, gnss->frame_zda.date.month);
  418. lua_settable(L, -3);
  419. lua_pushliteral(L, "day");
  420. lua_pushinteger(L, gnss->frame_zda.date.day);
  421. lua_settable(L, -3);
  422. lua_pushliteral(L, "hour");
  423. lua_pushinteger(L, gnss->frame_zda.time.hours);
  424. lua_settable(L, -3);
  425. lua_pushliteral(L, "min");
  426. lua_pushinteger(L, gnss->frame_zda.time.minutes);
  427. lua_settable(L, -3);
  428. lua_pushliteral(L, "sec");
  429. lua_pushinteger(L, gnss->frame_zda.time.seconds);
  430. lua_settable(L, -3);
  431. lua_pushliteral(L, "mic");
  432. lua_pushinteger(L, gnss->frame_zda.time.microseconds);
  433. lua_settable(L, -3);
  434. }
  435. return 1;
  436. }
  437. static int l_libgnss_debug(lua_State *L) {
  438. if (gnss == NULL && luat_libgnss_init(L)) {
  439. return 0;
  440. }
  441. if (lua_isboolean(L, 1) && lua_toboolean(L, 1)) {
  442. gnss->debug = 1;
  443. }
  444. else
  445. {
  446. gnss->debug = 0;
  447. }
  448. return 0;
  449. }
  450. static int l_libgnss_get_gga(lua_State* L) {
  451. if (gnss == NULL)
  452. return 0;
  453. lua_newtable(L);
  454. lua_pushstring(L, "altitude");
  455. lua_pushinteger(L, gnss->frame_gga.altitude.value);
  456. lua_settable(L, -3);
  457. lua_pushstring(L, "latitude");
  458. lua_pushinteger(L, gnss->frame_gga.latitude.value);
  459. lua_settable(L, -3);
  460. lua_pushstring(L, "longitude");
  461. lua_pushinteger(L, gnss->frame_gga.longitude.value);
  462. lua_settable(L, -3);
  463. lua_pushstring(L, "fix_quality");
  464. lua_pushinteger(L, gnss->frame_gga.fix_quality);
  465. lua_settable(L, -3);
  466. lua_pushstring(L, "satellites_tracked");
  467. lua_pushinteger(L, gnss->frame_gga.satellites_tracked);
  468. lua_settable(L, -3);
  469. lua_pushstring(L, "hdop");
  470. lua_pushinteger(L, gnss->frame_gga.hdop.value);
  471. lua_settable(L, -3);
  472. lua_pushstring(L, "height");
  473. lua_pushinteger(L, gnss->frame_gga.height.value);
  474. lua_settable(L, -3);
  475. lua_pushstring(L, "dgps_age");
  476. lua_pushinteger(L, gnss->frame_gga.dgps_age.value);
  477. lua_settable(L, -3);
  478. return 1;
  479. }
  480. #include "rotable2.h"
  481. static const rotable_Reg_t reg_libgnss[] =
  482. {
  483. { "parse", ROREG_FUNC(l_libgnss_parse)},
  484. { "isFix", ROREG_FUNC(l_libgnss_is_fix)},
  485. { "getIntLocation", ROREG_FUNC(l_libgnss_get_int_location)},
  486. { "getRmc", ROREG_FUNC(l_libgnss_get_rmc)},
  487. { "getGsv", ROREG_FUNC(l_libgnss_get_gsv)},
  488. { "getGsa", ROREG_FUNC(l_libgnss_get_gsa)},
  489. { "getVtg", ROREG_FUNC(l_libgnss_get_vtg)},
  490. { "getGga", ROREG_FUNC(l_libgnss_get_gga)},
  491. { "getZda", ROREG_FUNC(l_libgnss_get_zda)},
  492. { "debug", ROREG_FUNC(l_libgnss_debug)},
  493. { NULL, ROREG_INT(0)}
  494. };
  495. LUAMOD_API int luaopen_libgnss( lua_State *L ) {
  496. luat_newlib2(L, reg_libgnss);
  497. return 1;
  498. }