luat_lib_libgnss.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  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. @usage
  9. -- 方案1, 经lua层进行数据中转
  10. uart.setup(2, 115200)
  11. uart.on(2, "recv", function(id, len)
  12. while 1 do
  13. local data = uart.read(id, 1024)
  14. if data and #data > 1 then
  15. libgnss.parse(data)
  16. else
  17. break
  18. end
  19. end
  20. end)
  21. -- 方案2, 适合2022.12.26之后编译固件,效率更高一些
  22. uart.setup(2, 115200)
  23. libgnss.bind(2)
  24. -- 可选调试模式
  25. -- libgnss.debug(true)
  26. */
  27. #include "luat_base.h"
  28. #include "luat_msgbus.h"
  29. #include "luat_malloc.h"
  30. #include "luat_uart.h"
  31. #include "luat_mcu.h"
  32. #include "luat_rtc.h"
  33. #define LUAT_LOG_TAG "gnss"
  34. #include "luat_log.h"
  35. #include "minmea.h"
  36. extern luat_libgnss_t *libgnss_gnss;
  37. extern luat_libgnss_t *libgnss_gnsstmp;
  38. extern char* libgnss_recvbuff;
  39. void luat_uart_set_app_recv(int id, luat_uart_recv_callback_t cb);
  40. /**
  41. 处理nmea数据
  42. @api libgnss.parse(str)
  43. @string 原始nmea数据
  44. @usage
  45. -- 解析nmea
  46. libgnss.parse(indata)
  47. log.info("nmea", json.encode(libgnss.getRmc()))
  48. */
  49. static int l_libgnss_parse(lua_State *L) {
  50. size_t len = 0;
  51. const char* str = luaL_checklstring(L, 1, &len);
  52. if (len > 0) {
  53. luat_libgnss_parse_data(str, len);
  54. }
  55. return 0;
  56. }
  57. /**
  58. 当前是否已经定位成功
  59. @api libgnss.isFix()
  60. @return boolean 定位成功与否
  61. @usage
  62. -- 解析nmea
  63. libgnss.parse(indata)
  64. log.info("nmea", "isFix", libgnss.isFix())
  65. */
  66. static int l_libgnss_is_fix(lua_State *L) {
  67. if (libgnss_gnss == NULL) {
  68. lua_pushboolean(L, 0);
  69. }
  70. else
  71. lua_pushboolean(L, libgnss_gnss->frame_rmc.valid != 0 ? 1 : 0);
  72. return 1;
  73. }
  74. /**
  75. 获取位置信息
  76. @api libgnss.getIntLocation()
  77. @return int lat数据, 格式为 ddmmmmmmm
  78. @return int lng数据, 格式为 ddmmmmmmm
  79. @return int speed数据
  80. @usage
  81. -- 解析nmea
  82. libgnss.parse(indata)
  83. log.info("nmea", "loc", libgnss.getIntLocation())
  84. */
  85. static int l_libgnss_get_int_location(lua_State *L) {
  86. if (libgnss_gnss != NULL && libgnss_gnss->frame_rmc.valid) {
  87. lua_pushinteger(L, libgnss_gnss->frame_rmc.latitude.value);
  88. lua_pushinteger(L, libgnss_gnss->frame_rmc.longitude.value);
  89. lua_pushinteger(L, libgnss_gnss->frame_rmc.speed.value);
  90. } else {
  91. lua_pushinteger(L, 0);
  92. lua_pushinteger(L, 0);
  93. lua_pushinteger(L, 0);
  94. }
  95. return 3;
  96. }
  97. /**
  98. 获取原始RMC位置信息
  99. @api libgnss.getRmc()
  100. @return table 原始rmc数据
  101. @usage
  102. -- 解析nmea
  103. libgnss.parse(indata)
  104. log.info("nmea", "rmc", json.encode(libgnss.getRmc()))
  105. */
  106. static int l_libgnss_get_rmc(lua_State *L) {
  107. lua_createtable(L, 0, 12);
  108. if (libgnss_gnss != NULL) {
  109. lua_pushliteral(L, "valid");
  110. lua_pushboolean(L, libgnss_gnss->frame_rmc.valid);
  111. lua_settable(L, -3);
  112. lua_pushliteral(L, "lat");
  113. if (libgnss_gnss->frame_rmc.valid)
  114. lua_pushnumber(L, minmea_tofloat(&(libgnss_gnss->frame_rmc.latitude)));
  115. else
  116. lua_pushinteger(L, 0);
  117. lua_settable(L, -3);
  118. lua_pushliteral(L, "lng");
  119. if (libgnss_gnss->frame_rmc.valid)
  120. lua_pushnumber(L, minmea_tofloat(&(libgnss_gnss->frame_rmc.longitude)));
  121. else
  122. lua_pushinteger(L, 0);
  123. lua_settable(L, -3);
  124. lua_pushliteral(L, "speed");
  125. lua_pushinteger(L, libgnss_gnss->frame_rmc.speed.value);
  126. lua_settable(L, -3);
  127. lua_pushliteral(L, "course");
  128. lua_pushinteger(L, libgnss_gnss->frame_rmc.course.value);
  129. lua_settable(L, -3);
  130. lua_pushliteral(L, "variation");
  131. lua_pushinteger(L, libgnss_gnss->frame_rmc.variation.value);
  132. lua_settable(L, -3);
  133. lua_pushliteral(L, "year");
  134. lua_pushinteger(L, libgnss_gnss->frame_rmc.date.year + 2000);
  135. lua_settable(L, -3);
  136. lua_pushliteral(L, "month");
  137. lua_pushinteger(L, libgnss_gnss->frame_rmc.date.month);
  138. lua_settable(L, -3);
  139. lua_pushliteral(L, "day");
  140. lua_pushinteger(L, libgnss_gnss->frame_rmc.date.day);
  141. lua_settable(L, -3);
  142. lua_pushliteral(L, "hour");
  143. lua_pushinteger(L, libgnss_gnss->frame_rmc.time.hours);
  144. lua_settable(L, -3);
  145. lua_pushliteral(L, "min");
  146. lua_pushinteger(L, libgnss_gnss->frame_rmc.time.minutes);
  147. lua_settable(L, -3);
  148. lua_pushliteral(L, "sec");
  149. lua_pushinteger(L, libgnss_gnss->frame_rmc.time.seconds);
  150. lua_settable(L, -3);
  151. }
  152. return 1;
  153. }
  154. /**
  155. 获取原始GSV信息
  156. @api libgnss.getGsv()
  157. @return table 原始GSV数据
  158. @usage
  159. -- 解析nmea
  160. libgnss.parse(indata)
  161. log.info("nmea", "gsv", json.encode(libgnss.getGsv()))
  162. */
  163. static int l_libgnss_get_gsv(lua_State *L) {
  164. lua_createtable(L, 0, 2);
  165. if (libgnss_gnss != NULL) {
  166. int count = 1;
  167. lua_pushliteral(L, "total_sats");
  168. lua_pushinteger(L, libgnss_gnss->frame_gsv[0].total_sats);
  169. lua_settable(L, -3);
  170. lua_pushliteral(L, "sats");
  171. lua_createtable(L, 12, 0);
  172. for (size_t i = 0; i < 3; i++)
  173. {
  174. for (size_t j = 0; j < 4; j++)
  175. {
  176. //LLOGD("nr %d snr %d", gnss->frame_gsv[i].sats[j].nr, gnss->frame_gsv[i].sats[j].snr);
  177. if (libgnss_gnss->frame_gsv[i].sats[j].nr) {
  178. lua_pushinteger(L, count++);
  179. lua_createtable(L, 0, 4);
  180. lua_pushliteral(L, "nr");
  181. lua_pushinteger(L, libgnss_gnss->frame_gsv[i].sats[j].nr);
  182. lua_settable(L, -3);
  183. lua_pushliteral(L, "snr");
  184. lua_pushinteger(L, libgnss_gnss->frame_gsv[i].sats[j].snr);
  185. lua_settable(L, -3);
  186. lua_pushliteral(L, "elevation");
  187. lua_pushinteger(L, libgnss_gnss->frame_gsv[i].sats[j].elevation);
  188. lua_settable(L, -3);
  189. lua_pushliteral(L, "azimuth");
  190. lua_pushinteger(L, libgnss_gnss->frame_gsv[i].sats[j].azimuth);
  191. lua_settable(L, -3);
  192. lua_settable(L, -3);
  193. }
  194. }
  195. }
  196. lua_settable(L, -3);
  197. }
  198. return 1;
  199. }
  200. /**
  201. 获取原始GSA信息
  202. @api libgnss.getGsa()
  203. @return table 原始GSA数据
  204. @usage
  205. -- 解析nmea
  206. libgnss.parse(indata)
  207. log.info("nmea", "gsa", json.encode(libgnss.getGsa()))
  208. */
  209. static int l_libgnss_get_gsa(lua_State *L) {
  210. lua_createtable(L, 0, 10);
  211. //lua_pushliteral(L, "mode");
  212. //lua_pushlstring(L, gnss ? &(gnss->frame_gsa.mode) : "N", 1);
  213. //lua_settable(L, -3);
  214. lua_pushliteral(L, "fix_type");
  215. lua_pushinteger(L, libgnss_gnss ? libgnss_gnss->frame_gsa.fix_type : 0);
  216. lua_settable(L, -3);
  217. lua_pushliteral(L, "pdop");
  218. lua_pushinteger(L, libgnss_gnss ? libgnss_gnss->frame_gsa.pdop.value : 0);
  219. lua_settable(L, -3);
  220. lua_pushliteral(L, "hdop");
  221. lua_pushinteger(L, libgnss_gnss ? libgnss_gnss->frame_gsa.hdop.value : 0);
  222. lua_settable(L, -3);
  223. lua_pushliteral(L, "vdop");
  224. lua_pushinteger(L, libgnss_gnss ? libgnss_gnss->frame_gsa.vdop.value : 0);
  225. lua_settable(L, -3);
  226. lua_pushliteral(L, "sats");
  227. lua_createtable(L, 12, 0);
  228. if (libgnss_gnss != NULL) {
  229. for (size_t i = 0; i < 12; i++) {
  230. if (libgnss_gnss->frame_gsa.sats[i] == 0) break;
  231. lua_pushinteger(L, i + 1);
  232. lua_pushinteger(L, libgnss_gnss->frame_gsa.sats[i]);
  233. lua_settable(L, -3);
  234. }
  235. }
  236. lua_settable(L, -3);
  237. return 1;
  238. }
  239. /**
  240. 获取原始VTA位置信息
  241. @api libgnss.getVtg()
  242. @return table 原始VTA数据
  243. @usage
  244. -- 解析nmea
  245. libgnss.parse(indata)
  246. log.info("nmea", "vtg", json.encode(libgnss.getVtg()))
  247. */
  248. static int l_libgnss_get_vtg(lua_State *L) {
  249. lua_createtable(L, 0, 10);
  250. //lua_pushliteral(L, "faa_mode");
  251. //lua_pushlstring(L, gnss ? &(gnss->frame_vtg.faa_mode) : 'N', 1);
  252. //lua_settable(L, -3);
  253. lua_pushliteral(L, "true_track_degrees");
  254. lua_pushinteger(L, libgnss_gnss ? libgnss_gnss->frame_vtg.true_track_degrees.value : 0);
  255. lua_settable(L, -3);
  256. lua_pushliteral(L, "magnetic_track_degrees");
  257. lua_pushinteger(L, libgnss_gnss ? libgnss_gnss->frame_vtg.magnetic_track_degrees.value : 0);
  258. lua_settable(L, -3);
  259. lua_pushliteral(L, "speed_knots");
  260. lua_pushinteger(L, libgnss_gnss ? libgnss_gnss->frame_vtg.speed_knots.value : 0);
  261. lua_settable(L, -3);
  262. lua_pushliteral(L, "speed_kph");
  263. lua_pushinteger(L, libgnss_gnss ? libgnss_gnss->frame_vtg.speed_kph.value : 0);
  264. lua_settable(L, -3);
  265. return 1;
  266. }
  267. /**
  268. 获取原始ZDA时间和日期信息
  269. @api libgnss.getZda()
  270. @return table 原始zda数据
  271. @usage
  272. -- 解析nmea
  273. libgnss.parse(indata)
  274. log.info("nmea", "zda", json.encode(libgnss.getZda()))
  275. */
  276. static int l_libgnss_get_zda(lua_State *L) {
  277. lua_createtable(L, 0, 9);
  278. if (libgnss_gnss != NULL) {
  279. lua_pushliteral(L, "hour_offset");
  280. lua_pushinteger(L, libgnss_gnss->frame_zda.hour_offset);
  281. lua_settable(L, -3);
  282. lua_pushliteral(L, "minute_offset");
  283. lua_pushinteger(L, libgnss_gnss->frame_zda.minute_offset);
  284. lua_settable(L, -3);
  285. lua_pushliteral(L, "year");
  286. lua_pushinteger(L, libgnss_gnss->frame_zda.date.year + 2000);
  287. lua_settable(L, -3);
  288. lua_pushliteral(L, "month");
  289. lua_pushinteger(L, libgnss_gnss->frame_zda.date.month);
  290. lua_settable(L, -3);
  291. lua_pushliteral(L, "day");
  292. lua_pushinteger(L, libgnss_gnss->frame_zda.date.day);
  293. lua_settable(L, -3);
  294. lua_pushliteral(L, "hour");
  295. lua_pushinteger(L, libgnss_gnss->frame_zda.time.hours);
  296. lua_settable(L, -3);
  297. lua_pushliteral(L, "min");
  298. lua_pushinteger(L, libgnss_gnss->frame_zda.time.minutes);
  299. lua_settable(L, -3);
  300. lua_pushliteral(L, "sec");
  301. lua_pushinteger(L, libgnss_gnss->frame_zda.time.seconds);
  302. lua_settable(L, -3);
  303. lua_pushliteral(L, "mic");
  304. lua_pushinteger(L, libgnss_gnss->frame_zda.time.microseconds);
  305. lua_settable(L, -3);
  306. }
  307. return 1;
  308. }
  309. /**
  310. 设置调试模式
  311. @api libgnss.debug(mode)
  312. @bool true开启调试,false关闭调试,默认为false
  313. @usage
  314. -- 开启调试
  315. libgnss.debug(true)
  316. -- 关闭调试
  317. libgnss.debug(false)
  318. */
  319. static int l_libgnss_debug(lua_State *L) {
  320. if (libgnss_gnss == NULL && luat_libgnss_init()) {
  321. return 0;
  322. }
  323. if (lua_isboolean(L, 1) && lua_toboolean(L, 1)) {
  324. LLOGD("Debug ON");
  325. libgnss_gnss->debug = 1;
  326. }
  327. else
  328. {
  329. LLOGD("Debug OFF");
  330. libgnss_gnss->debug = 0;
  331. }
  332. return 0;
  333. }
  334. /*
  335. 获取GGA数据
  336. @api libgnss.getGga()
  337. @return table GGA数据, 若如不存在会返回nil
  338. local gga = libgnss.getGga()
  339. if gga then
  340. log.info("GGA", json.encode(gga))
  341. end
  342. */
  343. static int l_libgnss_get_gga(lua_State* L) {
  344. if (libgnss_gnss == NULL)
  345. return 0;
  346. lua_newtable(L);
  347. lua_pushstring(L, "altitude");
  348. lua_pushinteger(L, libgnss_gnss->frame_gga.altitude.value);
  349. lua_settable(L, -3);
  350. lua_pushstring(L, "latitude");
  351. lua_pushinteger(L, libgnss_gnss->frame_gga.latitude.value);
  352. lua_settable(L, -3);
  353. lua_pushstring(L, "longitude");
  354. lua_pushinteger(L, libgnss_gnss->frame_gga.longitude.value);
  355. lua_settable(L, -3);
  356. lua_pushstring(L, "fix_quality");
  357. lua_pushinteger(L, libgnss_gnss->frame_gga.fix_quality);
  358. lua_settable(L, -3);
  359. lua_pushstring(L, "satellites_tracked");
  360. lua_pushinteger(L, libgnss_gnss->frame_gga.satellites_tracked);
  361. lua_settable(L, -3);
  362. lua_pushstring(L, "hdop");
  363. lua_pushinteger(L, libgnss_gnss->frame_gga.hdop.value);
  364. lua_settable(L, -3);
  365. lua_pushstring(L, "height");
  366. lua_pushinteger(L, libgnss_gnss->frame_gga.height.value);
  367. lua_settable(L, -3);
  368. lua_pushstring(L, "dgps_age");
  369. lua_pushinteger(L, libgnss_gnss->frame_gga.dgps_age.value);
  370. lua_settable(L, -3);
  371. return 1;
  372. }
  373. /*
  374. 获取GLL数据
  375. @api libgnss.getGll()
  376. @return table GLL数据, 若如不存在会返回nil
  377. local gll = libgnss.getGll()
  378. if gll then
  379. log.info("GLL", json.encode(gll))
  380. end
  381. */
  382. static int l_libgnss_get_gll(lua_State* L) {
  383. if (libgnss_gnss == NULL)
  384. return 0;
  385. lua_newtable(L);
  386. lua_pushstring(L, "latitude");
  387. lua_pushinteger(L, libgnss_gnss->frame_gll.latitude.value);
  388. lua_settable(L, -3);
  389. lua_pushstring(L, "longitude");
  390. lua_pushinteger(L, libgnss_gnss->frame_gll.longitude.value);
  391. lua_settable(L, -3);
  392. lua_pushstring(L, "mode");
  393. lua_pushinteger(L, libgnss_gnss->frame_gll.mode);
  394. lua_settable(L, -3);
  395. lua_pushstring(L, "status");
  396. lua_pushinteger(L, libgnss_gnss->frame_gll.status);
  397. lua_settable(L, -3);
  398. lua_pushstring(L, "hour");
  399. lua_pushinteger(L, libgnss_gnss->frame_gll.time.hours);
  400. lua_settable(L, -3);
  401. lua_pushstring(L, "us");
  402. lua_pushinteger(L, libgnss_gnss->frame_gll.time.microseconds);
  403. lua_settable(L, -3);
  404. lua_pushstring(L, "min");
  405. lua_pushinteger(L, libgnss_gnss->frame_gll.time.minutes);
  406. lua_settable(L, -3);
  407. lua_pushstring(L, "sec");
  408. lua_pushinteger(L, libgnss_gnss->frame_gll.time.seconds);
  409. lua_settable(L, -3);
  410. return 1;
  411. }
  412. /**
  413. 清除历史定位数据
  414. @api libgnss.clear()
  415. @return nil 无返回值
  416. */
  417. static int l_libgnss_clear(lua_State*L) {
  418. (void)L;
  419. if (libgnss_gnss == NULL && !luat_libgnss_init())
  420. return 0;
  421. memset(libgnss_gnss, 0, sizeof(luat_libgnss_t));
  422. return 0;
  423. }
  424. /*
  425. 绑定uart端口进行GNSS数据读取
  426. @api libgnss.bind(id)
  427. @int uart端口号
  428. @usage
  429. -- 配置串口信息, 通常为 115200 8N1
  430. uart.setup(2, 115200)
  431. -- 绑定uart, 马上开始解析GNSS数据
  432. libgnss.bind(2)
  433. -- 无需再调用uart.on然后调用libgnss.parse
  434. -- 开发期可打开调试日志
  435. libgnss.debug(true)
  436. */
  437. static int l_libgnss_bind(lua_State* L) {
  438. int uart_id = luaL_checkinteger(L, 1);
  439. l_libgnss_clear(L);
  440. if (libgnss_recvbuff == NULL) {
  441. libgnss_recvbuff = luat_heap_malloc(2048);
  442. }
  443. if (luat_uart_exist(uart_id)) {
  444. //uart_app_recvs[uart_id] = nmea_uart_recv_cb;
  445. luat_uart_set_app_recv(uart_id, luat_libgnss_uart_recv_cb);
  446. }
  447. return 0;
  448. }
  449. #include "rotable2.h"
  450. static const rotable_Reg_t reg_libgnss[] =
  451. {
  452. { "parse", ROREG_FUNC(l_libgnss_parse)},
  453. { "isFix", ROREG_FUNC(l_libgnss_is_fix)},
  454. { "getIntLocation", ROREG_FUNC(l_libgnss_get_int_location)},
  455. { "getRmc", ROREG_FUNC(l_libgnss_get_rmc)},
  456. { "getGsv", ROREG_FUNC(l_libgnss_get_gsv)},
  457. { "getGsa", ROREG_FUNC(l_libgnss_get_gsa)},
  458. { "getVtg", ROREG_FUNC(l_libgnss_get_vtg)},
  459. { "getGga", ROREG_FUNC(l_libgnss_get_gga)},
  460. { "getGll", ROREG_FUNC(l_libgnss_get_gll)},
  461. { "getZda", ROREG_FUNC(l_libgnss_get_zda)},
  462. { "debug", ROREG_FUNC(l_libgnss_debug)},
  463. { "clear", ROREG_FUNC(l_libgnss_clear)},
  464. { "bind", ROREG_FUNC(l_libgnss_bind)},
  465. { NULL, ROREG_INT(0)}
  466. };
  467. LUAMOD_API int luaopen_libgnss( lua_State *L ) {
  468. luat_newlib2(L, reg_libgnss);
  469. return 1;
  470. }