| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- local lbsLoc2 = require "lbsLoc2"
- local hdgnss = {}
- function hdcrc(str, len)
- if not len then
- len = #str
- end
- local crc1 = 0
- local crc2 = 0
- for i = 3, len do
- crc1 = crc1 + str:byte(i)
- crc2 = crc2 + (crc1 & 0xff)
- end
- -- print(string.format("%02X%02X", crc1 & 0xFF, crc2 & 0xFF))
- return string.char(crc1 & 0xFF, crc2 & 0xFF)
- end
- function hdgnss.aideph()
- local url = "http://download.openluat.com/9501-xingli/HD_GPS_BDS.hdb"
- local eph_body = nil
- if io.fileSize("/hdgnss.bin") > 1024 then
- local date = os.date("!*t")
- -- log.info("gnss", "当前系统时间", os.date())
- if date.year < 2024 then
- date = os.date("!*t")
- end
- if date.year > 2023 then
- local tm = io.readFile("/hdgnss_tm")
- if tm then
- local t = tonumber(tm)
- if t and (os.time() - t < 3600*2) then
- log.info("hdgnss", "重用星历文件")
- eph_body = io.readFile("/hdgnss.bin")
- else
- log.info("hdgnss", "星历过期了")
- os.remove("/hdgnss.bin")
- end
- else
- log.info("hdgnss", "星历时间有问题")
- end
- else
- log.info("hdgnss", "系统时间有问题")
- end
- end
- if http and not eph_body then
- -- AGNSS 已调通
- for i = 1, 3 do
- local code, _, body = http.request("GET", url, nil, nil, {timeout=3000}).wait()
- log.info("hdgnss", "AGNSS", code, body and #body or 0)
- if code == 200 and body and #body > 1024 then
- io.writeFile("/hdgnss.bin", body)
- sys.wait(1000)
- local date = os.date("!*t")
- if date.year > 2022 then
- io.writeFile("/hdgnss_tm", tostring(os.time()))
- end
- eph_body = body
- break
- end
- sys.wait(6 * 1000)
- end
- end
- if eph_body and #eph_body > 1024 then
- local body = eph_body
- -- for offset = 1, #body, 512 do
- -- -- log.info("hdgnss", "AGNSS", "write >>>", #body:sub(offset, offset + 511))
- -- -- uart.write(gps_uart_id, body:sub(offset, offset + 511))
- -- -- sys.waitUntil("UART2_SEND", 100)
- -- sys.wait(100) -- 等100ms反而更成功
- -- end
- -- uart.write(gps_uart_id, body)
- local offset = 1
- local size = #body
- while offset < size do
- -- 前两个字符是F1D9
- if body:byte(offset) == 0xF1 and body:byte(offset + 1) == 0xD9 then
- -- log.info("hdgnss", "星历数据", body:sub(1, 16):toHex())
- local len = body:byte(offset + 4) + body:byte(offset + 5) * 256
- local tmp = body:sub(offset, offset + len + 7)
- -- log.info("hdgnss", "写入星历片段", offset, len, #tmp, tmp:toHex())
- uart.write(gps_uart_id, tmp)
- offset = offset + len + 8
- sys.wait(20)
- else
- log.warn("hdgnss", "分隔出错了", offset, size)
- break
- end
- end
- end
- sys.wait(20)
- end
- local function exec_agnss()
- for i = 1, 3 do
- local ip = socket.localIP()
- if ip and ip ~= "0.0.0.0" then
- break
- end
- sys.waitUntil("IP_READY", 3000)
- end
- socket.sntp()
- sys.waitUntil("NTP_UPDATE", 1000)
- -- 注入当前时间
- if os.date("*t").year > 2023 then
- hdgnss.aidtime()
- sys.wait(100)
- end
- -- 读取之前的位置信息
- local lat, lng
- local gnssloc = io.readFile("/hdloc")
- if gnssloc then
- log.info("hdgnss", "最后已知位置信息", gnssloc)
- local tmp = gnssloc:split(",")
- if tmp and #tmp == 2 then
- lat = tonumber(tmp[1])
- lng = tonumber(tmp[2])
- end
- end
- -- 写入参考位置
- if lat and lng and lat ~= 0 and lng ~= 0 then
- hdgnss.aidpos(lat, lng)
- sys.wait(100)
- else
- log.info("hdgnss", "当前无辅助位置信息")
- end
- -- 发起基站定位, 暂时禁用
- if mobile and false then
- mobile.reqCellInfo(6)
- sys.waitUntil("CELL_INFO_UPDATE", 6000)
- local lat2, lng2, t = lbsLoc2.request(5000)
- log.info("hdgnss", "基站定位结果", lat2, lng2)
- if lat2 and lng2 then
- lat2 = tonumber(lat2:sub(1, 3) .. lat2:sub(5))
- lng2 = tonumber(lng2:sub(1, 3) .. lng2:sub(5))
- if lat2 and lng2 then
- lat = lat
- lng = lng
- log.info("hdgnss", "基站定位结果", lat, lng)
- hdgnss.aidpos(lat, lng)
- end
- end
- end
- hdgnss.aideph()
- -- sys.wait(1000)
- end
- function hdgnss.aidpos(lat, lng)
- local gps_uart_id = hdgnss.opts.uart_id
- -- AID-POS
- local str = string.char(
- 0xF1, 0xD9, -- 帧头
- 0x0B, 0x10, 0x11, 0x00, -- 指令ID: 0x0B 0x11, 载荷17字节
- 0x01 -- LLA 1, ECEF 0
- )
- -- lat = 234068458 1132310388
- -- 234072543 1132310160
- log.info("hdgnss", "参考坐标(单位1/10000000度)", lat, lng)
- str = str .. pack.pack("<IIII", lat, lng, 5000, 0)
- str = str .. hdcrc(str)
- log.info("hdgnss", "写入AID-POS", str:toHex())
- uart.write(gps_uart_id, str)
- end
- function hdgnss.aidtime()
- local gps_uart_id = hdgnss.opts.uart_id
- local date = os.date("!*t")
- if date.year > 2023 then
- -- AID-TIME, 时间精度要在3秒以内
- log.info("hdgnss", "当前时间", date.year, date.month, date.day, date.hour, date.min, date.sec)
- local str = string.char(
- 0xF1, 0xD9, -- 帧头
- 0x0B, 0x11, 0x14, 0x00, -- 指令ID: 0x0B 0x11, 载荷20字节
- 0x00, -- UTC 0, TNOW 1
- 0x00, -- 保留参数,填0
- 0x11, -- 闰秒
- date.year & 0xFF, date.year >> 8, -- 年
- date.month, -- 月
- date.day, -- 日
- date.hour, -- 小时
- date.min, -- 分钟
- date.sec, -- 秒
- 0x00, 0x00, 0x00, 0x00, -- 亚毫秒
- 0x00, 0x00, -- 时间精度(秒)
- 0x00, 0x00, 0x00, 0x00 -- 时间精度(亚毫秒)
- )
- str = str .. hdcrc(str)
- log.info("hdgnss", "写入AID-TIME", str:toHex())
- uart.write(gps_uart_id, str)
- -- sys.wait(20)
- end
- end
- function hdgnss.setup(opts)
- if not opts then
- opts = {}
- end
- if not opts.uart_id then
- opts.uart_id = 2
- end
- hdgnss.opts = opts
- end
- function hdgnss.start()
- log.debug("提醒", "室内无GNSS信号,定位不会成功, 要到空旷的室外,起码要看得到天空")
- local gps_uart_id = hdgnss.opts.uart_id
- local uart_forward = hdgnss.opts.uart_forward
- log.info("hdgnss", "start")
- libgnss.on("raw", function(data)
- -- sys.publish("uplink", nmea_topic, data, 1)
- if data:byte(1) == 0xF1 then
- log.info("hdgnss", "二进制协议数据", data:toHex())
- end
- end)
- uart.setup(gps_uart_id, 9600)
- if uart_forward then
- uart.setup(uart_forward, 115200)
- end
- pm.power(pm.GPS, true)
- sys.wait(250) -- GPNSS芯片启动需要时间,大概250ms
- -- 串口配置, 切换到115200
- uart.write(gps_uart_id, (string.fromHex("F1D9060008000000000000C20100D1E0")))
- sys.wait(20)
- uart.close(gps_uart_id)
- sys.wait(10)
- uart.setup(gps_uart_id, 115200)
- -- 调试日志,可选
- libgnss.debug(hdgnss.opts.debug)
- libgnss.bind(gps_uart_id, uart_forward)
- if not hdgnss.opts.no_agps then
- exec_agnss()
- end
- hdgnss.running = true
- end
- function hdgnss.stop()
- hdgnss.running = false
- if hdgnss.opts and hdgnss.opts.uart_id then
- uart.close(hdgnss.opts.uart_id)
- end
- end
- function hdgnss.saveloc()
- local rmc = libgnss.getRmc(1)
- log.info("hdgnss", "rmc", rmc.lat, rmc.lng)
- io.writeFile("/hdloc", string.format("%d,%d", rmc.lat, rmc.lng))
- end
- -- 订阅GNSS状态编码
- sys.subscribe("GNSS_STATE", function(event, ticks)
- -- event取值有
- -- FIXED 定位成功
- -- LOSE 定位丢失
- -- ticks是事件发生的时间,一般可以忽略
- log.info("hdgnss", "state", event, ticks)
- if event == "FIXED" then
- hdgnss.saveloc()
- end
- end)
- sys.taskInit(function()
- while 1 do
- sys.wait(600 * 1000) -- 10分钟检查一次
- local fixed = libgnss.isFix()
- if not fixed and not hdgnss.opts.no_agps and hdgnss.running then
- exec_agnss()
- end
- if fixed then
- hdgnss.saveloc()
- end
- end
- end)
- return hdgnss
|