| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- --- 模块功能:GPS辅助定位以及星历更新服务.
- -- 本功能模块只能配合Air512G、Air551G、Air552G使用;
- -- require"agps"后,会自动开启本功能模块的任务;
- -- 开机后,仅获取一次基站对应的经纬度位置和当前时间,把经纬度位置和时间写到GPS芯片中,可以加速GPS定位
- -- 会定期更新GPS星历,星历更新算法如下:
- -- 从最后一次GPS定位成功的时间算起,每隔4小时连接星历服务器下载一次星历数据(大概4K字节),写入GPS芯片。
- -- 例如01:00分开机后,更新了一次星历文件,截止到05:00,“一直没有开启过GPS”或者“开启过GPS,但是GPS从来没有定位成功”,在05:00就会下载星历数据然后写入GPS芯片;
- -- 05:00更新星历数据后,在06:00打开了GPS,并且GPS定位成功,然后在07:00关闭了GPS,关闭前GPS仍然处于定位成功状态;
- -- 截止到11:00,“一直没有开启过GPS”或者“开启过GPS,但是GPS从来没有定位成功”,在11:00就会下载星历数据然后写入GPS芯片;
- -- @module agps9701
- -- @author openLuat
- -- @license MIT
- -- @copyright openLuat
- -- @release 2018.03.26
- require"http"
- require"lbsLoc"
- require"net"
- local gps = require"gps9701"
- module(..., package.seeall)
- local EPH_TIME_FILE = "/ephTime.txt"
- local EPH_DATA_FILE = "/ephData.bin"
- local writeEphIdx,sEphData,writeEphSta = 0
- local EPH_UPDATE_INTERVAL = 4*3600
- local lastLbsLng,lastLbsLat = "",""
- local fneed_xingli=false
- local cachepack = ""
- local gpsresult = nil
- local agpsend = nil
- local tasklock = true
- --重置写入agps星历包
- local function agpsreag()
- tasklock = false
- sys.taskInit(function()
- while true do
- if agpsend then
- log.info("agpsend")
- tasklock = true
- agpsend = false
- break
- end
- sys.wait(1000)
- if gps.checkdatapack then
- while true do
- if agpsend then
- break
- end
- gpsresult = sys.waitUntil("NOEMAL_RECE",1000)
- if (not gpsresult) and (not agpsend) then
- gps.writeCmd(cachepack:fromHex(),true)
- end
- end
- end
- end
- end)
- end
- local function runTimer()
- sys.timerStart(updateEph,EPH_UPDATE_INTERVAL*1000)
- end
- local function writeEphEnd()
- agpsend = true
- log.info("agps.writeEphEnd",pack.pack("<i",gps.uartBaudrate):toHex())
- local cmd,sum = (("AAF00F00950000"):fromHex())..pack.pack("<i",gps.uartBaudrate),0
- for i=3,cmd:len() do
- sum = bit.bxor(sum,cmd:byte(i))
- end
- local validate = "00AA0F"
- gps.writeCmd(cmd..string.char(sum)..validate:fromHex(),true)
- sys.timerStart(gps.close,2000,gps.TIMER,{tag="lib.agps.lua.eph"})
- writeEphIdx,sEphData,writeEphSta = 0
- end
- local function writeEph()
- log.info("agps.writeEph",writeEphSta)
- if writeEphSta=="IDLE" then
- if tasklock then
- agpsreag()
- end
- gps.writeCmd("$PGKC149,1,"..gps.uartBaudrate.."*")
- writeEphSta = "WAIT_BINARY_CMD_ACK"
- elseif writeEphSta=="WAIT_BINARY_CMD_ACK" or writeEphSta=="WAIT_WRITE_EPH_CMD_ACK" then
- if sEphData and sEphData:len()>0 then
- local hexStr = sEphData:sub(1,1024)
- if hexStr:len()<1024 then hexStr = hexStr..("0"):rep(1024-hexStr:len()) end
- hexStr = "AAF00C026602"..string.format("%02X",writeEphIdx):upper().."00"..hexStr
- local checkSum = 0
- local binStr = hexStr:fromHex()
- for i=3,binStr:len() do
- checkSum = bit.bxor(checkSum,binStr:byte(i))
- end
- string.format("%02X",checkSum):upper()
-
- hexStr = hexStr..(string.format("%02X",checkSum):upper()).."00".."AA0F"
- cachepack = hexStr
- gps.writeCmd(hexStr:fromHex(),true)
-
- sEphData = sEphData:sub(1025,-1)
- writeEphIdx = writeEphIdx+1
- writeEphSta = "WAIT_WRITE_EPH_CMD_ACK"
- else
- gps.writeCmd(("AAF00C006602FFFF6800AA0F"):fromHex(),true)
- writeEphSta = "WAIT_WRITE_EPH_END_CMD_ACK"
- end
- elseif writeEphSta=="WAIT_WRITE_EPH_END_CMD_ACK" then
- io.writeFile(EPH_TIME_FILE,tostring(os.time()))
- writeEphEnd()
- end
- end
- -- sys.taskInit(function()
- -- sys.waitUntil()
- -- while true do
- -- if agpsend then
- -- log.info("agpsend")
- -- break
- -- end
- -- sys.wait(1000)
- -- if gps.checkdatapack then
- -- while true do
- -- if agpsend then
- -- break
- -- end
- -- gpsresult = sys.waitUntil("NOEMAL_RECE",1000)
- -- if (not gpsresult) and (not agpsend) then
- -- gps.writeCmd(cachepack:fromHex(),true)
- -- end
- -- end
- -- end
- -- end
- -- end)
- local function writeEphBegin()
- writeEphSta = "IDLE"
- writeEph()
- end
- local function downloadEphCb(result,prompt,head,body)
- log.info("agps.downloadEphCb",result,prompt,body)
- runTimer()
- if result and prompt=="200" and body then
- io.writeFile(EPH_DATA_FILE,body)
- if gps.isFix() then
- io.writeFile(EPH_TIME_FILE,tostring(os.time()))
- else
- fneed_xingli=false
- sEphData = body:toHex()
- gps.open(gps.TIMER,{tag="lib.agps.lua.eph",val=10,cb=writeEphEnd})
- sys.timerStart(writeEphBegin,2000)
- return
- end
- end
- end
- --连接服务器下载星历
- function updateEph()
- if gps.isFix() then runTimer() return end
- http.request("GET","download.openluat.com/9501-xingli/brdcGPD.dat_rda",nil,nil,nil,20000,downloadEphCb)
- end
- --JWL在星历的时间范围内,如果有星历文件,重启模块就直接把本地的星历文件写入GPS芯片
- --在AGPS_LOCATED 的订阅事件中,调用此接口。
- function upd_xingli()
- if not gps.isFix() then
- local lstm = io.readFile(EPH_TIME_FILE)
- if not lstm or lstm=="" then return end
- log.info("agps.upd_xingli lstm=",lstm)
- if os.time()-tonumber(lstm) < EPH_UPDATE_INTERVAL then
- local body = io.readFile(EPH_DATA_FILE)
- if body and #body >0 then
- log.info("agps.upd_xingli length=",#body)
- fneed_xingli=false
- sEphData = body:toHex()
- gps.open(gps.TIMER,{tag="lib.agps.lua.eph",val=10,cb=writeEphEnd})
- sys.timerStart(writeEphBegin,2000)
- else
- log.info("agps.upd_xingli wanto update xingli data")
- updateEph()
- end
- end
- end
- end
- sys.subscribe("AGPS_LOCATED", function()
- sys.timerStart(function()
- log.info("agps.want to upd_xingli",fneed_xingli)
- if fneed_xingli then
- upd_xingli()
- end
- end,7000)
- end)
- --检查是否需要更新星历
- local function checkEph()
- local result
- if not gps.isFix() then
- lastTm = io.readFile(EPH_TIME_FILE)
- if not lastTm or lastTm=="" then return true end
- log.info("agps.checkEph",os.time(),tonumber(lastTm)," DELTA=",os.time()-tonumber(lastTm))
- result = (os.time()-tonumber(lastTm) >= EPH_UPDATE_INTERVAL)
- end
- if not result then runTimer() end
- return result
- end
- local function setFastFix(lng,lat,tm)
- gps.setFastFix(lat,lng,tm)
- if checkEph() then
- updateEph()
- end
- end
- local getloc = 0
- local lbsLocRequesting
- --获取到基站对应的经纬度,写到GPS芯片中
- local function getLocCb(result,lat,lng,addr,time)
- fneed_xingli=true
- log.info("agps.getLocCb",result,lat,lng,time and time:len() or 0)
- lbsLocRequesting = false
- if result==0 then
- lastLbsLng,lastLbsLat = lng,lat
- sys.publish("AGPS_LOCATED", lng,lat)
- if not gps.isFix() then
- local tm = {year=0,month=0,day=0,hour=0,min=0,sec=0}
- if time:len()==6 then
- tm = {year=time:byte(1)+2000,month=time:byte(2),day=time:byte(3),hour=time:byte(4),min=time:byte(5),sec=time:byte(6)}
- misc.setClock(tm)
- tm = common.timeZoneConvert(tm.year,tm.month,tm.day,tm.hour,tm.min,tm.sec,8,0)
- end
- gps.open(gps.TIMERORSUC,{tag="lib.agps.lua.fastFix",val=4})
- sys.timerStart(setFastFix,2000,lng,lat,tm)
- getloc = 1
- end
- end
-
- if result~=0 or gps.isFix() then
- if checkEph() then updateEph() end
- end
- end
- --是否获取到基站对应的经纬度
- function isgetloc()
- return getloc
- end
- local function ipReady()
- if gps.isFix() then
- runTimer()
- else
- if not lbsLocRequesting then
- lbsLocRequesting = true
- lbsLoc.request(getLocCb,nil,30000,"0","bs.openluat.com","12412",true)
- end
- end
- end
- local function gpsState(evt,para)
- log.info("agps.GPS_STATE",evt,para)
- if evt=="LOCATION_SUCCESS" or (evt=="CLOSE" and para==true) then
- runTimer()
- elseif evt=="BINARY_CMD_ACK" or evt=="WRITE_EPH_ACK" or evt=="WRITE_EPH_END_ACK" then
- writeEph()
- elseif evt=="OPEN" then
- local lng,lat = gps.getLastLocation()
- if lng=="" or lat=="" then
- lng,lat = lastLbsLng,lastLbsLat
- end
- if lng~="" and lat~="" then
- gps.open(gps.TIMERORSUC,{tag="lib.agps.lua.fastFix",val=4})
- local tm = os.date("*t")
- sys.timerStart(gps.setFastFix,2000,lat,lng,common.timeZoneConvert(tm.year,tm.month,tm.day,tm.hour,tm.min,tm.sec,8,0))
- end
- end
- end
- function init()
- sys.subscribe("GPS_STATE",gpsState)
- sys.subscribe("IP_READY_IND",ipReady)
- log.info("agps.init")
- end
- function unInit()
- sys.unsubscribe("GPS_STATE",gpsState)
- sys.unsubscribe("IP_READY_IND",ipReady)
- log.info("agps.unInit")
- end
- init()
|