luat_lib_libgnss.c 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268
  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. -- 提醒: 本库输出的坐标,均为 WGS84 坐标系
  10. -- 如需要在国内地图使用, 要转换成对应地图的坐标系, 例如 GCJ02 BD09
  11. -- 相关链接: https://lbsyun.baidu.com/index.php?title=coordinate
  12. -- 相关链接: https://www.openluat.com/GPS-Offset.html
  13. -- 提醒: GPS功能, GNSS功能, NMEA解析功能,均为当前库的子功能
  14. -- 本库的主要功能就是解析NMEA协议, 支持内置GNSS也支持外置GNSS
  15. -- 以下是使用本libgnss的示例代码
  16. -- 方案1, 经lua层进行数据中转
  17. uart.setup(2, 115200)
  18. uart.on(2, "recv", function(id, len)
  19. while 1 do
  20. local data = uart.read(id, 1024)
  21. if data and #data > 1 then
  22. libgnss.parse(data)
  23. else
  24. break
  25. end
  26. end
  27. end)
  28. -- 方案2, 适合2022.12.26之后编译固件,效率更高一些
  29. uart.setup(2, 115200)
  30. libgnss.bind(2)
  31. -- 可选调试模式
  32. -- libgnss.debug(true)
  33. sys.subscribe("GNSS_STATE", function(event, ticks)
  34. -- event取值有
  35. -- FIXED 定位成功
  36. -- LOSE 定位丢失
  37. -- ticks是事件发生的时间,一般可以忽略
  38. log.info("gnss", "state", event, ticks)
  39. end)
  40. */
  41. #include "luat_base.h"
  42. #include "luat_msgbus.h"
  43. #include "luat_mem.h"
  44. #include "luat_uart.h"
  45. #include "luat_mcu.h"
  46. #include "luat_rtc.h"
  47. #include "luat_zbuff.h"
  48. #define LUAT_LOG_TAG "gnss"
  49. #include "luat_log.h"
  50. #include "minmea.h"
  51. extern luat_libgnss_t gnssctx;
  52. // extern luat_libgnss_t *libgnss_gnsstmp;
  53. extern char* libgnss_recvbuff;
  54. extern int libgnss_route_uart_id;
  55. extern int gnss_debug;
  56. static int gnss_raw_cb = 0;
  57. static int gnss_txt_cb = 0;
  58. // static int gnss_rmc_cb = 0;
  59. static int gnss_other_cb = 0;
  60. static inline void push_gnss_value(lua_State *L, struct minmea_float *f, int mode) {
  61. if (f->value == 0) {
  62. lua_pushinteger(L, 0);
  63. return;
  64. }
  65. switch (mode)
  66. {
  67. case 0:
  68. lua_pushnumber(L, minmea_tofloat(f));
  69. break;
  70. case 1:
  71. lua_pushinteger(L, minmea_tocoord2(f));
  72. break;
  73. case 2:
  74. lua_pushnumber(L, minmea_tocoord(f));
  75. break;
  76. default:
  77. lua_pushnumber(L, minmea_tocoord(f));
  78. break;
  79. }
  80. }
  81. static int luat_libgnss_state_handler(lua_State *L, void* ptr) {
  82. (void)ptr;
  83. rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
  84. lua_getglobal(L, "sys_pub");
  85. if (!lua_isfunction(L, -1)) {
  86. return 0;
  87. }
  88. /*
  89. @sys_pub libgnss
  90. GNSS状态变化
  91. GNSS_STATE
  92. @usage
  93. sys.subscribe("GNSS_STATE", function(event, ticks)
  94. -- event取值有
  95. -- FIXED 定位成功
  96. -- LOSE 定位丢失
  97. -- ticks是事件发生的时间,一般可以忽略
  98. log.info("gnss", "state", event, ticks)
  99. end)
  100. */
  101. lua_pushliteral(L, "GNSS_STATE");
  102. switch (msg->arg1)
  103. {
  104. case GNSS_STATE_FIXED:
  105. lua_pushliteral(L, "FIXED");
  106. break;
  107. case GNSS_STATE_LOSE:
  108. lua_pushliteral(L, "LOSE");
  109. break;
  110. case GNSS_STATE_OPEN:
  111. lua_pushliteral(L, "OPEN");
  112. break;
  113. case GNSS_STATE_CLOSE:
  114. lua_pushliteral(L, "CLOSE");
  115. break;
  116. default:
  117. return 0;
  118. }
  119. lua_pushinteger(L, msg->arg2);
  120. lua_call(L, 3, 0);
  121. return 0;
  122. }
  123. int luat_libgnss_state_onchanged(int state) {
  124. rtos_msg_t msg = {0};
  125. msg.handler = luat_libgnss_state_handler;
  126. msg.arg1 = state;
  127. #ifdef LUAT_USE_MCU
  128. msg.arg2 = luat_mcu_ticks();
  129. #endif
  130. luat_msgbus_put(&msg, 0);
  131. return 0;
  132. }
  133. static void put_datetime(lua_State*L, struct tm* rtime) {
  134. lua_pushliteral(L, "year");
  135. lua_pushinteger(L, rtime->tm_year);
  136. lua_settable(L, -3);
  137. lua_pushliteral(L, "month");
  138. lua_pushinteger(L, rtime->tm_mon + 1); // 比较纠结, 要不要兼容老的呢?
  139. lua_settable(L, -3);
  140. lua_pushliteral(L, "day");
  141. lua_pushinteger(L, rtime->tm_mday);
  142. lua_settable(L, -3);
  143. lua_pushliteral(L, "hour");
  144. lua_pushinteger(L, rtime->tm_hour);
  145. lua_settable(L, -3);
  146. lua_pushliteral(L, "min");
  147. lua_pushinteger(L, rtime->tm_min);
  148. lua_settable(L, -3);
  149. lua_pushliteral(L, "sec");
  150. lua_pushinteger(L, rtime->tm_sec);
  151. lua_settable(L, -3);
  152. }
  153. static int l_gnss_callback(lua_State *L, void* ptr){
  154. (void)ptr;
  155. rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
  156. luat_libgnss_uart_recv_cb(msg->arg1, msg->arg2);
  157. return 0;
  158. }
  159. static void l_libgnss_uart_recv_cb(int uart_id, uint32_t data_len)
  160. {
  161. rtos_msg_t msg = {0};
  162. msg.handler = l_gnss_callback;
  163. msg.arg1 = uart_id;
  164. msg.arg2 = data_len;
  165. luat_msgbus_put(&msg, 0);
  166. }
  167. /**
  168. 处理nmea数据
  169. @api libgnss.parse(str)
  170. @string 原始nmea数据
  171. @usage
  172. -- 解析nmea数据
  173. libgnss.parse(indata)
  174. log.info("nmea", json.encode(libgnss.getRmc(), "11g"))
  175. */
  176. static int l_libgnss_parse(lua_State *L) {
  177. size_t len = 0;
  178. const char* str = NULL;
  179. luat_zbuff_t* zbuff = NULL;
  180. if (lua_type(L, 1) == LUA_TSTRING) {
  181. str = luaL_checklstring(L, 1, &len);
  182. }
  183. else if (lua_isuserdata(L, 1)) {
  184. zbuff = tozbuff(L);
  185. str = (const char*)zbuff->addr;
  186. len = zbuff->used;
  187. }
  188. else {
  189. return 0;
  190. }
  191. if (len > 0) {
  192. luat_libgnss_parse_data(str, len);
  193. }
  194. return 0;
  195. }
  196. /**
  197. 当前是否已经定位成功
  198. @api libgnss.isFix()
  199. @return boolean 定位成功与否
  200. @usage
  201. log.info("nmea", "isFix", libgnss.isFix())
  202. */
  203. static int l_libgnss_is_fix(lua_State *L) {
  204. lua_pushboolean(L, gnssctx.frame_rmc.valid != 0 ? 1 : 0);
  205. return 1;
  206. }
  207. /**
  208. 获取位置信息
  209. @api libgnss.getIntLocation(speed_type)
  210. @int 速度单位,默认是m/h
  211. @return int lat数据, 格式为 ddddddddd
  212. @return int lng数据, 格式为 ddddddddd
  213. @return int speed数据, 单位米. 于2023.9.26修正
  214. @usage
  215. -- 建议用libgnss.getRmc(1)
  216. log.info("nmea", "loc", libgnss.getIntLocation())
  217. -- 2023.12.11 新增speed_type参数
  218. --[[
  219. 速度单位可选值
  220. 0 - m/h 米/小时, 默认值, 整型
  221. 1 - m/s 米/秒, 浮点数
  222. 2 - km/h 千米/小时, 浮点数
  223. 3 - kn/h 英里/小时, 浮点数
  224. ]]
  225. -- 默认 米/小时
  226. log.info("nmea", "loc", libgnss.getIntLocation())
  227. -- 米/秒
  228. log.info("nmea", "loc", libgnss.getIntLocation(1))
  229. -- 千米/小时
  230. log.info("nmea", "loc", libgnss.getIntLocation(2))
  231. -- 英里/小时
  232. log.info("nmea", "loc", libgnss.getIntLocation(3))
  233. */
  234. static int l_libgnss_get_int_location(lua_State *L) {
  235. if (gnssctx.frame_rmc.valid) {
  236. lua_pushinteger(L, gnssctx.frame_rmc.latitude.value);
  237. lua_pushinteger(L, gnssctx.frame_rmc.longitude.value);
  238. int speed_type = luaL_optinteger(L, 1, 0);
  239. switch (speed_type)
  240. {
  241. case 1: // 米/秒
  242. lua_pushnumber(L, (minmea_tofloat(&(gnssctx.frame_rmc.speed)) * 1852 / 3600));
  243. break;
  244. case 2: // 千米/小时
  245. lua_pushnumber(L, (minmea_tofloat(&(gnssctx.frame_rmc.speed)) * 1.852));
  246. break;
  247. case 3: // 英里/小时
  248. lua_pushnumber(L, minmea_tofloat(&(gnssctx.frame_rmc.speed)));
  249. break;
  250. default: // 米/小时
  251. lua_pushinteger(L, (int32_t)(minmea_tofloat(&(gnssctx.frame_rmc.speed)) * 1852));
  252. break;
  253. }
  254. } else {
  255. lua_pushinteger(L, 0);
  256. lua_pushinteger(L, 0);
  257. lua_pushinteger(L, 0);
  258. }
  259. return 3;
  260. }
  261. /**
  262. 获取原始RMC位置信息
  263. @api libgnss.getRmc(data_mode)
  264. @int 坐标类数据的格式, 0-DDMM.MMM格式, 1-DDDDDDD格式, 2-DD.DDDDD格式, 3-原始RMC字符串
  265. @return table 原始rmc数据
  266. @usage
  267. -- 解析nmea
  268. log.info("nmea", "rmc", json.encode(libgnss.getRmc(2)))
  269. -- 实例输出
  270. --[[
  271. {
  272. "course":0,
  273. "valid":true, // true定位成功,false定位丢失
  274. "lat":23.4067, // 纬度, 正数为北纬, 负数为南纬
  275. "lng":113.231, // 经度, 正数为东经, 负数为西经
  276. "variation":0, // 地面航向,单位为度,从北向起顺时针计算
  277. "speed":0 // 地面速度, 单位为"节"
  278. "year":2023, // 年份
  279. "month":1, // 月份, 1-12
  280. "day":5, // 月份天, 1-31
  281. "hour":7, // 小时,0-23
  282. "min":23, // 分钟,0-59
  283. "sec":20, // 秒,0-59
  284. }
  285. ]]
  286. */
  287. static int l_libgnss_get_rmc(lua_State *L) {
  288. int mode = luaL_optinteger(L, 1, 0);
  289. lua_settop(L, 0);
  290. lua_createtable(L, 0, 12);
  291. struct tm rtime = {0};
  292. if (mode == 3) {
  293. if (gnssctx.rmc == NULL)
  294. return 0;
  295. lua_pushstring(L, gnssctx.rmc->data);
  296. return 1;
  297. }
  298. if (1) {
  299. lua_pushboolean(L, gnssctx.frame_rmc.valid);
  300. lua_setfield(L, -2, "valid");
  301. if (gnssctx.frame_rmc.valid) {
  302. push_gnss_value(L, &(gnssctx.frame_rmc.latitude), mode);
  303. }
  304. else
  305. lua_pushinteger(L, 0);
  306. lua_setfield(L, -2, "lat");
  307. if (gnssctx.frame_rmc.valid) {
  308. push_gnss_value(L, &(gnssctx.frame_rmc.longitude), mode);
  309. }
  310. else
  311. lua_pushinteger(L, 0);
  312. lua_setfield(L, -2, "lng");
  313. if (gnssctx.frame_rmc.valid) {
  314. push_gnss_value(L, &(gnssctx.frame_rmc.speed), 0);
  315. }
  316. else
  317. lua_pushinteger(L, 0);
  318. lua_setfield(L, -2, "speed");
  319. if (gnssctx.frame_rmc.valid) {
  320. push_gnss_value(L, &(gnssctx.frame_rmc.course), 0);
  321. }
  322. else
  323. lua_pushinteger(L, 0);
  324. lua_setfield(L, -2, "course");
  325. if (gnssctx.frame_rmc.valid) {
  326. push_gnss_value(L, &(gnssctx.frame_rmc.variation), 0);
  327. }
  328. else
  329. lua_pushinteger(L, 0);
  330. lua_setfield(L, -2, "variation");
  331. // 时间类
  332. minmea_getdatetime(&rtime, &gnssctx.frame_rmc.date, &gnssctx.frame_rmc.time);
  333. put_datetime(L, &rtime);
  334. }
  335. return 1;
  336. }
  337. /**
  338. 获取原始GSV信息
  339. @api libgnss.getGsv()
  340. @return table 原始GSV数据
  341. @usage
  342. -- 解析nmea
  343. log.info("nmea", "gsv", json.encode(libgnss.getGsv()))
  344. --[[实例输出
  345. {
  346. "total_sats":24, // 总可见卫星数量
  347. "sats":[
  348. {
  349. "snr":27, // 信噪比
  350. "azimuth":278, // 方向角
  351. "elevation":59, // 仰角
  352. "tp":0, // 0 - GPS, 1 - BD
  353. "nr":4 // 卫星编号
  354. },
  355. // 这里忽略了22个卫星的信息
  356. {
  357. "snr":0,
  358. "azimuth":107,
  359. "elevation":19,
  360. "tp":1,
  361. "nr":31
  362. }
  363. ]
  364. }
  365. ]]
  366. */
  367. static int l_libgnss_get_gsv(lua_State *L) {
  368. lua_createtable(L, 0, 2);
  369. size_t count = 1;
  370. uint64_t tnow = luat_mcu_tick64_ms();
  371. struct minmea_sentence_gsv frame_gsv = {0};
  372. lua_createtable(L, FRAME_GSV_MAX, 0);
  373. for (size_t i = 0; i < FRAME_GSV_MAX; i++)
  374. {
  375. if (!luat_libgnss_data_check(gnssctx.gsv[i], 3500, tnow) || !minmea_parse_gsv(&frame_gsv, gnssctx.gsv[i]->data)) {
  376. continue;
  377. }
  378. for (size_t j = 0; j < 4; j++)
  379. {
  380. if (!frame_gsv.sats[j].nr) {
  381. continue;
  382. }
  383. lua_pushinteger(L, count);
  384. lua_createtable(L, 0, 4);
  385. lua_pushliteral(L, "nr");
  386. lua_pushinteger(L, frame_gsv.sats[j].nr);
  387. lua_settable(L, -3);
  388. lua_pushliteral(L, "snr");
  389. lua_pushinteger(L, frame_gsv.sats[j].snr);
  390. lua_settable(L, -3);
  391. lua_pushliteral(L, "elevation");
  392. lua_pushinteger(L, frame_gsv.sats[j].elevation);
  393. lua_settable(L, -3);
  394. lua_pushliteral(L, "azimuth");
  395. lua_pushinteger(L, frame_gsv.sats[j].azimuth);
  396. lua_settable(L, -3);
  397. // 区分不同的卫星系统
  398. // https://receiverhelp.trimble.com/alloy-gnss/en-us/NMEA-0183messages_GSA.html
  399. lua_pushliteral(L, "tp");
  400. if (memcmp(gnssctx.gsv[i], "$GP", 3) == 0) {
  401. lua_pushinteger(L, 0);
  402. }
  403. else if (memcmp(gnssctx.gsv[i], "$GL", 3) == 0) {
  404. lua_pushinteger(L, 2);
  405. }
  406. else if (memcmp(gnssctx.gsv[i], "$GA", 3) == 0) {
  407. lua_pushinteger(L, 3);
  408. }
  409. else if (memcmp(gnssctx.gsv[i], "$BD", 3) == 0 || memcmp(gnssctx.gsv[i], "$GB", 3) == 0) {
  410. lua_pushinteger(L, 1);
  411. }
  412. else if (memcmp(gnssctx.gsv[i], "$QZ", 3) == 0) {
  413. lua_pushinteger(L, 4);
  414. }
  415. else {
  416. lua_pushinteger(L, 0);
  417. }
  418. lua_settable(L, -3);
  419. // 新增一个类型, 字符串的, 实在是各种变化无法应对
  420. lua_pushliteral(L, "tpstr");
  421. lua_pushlstring(L, gnssctx.gsv[i]->data + 1, 2);
  422. lua_settable(L, -3);
  423. lua_settable(L, -3);
  424. count = count + 1;
  425. }
  426. }
  427. lua_setfield(L, -2, "sats");
  428. lua_pushliteral(L, "total_sats");
  429. lua_pushinteger(L, count - 1);
  430. lua_settable(L, -3);
  431. return 1;
  432. }
  433. /**
  434. 获取原始GSA信息
  435. @api libgnss.getGsa(data_mode)
  436. @int 模式
  437. @return table 原始GSA数据
  438. @usage
  439. -- 获取
  440. log.info("nmea", "gsa", json.encode(libgnss.getGsa(), "11g"))
  441. -- 示例数据(模式0, 也就是默认模式)
  442. --[[
  443. {
  444. "sats":[ // 正在使用的卫星编号
  445. 9,
  446. 6,
  447. 16,
  448. 16,
  449. 26,
  450. 21,
  451. 27,
  452. 27,
  453. 4,
  454. 36,
  455. 3,
  456. 7,
  457. 8,
  458. 194
  459. ],
  460. "vdop":0.03083333, // 垂直精度因子,0.00 - 99.99,不定位时值为 99.99
  461. "pdop":0.0455, // 水平精度因子,0.00 - 99.99,不定位时值为 99.99
  462. "fix_type":3, // 定位模式, 1-未定位, 2-2D定位, 3-3D定位
  463. "hdop":0.0335 // 位置精度因子,0.00 - 99.99,不定位时值为 99.99
  464. }
  465. ]]
  466. -- 示例数据(模式1), 2024.5.26新增
  467. [
  468. {"pdop":7.8299999,"sats":[13,15,18,23],"vdop":3.2400000,"hdop":7.1300001,"fix_type":3},
  469. {"pdop":7.8299999,"sats":[20,35,8,13],"vdop":3.2400000,"hdop":7.1300001,"fix_type":3}
  470. ]
  471. */
  472. static int l_libgnss_get_gsa_mode0(lua_State *L) {
  473. struct minmea_sentence_gsa frame_gsa = {0};
  474. uint64_t tnow = luat_mcu_tick64_ms();
  475. lua_createtable(L, 0, 12);
  476. for (size_t i = 0; i < FRAME_GSA_MAX; i++)
  477. {
  478. if (!luat_libgnss_data_check(gnssctx.gsa[i], 1500, tnow) || minmea_parse_gsa(&frame_gsa, gnssctx.gsa[i]->data) != 1)
  479. {
  480. continue;
  481. }
  482. lua_pushliteral(L, "fix_type");
  483. lua_pushinteger(L, frame_gsa.fix_type);
  484. lua_settable(L, -3);
  485. lua_pushliteral(L, "pdop");
  486. push_gnss_value(L, &(frame_gsa.pdop), 0);
  487. lua_settable(L, -3);
  488. lua_pushliteral(L, "hdop");
  489. push_gnss_value(L, &(frame_gsa.hdop), 0);
  490. lua_settable(L, -3);
  491. lua_pushliteral(L, "vdop");
  492. push_gnss_value(L, &(frame_gsa.vdop), 0);
  493. lua_settable(L, -3);
  494. lua_pushliteral(L, "sysid");
  495. lua_pushinteger(L, frame_gsa.sysid);
  496. lua_settable(L, -3);
  497. break;
  498. }
  499. lua_pushliteral(L, "sats");
  500. lua_createtable(L, FRAME_GSA_MAX, 0);
  501. size_t pos = 1;
  502. for (size_t i = 0; i < FRAME_GSA_MAX; i++) {
  503. if (gnssctx.gsa[i] == NULL || minmea_parse_gsa(&frame_gsa, gnssctx.gsa[i]->data) != 1)
  504. {
  505. continue;
  506. }
  507. if (tnow - gnssctx.gsa[i]->tm > 1000) {
  508. continue;
  509. }
  510. // LLOGD("GSA: %s", gnssctx.gsa[i]->data);
  511. for (size_t j = 0; j < 12; j++)
  512. {
  513. if (frame_gsa.sats[j] == 0)
  514. continue;
  515. lua_pushinteger(L, frame_gsa.sats[j]);
  516. lua_seti(L, -2, pos);
  517. pos ++;
  518. }
  519. }
  520. lua_settable(L, -3);
  521. return 1;
  522. }
  523. static int l_libgnss_get_gsa_mode1(lua_State *L) {
  524. struct minmea_sentence_gsa frame_gsa = {0};
  525. uint64_t tnow = luat_mcu_tick64_ms();
  526. lua_createtable(L, FRAME_GSA_MAX, 0);
  527. size_t count = 0;
  528. for (size_t i = 0; i < FRAME_GSA_MAX; i++) {
  529. if (gnssctx.gsa[i] == NULL || minmea_parse_gsa(&frame_gsa, gnssctx.gsa[i]->data) != 1)
  530. {
  531. continue;
  532. }
  533. if (tnow - gnssctx.gsa[i]->tm > 1000) {
  534. continue;
  535. }
  536. count ++;
  537. lua_createtable(L, 0, 12);
  538. lua_pushliteral(L, "fix_type");
  539. lua_pushinteger(L, frame_gsa.fix_type);
  540. lua_settable(L, -3);
  541. lua_pushliteral(L, "pdop");
  542. push_gnss_value(L, &(frame_gsa.pdop), 0);
  543. lua_settable(L, -3);
  544. lua_pushliteral(L, "hdop");
  545. push_gnss_value(L, &(frame_gsa.hdop), 0);
  546. lua_settable(L, -3);
  547. lua_pushliteral(L, "vdop");
  548. push_gnss_value(L, &(frame_gsa.vdop), 0);
  549. lua_settable(L, -3);
  550. lua_pushliteral(L, "sysid");
  551. lua_pushinteger(L, frame_gsa.sysid);
  552. lua_settable(L, -3);
  553. lua_pushliteral(L, "sats");
  554. lua_createtable(L, 12, 0);
  555. size_t pos = 1;
  556. for (size_t j = 0; j < 12; j++)
  557. {
  558. if (frame_gsa.sats[j] == 0)
  559. continue;
  560. lua_pushinteger(L, frame_gsa.sats[j]);
  561. lua_seti(L, -2, pos);
  562. pos ++;
  563. }
  564. lua_settable(L, -3);
  565. lua_seti(L, -2, count);
  566. }
  567. return 1;
  568. }
  569. static int l_libgnss_get_gsa(lua_State *L) {
  570. int mode = luaL_optinteger(L, 1, 0);
  571. lua_settop(L, 0);
  572. if (1 == mode) {
  573. return l_libgnss_get_gsa_mode1(L);
  574. }
  575. else {
  576. return l_libgnss_get_gsa_mode0(L);
  577. }
  578. }
  579. /**
  580. 获取VTA速度信息
  581. @api libgnss.getVtg(data_mode)
  582. @int 可选, 3-原始字符串, 不传或者传其他值, 则返回浮点值
  583. @return table 原始VTA数据
  584. @usage
  585. -- 解析nmea
  586. log.info("nmea", "vtg", json.encode(libgnss.getVtg()))
  587. -- 示例
  588. --[[
  589. {
  590. "speed_knots":0, // 速度, 英里/小时
  591. "true_track_degrees":0, // 真北方向角
  592. "magnetic_track_degrees":0, // 磁北方向角
  593. "speed_kph":0 // 速度, 千米/小时
  594. }
  595. -- 提醒: Air780EG和Air510U,在速度<5km/h时, 不会返回方向角
  596. ]]
  597. */
  598. static int l_libgnss_get_vtg(lua_State *L) {
  599. int mode = luaL_optinteger(L, 1, 0);
  600. lua_settop(L, 0);
  601. if (gnssctx.vtg == NULL)
  602. return 0;
  603. if (mode == 3) {
  604. lua_pushstring(L, gnssctx.vtg->data);
  605. return 1;
  606. }
  607. lua_createtable(L, 0, 10);
  608. struct minmea_sentence_vtg frame_vtg = {0};
  609. minmea_parse_vtg(&frame_vtg, gnssctx.vtg->data);
  610. // lua_pushliteral(L, "faa_mode");
  611. // lua_pushlstring(L, gnssctx.frame_vtg.faa_mode, 1);
  612. // lua_settable(L, -3);
  613. lua_pushliteral(L, "true_track_degrees");
  614. push_gnss_value(L, &(frame_vtg.true_track_degrees), 0);
  615. lua_settable(L, -3);
  616. lua_pushliteral(L, "magnetic_track_degrees");
  617. push_gnss_value(L, &(frame_vtg.magnetic_track_degrees), 0);
  618. lua_settable(L, -3);
  619. lua_pushliteral(L, "speed_knots");
  620. push_gnss_value(L, &(frame_vtg.speed_knots), 0);
  621. lua_settable(L, -3);
  622. lua_pushliteral(L, "speed_kph");
  623. push_gnss_value(L, &(frame_vtg.speed_kph), 0);
  624. lua_settable(L, -3);
  625. return 1;
  626. }
  627. /**
  628. 获取原始ZDA时间和日期信息
  629. @api libgnss.getZda()
  630. @return table 原始zda数据
  631. @usage
  632. log.info("nmea", "zda", json.encode(libgnss.getZda()))
  633. -- 实例输出
  634. --[[
  635. {
  636. "minute_offset":0, // 本地时区的分钟, 一般固定输出0
  637. "hour_offset":0, // 本地时区的小时, 一般固定输出0
  638. "year":2023 // UTC 年,四位数字
  639. "month":1, // UTC 月,两位,01 ~ 12
  640. "day":5, // UTC 日,两位数字,01 ~ 31
  641. "hour":7, // 小时
  642. "min":50, // 分
  643. "sec":14, // 秒
  644. }
  645. ]]
  646. */
  647. static int l_libgnss_get_zda(lua_State *L) {
  648. lua_createtable(L, 0, 9);
  649. struct tm rtime = {0};
  650. if (gnssctx.zda != NULL) {
  651. struct minmea_sentence_zda frame_zda = {0};
  652. minmea_parse_zda(&frame_zda, gnssctx.zda->data);
  653. lua_pushliteral(L, "hour_offset");
  654. lua_pushinteger(L, frame_zda.hour_offset);
  655. lua_settable(L, -3);
  656. lua_pushliteral(L, "minute_offset");
  657. lua_pushinteger(L, frame_zda.minute_offset);
  658. lua_settable(L, -3);
  659. // 时间相关
  660. minmea_getdatetime(&rtime, &frame_zda.date, &frame_zda.time);
  661. put_datetime(L, &rtime);
  662. }
  663. return 1;
  664. }
  665. /**
  666. 设置调试模式
  667. @api libgnss.debug(mode)
  668. @bool true开启调试,false关闭调试,默认为false
  669. @usage
  670. -- 开启调试, 会输出GNSS原始数据到日志中
  671. libgnss.debug(true)
  672. -- 关闭调试
  673. libgnss.debug(false)
  674. */
  675. static int l_libgnss_debug(lua_State *L) {
  676. if (lua_isboolean(L, 1) && lua_toboolean(L, 1)) {
  677. LLOGD("Debug ON");
  678. gnss_debug = 1;
  679. }
  680. else
  681. {
  682. LLOGD("Debug OFF");
  683. gnss_debug = 0;
  684. }
  685. return 0;
  686. }
  687. /*
  688. 获取GGA数据
  689. @api libgnss.getGga(data_mode)
  690. @int 坐标类数据的格式, 0-DDMM.MMM格式, 1-DDDDDDD格式, 2-DD.DDDDD格式, 3-原始字符串
  691. @return table GGA数据, 若如不存在会返回nil
  692. @usage
  693. local gga = libgnss.getGga(2)
  694. if gga then
  695. log.info("GGA", json.encode(gga, "11g"))
  696. end
  697. --实例输出
  698. --[[
  699. {
  700. "dgps_age":0, // 差分校正时延,单位为秒
  701. "fix_quality":1, // 定位状态标识 0 - 无效,1 - 单点定位,2 - 差分定位
  702. "satellites_tracked":14, // 参与定位的卫星数量
  703. "altitude":0.255, // 海平面分离度, 或者成为海拔, 单位是米,
  704. "hdop":0.0335, // 水平精度因子,0.00 - 99.99,不定位时值为 99.99
  705. "longitude":113.231, // 经度, 正数为东经, 负数为西经
  706. "latitude":23.4067, // 纬度, 正数为北纬, 负数为南纬
  707. "height":0 // 椭球高,固定输出 1 位小数
  708. }
  709. ]]
  710. */
  711. static int l_libgnss_get_gga(lua_State* L) {
  712. int mode = luaL_optinteger(L, 1, 0);
  713. lua_settop(L, 0);
  714. if (gnssctx.gga == NULL)
  715. return 0;
  716. if (mode == 3) {
  717. lua_pushstring(L, gnssctx.gga->data);
  718. return 1;
  719. }
  720. lua_newtable(L);
  721. struct minmea_sentence_gga frame_gga = {0};
  722. minmea_parse_gga(&frame_gga, gnssctx.gga->data);
  723. lua_pushstring(L, "altitude");
  724. push_gnss_value(L, &(frame_gga.altitude), 0);
  725. lua_settable(L, -3);
  726. lua_pushstring(L, "latitude");
  727. push_gnss_value(L, &(frame_gga.latitude), mode);
  728. lua_settable(L, -3);
  729. lua_pushstring(L, "longitude");
  730. push_gnss_value(L, &(frame_gga.longitude), mode);
  731. lua_settable(L, -3);
  732. lua_pushstring(L, "fix_quality");
  733. lua_pushinteger(L, frame_gga.fix_quality);
  734. lua_settable(L, -3);
  735. lua_pushstring(L, "satellites_tracked");
  736. lua_pushinteger(L, frame_gga.satellites_tracked);
  737. lua_settable(L, -3);
  738. lua_pushstring(L, "hdop");
  739. push_gnss_value(L, &(frame_gga.hdop), 0);
  740. lua_settable(L, -3);
  741. lua_pushstring(L, "height");
  742. push_gnss_value(L, &(frame_gga.height), 0);
  743. lua_settable(L, -3);
  744. lua_pushstring(L, "dgps_age");
  745. push_gnss_value(L, &(frame_gga.dgps_age), 0);
  746. lua_settable(L, -3);
  747. return 1;
  748. }
  749. /*
  750. 获取GLL数据
  751. @api libgnss.getGll(data_mode)
  752. @int 坐标类数据的格式, 0-DDMM.MMM格式, 1-DDDDDDD格式, 2-DD.DDDDD格式
  753. @return table GLL数据, 若如不存在会返回nil
  754. @usage
  755. local gll = libgnss.getGll(2)
  756. if gll then
  757. log.info("GLL", json.encode(gll, "11g"))
  758. end
  759. -- 实例数据
  760. --[[
  761. {
  762. "status":"A", // 定位状态, A有效, B无效
  763. "mode":"A", // 定位模式, V无效, A单点解, D差分解
  764. "sec":20, // 秒, UTC时间为准
  765. "min":23, // 分钟, UTC时间为准
  766. "hour":7, // 小时, UTC时间为准
  767. "longitude":113.231, // 经度, 正数为东经, 负数为西经
  768. "latitude":23.4067, // 纬度, 正数为北纬, 负数为南纬
  769. "us":0 // 微妙数, 通常为0
  770. }
  771. ]]
  772. */
  773. static int l_libgnss_get_gll(lua_State* L) {
  774. int mode = luaL_optinteger(L, 1, 0);
  775. lua_settop(L, 0);
  776. if (gnssctx.gll == NULL)
  777. return 0;
  778. if (mode == 3) {
  779. lua_pushstring(L, gnssctx.vtg->data);
  780. return 1;
  781. }
  782. lua_newtable(L);
  783. struct minmea_sentence_gll frame_gll = {0};
  784. minmea_parse_gll(&frame_gll, gnssctx.gll->data);
  785. lua_pushstring(L, "latitude");
  786. push_gnss_value(L, &(frame_gll.latitude), mode);
  787. lua_settable(L, -3);
  788. lua_pushstring(L, "longitude");
  789. push_gnss_value(L, &(frame_gll.longitude), mode);
  790. lua_settable(L, -3);
  791. lua_pushstring(L, "mode");
  792. lua_pushfstring(L, "%c", frame_gll.mode);
  793. lua_settable(L, -3);
  794. lua_pushstring(L, "status");
  795. lua_pushfstring(L, "%c", frame_gll.status);
  796. lua_settable(L, -3);
  797. lua_pushstring(L, "hour");
  798. lua_pushinteger(L, frame_gll.time.hours);
  799. lua_settable(L, -3);
  800. lua_pushstring(L, "us");
  801. lua_pushinteger(L, frame_gll.time.microseconds);
  802. lua_settable(L, -3);
  803. lua_pushstring(L, "min");
  804. lua_pushinteger(L, frame_gll.time.minutes);
  805. lua_settable(L, -3);
  806. lua_pushstring(L, "sec");
  807. lua_pushinteger(L, frame_gll.time.seconds);
  808. lua_settable(L, -3);
  809. return 1;
  810. }
  811. /**
  812. 清除历史定位数据
  813. @api libgnss.clear()
  814. @return nil 无返回值
  815. @usage
  816. -- 该操作会清除所有定位数据
  817. */
  818. static int l_libgnss_clear(lua_State*L) {
  819. (void)L;
  820. luat_libgnss_init(true);
  821. return 0;
  822. }
  823. /*
  824. 绑定uart端口进行GNSS数据读取
  825. @api libgnss.bind(id, next_id)
  826. @int uart端口号
  827. @int 转发到uart的id, 例如虚拟uart.VUART_0
  828. @usage
  829. -- 配置串口信息, 通常为 115200 8N1
  830. uart.setup(2, 115200)
  831. -- 绑定uart, 马上开始解析GNSS数据
  832. libgnss.bind(2)
  833. -- 无需再调用uart.on然后调用libgnss.parse
  834. -- 开发期可打开调试日志
  835. libgnss.debug(true)
  836. -- 2023-01-02之后编译的固件有效
  837. -- 从uart2读取并解析, 同时转发到虚拟串口0
  838. libgnss.bind(2, uart.VUART_0)
  839. */
  840. static int l_libgnss_bind(lua_State* L) {
  841. int uart_id = luaL_checkinteger(L, 1);
  842. int next_uart_id = 0;
  843. l_libgnss_clear(L);
  844. if (libgnss_recvbuff == NULL) {
  845. libgnss_recvbuff = luat_heap_malloc(RECV_BUFF_SIZE);
  846. }
  847. luat_uart_set_app_recv(uart_id, l_libgnss_uart_recv_cb);
  848. if (lua_isinteger(L, 2)) {
  849. next_uart_id = luaL_checkinteger(L, 2);
  850. if (uart_id == libgnss_route_uart_id) {
  851. LLOGW("id == next_id , is NOT allow. %d", uart_id);
  852. return 0;
  853. }
  854. libgnss_route_uart_id = next_uart_id;
  855. }
  856. return 0;
  857. }
  858. /**
  859. 获取位置字符串
  860. @api libgnss.locStr(mode)
  861. @int 字符串模式. 0- Air780EG所需的格式
  862. @return 指定模式的字符串
  863. @usage
  864. -- 仅推荐在定位成功后调用
  865. */
  866. static int l_libgnss_locStr(lua_State *L) {
  867. int mode = luaL_optinteger(L, 1, 0);
  868. char buff[64] = {0};
  869. float lat_f = minmea_tofloat(&gnssctx.frame_rmc.latitude);
  870. float lng_f = minmea_tofloat(&gnssctx.frame_rmc.longitude);
  871. switch (mode)
  872. {
  873. case 0:
  874. snprintf_(buff, 63, "%.7g,%c,%.7g,%c,1.0",
  875. fabs(lat_f), lat_f > 0 ? 'N' : 'S',
  876. fabs(lng_f), lng_f > 0 ? 'E' : 'W');
  877. break;
  878. case 1:
  879. snprintf_(buff, 63, "%ld,%ld", gnssctx.frame_rmc.latitude.value, gnssctx.frame_rmc.longitude.value);
  880. break;
  881. default:
  882. break;
  883. }
  884. lua_pushstring(L, buff);
  885. return 1;
  886. }
  887. /**
  888. 定位成功后自动设置RTC
  889. @api libgnss.rtcAuto(enable)
  890. @bool 开启与否, 默认是false关闭
  891. @usage
  892. -- 开启自动设置RTC
  893. libgnss.rtcAuto(true)
  894. */
  895. static int l_libgnss_rtc_auto(lua_State *L) {
  896. if (lua_isboolean(L, 1) && lua_toboolean(L, 1)) {
  897. gnssctx.rtc_auto = 1;
  898. LLOGD("GNSS->RTC Auto-Set now is ON");
  899. }
  900. else {
  901. gnssctx.rtc_auto = 0;
  902. LLOGD("GNSS->RTC Auto-Set now is OFF");
  903. }
  904. return 0;
  905. }
  906. static int l_libgnss_data_cb(lua_State *L, void* ptr) {
  907. rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
  908. // lua_getglobal(L, "sys_pub");
  909. lua_geti(L, LUA_REGISTRYINDEX, msg->arg2);
  910. if (lua_isfunction(L, -1)) {
  911. // lua_pushliteral(gnss_L, "GNSS_RAW_DATA");
  912. lua_pushlstring(L, ptr, msg->arg1);
  913. luat_heap_free(ptr);
  914. ptr = NULL;
  915. lua_call(L, 1, 0);
  916. }
  917. else {
  918. luat_heap_free(ptr);
  919. }
  920. return 0;
  921. }
  922. int luat_libgnss_on_rawdata(const char* data, size_t len, int type) {
  923. int cb = 0;
  924. if (type == 0) {
  925. if (gnss_raw_cb == 0)
  926. return 0;
  927. cb = gnss_raw_cb;
  928. }
  929. else if (type == 1) {
  930. if (gnss_txt_cb == 0)
  931. return 0;
  932. cb = gnss_txt_cb;
  933. }
  934. else if (type == 2) {
  935. if (gnss_other_cb == 0)
  936. return 0;
  937. cb = gnss_other_cb;
  938. }
  939. else {
  940. return 0;
  941. }
  942. char* ptr = luat_heap_malloc(len);
  943. if (ptr == NULL)
  944. return 0;
  945. memcpy(ptr, data, len);
  946. rtos_msg_t msg = {
  947. .handler = l_libgnss_data_cb,
  948. .arg1 = len,
  949. .arg2 = cb,
  950. .ptr = ptr
  951. };
  952. luat_msgbus_put(&msg, 0);
  953. return 0;
  954. }
  955. /**
  956. 底层事件回调
  957. @api libgnss.on(tp, fn)
  958. @string 事件类型,当前支持"raw"
  959. @usage
  960. -- 本函数一般用于调试, 用于获取底层实际收到的数据
  961. libgnss.on("raw", function(data)
  962. log.info("GNSS", data)
  963. end)
  964. */
  965. static int l_libgnss_on(lua_State *L) {
  966. size_t len = 0;
  967. const char* tp = luaL_checklstring(L, 1, &len);
  968. if (!strcmp("raw", tp)) {
  969. if (gnss_raw_cb != 0) {
  970. luaL_unref(L, LUA_REGISTRYINDEX, gnss_raw_cb);
  971. gnss_raw_cb = 0;
  972. }
  973. if (lua_isfunction(L, 2)) {
  974. lua_pushvalue(L, 2);
  975. gnss_raw_cb = luaL_ref(L, LUA_REGISTRYINDEX);
  976. }
  977. }
  978. else if (!strcmp("txt", tp)) {
  979. if (gnss_txt_cb != 0) {
  980. luaL_unref(L, LUA_REGISTRYINDEX, gnss_txt_cb);
  981. gnss_txt_cb = 0;
  982. }
  983. if (lua_isfunction(L, 2)) {
  984. lua_pushvalue(L, 2);
  985. gnss_txt_cb = luaL_ref(L, LUA_REGISTRYINDEX);
  986. }
  987. }
  988. else if (!strcmp("other", tp)) {
  989. if (gnss_other_cb != 0) {
  990. luaL_unref(L, LUA_REGISTRYINDEX, gnss_other_cb);
  991. gnss_other_cb = 0;
  992. }
  993. if (lua_isfunction(L, 2)) {
  994. lua_pushvalue(L, 2);
  995. gnss_other_cb = luaL_ref(L, LUA_REGISTRYINDEX);
  996. }
  997. }
  998. return 0;
  999. }
  1000. /**
  1001. 获取非标的GPTXT数据
  1002. @api libgnss.getTxt()
  1003. @return GPTXT所携带的字符串
  1004. @usage
  1005. -- 本函数于2023.6.6 添加
  1006. log.info("gnss", "txt", libgnss.getTxt())
  1007. -- 测试语句
  1008. libgnss.parse("$GPTXT,01,01,01,ANTENNA SHORT*63\r\n")
  1009. log.info("GNSS", libgnss.getTxt())
  1010. libgnss.parse("$GPTXT,01,01,01,ANTENNA OPEN*25\r\n")
  1011. log.info("GNSS", libgnss.getTxt())
  1012. libgnss.parse("$GPTXT,01,01,01,ANTENNA OK*35\r\n")
  1013. log.info("GNSS", libgnss.getTxt())
  1014. */
  1015. static int l_libgnss_get_txt(lua_State *L) {
  1016. if (gnssctx.txt == NULL) {
  1017. lua_pushliteral(L, "");
  1018. return 1;
  1019. }
  1020. struct minmea_sentence_txt txt = {0};
  1021. minmea_parse_txt(&txt, gnssctx.txt->data);
  1022. txt.txt[FRAME_TXT_MAX_LEN] = 0x00;
  1023. lua_pushstring(L, txt.txt);
  1024. return 1;
  1025. }
  1026. /*
  1027. 合成Air530Z所需要的辅助定位数据
  1028. @api libgnss.casic_aid(dt, loc)
  1029. @table 时间信息
  1030. @table 经纬度及海拔
  1031. @return string 辅助定位数据
  1032. @usage
  1033. -- 本函数适合CASIC系列GNSS模块的辅助定位信息的合成
  1034. -- 本函数 2023.11.14 新增
  1035. -- 首先是时间信息,注意是UTC时间
  1036. -- 时间来源很多, 一般建议socket.sntp()时间同步后的系统时间
  1037. local dt = os.date("!*t")
  1038. -- 然后是辅助定位坐标
  1039. -- 来源有很多方式:
  1040. -- 1. 从历史定位数据得到, 例如之前定位成功后保存到本地文件系统了
  1041. -- 2. 通过基站定位或者wifi定位获取到
  1042. -- 3. 通过IP定位获取到大概坐标
  1043. -- 坐标系是WGS84, 但鉴于是辅助定位,精度不是关键因素
  1044. local lla = {
  1045. lat = 23.12,
  1046. lng = 114.12
  1047. }
  1048. local aid = libgnss.casic_aid(dt, lla)
  1049. */
  1050. #include "luat_casic_gnss.h"
  1051. double strtod(const char *s,char **ptr);
  1052. static int l_libgnss_casic_aid(lua_State* L) {
  1053. DATETIME_STR dt = {0};
  1054. POS_LLA_STR lla = {0};
  1055. const char* data = "";
  1056. if (lua_istable(L, 1)) {
  1057. if (LUA_TNUMBER == lua_getfield(L, 1, "day")) {
  1058. dt.day = lua_tointeger(L, -1);
  1059. };
  1060. lua_pop(L, 1);
  1061. // 这里兼容month和mon两种, os.date 和 rtc.get
  1062. if (LUA_TNUMBER == lua_getfield(L, 1, "month")) {
  1063. dt.month = lua_tointeger(L, -1);
  1064. };
  1065. lua_pop(L, 1);
  1066. if (LUA_TNUMBER == lua_getfield(L, 1, "mon")) {
  1067. dt.month = lua_tointeger(L, -1);
  1068. };
  1069. lua_pop(L, 1);
  1070. if (LUA_TNUMBER == lua_getfield(L, 1, "year")) {
  1071. dt.year = lua_tointeger(L, -1);
  1072. if (dt.year > 2022)
  1073. dt.valid = 1;
  1074. };
  1075. lua_pop(L, 1);
  1076. if (LUA_TNUMBER == lua_getfield(L, 1, "hour")) {
  1077. dt.hour = lua_tointeger(L, -1);
  1078. };
  1079. lua_pop(L, 1);
  1080. if (LUA_TNUMBER == lua_getfield(L, 1, "min")) {
  1081. dt.minute = lua_tointeger(L, -1);
  1082. };
  1083. lua_pop(L, 1);
  1084. if (LUA_TNUMBER == lua_getfield(L, 1, "sec")) {
  1085. dt.second = lua_tointeger(L, -1);
  1086. };
  1087. lua_pop(L, 1);
  1088. }
  1089. if (lua_istable(L, 2)) {
  1090. lua_getfield(L, 2, "lat");
  1091. if (LUA_TNUMBER == lua_type(L, -1)) {
  1092. lla.lat = lua_tonumber(L, -1);
  1093. }
  1094. else if (LUA_TSTRING == lua_type(L, -1)) {
  1095. data = luaL_checkstring(L, -1);
  1096. lla.lat = strtod(data, NULL);
  1097. }
  1098. lua_pop(L, 1);
  1099. lua_getfield(L, 2, "lng");
  1100. if (LUA_TNUMBER == lua_type(L, -1)) {
  1101. lla.lon = lua_tonumber(L, -1);
  1102. }
  1103. else if (LUA_TSTRING == lua_type(L, -1)) {
  1104. data = luaL_checkstring(L, -1);
  1105. lla.lon = strtod(data, NULL);
  1106. }
  1107. lua_pop(L, 1);
  1108. if (LUA_TNUMBER == lua_getfield(L, 2, "alt")) {
  1109. lla.alt = lua_tonumber(L, -1);
  1110. };
  1111. if (lla.lat > 0.001 || lla.lat < -0.01)
  1112. if (lla.lon > 0.001 || lla.lon < -0.01)
  1113. lla.valid = 1;
  1114. }
  1115. char tmp[66] = {0};
  1116. casicAgnssAidIni(&dt, &lla, tmp);
  1117. lua_pushlstring(L, tmp, 66);
  1118. return 1;
  1119. };
  1120. #include "rotable2.h"
  1121. static const rotable_Reg_t reg_libgnss[] =
  1122. {
  1123. { "parse", ROREG_FUNC(l_libgnss_parse)},
  1124. { "isFix", ROREG_FUNC(l_libgnss_is_fix)},
  1125. { "getIntLocation", ROREG_FUNC(l_libgnss_get_int_location)},
  1126. { "getRmc", ROREG_FUNC(l_libgnss_get_rmc)},
  1127. { "getGsv", ROREG_FUNC(l_libgnss_get_gsv)},
  1128. { "getGsa", ROREG_FUNC(l_libgnss_get_gsa)},
  1129. { "getVtg", ROREG_FUNC(l_libgnss_get_vtg)},
  1130. { "getGga", ROREG_FUNC(l_libgnss_get_gga)},
  1131. { "getGll", ROREG_FUNC(l_libgnss_get_gll)},
  1132. { "getZda", ROREG_FUNC(l_libgnss_get_zda)},
  1133. { "locStr", ROREG_FUNC(l_libgnss_locStr)},
  1134. { "rtcAuto",ROREG_FUNC(l_libgnss_rtc_auto)},
  1135. { "on", ROREG_FUNC(l_libgnss_on)},
  1136. { "debug", ROREG_FUNC(l_libgnss_debug)},
  1137. { "clear", ROREG_FUNC(l_libgnss_clear)},
  1138. { "bind", ROREG_FUNC(l_libgnss_bind)},
  1139. { "getTxt", ROREG_FUNC(l_libgnss_get_txt)},
  1140. { "casic_aid", ROREG_FUNC(l_libgnss_casic_aid)},
  1141. { NULL, ROREG_INT(0)}
  1142. };
  1143. LUAMOD_API int luaopen_libgnss( lua_State *L ) {
  1144. luat_newlib2(L, reg_libgnss);
  1145. return 1;
  1146. }