gpsv2.lua 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556
  1. --- 模块功能:GPS模块管理
  2. -- @module gpsv2
  3. -- @author openLuat
  4. -- @license MIT
  5. -- @copyright openLuat
  6. -- @release 2018.08.28
  7. require "pm"
  8. require "httpv2"
  9. require "utils"
  10. require "lbsLoc"
  11. module(..., package.seeall)
  12. -- 浮点支持
  13. local float = rtos.get_version():upper():find("FLOAT")
  14. -- GPS任务线程ID
  15. local GPS_CO
  16. --串口配置
  17. local uartID, uartBaudrate = 2, 9600
  18. -- 星历的保存地址
  19. local GPD_FILE = "/ephdat.bin"
  20. -- 下载超时设置单位分钟
  21. local timeout = 5 * 60000
  22. -- 设置星历和基站定位的循环定时器时间
  23. local EPH_UPDATE_INTERVAL = 4 * 3600
  24. -- 星历写入标记
  25. local ephFlag = false
  26. --GPS开启标志,true表示开启状态,false或者nil表示关闭状态
  27. local openFlag
  28. --GPS定位标志,true表示,其余表示未定位,hdop 水平精度
  29. local fixFlag, hdop = false, "0"
  30. -- 经纬度类型和数据
  31. local latitudeType, latitude, longitudeType, longitude = "N", "", "E", ""
  32. -- 海拔,速度,时速,方向角
  33. local altitude, speed, kmHour, azimuth = "0", "0", "0", "0"
  34. -- 参与定位的卫星个数,GPS和北斗可见卫星个数
  35. local usedSateCnt, viewedGpsSateCnt, viewedBdSateCnt = "0", "0", "0"
  36. -- 可用卫星号,UTC时间
  37. local SateSn, UtcTime, utcStamp = {}, {}, 0
  38. -- 大地高,度分经度,度分纬度
  39. local Sep, Ggalng, Ggalat
  40. -- GPS和北斗GSV解析保存的表
  41. local gpgsvTab, bdgsvTab = {}, {}
  42. -- GPGSV解析后的CNO信息
  43. local gsvCnoTab = {}
  44. -- 基站定位坐标
  45. local lbs_lat, lbs_lng
  46. -- 日志开关
  47. local isLog = true
  48. --解析GPS模块返回的信息
  49. local function parseNmea(s)
  50. if not s or s == "" then return end
  51. if isLog then log.warn("定位模块上报的信息:", s) end
  52. local lat, lng, spd, cog, gpsFind, gpsTime, gpsDate, locSateCnt, hdp, latTyp, lngTyp, altd
  53. if s:match("GGA") then
  54. lat, latTyp, lng, lngTyp, gpsFind, locSateCnt, hdp, altd, sep = s:match("GGA,%d+%.%d+,(%d+%.%d+),([NS]),(%d+%.%d+),([EW]),(%d),(%d+),([%d%.]*),(.*),M,(.*),M")
  55. if (gpsFind == "1" or gpsFind == "2" or gpsFind == "4") and altd then
  56. altitude = altd
  57. usedSateCnt = locSateCnt
  58. Sep = sep
  59. hdop = hdp
  60. end
  61. Ggalng, Ggalat = (lngTyp == "W" and "-" or "") .. lng, (latTyp == "S" and "-" or "") .. lat
  62. latitudeType, longitudeType, latitude, longitude = latTyp, lngTyp, lat, lng
  63. elseif s:match("GSA") then
  64. local satesn = s:match("GSA,%w*,%d*,(%d*,%d*,%d*,%d*,%d*,%d*,%d*,%d*,%d*,%d*,%d*,%d*,)") or ""
  65. if #satesn > 0 and s:match("%d+,") then SateSn = satesn end
  66. elseif s:match("GPGSV") then
  67. local curnum, lineno, sateNum, gsv_str = s:match("GPGSV,(%d),(%d),(%d+),(.*)%*.*")
  68. if curnum and lineno and sateNum and gsv_str then
  69. if tonumber(lineno) == 1 then
  70. gpgsvTab = {}
  71. gsvCnoTab = {}
  72. gpgsvTab.sateNum = sateNum
  73. gpgsvTab.sateType = "GPS"
  74. end
  75. for i = 1, 4 do
  76. local msg = {id, elevation, azimuth, cno}
  77. -- 找到的字符串的开始位置,结束位置,仰角,方位角,载波信噪比
  78. msg.id, msg.elevation, msg.azimuth, msg.cno, gsv_str = gsv_str:match("(%d+),([%-]*%d*),(%d*),(%d*)(.*)")
  79. if not msg.id then break end
  80. msg.id, msg.elevation, msg.azimuth, msg.cno = tonumber(msg.id) or 0, tonumber(msg.elevation) or 0, tonumber(msg.azimuth) or 0, tonumber(msg.cno) or 0
  81. table.insert(gpgsvTab, msg)
  82. table.insert(gsvCnoTab, msg.cno)
  83. end
  84. viewedGpsSateCnt = sateNum or "0"
  85. end
  86. -- log.info("GPGSV is value:", json.encode(gsvCnoTab))
  87. elseif s:match("BDGSV") then
  88. local curnum, lineno, sateNum, gsv_str = s:match("GPGSV,(%d),(%d),(%d+),(.*)%*.*")
  89. if curnum and lineno and sateNum and gsv_str then
  90. if tonumber(lineno) == 1 then
  91. bdgsvTab = {}
  92. bdgsvTab.sateNum = sateNum
  93. bdgsvTab.sateType = "BD"
  94. end
  95. -- 将同一消息编号的归类插入同一个编号中
  96. for i = 1, 4 do
  97. local msg = {id, elevation, azimuth, cno}
  98. -- 找到的字符串的开始位置,结束位置,仰角,方位角,载波信噪比
  99. msg.id, msg.elevation, msg.azimuth, msg.cno, gsv_str = gsv_str:match("(%d+),([%-]*%d*),(%d*),(%d*)(.*)")
  100. if not msg.id then break end
  101. msg.id, msg.elevation, msg.azimuth, msg.cno = tonumber(msg.id) or 0, tonumber(msg.elevation) or 0, tonumber(msg.azimuth) or 0, tonumber(msg.cno) or 0
  102. table.insert(bdgsvTab, msg)
  103. end
  104. end
  105. viewedBdSateCnt = sateNum or "0"
  106. elseif s:match("RMC") then
  107. gpsTime, gpsFind, lat, latTyp, lng, lngTyp, spd, cog, gpsDate = s:match("RMC,(%d%d%d%d%d%d)%.%d+,(%w),(%d*%.*%d*),([NS]*),(%d*%.*%d*),([EW]*),(.-),(.-),(%d%d%d%d%d%d),")
  108. if gpsFind == "A" and cog then
  109. fixFlag = true
  110. speed = spd
  111. azimuth = cog
  112. else
  113. fixFlag = false
  114. end
  115. latitudeType, longitudeType, latitude, longitude = latTyp, lngTyp, lat, lng
  116. if gpsFind == "A" and gpsTime and gpsDate and gpsTime ~= "" and gpsDate ~= "" then
  117. local yy, mm, dd, h, m, s = tonumber(gpsDate:sub(5, 6)), tonumber(gpsDate:sub(3, 4)), tonumber(gpsDate:sub(1, 2)), tonumber(gpsTime:sub(1, 2)), tonumber(gpsTime:sub(3, 4)), tonumber(gpsTime:sub(5, 6))
  118. utcStamp = os.time({year = 2000 + yy, month = mm, day = dd, hour = h, min = m, sec = s})
  119. UtcTime = os.date("*t", os.time({year = 2000 + yy, month = mm, day = dd, hour = h, min = m, sec = s}) + 28800)
  120. -- misc.setClock(UtcTime)
  121. sys.publish("GPS_TIMING_SUCCEED", UtcTime)
  122. end
  123. elseif s:match("VTG") then
  124. kmHour = s:match("VTG,%d*%.*%d*,%w*,%d*%.*%d*,%w*,%d*%.*%d*,%w*,(%d*%.*%d*)")
  125. -- if fixFlag then sys.publish("GPS_MSG_REPORT", 1) else sys.publish("GPS_MSG_NOREPORT", 0) end
  126. sys.publish("GPS_MSG_REPORT", fixFlag and 1 or 0)
  127. end
  128. end
  129. -- 阻塞模式读取串口数据,需要线程支持
  130. -- @return 返回以\r\n结尾的一行数据
  131. -- @usage local str = gpsv2.read()
  132. local function read()
  133. local cache_data = ""
  134. local co = coroutine.running()
  135. while true do
  136. local s = uart.read(uartID, "*l")
  137. if s == "" then
  138. uart.on(uartID, "receive", function()coroutine.resume(co) end)
  139. coroutine.yield()
  140. uart.on(uartID, "receive")
  141. else
  142. cache_data = cache_data .. s
  143. if cache_data:find("\r\n") then return cache_data end
  144. end
  145. end
  146. end
  147. -- GPS串口写命令操作
  148. -- @string cmd,GPS指令(cmd格式:"$PGKC149,1,115200*"或者"$PGKC149,1,115200*XX\r\n")
  149. -- @bool isFull,cmd是否为完整的指令格式,包括校验和以及\r\n;true表示完整,false或者nil为不完整
  150. -- @return nil
  151. -- @usage gpsv2.writeCmd(cmd)
  152. local function writeCmd(cmd, isFull)
  153. local tmp = cmd
  154. if not isFull then
  155. tmp = 0
  156. for i = 2, cmd:len() - 1 do
  157. tmp = bit.bxor(tmp, cmd:byte(i))
  158. end
  159. tmp = cmd .. (string.format("%02X", tmp)):upper() .. "\r\n"
  160. end
  161. uart.write(uartID, tmp)
  162. -- log.info("gpsv2.writecmd", tmp)
  163. end
  164. -- GPS串口写数据操作
  165. -- @string str,HEX形式的字符串
  166. -- @return 无
  167. -- @usage gpsv2.writeData(str)
  168. local function writeData(str)
  169. uart.write(uartID, (str:fromHex()))
  170. -- log.info("gpsv2.writeData", str)
  171. end
  172. -- AIR530的校验和算法
  173. local function hexCheckSum(str)
  174. local sum = 0
  175. for i = 5, str:len(), 2 do
  176. sum = bit.bxor(sum, tonumber(str:sub(i, i + 1), 16))
  177. end
  178. return string.upper(string.format("%02X", sum))
  179. end
  180. local function setFastFix(lat, lng)
  181. if not lat or not lng or not openFlag or os.time() < 1514779200 then return end
  182. local tm = os.date("*t")
  183. tm = common.timeZoneConvert(tm.year, tm.month, tm.day, tm.hour, tm.min, tm.sec, 8, 0)
  184. t = tm.year .. "," .. tm.month .. "," .. tm.day .. "," .. tm.hour .. "," .. tm.min .. "," .. tm.sec .. "*"
  185. -- log.info("写入秒定位需要的坐标和时间:", lat, lng, t)
  186. writeCmd("$PGKC634," .. t)
  187. writeCmd("$PGKC634," .. t)
  188. writeCmd("$PGKC635," .. lat .. "," .. lng .. ",0," .. t)
  189. end
  190. -- 定时自动下载坐标和星历的任务
  191. local function getlbs(result, lat, lng, addr)
  192. if result and lat and lng then
  193. lbs_lat, lbs_lng = lat, lng
  194. setFastFix(lat, lng)
  195. end
  196. end
  197. local function saveEph(timeout)
  198. sys.taskInit(function()
  199. while true do
  200. local code, head, data = httpv2.request("GET", "download.openluat.com/9501-xingli/brdcGPD.dat_rda", timeout)
  201. if tonumber(code) and tonumber(code) == 200 then
  202. log.info("保存下载的星历:", io.writeFile(GPD_FILE, data))
  203. ephFlag = false
  204. break
  205. end
  206. end
  207. end)
  208. end
  209. --- 打开GPS模块
  210. -- @number id,UART ID,支持1和2,1表示UART1,2表示UART2
  211. -- @number baudrate,波特率,支持1200,2400,4800,9600,10400,14400,19200,28800,38400,57600,76800,115200,230400,460800,576000,921600,1152000,4000000
  212. -- @nunber mode,功耗模式0正常功耗,2周期唤醒
  213. -- @number sleepTm,间隔唤醒的时间 秒
  214. -- @param fnc,外部模块使用的电源管理函数
  215. -- @return 无
  216. -- @usage gpsv2.open()
  217. -- @usage gpsv2.open(2, 115200, 0, 1) -- 打开GPS,串口2,波特率115200,正常功耗模式,1秒1个点
  218. -- @usage gpsv2.open(2, 115200, 2, 5) -- 打开GPS,串口2,波特率115200,周期低功耗模式1秒输出,5秒睡眠
  219. function open(id, baudrate, mode, sleepTm, fnc)
  220. uartID, uartBaudrate = tonumber(id) or uartID, tonumber(baudrate) or uartBaudrate
  221. mode, sleepTm = tonumber(mode) or 0, tonumber(sleepTm) and sleepTm * 1000 or 1000
  222. pm.wake("gpsv2.lua")
  223. uart.close(uartID)
  224. uart.setup(uartID, uartBaudrate, 8, uart.PAR_NONE, uart.STOP_1)
  225. -- if fnc and type(fnc) == "function" then
  226. -- fnc()
  227. -- else
  228. -- pmd.ldoset(7, pmd.LDO_VIB)
  229. -- pmd.ldoset(7, pmd.LDO_VCAM)
  230. -- rtos.sys32k_clk_out(1)
  231. -- end
  232. openFlag = true
  233. local fullPowerMode = false
  234. local wakeFlag = false
  235. ---------------------------------- 初始化GPS任务--------------------------------------------
  236. -- 获取基站定位坐标
  237. lbsLoc.request(getlbs, nil, timeout)
  238. --连接服务器下载星历
  239. saveEph(timeout)
  240. -- 自动定时下载定位坐标
  241. sys.timerLoopStart(function()lbsLoc.request(getlbs, nil, timeout) end, EPH_UPDATE_INTERVAL * 1000)
  242. -- 自动定时下载星历数据
  243. sys.timerLoopStart(saveEph, EPH_UPDATE_INTERVAL * 1000, timeout)
  244. log.info("----------------------------------- GPS OPEN -----------------------------------")
  245. GPS_CO = sys.taskInit(function()
  246. read()
  247. -- 发送GPD传送结束语句
  248. writeData("AAF00B006602FFFF6F0D0A")
  249. -- 切换为NMEA接收模式
  250. local nmea = "AAF00E00950000" .. (pack.pack("<i", uartBaudrate):toHex())
  251. nmea = nmea .. hexCheckSum(nmea) .. "0D0A"
  252. writeData(nmea)
  253. writeCmd("$PGKC147," .. uartBaudrate .. "*")
  254. setReport(1000)
  255. while openFlag do
  256. if not fixFlag and not ephFlag and io.exists(GPD_FILE) and os.time() > 1514779200 then
  257. local tmp, data, len = "", io.readFile(GPD_FILE):toHex()
  258. log.info("模块写星历数据开始!")
  259. -- 切换到BINARY模式
  260. while read():toHex() ~= "AAF00C0001009500039B0D0A" do writeCmd("$PGKC149,1," .. uartBaudrate .. "*") end
  261. -- 写入星历数据
  262. local cnt = 0 -- 包序号
  263. for i = 1, #data, 1024 do
  264. local tmp = data:sub(i, i + 1023)
  265. if tmp:len() < 1024 then tmp = tmp .. ("F"):rep(1024 - tmp:len()) end
  266. tmp = "AAF00B026602" .. string.format("%04X", cnt):upper() .. tmp
  267. tmp = tmp .. hexCheckSum(tmp) .. "0D0A"
  268. writeData(tmp)
  269. for j = 1, 30 do
  270. local ack, len = read():toHex()
  271. if len == 12 or ack:find("AAF00C0003") then break end
  272. end
  273. cnt = cnt + 1
  274. end
  275. -- 发送GPD传送结束语句
  276. writeData("AAF00B006602FFFF6F0D0A")
  277. -- 切换为NMEA接收模式
  278. while not read():find("$G") do writeData(nmea) end
  279. setFastFix(lbs_lat, lbs_lng)
  280. ephFlag = true
  281. fullPowerMode = true
  282. log.info("模块写星历数据完成!")
  283. end
  284. if tonumber(mode) == 2 then
  285. fixFlag = false
  286. -- setRunMode(0, 1000, sleepTm)
  287. setReport(1000)
  288. while not fixFlag do
  289. parseNmea(read())
  290. end
  291. parseNmea(read())
  292. if fixFlag then end
  293. -- while not read():match("PGKC001,105,(3)") do setRunMode(2, 1000, sleepTm) end
  294. writeCmd("$PGKC051,1*")
  295. sys.wait(sleepTm)
  296. -- while fixFlag do parseNmea(read()) end
  297. else
  298. if not wakeFlag then
  299. setRunMode(mode, 1000, sleepTm)
  300. setReport(sleepTm)
  301. wakeFlag = true
  302. end
  303. parseNmea(read())
  304. end
  305. end
  306. sys.publish("GPS_CLOSE_MSG")
  307. log.info("GPS 任务结束退出!")
  308. end)
  309. end
  310. --- 关闭GPS模块
  311. -- @param fnc,外部模块使用的电源管理函数
  312. -- @return 无
  313. -- @usage gpsv2.close()
  314. function close(id, fnc)
  315. openFlag = false
  316. fixFlag = false
  317. while GPS_CO ~= nil and coroutine.status(GPS_CO) ~= "dead" do coroutine.resume(GPS_CO) end
  318. uart.close(tonumber(id) or uartID)
  319. if fnc and type(fnc) == "function" then
  320. fnc()
  321. else
  322. pmd.ldoset(0, pmd.LDO_VIB)
  323. pmd.ldoset(0, pmd.LDO_VCAM)
  324. rtos.sys32k_clk_out(0)
  325. end
  326. pm.sleep("gpsv2.lua")
  327. sys.timerStopAll(restart)
  328. log.info("----------------------------------- GPS CLOSE -----------------------------------")
  329. end
  330. --- 重启GPS模块
  331. -- @number r,重启方式-0:外部电源重置; 1:热启动; 2:温启动; 3:冷启动
  332. -- @return 无
  333. -- @usage gpsv2.restart()
  334. function restart(r)
  335. r = tonumber(r) or 1
  336. if r > 0 and r < 4 then writeCmd("$PGKC030," .. r .. "*") end
  337. end
  338. --- 设置GPS模块搜星模式.
  339. -- 如果使用的是Air800或者Air530,不调用此接口配置,则默认同时开启GPS和北斗定位
  340. -- @number gps,GPS定位系统,1是打开,0是关闭
  341. -- @number beidou,中国北斗定位系统,1是打开,0是关闭
  342. -- @number glonass,俄罗斯Glonass定位系统,1是打开,0是关闭
  343. -- @number galieo,欧盟伽利略定位系统,1是打开,0是关闭
  344. -- @return nil
  345. -- @usage gpsv2.setAeriaMode(1,1,0,0)
  346. function setAerialMode(gps, beidou, glonass, galieo)
  347. local gps = gps or 0
  348. local glonass = glonass or 0
  349. local beidou = beidou or 0
  350. local galieo = galieo or 0
  351. if gps + glonass + beidou + galieo == 0 then gps = 1; beidou = 1 end
  352. if openFlag then writeCmd("$PGKC115," .. gps .. "," .. glonass .. "," .. beidou .. "," .. galieo .. "*") end
  353. end
  354. --- 设置GPS模块的运行模式.
  355. -- 如果不调用此接口配置,则默认为正常运行模式
  356. -- @number mode,运行模式
  357. -- 0:正常运行模式
  358. -- 1:周期超低功耗跟踪模式
  359. -- 2:周期低功耗模式
  360. -- 4:直接进入超低功耗跟踪模式
  361. -- 8:自动低功耗模式,可以通过串口唤醒
  362. -- 9:自动超低功耗跟踪模式,需要force on来唤醒
  363. -- @number runTm,单位毫秒,mode为1或者2时表示运行时长,其余mode时此值无意义
  364. -- @number sleepTm,单位毫秒,mode为1或者2时表示睡眠时长,其余mode时此值无意义
  365. -- @return nil
  366. -- @usage gpsv2.setRunMode(0,1000)
  367. -- @usage gpsv2.setRunMode(1,5000,2000)
  368. function setRunMode(mode, runTm, sleepTm)
  369. local rt, st = tonumber(runTm) or "", tonumber(sleepTm) or ""
  370. if openFlag then
  371. writeCmd("$PGKC105," .. mode .. ((mode == 1 or mode == 2) and ("," .. rt .. "," .. st) or "") .. "*")
  372. end
  373. end
  374. --- 设置NMEA消息上报的间隔
  375. -- @number tm,上报消息的间隔时间
  376. -- @return 无
  377. -- @usage gpsv2.setReport(tm)
  378. function setReport(tm)
  379. if openFlag then
  380. tm = tonumber(tm) or 1000
  381. if tm > 10000 then tm = 10000 end
  382. if tm < 200 then tm = 200 end
  383. writeCmd("$PGKC101," .. tm .. "*")
  384. end
  385. end
  386. --- 获取GPS模块是否处于开启状态
  387. -- @return bool result,true表示开启状态,false或者nil表示关闭状态
  388. -- @usage gpsv2.isOpen()
  389. function isOpen()
  390. return openFlag
  391. end
  392. --- 获取GPS模块是否定位成功
  393. -- @return bool result,true表示定位成功,false或者nil表示定位失败
  394. -- @usage gpsv2.isFix()
  395. function isFix()
  396. return fixFlag
  397. end
  398. --- 获取返回值为度的10&7方的整数值(度*10^7的值)
  399. -- @return number,number,INT32整数型,经度,维度,符号(正东负西,正北负南)
  400. -- @usage gpsv2.getIntLocation()
  401. function getIntLocation()
  402. local lng, lat = "0.0", "0.0"
  403. lng = longitudeType == "W" and ("-" .. longitude) or longitude
  404. lat = latitudeType == "S" and ("-" .. latitude) or latitude
  405. if lng and lat and lng ~= "" and lat ~= "" then
  406. local integer, decimal = lng:match("(%d+).(%d+)")
  407. if tonumber(integer) and tonumber(decimal) then
  408. decimal = decimal:sub(1, 7)
  409. local tmp = (integer % 100) * 10 ^ 7 + decimal * 10 ^ (7 - #decimal)
  410. lng = ((integer - integer % 100) / 100) * 10 ^ 7 + (tmp - tmp % 60) / 60
  411. end
  412. integer, decimal = lat:match("(%d+).(%d+)")
  413. if tonumber(integer) and tonumber(decimal) then
  414. decimal = decimal:sub(1, 7)
  415. tmp = (integer % 100) * 10 ^ 7 + decimal * 10 ^ (7 - #decimal)
  416. lat = ((integer - integer % 100) / 100) * 10 ^ 7 + (tmp - tmp % 60) / 60
  417. end
  418. return lng, lat
  419. end
  420. return 0, 0
  421. end
  422. --- 获取基站定位的经纬度信息dd.dddd
  423. function getDeglbs()
  424. return lbs_lng or "0.0", lbs_lat or "0.0"
  425. end
  426. --- 获取度格式的经纬度信息dd.dddddd
  427. -- @return string,string,固件为非浮点时返回度格式的字符串经度,维度,符号(正东负西,正北负南)
  428. -- @return float,float,固件为浮点的时候,返回浮点类型
  429. -- @usage gpsv2.getLocation()
  430. function getDegLocation()
  431. local lng, lat = getIntLocation()
  432. if float then return lng / 10 ^ 7, lat / 10 ^ 7 end
  433. return string.format("%d.%07d", lng / 10 ^ 7, lng % 10 ^ 7), string.format("%d.%07d", lat / 10 ^ 7, lat % 10 ^ 7)
  434. end
  435. --- 获取度分格式的经纬度信息ddmm.mmmm
  436. -- @return string,string,返回度格式的字符串经度,维度,符号(正东负西,正北负南)
  437. -- @usage gpsv2.getCentLocation()
  438. function getCentLocation()
  439. if float then return tonumber(Ggalng or 0), tonumber(Ggalat or 0) end
  440. return Ggalng or 0, Ggalat or 0
  441. end
  442. --- 获取海拔
  443. -- @return number altitude,海拔,单位米
  444. -- @usage gpsv2.getAltitude()
  445. function getAltitude()
  446. return tonumber(altitude and altitude:match("(%d+)")) or 0
  447. end
  448. --- 获取速度
  449. -- @return number kmSpeed,第一个返回值为公里每小时的速度
  450. -- @return number nmSpeed,第二个返回值为海里每小时的速度
  451. -- @usage gpsv2.getSpeed()
  452. function getSpeed()
  453. local integer = tonumber(speed and speed:match("(%d+)")) or 0
  454. return (integer * 1852 - (integer * 1852 % 1000)) / 1000, integer
  455. end
  456. --- 获取时速(KM/H)的整数型和浮点型(字符串)
  457. function getKmHour()
  458. return tonumber(kmHour and kmHour:match("(%d+)")) or 0, (float and tonumber(kmHour) or kmHour) or "0"
  459. end
  460. --- 获取方向角
  461. -- @return number Azimuth,方位角
  462. -- @usage gpsv2.getAzimuth()
  463. function getAzimuth()
  464. return tonumber(azimuth and azimuth:match("(%d+)")) or 0
  465. end
  466. --- 获取可见卫星的个数
  467. -- @return number count,可见卫星的个数
  468. -- @usage gpsv2.getViewedSateCnt()
  469. function getViewedSateCnt()
  470. return tonumber(viewedGpsSateCnt) or 0 + tonumber(viewedBdSateCnt) or 0
  471. end
  472. --- 获取定位使用的卫星个数
  473. -- @return number count,定位使用的卫星个数
  474. -- @usage gpsv2.getUsedSateCnt()
  475. function getUsedSateCnt()
  476. return tonumber(usedSateCnt) or 0
  477. end
  478. --- 获取RMC语句中的UTC时间
  479. -- 只有同时满足如下两个条件,返回值才有效
  480. -- 1、开启了GPS,并且定位成功
  481. -- 2、调用setParseItem接口,第一个参数设置为true
  482. -- @return table utcTime,UTC时间,nil表示无效,例如{year=2018,month=4,day=24,hour=11,min=52,sec=10}
  483. -- @usage gpsv2.getUtcTime()
  484. function getUtcTime()
  485. return UtcTime
  486. end
  487. --- 获取gps的UTC时间戳
  488. -- @retrun number,时间戳
  489. -- @usage gpsv2.getUtcStamp()
  490. function getUtcStamp()
  491. return utcStamp or 0
  492. end
  493. --- 获取定位使用的大地高
  494. -- @return number sep,大地高
  495. -- @usage gpsv2.getSep()
  496. function getSep()
  497. return tonumber(Sep) or 0
  498. end
  499. --- 获取水平精度
  500. function getHdop()
  501. return tonumber(hdop) or 0
  502. end
  503. --- 获取GSA语句中的可见卫星号
  504. -- 只有同时满足如下两个条件,返回值才有效
  505. -- 1、开启了GPS,并且定位成功
  506. -- 2、调用setParseItem接口,第三个参数设置为true
  507. -- @return string viewedSateId,可用卫星号,""表示无效
  508. -- @usage gpsv2.getSateSn()
  509. function getSateSn()
  510. return tonumber(SateSn) or 0
  511. end
  512. --- 获取BDGSV解析结果
  513. -- @return table, GSV解析后的数组
  514. -- @usage gpsv2.getBDGsv()
  515. function getBDGsv()
  516. return bdgsvTab
  517. end
  518. --- 获取GPGSV解析结果
  519. -- @return table, GSV解析后的数组
  520. -- @usage gpsv2.getGPGsv()
  521. function getGPGsv()
  522. return gpgsvTab
  523. end
  524. --- 获取GPSGSV解析后的CNO数据
  525. function getCno()
  526. return gsvCnoTab
  527. end
  528. --- 是否显示日志
  529. function openLog(v)
  530. isLog = v == nil and true or v
  531. end