gnss.lua 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994
  1. --[[
  2. @module gnss
  3. @summary gnss拓展库
  4. @version 1.0
  5. @date 2025.07.16
  6. @author 李源龙
  7. @usage
  8. -- 用法实例
  9. -- 注意:gnss.lua适用的产品范围,只能用于合宙内部集成GNSS功能的产品,目前有Air780EGH,Air8000系列
  10. -- 提醒: 本库输出的坐标,均为 WGS84 坐标系
  11. -- 如需要在国内地图使用, 要转换成对应地图的坐标系, 例如 GCJ02 BD09
  12. -- 相关链接: https://lbsyun.baidu.com/index.php?title=coordinate
  13. -- 相关链接: https://www.openluat.com/GPS-Offset.html
  14. --关于gnss的三种应用场景:
  15. gnss.DEFAULT:
  16. --- gnss应用模式1.
  17. -- 打开gnss后,gnss定位成功时,如果有回调函数,会调用回调函数
  18. -- 使用此应用模式调用gnss.open打开的“gnss应用”,必须主动调用gnss.close
  19. -- 或者gnss.closeAll才能关闭此“gnss应用”,主动关闭时,即使有回调函数,也不会调用回调函数
  20. -- 通俗点说就是一直打开,除非自己手动关闭掉
  21. gnss.TIMERORSUC:
  22. --- gnss应用模式2.
  23. -- 打开gnss后,如果在gnss开启最大时长到达时,没有定位成功,如果有回调函数,
  24. -- 会调用回调函数,然后自动关闭此“gnss应用”
  25. -- 打开gnss后,如果在gnss开启最大时长内,定位成功,如果有回调函数,
  26. -- 会调用回调函数,然后自动关闭此“gnss应用”
  27. -- 打开gnss后,在自动关闭此“gnss应用”前,可以调用gnss.close或者
  28. -- gnss.closeAll主动关闭此“gnss应用”,主动关闭时,即使有回调函数,也不会调用回调函数
  29. -- 通俗点说就是设置规定时间打开,如果规定时间内定位成功就会自动关闭此应用,
  30. -- 如果没有定位成功,时间到了也会自动关闭此应用
  31. gnss.TIMER:
  32. --- gnss应用模式3.
  33. -- 打开gnss后,在gnss开启最大时长时间到达时,无论是否定位成功,如果有回调函数,
  34. -- 会调用回调函数,然后自动关闭此“gnss应用”
  35. -- 打开gnss后,在自动关闭此“gnss应用”前,可以调用gnss.close或者gnss.closeAll
  36. -- 主动关闭此“gnss应用”,主动关闭时,即使有回调函数,也不会调用回调函数
  37. -- 通俗点说就是设置规定时间打开,无论是否定位成功,到了时间都会自动关闭此应用,
  38. -- 和第二种的区别在于定位成功之后不会自动关闭,到时间之后才会自动关闭
  39. gnss=require("gnss")
  40. local function mode1_cb(tag)
  41. log.info("TAGmode1_cb+++++++++",tag)
  42. log.info("nmea", "rmc", json.encode(gnss.getRmc(2)))
  43. end
  44. local function mode2_cb(tag)
  45. log.info("TAGmode2_cb+++++++++",tag)
  46. log.info("nmea", "rmc", json.encode(gnss.getRmc(2)))
  47. end
  48. local function mode3_cb(tag)
  49. log.info("TAGmode3_cb+++++++++",tag)
  50. log.info("nmea", "rmc", json.encode(gnss.getRmc(2)))
  51. end
  52. local function gnss_fnc()
  53. local gnssotps={
  54. gnssmode=1, --1为卫星全定位,2为单北斗
  55. agps_enable=true, --是否使用AGPS,开启AGPS后定位速度更快,会访问服务器下载星历,星历时效性为北斗1小时,GPS4小时,默认下载星历的时间为1小时,即一小时内只会下载一次
  56. debug=true, --是否输出调试信息
  57. -- uart=2, --使用的串口,780EGH和8000默认串口2
  58. -- uartbaud=115200, --串口波特率,780EGH和8000默认115200
  59. -- bind=1, --绑定uart端口进行GNSS数据读取,是否设置串口转发,指定串口号
  60. -- rtc=false --定位成功后自动设置RTC true开启,flase关闭
  61. }
  62. --设置gnss参数
  63. gnss.setup(gnssotps)
  64. --开启gnss应用
  65. gnss.open(gnss.TIMER,{tag="MODE1",val=60,cb=mode1_cb})
  66. gnss.open(gnss.DEFAULT,{tag="MODE2",cb=mode2_cb})
  67. gnss.open(gnss.TIMERORSUC,{tag="MODE3",val=60,cb=mode3_cb})
  68. sys.wait(40000)
  69. log.info("关闭一个gnss应用,然后查看下所有应用的状态")
  70. --关闭一个gnss应用
  71. gnss.close(gnss.TIMER,{tag="MODE1"})
  72. --查询3个gnss应用状态
  73. log.info("gnss应用状态1",gnss.isActive(gnss.TIMER,{tag="MODE1"}))
  74. log.info("gnss应用状态2",gnss.isActive(gnss.DEFAULT,{tag="MODE2"}))
  75. log.info("gnss应用状态3",gnss.isActive(gnss.TIMERORSUC,{tag="MODE3"}))
  76. sys.wait(10000)
  77. --关闭所有gnss应用
  78. gnss.closeAll()
  79. --查询3个gnss应用状态
  80. log.info("gnss应用状态1",gnss.isActive(gnss.TIMER,{tag="MODE1"}))
  81. log.info("gnss应用状态2",gnss.isActive(gnss.DEFAULT,{tag="MODE2"}))
  82. log.info("gnss应用状态3",gnss.isActive(gnss.TIMERORSUC,{tag="MODE3"}))
  83. --查询最后一次定位结果
  84. local loc= gnss.getlastloc()
  85. if loc then
  86. log.info("lastloc", loc.lat,loc.lng)
  87. end
  88. end
  89. sys.taskInit(gnss_fnc)
  90. --GNSS定位状态的消息处理函数:
  91. local function gnss_state(event, ticks)
  92. -- event取值有
  93. -- FIXED:string类型 定位成功
  94. -- LOSE: string类型 定位丢失
  95. -- CLOSE: string类型 GNSS关闭,仅配合使用gnss.lua有效
  96. -- ticks number类型 是事件发生的时间,一般可以忽略
  97. log.info("gnss", "state", event)
  98. end
  99. sys.subscribe(gnss_state)
  100. ]]
  101. local gnss = {}
  102. --gnss开启标志,true表示开启状态,false或者nil表示关闭状态
  103. local openFlag
  104. --gnss定位标志,true表示,其余表示未定位
  105. local fixFlag=nil
  106. --串口配置
  107. local uart_baudrate = 115200
  108. local uart_id = 2
  109. --gnss 的串口线程是否在工作;
  110. local taskFlag=false
  111. local agpsFlag=false
  112. --保存经纬度到文件区
  113. function gnss.saveloc(lat, lng)
  114. if not lat or not lng then
  115. if libgnss.isFix() then
  116. local rmc = libgnss.getRmc(0)
  117. if rmc then
  118. lat, lng = rmc.lat, rmc.lng
  119. end
  120. end
  121. end
  122. if lat and lng then
  123. -- log.info("待保存的GPS位置", lat, lng)
  124. local locStr = string.format('{"lat":%.5f,"lng":%.5f}', lat, lng)
  125. -- log.info("gnss", "保存GPS位置", locStr)
  126. io.writeFile("/hxxtloc", locStr)
  127. end
  128. local now = os.time()
  129. io.writeFile("/hxxt_tm", tostring(now))
  130. -- log.info("now", now)
  131. end
  132. local tid
  133. sys.subscribe("GNSS_STATE", function(event)
  134. -- log.info("libagps","libagps is "..event)
  135. if event == "FIXED" then
  136. gnss.saveloc()
  137. tid=sys.timerLoopStart(gnss.saveloc,600000)
  138. elseif event == "LOSE" or event == "CLOSE" then
  139. -- log.info("libagps","libagps is close")
  140. sys.timerStop(tid)
  141. end
  142. end)
  143. --agps操作,联网访问服务器获取星历数据
  144. local function _agps()
  145. local lat, lng
  146. --此逻辑在agps定位成功之后,还会继续开启10s-15s,
  147. --原因是因为如果第一次冷启动之后,定位成功之后,
  148. --如果直接关闭gnss会导致gnss芯片的星历没有解析完毕,会影响下一次的定位为冷启动
  149. --如果对功耗有需求,需要定位快,可以每次都使用agps,不需要这句,直接屏蔽掉即可
  150. --代价是每次定位都会进行基站定位,
  151. -- gnss.open(gnss.TIMER,{tag="libagps",val=20})
  152. -- 判断星历时间和下载星历
  153. local now = os.time()
  154. local agps_time = tonumber(io.readFile("/hxxt_tm") or "0") or 0
  155. log.info("os.time",now)
  156. log.info("agps_time",agps_time)
  157. if now - agps_time > 3600 or io.fileSize("/hxxt.dat") < 1024 then
  158. local url = gnss.opts.url
  159. if not gnss.opts.url then
  160. if gnss.opts.gnssmode and 2 == gnss.opts.gnssmode then
  161. -- 单北斗
  162. url = "http://download.openluat.com/9501-xingli/HXXT_BDS_AGNSS_DATA.dat"
  163. else
  164. url = "http://download.openluat.com/9501-xingli/HXXT_GPS_BDS_AGNSS_DATA.dat"
  165. end
  166. end
  167. local code = http.request("GET", url, nil, nil, {dst="/hxxt.dat"}).wait()
  168. if code and code == 200 then
  169. log.info("gnss.opts", "下载星历成功", url)
  170. io.writeFile("/hxxt_tm", tostring(now))
  171. else
  172. log.info("gnss.opts", "下载星历失败", code)
  173. end
  174. else
  175. log.info("gnss.opts", "星历不需要更新", now - agps_time)
  176. end
  177. --进行基站定位,给到gnss芯片一个大概的位置
  178. if mobile then
  179. local lbsLoc2 = require("lbsLoc2")
  180. lat, lng = lbsLoc2.request(5000)
  181. -- local lat, lng, t = lbsLoc2.request(5000, "bs.openluat.com")
  182. -- log.info("lbsLoc2", lat, lng)
  183. if lat and lng then
  184. lat = tonumber(lat)
  185. lng = tonumber(lng)
  186. log.info("lbsLoc2", lat, lng)
  187. -- 转换单位
  188. local lat_dd,lat_mm = math.modf(lat)
  189. local lng_dd,lng_mm = math.modf(lng)
  190. lat = lat_dd * 100 + lat_mm * 60
  191. lng = lng_dd * 100 + lng_mm * 60
  192. end
  193. elseif wlan then
  194. -- wlan.scan()
  195. -- sys.waitUntil("WLAN_SCAN_DONE", 5000)
  196. end
  197. --获取基站定位失败则使用本地之前保存的位置
  198. if not lat then
  199. -- 获取最后的本地位置
  200. local locStr = io.readFile("/hxxtloc")
  201. if locStr then
  202. local jdata = json.decode(locStr)
  203. if jdata and jdata.lat then
  204. lat = jdata.lat
  205. lng = jdata.lng
  206. end
  207. end
  208. end
  209. local gps_uart_id = uart_id
  210. -- 写入星历
  211. local agps_data = io.readFile("/hxxt.dat")
  212. if agps_data and #agps_data > 1024 then
  213. log.info("gnss.opts", "写入星历数据", "长度", #agps_data)
  214. for offset=1,#agps_data,512 do
  215. log.info("gnss", "AGNSS", "write >>>", #agps_data:sub(offset, offset + 511))
  216. uart.write(gps_uart_id, agps_data:sub(offset, offset + 511))
  217. sys.wait(100) -- 等100ms反而更成功
  218. end
  219. -- uart.write(gps_uart_id, agps_data)
  220. else
  221. log.info("gnss.opts", "没有星历数据")
  222. return
  223. end
  224. -- "lat":23.4068813,"min":27,"valid":true,"day":27,"lng":113.2317505
  225. --如果没有经纬度的话,定位时间会变长,大概10-20s左右
  226. if not lat or not lng then
  227. -- lat, lng = 23.4068813, 113.2317505
  228. log.info("gnss.opts", "没有GPS坐标", lat, lng)
  229. return --暂时不写入参考位置
  230. else
  231. log.info("gnss.opts", "写入GPS坐标", lat, lng)
  232. end
  233. --写入时间
  234. local date = os.date("!*t")
  235. if date.year > 2023 then
  236. local str = string.format("$AIDTIME,%d,%d,%d,%d,%d,%d,000", date["year"], date["month"], date["day"],
  237. date["hour"], date["min"], date["sec"])
  238. log.info("gnss.opts", "参考时间", str)
  239. uart.write(gps_uart_id, str .. "\r\n")
  240. sys.wait(20)
  241. end
  242. -- 写入参考位置
  243. local str = string.format("$AIDPOS,%.7f,%s,%.7f,%s,1.0\r\n",
  244. lat > 0 and lat or (0 - lat), lat > 0 and 'N' or 'S',
  245. lng > 0 and lng or (0 - lng), lng > 0 and 'E' or 'W')
  246. log.info("gnss.opts", "写入AGPS参考位置", str)
  247. uart.write(gps_uart_id, str)
  248. -- 结束
  249. gnss.opts.agps_tm = now
  250. agpsFlag=true
  251. end
  252. --执行agps操作判断
  253. function gnss.agps()
  254. -- 如果不是强制写入AGPS信息, 而且是已经定位成功的状态,那就没必要了
  255. if libgnss.isFix() then return end
  256. -- 先判断一下时间
  257. while not socket.adapter() do
  258. log.warn("gnss_agps", "wait IP_READY")
  259. -- 在此处阻塞等待WIFI连接成功的消息"IP_READY"
  260. -- 或者等待30秒超时退出阻塞等待状态
  261. local result=sys.waitUntil("IP_READY", 30000)
  262. if result == false then
  263. log.warn("gnss_agps", "wait IP_READY timeout")
  264. return
  265. end
  266. end
  267. if not gnss.opts.agps_tm then
  268. socket.sntp()
  269. sys.waitUntil("NTP_UPDATE", 5000)
  270. end
  271. local now = os.time()
  272. local agps_time = tonumber(io.readFile("/hxxt_tm") or "0") or 0
  273. -- if ((not gnss.opts.agps_tm) and (now - agps_time > 300)) or now - agps_time > 3600 then
  274. if not gnss.opts.agps_tm or now - agps_time > 3600 then
  275. -- 执行AGPS
  276. log.info("gnss.opts", "开始执行AGPS")
  277. sys.taskInit(_agps)
  278. else
  279. log.info("gnss.opts", "暂不需要写入AGPS")
  280. end
  281. end
  282. function gnss.openres()
  283. return openFlag
  284. end
  285. --打开gnss,内部函数使用,不推荐给脚本层使用
  286. local function _open()
  287. if openFlag then return end
  288. libgnss.clear() -- 清空数据,兼初始化
  289. uart.setup(uart_id, uart_baudrate)
  290. -- pm.power(pm.GPS, false)
  291. pm.power(pm.GPS, true)
  292. if gnss.opts.gnssmode==1 then
  293. --默认全开启
  294. log.info("全卫星开启")
  295. elseif gnss.opts.gnssmode==2 then
  296. --默认开启单北斗
  297. sys.timerStart(function()
  298. uart.write(uart_id, "$CFGSYS,h10\r\n")
  299. end,200)
  300. log.info("单北斗开启")
  301. end
  302. if gnss.opts.debug==true then
  303. log.info("debug开启")
  304. libgnss.debug(true)
  305. elseif gnss.opts.debug==false then
  306. log.info("debug关闭")
  307. libgnss.debug(false)
  308. end
  309. if type(gnss.opts.bind)=="number" then
  310. log.info("绑定bind事件")
  311. libgnss.bind(uart_id,gnss.opts.bind)
  312. else
  313. libgnss.bind(uart_id)
  314. end
  315. if gnss.opts.rtc==true then
  316. log.info("rtc开启")
  317. libgnss.rtcAuto(true)
  318. elseif gnss.opts.rtc==false then
  319. log.info("rtc关闭")
  320. libgnss.rtcAuto(false)
  321. end
  322. if gnss.opts.agps_enable==true then
  323. log.info("agps开启")
  324. sys.taskInit(gnss.agps)
  325. end
  326. --设置输出VTG内容
  327. sys.timerStart(function()
  328. uart.write(uart_id,"$CFGMSG,0,5,1,1\r\n")
  329. end,800)
  330. --设置输出ZDA内容
  331. sys.timerStart(function()
  332. uart.write(uart_id,"$CFGMSG,0,6,1,1\r\n")
  333. end,900)
  334. openFlag = true
  335. sys.publish("GNSS_STATE","OPEN")
  336. log.info("gnss._open")
  337. end
  338. --关闭gnss,内部函数使用,不推荐给脚本层使用
  339. local function _close()
  340. if not openFlag then return end
  341. gnss.saveloc()
  342. pm.power(pm.GPS, false)
  343. uart.close(uart_id)
  344. openFlag = false
  345. fixFlag = false
  346. sys.publish("GNSS_STATE","CLOSE",fixFlag)
  347. log.info("gnss._close")
  348. libgnss.clear()
  349. end
  350. --- gnss应用模式1.
  351. --
  352. -- 打开gnss后,gnss定位成功时,如果有回调函数,会调用回调函数
  353. --
  354. -- 使用此应用模式调用gnss.open打开的“gnss应用”,必须主动调用gnss.close或者gnss.closeAll才能关闭此“gnss应用”,主动关闭时,即使有回调函数,也不会调用回调函数
  355. gnss.DEFAULT = 1
  356. --- gnss应用模式2.
  357. --
  358. -- 打开gnss后,如果在gnss开启最大时长到达时,没有定位成功,如果有回调函数,会调用回调函数,然后自动关闭此“gnss应用”
  359. --
  360. -- 打开gnss后,如果在gnss开启最大时长内,定位成功,如果有回调函数,会调用回调函数,然后自动关闭此“gnss应用”
  361. --
  362. -- 打开gnss后,在自动关闭此“gnss应用”前,可以调用gnss.close或者gnss.closeAll主动关闭此“gnss应用”,主动关闭时,即使有回调函数,也不会调用回调函数
  363. gnss.TIMERORSUC = 2
  364. --- gnss应用模式3.
  365. --
  366. -- 打开gnss后,在gnss开启最大时长时间到达时,无论是否定位成功,如果有回调函数,会调用回调函数,然后自动关闭此“gnss应用”
  367. --
  368. -- 打开gnss后,在自动关闭此“gnss应用”前,可以调用gnss.close或者gnss.closeAll主动关闭此“gnss应用”,主动关闭时,即使有回调函数,也不会调用回调函数
  369. gnss.TIMER = 3
  370. --“gnss应用”表
  371. local tList = {}
  372. --[[
  373. 函数名:delItem
  374. 功能 :从“gnss应用”表中删除一项“gnss应用”,并不是真正的删除,只是设置一个无效标志
  375. 参数 :
  376. mode:gnss应用模式
  377. para:
  378. para.tag:“gnss应用”标记
  379. para.val:gnss开启最大时长
  380. para.cb:回调函数
  381. 返回值:无
  382. ]]
  383. local function delItem(mode,para)
  384. for i=1,#tList do
  385. --标志有效 并且 gnss应用模式相同 并且 “gnss应用”标记相同
  386. if tList[i].flag and tList[i].mode==mode and tList[i].para.tag==para.tag then
  387. --设置无效标志
  388. tList[i].flag,tList[i].delay = false
  389. break
  390. end
  391. end
  392. end
  393. --[[
  394. 函数名:addItem
  395. 功能 :新增一项“gnss应用”到“gnss应用”表
  396. 参数 :
  397. mode:gnss应用模式
  398. para:
  399. para.tag:“gnss应用”标记
  400. para.val:gnss开启最大时长
  401. para.cb:回调函数
  402. 返回值:无
  403. ]]
  404. local function addItem(mode,para)
  405. --删除相同的“gnss应用”
  406. delItem(mode,para)
  407. local item,i,fnd = {flag=true, mode=mode, para=para}
  408. --如果是TIMERORSUC或者TIMER模式,初始化gnss工作剩余时间
  409. if mode==gnss.TIMERORSUC or mode==gnss.TIMER then item.para.remain = para.val end
  410. for i=1,#tList do
  411. --如果存在无效的“gnss应用”项,直接使用此位置
  412. if not tList[i].flag then
  413. tList[i] = item
  414. fnd = true
  415. break
  416. end
  417. end
  418. --新增一项
  419. if not fnd then table.insert(tList,item) end
  420. end
  421. --退出GNSS定时器
  422. local function existTimerItem()
  423. for i=1,#tList do
  424. if tList[i].flag and (tList[i].mode==gnss.TIMERORSUC or tList[i].mode==gnss.TIMER or tList[i].para.delay) then return true end
  425. end
  426. end
  427. --GNSS定时器
  428. local function timerFnc()
  429. for i=1,#tList do
  430. if tList[i].flag then
  431. log.info("gnss.timerFnc@"..i,tList[i].mode,tList[i].para.tag,tList[i].para.val,tList[i].para.remain,tList[i].para.delay)
  432. local rmn,dly,md,cb = tList[i].para.remain,tList[i].para.delay,tList[i].mode,tList[i].para.cb
  433. if rmn and rmn>0 then
  434. tList[i].para.remain = rmn-1
  435. end
  436. if dly and dly>0 then
  437. tList[i].para.delay = dly-1
  438. end
  439. rmn = tList[i].para.remain
  440. if libgnss.isFix() and md==gnss.TIMER and rmn==0 and not tList[i].para.delay then
  441. tList[i].para.delay = 1
  442. end
  443. dly = tList[i].para.delay
  444. if libgnss.isFix() then
  445. if dly and dly==0 then
  446. if cb then cb(tList[i].para.tag) end
  447. if md == gnss.DEFAULT then
  448. tList[i].para.delay = nil
  449. else
  450. gnss.close(md,tList[i].para)
  451. end
  452. end
  453. else
  454. if rmn and rmn == 0 then
  455. if cb then cb(tList[i].para.tag) end
  456. gnss.close(md,tList[i].para)
  457. end
  458. end
  459. end
  460. end
  461. if existTimerItem() then sys.timerStart(timerFnc,1000) end
  462. end
  463. --[[
  464. 函数名:statInd
  465. 功能 :处理gnss定位成功的消息
  466. 参数 :
  467. evt:gnss消息类型
  468. 返回值:无
  469. ]]
  470. local function statInd(evt)
  471. --定位成功的消息
  472. if evt == "FIXED" then
  473. fixFlag = true
  474. for i=1,#tList do
  475. log.info("gnss.statInd@"..i,tList[i].flag,tList[i].mode,tList[i].para.tag,tList[i].para.val,tList[i].para.remain,tList[i].para.delay,tList[i].para.cb)
  476. if tList[i].flag then
  477. if tList[i].mode ~= gnss.TIMER then
  478. tList[i].para.delay = 1
  479. if tList[i].mode == gnss.DEFAULT then
  480. if existTimerItem() then sys.timerStart(timerFnc,1000) end
  481. end
  482. end
  483. end
  484. end
  485. end
  486. end
  487. --[[
  488. 设置gnss定位参数
  489. @api gnss.setup(opts)
  490. @table opts gnss定位参数,可选值gnssmode:定位卫星模式,1为卫星全定位,2为单北斗,默认为卫星全定位
  491. agps_enable:是否启用AGPS,true为启用,false为不启用,默认为false
  492. debug:是否输出调试信息到luatools,true为输出,false为不输出,默认为false
  493. uart:GNSS串口配置,780EGH和8000默认为uart2,可不填
  494. uartbaud:GNSS串口波特率,780EGH和8000默认为115200,可不填
  495. bind:绑定uart端口进行GNSS数据读取,是否设置串口转发,指定串口号,不需要转发可不填
  496. rtc:定位成功后自动设置RTC true开启,flase关闭,默认为flase,不需要可不填
  497. @return nil
  498. @usage
  499. local gnssotps={
  500. gnssmode=1, --1为卫星全定位,2为单北斗
  501. agps_enable=true, --是否使用AGPS,开启AGPS后定位速度更快,会访问服务器下载星历,星历时效性为北斗1小时,GPS4小时,默认下载星历的时间为1小时,即一小时内只会下载一次
  502. debug=true, --是否输出调试信息
  503. -- uart=2, --使用的串口,780EGH和8000默认串口2
  504. -- uartbaud=115200, --串口波特率,780EGH和8000默认115200
  505. -- bind=1, --绑定uart端口进行GNSS数据读取,是否设置串口转发,指定串口号
  506. -- rtc=false --定位成功后自动设置RTC true开启,flase关闭
  507. }
  508. gnss.setup(gnssotps)
  509. ]]
  510. function gnss.setup(opts)
  511. gnss.opts=opts
  512. if hmeta.model():find("780EGH") or hmeta.model():find("8000") then
  513. uart_id=2
  514. uart_baudrate=115200
  515. else
  516. if gnss.opts.uart_id then
  517. uart_id=gnss.opts.uart_id
  518. else
  519. uart_id=2
  520. end
  521. if gnss.opts.uartbaud then
  522. uart_baudrate=gnss.opts.uartbaud
  523. else
  524. uart_baudrate=115200
  525. end
  526. end
  527. end
  528. --[[
  529. 打开一个“gnss应用”
  530. @api gnss.open(mode,para)
  531. @number mode gnss应用模式,支持gnss.DEFAULT,gnss.TIMERORSUC,gnss.TIMER三种
  532. @param para table类型,gnss应用参数,para.tag:string类型,gnss应用标记,para.val:number类型,gnss应用开启最大时长,单位:秒,mode参数为gnss.TIMERORSUC或者gnss.TIMER时,此值才有意义;使用close接口时,不需要传入此参数,para.cb:gnss应用结束时的回调函数,回调函数的调用形式为para.cb(para.tag);使用close接口时,不需要传入此参数
  533. @return nil
  534. @usage
  535. -- “gnss应用”:指的是使用gnss功能的一个应用
  536. -- 例如,假设有如下3种需求,要打开gnss,则一共有3个“gnss应用”:
  537. -- “gnss应用1”:每隔1分钟打开一次gnss
  538. -- “gnss应用2”:设备发生震动时打开gnss
  539. -- “gnss应用3”:收到一条特殊短信时打开gnss
  540. -- 只有所有“gnss应用”都关闭了,才会去真正关闭gnss
  541. -- 每个“gnss应用”打开或者关闭gnss时,最多有4个参数,其中 gnss应用模式和gnss应用标记 共同决定了一个唯一的“gnss应用”:
  542. -- 1、gnss应用模式(必选)
  543. -- 2、gnss应用标记(必选)
  544. -- 3、gnss开启最大时长[可选]
  545. -- 4、回调函数[可选]
  546. -- 例如gnss.open(gnss.TIMER,{tag="MODE1",val=60,cb=mode1_cb})
  547. -- gnss.TIMER为gnss应用模式,"MODE1"为gnss应用标记,60秒为gnss开启最大时长,mode1_cb为回调函数
  548. gnss.open(gnss.TIMER,{tag="MODE1",val=60,cb=mode1_cb})
  549. gnss.open(gnss.DEFAULT,{tag="MODE2",cb=mode2_cb})
  550. gnss.open(gnss.TIMERORSUC,{tag="MODE3",val=60,cb=mode3_cb})
  551. ]]
  552. function gnss.open(mode,para)
  553. assert((para and type(para) == "table" and para.tag and type(para.tag) == "string"),"gnss.open para invalid")
  554. log.info("gnss.open",mode,para.tag,para.val,para.cb)
  555. --如果gnss定位成功
  556. if libgnss.isFix() then
  557. if mode~=gnss.TIMER then
  558. --执行回调函数
  559. if para.cb then para.cb(para.tag) end
  560. if mode==gnss.TIMERORSUC then return end
  561. end
  562. end
  563. addItem(mode,para)
  564. --真正去打开gnss
  565. _open()
  566. --启动1秒的定时器
  567. if existTimerItem() and not sys.timerIsActive(timerFnc) then
  568. sys.timerStart(timerFnc,1000)
  569. end
  570. end
  571. --[[
  572. 关闭一个“gnss应用”,只是从逻辑上关闭一个gnss应用,并不一定真正关闭gnss,是有所有的gnss应用都处于关闭状态,才会去真正关闭gnss
  573. @api gnss.close()
  574. @number mode gnss应用模式,支持gnss.DEFAULT,gnss.TIMERORSUC,gnss.TIMER三种
  575. @param para table类型,gnss应用参数,para.tag:string类型,gnss应用标记,para.val:number类型,gnss应用开启最大时长,单位:秒,mode参数为gnss.TIMERORSUC或者gnss.TIMER时,此值才有意义;使用close接口时,不需要传入此参数,para.cb:gnss应用结束时的回调函数,回调函数的调用形式为para.cb(para.tag);使用close接口时,不需要传入此参数
  576. @return nil
  577. @usage
  578. gnss.open(gnss.TIMER,{tag="MODE1",val=60,cb=mode1_cb})
  579. gnss.close(gnss.TIMER,{tag="MODE1"})
  580. ]]
  581. function gnss.close(mode,para)
  582. assert((para and type(para)=="table" and para.tag and type(para.tag)=="string"),"gnss.close para invalid")
  583. log.info("gnss.close",mode,para.tag,para.val,para.cb)
  584. --删除此“gnss应用”
  585. delItem(mode,para)
  586. local valid,i
  587. for i=1,#tList do
  588. if tList[i].flag then
  589. valid = true
  590. end
  591. end
  592. --如果没有一个“gnss应用”有效,则关闭gnss
  593. if not valid then _close() end
  594. end
  595. --[[
  596. 关闭所有“gnss应用”
  597. @api gnss.closeAll()
  598. @return nil
  599. @usage
  600. gnss.open(gnss.TIMER,{tag="MODE1",val=60,cb=mode1_cb})
  601. gnss.open(gnss.DEFAULT,{tag="MODE2",cb=mode2_cb})
  602. gnss.open(gnss.TIMERORSUC,{tag="MODE3",val=60,cb=mode3_cb})
  603. gnss.closeAll()
  604. ]]
  605. function gnss.closeAll()
  606. for i=1,#tList do
  607. if tList[i].flag and tList[i].para.cb then tList[i].para.cb(tList[i].para.tag) end
  608. gnss.close(tList[i].mode,tList[i].para)
  609. end
  610. end
  611. --[[
  612. 判断一个“gnss应用”是否处于激活状态
  613. @api gnss.isActive(mode,para)
  614. @number mode gnss应用模式,支持gnss.DEFAULT,gnss.TIMERORSUC,gnss.TIMER三种
  615. @param para table类型,gnss应用参数,para.tag:string类型,gnss应用标记,para.val:number类型,gnss应用开启最大时长,单位:秒,mode参数为gnss.TIMERORSUC或者gnss.TIMER时,此值才有意义;使用close接口时,不需要传入此参数,para.cb:gnss应用结束时的回调函数,回调函数的调用形式为para.cb(para.tag);使用close接口时,不需要传入此参数,gnss应用模式和gnss应用标记唯一确定一个“gnss应用”,调用本接口查询状态时,mode和para.tag要和gnss.open打开一个“gnss应用”时传入的mode和para.tag保持一致
  616. @return bool result,处于激活状态返回true,否则返回nil
  617. @usage
  618. gnss.open(gnss.TIMER,{tag="MODE1",val=60,cb=mode1_cb})
  619. gnss.open(gnss.DEFAULT,{tag="MODE2",cb=mode2_cb})
  620. gnss.open(gnss.TIMERORSUC,{tag="MODE3",val=60,cb=mode3_cb})
  621. log.info("gnss应用状态1",gnss.isActive(gnss.TIMER,{tag="MODE1"}))
  622. log.info("gnss应用状态2",gnss.isActive(gnss.DEFAULT,{tag="MODE2"}))
  623. log.info("gnss应用状态3",gnss.isActive(gnss.TIMERORSUC,{tag="MODE3"}))
  624. ]]
  625. function gnss.isActive(mode,para)
  626. assert((para and type(para)=="table" and para.tag and type(para.tag)=="string"),"gnss.isActive para invalid")
  627. for i=1,#tList do
  628. if tList[i].flag and tList[i].mode==mode and tList[i].para.tag==para.tag then return true end
  629. end
  630. end
  631. sys.subscribe("GNSS_STATE",statInd)
  632. --[[
  633. 当前是否已经定位成功
  634. @api gnss.isFix()
  635. @return boolean true/false,定位成功返回true,否则返回false
  636. @usage
  637. log.info("nmea", "isFix", gnss.isFix())
  638. ]]
  639. function gnss.isFix()
  640. return libgnss.isFix()
  641. end
  642. --[[
  643. 获取number类型的位置和速度信息
  644. @api gnss.getIntLocation(speed_type)
  645. @number 速度单位,默认是m/h,
  646. 0 - m/h 米/小时, 默认值, 整型
  647. 1 - m/s 米/秒, 浮点数
  648. 2 - km/h 千米/小时, 浮点数
  649. 3 - kn/h 英里/小时, 浮点数
  650. @return number lat数据, 格式为 DDDDDDDDD,示例:343482649,DDDDDDDDD格式是由DD.DDDDDDD*10000000转换而来,目的是作为整数,方便某些场景使用
  651. @return number lng数据, 格式为 DDDDDDDDD,示例:1135039700,DDDDDDDDD格式是由DD.DDDDDDD*10000000转换而来,目的是作为整数,方便某些场景使用
  652. @return number speed数据, 单位根据speed_type决定,m/h, m/s, km/h, kn/h
  653. @usage
  654. --DDDDDDDDD格式是由DD.DDDDDDD*10000000转换而来,目的是作为整数,方便某些场景使用,示例:343482649对应的原始值是34.3482649
  655. -- 该数据是通过RMC转换的,如果想获取更详细的可以用gnss.getRmc(1)
  656. -- speed数据默认 米/小时,返回值例如:343482649 1135039700 390m/h
  657. log.info("nmea", "loc", gnss.getIntLocation())
  658. -- speed数据米/秒,返回值例如:343482649 1135039700 0.1085478m/s
  659. log.info("nmea", "loc", gnss.getIntLocation(1))
  660. -- speed数据千米/小时,返回值例如:343482649 1135039700 0.3907720km/h
  661. log.info("nmea", "loc", gnss.getIntLocation(2))
  662. -- speed数据英里/小时,返回值例如:343482649 1135039700 0.2110000kn/h
  663. log.info("nmea", "loc", gnss.getIntLocation(3))
  664. ]]
  665. function gnss.getIntLocation(speed_type)
  666. return libgnss.getIntLocation(speed_type)
  667. end
  668. --[[
  669. 获取RMC的信息,经纬度,时间,速度,航向,定位是否有效,磁偏角
  670. @api gnss.getRmc(lnglat_mode)
  671. @number 经纬度数据的格式, 0-ddmm.mmmmm格式, 1-DDDDDDDDD格式, 2-DD.DDDDDDD格式, 3-原始RMC字符串
  672. @return table/string rmc数据
  673. @usage
  674. -- 解析nmea
  675. log.info("nmea", "rmc", json.encode(gnss.getRmc(2)))
  676. -- 实例输出,获取值的解释
  677. -- {
  678. -- "course":344.9920044, // 地面航向,单位为度,从北向起顺时针计算
  679. -- "valid":true, // true定位成功,false定位丢失
  680. -- "lat":34.5804405, // 纬度, 正数为北纬, 负数为南纬
  681. -- "lng":113.8399506, // 经度, 正数为东经, 负数为西经
  682. -- "variation":0, // 磁偏角,固定为0
  683. -- "speed":0.2110000 // 地面速度, 单位为"节"
  684. -- "year":2023, // 年份
  685. -- "month":1, // 月份, 1-12
  686. -- "day":5, // 月份天, 1-31
  687. -- "hour":7, // 小时,0-23
  688. -- "min":23, // 分钟,0-59
  689. -- "sec":20, // 秒,0-59
  690. -- }
  691. --模式0示例:
  692. --json.encode默认输出"7f"格式保留7位小数,可以根据自己需要的格式调整小数位,本示例保留5位小数
  693. log.info("nmea", "rmc0", json.encode(gnss.getRmc(0),"5f"))
  694. {"variation":0,"lat":3434.82666,"min":54,"valid":true,"day":17,"lng":11350.39746,"speed":0.21100,"year":2025,"month":7,"sec":30,"hour":11,"course":344.99200}
  695. --模式1示例:
  696. --DDDDDDDDD格式是由DD.DDDDDDD*10000000转换而来,目的是作为整数,方便某些场景使用
  697. log.info("nmea", "rmc1", json.encode(gnss.getRmc(1)))
  698. {"variation":0,"lat":345804414,"min":54,"valid":true,"day":17,"lng":1138399500,"speed":0.2110000,"year":2025,"month":7,"sec":30,"hour":11,"course":344.9920044}
  699. --模式2示例:
  700. --json.encode默认输出"7f"格式保留7位小数,可以根据自己需要的格式调整小数位
  701. log.info("nmea", "rmc2", json.encode(gnss.getRmc(2)))
  702. {"variation":0,"lat":34.5804405,"min":54,"valid":true,"day":17,"lng":113.8399506,"speed":0.2110000,"year":2025,"month":7,"sec":30,"hour":11,"course":344.9920044}
  703. --模式3示例:
  704. log.info("nmea", "rmc3", gnss.getRmc(3))
  705. $GNRMC,115430.000,A,3434.82649,N,11350.39700,E,0.211,344.992,170725,,,A,S*02\r
  706. ]]
  707. function gnss.getRmc(lnglat_mode)
  708. return libgnss.getRmc(lnglat_mode)
  709. end
  710. --[[
  711. 获取原始GSV信息
  712. @api gnss.getGsv()
  713. @return table 原始GSV数据
  714. @usage
  715. -- 解析nmea
  716. log.info("nmea", "gsv", json.encode(gnss.getGsv()))
  717. -- 实例输出
  718. -- {
  719. -- "total_sats":24, // 总可见卫星数量
  720. -- "sats":[
  721. -- {
  722. -- "snr":27, // 信噪比
  723. -- "azimuth":278, // 方向角
  724. -- "elevation":59, // 仰角
  725. -- "tp":0, // 0 - GPS, 1 - BD, 2 - GLONASS, 3 - Galileo, 4 - QZSS
  726. -- "nr":4 // 卫星编号
  727. -- },
  728. -- // 这里忽略了22个卫星的信息
  729. -- {
  730. -- "snr":0,
  731. -- "azimuth":107,
  732. -- "elevation":19,
  733. -- "tp":1,
  734. -- "nr":31
  735. -- }
  736. -- ]
  737. -- }
  738. ]]
  739. function gnss.getGsv()
  740. return libgnss.getGsv()
  741. end
  742. --[[
  743. 获取原始GSA信息
  744. @api gnss.getGsa(data_mode)
  745. @number 模式,默认为0 -所有卫星系统全部输出在一起,1 - 每个卫星系统单独分开输出
  746. @return table 原始GSA数据
  747. @usage
  748. -- 获取
  749. log.info("nmea", "gsa", json.encode(gnss.getGsa()))
  750. -- 示例数据(模式0, 也就是默认模式)
  751. --sysid:1为GPS,4为北斗,2为GLONASS,3为Galileo
  752. {"pdop":1.1770000, 垂直精度因子,0.00 - 99.99,不定位时值为 99.99
  753. "sats":[15,13,5,18,23,20,24,30,24,13,33,38,8,14,28,41,6,39,25,16,32,27], // 正在使用的卫星编号
  754. "vdop":1.0160000, 垂直精度因子,0.00 - 99.99,不定位时值为 99.99
  755. "hdop":0.5940000, // 位置精度因子,0.00 - 99.99,不定位时值为 99.99
  756. "sysid":1, // 卫星系统编号1为GPS,4为北斗,2为GLONASS,3为Galileo
  757. "fix_type":3 // 定位模式, 1-未定位, 2-2D定位, 3-3D定位
  758. }
  759. --模式1
  760. log.info("nmea", "gsa", json.encode(gnss.getGsa()))
  761. [{"pdop":1.1770000,"sats":[15,13,5,18,23,20,24],"vdop":1.0160000,"hdop":0.5940000,"sysid":1,"fix_type":3},
  762. {"pdop":1.1770000,"sats":[30,24,13,33,38,8,14,28,41,6,39,25],"vdop":1.0160000,"hdop":0.5940000,"sysid":4,"fix_type":3},
  763. {"pdop":1.1770000,"sats":[16,32,27],"vdop":1.0160000,"hdop":0.5940000,"sysid":4,"fix_type":3},
  764. {"pdop":1.1770000,"sats":{},"vdop":1.0160000,"hdop":0.5940000,"sysid":2,"fix_type":3},
  765. {"pdop":1.1770000,"sats":{},"vdop":1.0160000,"hdop":0.5940000,"sysid":3,"fix_type":3}]
  766. ]]
  767. function gnss.getGsa(data_mode)
  768. return libgnss.getGsa(data_mode)
  769. end
  770. --[[
  771. 获取VTG速度信息
  772. @api gnss.getVtg(data_mode)
  773. @number 可选, 3-原始字符串, 不传或者传其他值, 则返回浮点值
  774. @return table/string 原始VTG数据
  775. @usage
  776. -- 解析nmea
  777. log.info("nmea", "vtg", json.encode(gnss.getVtg()))
  778. -- 示例
  779. {
  780. "speed_knots":0, // 速度, 英里/小时
  781. "true_track_degrees":0, // 真北方向角
  782. "magnetic_track_degrees":0, // 磁北方向角
  783. "speed_kph":0 // 速度, 千米/小时
  784. }
  785. --模式3
  786. log.info("nmea", "vtg", gnss.getVtg(3))
  787. -- 返回值:$GNVTG,0.000,T,,M,0.000,N,0.000,K,A*13\r
  788. -- 提醒: 在速度<5km/h时, 不会返回方向角
  789. ]]
  790. function gnss.getVtg(data_mode)
  791. return libgnss.getVtg(data_mode)
  792. end
  793. --获取原始ZDA时间和日期信息
  794. --[[
  795. 获取原始ZDA时间和日期信息
  796. @api gnss.getZda()
  797. @return table 原始zda数据
  798. @usage
  799. log.info("nmea", "zda", json.encode(gnss.getZda()))
  800. -- 实例输出
  801. -- {
  802. -- "minute_offset":0, // 本地时区的分钟, 一般固定输出0
  803. -- "hour_offset":0, // 本地时区的小时, 一般固定输出0
  804. -- "year":2023 // UTC 年,四位数字
  805. -- "month":1, // UTC 月,两位,01 ~ 12
  806. -- "day":5, // UTC 日,两位数字,01 ~ 31
  807. -- "hour":7, // 小时
  808. -- "min":50, // 分
  809. -- "sec":14, // 秒
  810. -- }
  811. ]]
  812. function gnss.getZda()
  813. return libgnss.getZda()
  814. end
  815. --[[
  816. 获取GGA数据
  817. @api gnss.getGga(lnglat_mode)
  818. @number 经纬度数据的格式, 0-ddmm.mmmmm格式, 1-DDDDDDDDD格式, 2-DD.DDDDDDD格式, 3-原始GGA字符串
  819. @return table GGA数据, 若如不存在会返回nil
  820. @usage
  821. local gga = gnss.getGga(2)
  822. log.info("GGA", json.encode(gga, "11g"))
  823. --实例输出,获取值的解释:
  824. -- {
  825. -- "dgps_age":0, // 差分校正时延,单位为秒
  826. -- "fix_quality":1, // 定位状态标识 0 - 无效,1 - 单点定位,2 - 差分定位
  827. -- "satellites_tracked":14, // 参与定位的卫星数量
  828. -- "altitude":0.255, // 海平面分离度, 或者成为海拔, 单位是米,
  829. -- "hdop":0.0335, // 水平精度因子,0.00 - 99.99,不定位时值为 99.99
  830. -- "longitude":113.231, // 经度, 正数为东经, 负数为西经
  831. -- "latitude":23.4067, // 纬度, 正数为北纬, 负数为南纬
  832. -- "height":0 // 椭球高,固定输出 1 位小数
  833. -- }
  834. 模式0示例:
  835. json.encode默认输出"7f"格式保留7位小数,可以根据自己需要的格式调整小数位,本示例保留5位小数
  836. local gga = gnss.getGga(0)
  837. if gga then
  838. log.info("GGA0", json.encode(gga, "5f"))
  839. end
  840. {"longitude":11419.19531,"dgps_age":0,"altitude":86.40000,"hdop":0.59400,"height":-13.70000,"fix_quality":1,"satellites_tracked":22,"latitude":3447.86914}
  841. 模式1示例:
  842. DDDDDDDDD格式是由DD.DDDDDDD*10000000转换而来,目的是作为整数,方便某些场景使用
  843. local gga1 = gnss.getGga(1)
  844. if gga1 then
  845. log.info("GGA1", json.encode(gga1))
  846. end
  847. {"longitude":1143199103,"dgps_age":0,"altitude":86.4000015,"hdop":0.5940000,"height":-13.6999998,"fix_quality":1,"satellites_tracked":22,"latitude":347978178}
  848. 模式2示例:
  849. json.encode默认输出"7f"格式保留7位小数,可以根据自己需要的格式调整小数位
  850. local gga2 = gnss.getGga(2)
  851. if gga2 then
  852. log.info("GGA2", json.encode(gga2))
  853. end
  854. {"longitude":114.3199081,"dgps_age":0,"altitude":86.4000015,"hdop":0.5940000,"height":-13.6999998,"fix_quality":1,"satellites_tracked":22,"latitude":34.7978172}
  855. 模式3示例:
  856. local gga3 = gnss.getGga(3)
  857. if gga3 then
  858. log.info("GGA3", gga3)
  859. end
  860. $GNGGA,131241.000,3434.81372,N,11350.39930,E,1,05,4.924,165.5,M,-15.2,M,,*6D\r
  861. ]]
  862. function gnss.getGga(lnglat_mode)
  863. return libgnss.getGga(lnglat_mode)
  864. end
  865. --[[
  866. 获取GLL数据
  867. @api gnss.getGll(data_mode)
  868. @number 经纬度数据的格式, 0-ddmm.mmmmm格式, 1-DDDDDDDDD格式, 2-DD.DDDDDDD格式
  869. @return table GLL数据, 若如不存在会返回nil
  870. @usage
  871. local gll = gnss.getGll(2)
  872. if gll then
  873. log.info("GLL", json.encode(gll, "11g"))
  874. end
  875. -- 实例数据,获取值的解释:
  876. -- {
  877. -- "status":"A", // 定位状态, A有效, B无效
  878. -- "mode":"A", // 定位模式, V无效, A单点解, D差分解
  879. -- "sec":20, // 秒, UTC时间为准
  880. -- "min":23, // 分钟, UTC时间为准
  881. -- "hour":7, // 小时, UTC时间为准
  882. -- "longitude":113.231, // 经度, 正数为东经, 负数为西经
  883. -- "latitude":23.4067, // 纬度, 正数为北纬, 负数为南纬
  884. -- "us":0 // 微妙数, 通常为0
  885. -- }
  886. --模式0示例:
  887. --json.encode默认输出"7f"格式保留7位小数,可以根据自己需要的格式调整小数位,本示例保留5位小数
  888. local gll = gnss.getGll(0)
  889. if gll then
  890. log.info("GLL0", json.encode(gll, "5f"))
  891. end
  892. {"longitude":11419.19531,"sec":14,"min":32,"mode":"A","hour":6,"us":0,"status":"A","latitude":3447.86914}
  893. --模式1示例:
  894. --DDDDDDDDD格式是由DD.DDDDDDD*10000000转换而来,目的是作为整数,方便某些场景使用
  895. local gll1 = gnss.getGll(1)
  896. if gll1 then
  897. log.info("GLL1", json.encode(gll1))
  898. end
  899. {"longitude":1143199103,"sec":14,"min":32,"mode":"A","hour":6,"us":0,"status":"A","latitude":347978178}
  900. 模式2示例:
  901. --json.encode默认输出"7f"格式保留7位小数,可以根据自己需要的格式调整小数位
  902. local gll2 = gnss.getGll(2)
  903. if gll2 then
  904. log.info("GLL2", json.encode(gll2))
  905. end
  906. {"longitude":114.3199081,"sec":14,"min":32,"mode":"A","hour":6,"us":0,"status":"A","latitude":34.7978172}
  907. ]]
  908. function gnss.getGll(data_mode)
  909. return libgnss.getGll(data_mode)
  910. end
  911. --[[
  912. 获取最后的经纬度数据
  913. @api gnss.getlastloc()
  914. @return table 经纬度数据,格式:ddmm.mmmmm0000,返回nil表示没有数据,此数据在定位成功,关闭gps时,会自动保存到文件系统中,定位成功之后每10分钟如果还处于定位成功状态会更新
  915. @usage
  916. local loc= gnss.getlastloc()
  917. if loc then
  918. log.info("lastloc", loc.lat,loc.lng)
  919. end
  920. 输出示例:
  921. 3434.7937000000 11350.386720000
  922. ]]
  923. function gnss.getlastloc()
  924. local locStr = io.readFile("/hxxtloc")
  925. if locStr then
  926. local jdata = json.decode(locStr)
  927. return jdata
  928. end
  929. end
  930. return gnss