luat_lib_libgnss.c 17 KB

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