跳转至

辅助定位(AGPS)

一、AGPS 概述

AGPS(Assisted GPS,辅助全球卫星定位系统)通过移动网络预先获取卫星星历、时间等辅助数据,可大幅缩短 GPS 首次定位时间。LuatOS 提供 AGPS 原生支持,适用于物流追踪、车载定位等场景。

1.1 GPS、WiFi、基站、AGPS 几种常用定位原理介绍与区别

GPS

GPS(Global Positioning System)即全球定位系统,它是由美国研究的一种定位方式,特点是:不需要 SIM 卡,不需要连接网络,只要在户外,基本上就能随时随地的准确定位。但是 GPS 启动后搜索卫星的时间比较多,一般需要 2 分钟左右(俗称冷启动,冷启动包括:1、GPS 初次使用 2、GPS 电池耗尽 3、关机状态下移动 1000 公里以上的距离或持续关机超过 4 小时)。

原理:接收机接收 GPS 卫星广播,通过解析可见 GPS 卫星的位置、距离等信息以及相应算法得出自己的位置信息。

优势:定位精度高,只要能接收到四颗卫星的定位信号,就可以进行定位。

缺点:GPS 受天气和位置的影响较大。当遇到天气不佳的时候、或者处于高架桥/树荫的下面,或者在高楼的旁边角落、地下车库、室内或露天的下层车库(或者简单地说当见不到天空的时候),GPS 的定位就会受到相当大的影响,甚至无法进行定位服务。

注意:各国定位系统有:中国北斗、美国 GPS、俄罗斯 GLONASS、欧洲伽利略等,统称卫星定位。

合宙 gps 模组定位精度:3~5 米

LBS(基站)定位

基站包括移动、联通和电信基站。基站定位是通过移动通信的基站信号差异,通过一定的算法来计算出手机所在的位置,取决于定位地点附近所处的基站覆盖密度,如果基站多,定位则准确,如果是山区,基站少,则定位就不那么精确;LBS 定位必须联网,手机处于 SIM 卡注册状态(飞行模式下开 wifi 和拔出 SIM 卡都不行)。

原理:运营商蜂窝基站的位置信息都是固定的,通过接收一个或多个基站信号终端,再根据信号强度及基站位置进行推算自身位置

优点:方便,因为它是通过 SIM 卡接收基站信号进行定位的。理论上说,只要计算三个基站的信号差异,就可以判断出手机所在的位置。因此,只要用户手机处于移动通信网络的有效范围之内,就可以随时进行位置定位,而不受天气、高楼、位置等等的影响。

缺点:通过计算基站信号差异而得出的位置坐标值,很明显地逊于 GPS 的定位精度,受环境影响较大,在郊区和农村可以将移动台定位在 10~20 米范围内,在城区由于高大建筑物较多,电波传播环境不好,信号很难直接从基站到达移动台,一般要经过折射或反射,因此定位精度会受到影响;其次是使用范围较窄,LBS 虽然不会受到天气、高架桥或高楼的影响,但如果超出手机的服务范围,或者手机所处的基站数量不足,则无法进行 LBS 定位,从这一点上说不太适合野外使用。

定位精度:10-2000 米。

WIFI 定位

Wifi 定位,顾名思义,周围必须有 wifi 才可以!WiFi 定位的目的是解决室内精确定位,原理类似基站定位。WiFi 定位的条件是:1、必须具有 WIFISCAN 功能,可以扫描到周围 wifi 的 mac 地址。2、必须能上网,移动数据或者 wifi 联网皆可。

原理:每一个无线 AP 都有一个全球唯一的 MAC 地址, WiFi 定位靠的是侦测附近周围所有的无线网络基地台 (WiFi Access Point) 的 MAC 地址,去比对数据库中该 MAC 地址的坐标,交叉计算出所在地。

优点:1、定位精度高,wifi 密集人流多的地方相当精确;2、速度快;3、周围的 wifi 即使连接不上也能定位。在不依赖外部设备的情况下,没有比 WIFI 定位更精准的室内定位方式,室内定位不精准,偏二三十米远,这个问题当前科技无解。

缺点:显而易见的,1、wifi 依赖! 没有 wifiscan 就不能定位;2、必须处于联网状态。3、用户被迫共享了一点流量

精确度:10~200 米

AGPS 辅助定位

AGPS 是辅助 GPS 定位的一种方法。AGPS 和 GPS 是一样的,只是加上网络的辅助而已,定位时,必须有 GPS 模块存在,如果没有 GPS 模块,这种定位是不起什么作用的。A-GPS 定位是用来加快定位速度的,由于 GPS 冷启动时,搜星速度很慢(需要把头上二十多颗卫星挨个搜一遍),大约 2 分钟才能搜到,合宙定位模组冷启动 35s 左右就可以定上位。增加了 AGPS 定位之后可以利用基站大体定位下你所在的位置,然后通过网络将这个位置发送到服务器,服务器根据这个位置将此时经过你头顶的卫星参数(哪几颗、频率、位置、仰角等信息)反馈给你的定位设备,设备上的 GPS 就可以很有目的的去搜索卫星,此时你的搜星速度大大提高,几秒钟就可以定位。

原理:接收机接收 GPS 星历文件,通过解析可见 GPS 卫星的位置、距离等信息以及相应算法得出自己的位置信息。

优势:和 GPS 比,1、搜星定位快,不管是冷启动、热启动,秒定 2、有效减少设备的电量消耗 3、缓解弱 GPS 信号情况下无法定位或精度降低的问题 4、对移动设备的计算能力要求更低。

缺点:1、必须联网,如果你的设备不能上网,或是停机了身边又没有 wifi,是没法应用 AGPS 达到秒定效果的。2、必须有 AGPS 位置服务器的支持 3、与 GPS 一样,仍无法完美解决室内(室内无法接收 GPS 信号)定位的问题。

精确度:3~5 米

二、演示功能概述

本教程将演示如何使用 Air8000 的 GPS 功能,使用 agps 实现快速定位功能。agps 实现流程图如下:

Air8000 的 AGPS 实现原理为:通过蜂窝基站或 Wi-Fi 定位获取粗略位置坐标,再结合网络下发的卫星辅助数据(星历),显著缩短卫星信号搜索时间并加速定位解算,最终实现快速精准定位。

注意:GPS 星历文件能保持 4 小时,定位成功后会自动更新星历。

由上面原理可知 Air8000 使用 agps 功能需要访问两个服务器,基站定位服务器和星历下载服务器。(注意:如果使用的是专网卡,需要将下面两个服务器配置在 sim 卡的白名单中,基站定位服务器 bs.openluat.com 和星历下载服务器 download.openluat.com)

基站定位使用教程以及基站定位收费情况可以参考这篇文章基站和 WiFi 定位

三、准备硬件环境

3.1 Air8000 核心板

淘宝购买链接:Air8000 核心板淘宝购买链接

核心板使用教程参考:Air8000 核心板使用说明

3.2 GPS 天线

上面购买链接可以选择套餐三,里面包含一个 gps 天线。

参考:硬件环境清单,准备以及组装好硬件环境。

四、准备软件环境

1. 烧录工具 Luatools

2. 内核固件文件(底层 core 固件文件):LuatOS-SoC_V2005_Air8000;此页面有新版本固件的话选用最新版本固件。

3. LuatOS 需要的脚本和资源文件:https://gitee.com/openLuat/LuatOS/tree/master/module/Air8000/demo/GPS

4. lib 脚本文件:使用 Luatools 烧录时,勾选 添加默认 lib 选项,使用默认 lib 脚本文件;

准备好软件环境之后,接下来查看如何烧录项目文件到 Air8000 开发板中,将本篇文章中演示使用的项目文件烧录到 Air8000 开发板中。

五、GPS 软硬件参考

5.1 API 接口介绍

本教程使用 api 接口为:

https://docs.openluat.com/air8000/luatos/api/core/libgnss/

5.2 GPS 硬件设计

GPS 在硬件设计中天线部分是比较关键的,可以参考这篇文章:Air8000 GNSS 硬件设计指导

在核心板上内置 GNSS ipex 连接器,同时内置 3.3V LDO, 用于有源天线供电。因此可以使用外部有源天线直接连接 GNSS 连接器。

注意:目前有源天线供电仅支持 3.3V 有源天线,请注意连接的有源天线的供电范围。

六、代码示例介绍

6.1 软件代码介绍

--[[
必须定义PROJECT和VERSION变量,Luatools工具会用到这两个变量,远程升级功能也会用到这两个变量
PROJECT:项目名,ascii string类型
        可以随便定义,只要不使用,就行
VERSION:项目版本号,ascii string类型
        如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
            X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
            因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
        如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可

本demo演示的功能为:
使用Air8000核心板演示GPS定位功能以及agps辅助功能
]]
PROJECT = "air8000_gnss"
VERSION = "1.0.0"

log.info("main", PROJECT, VERSION)

-- sys库是标配
_G.sys = require("sys")
--[[特别注意, 使用http库需要下列语句]]
_G.sysplus = require("sysplus")

-- mobile.flymode(0,true)
if wdt then
    --添加硬狗防止程序卡死,在支持的设备上启用这个功能
    wdt.init(9000)--初始化watchdog设置为9s
    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
end
log.info("main", "air8000_gnss")

mcu.hardfault(0)    --死机后停机,一般用于调试状态
pm.ioVol(pm.IOVOL_ALL_GPIO, 3300) -- 所有GPIO高电平输出3.3V

local gnss = require("agps_icoe")
function test_gnss()
    log.debug("提醒", "室内无GNSS信号,定位不会成功, 要到空旷的室外,起码要看得到天空")
    pm.power(pm.GPS, true)
    gnss.setup({
        uart_id=2,
        uart_forward = uart.VUART_0, -- 转发到虚拟串口,方便对接GnssToolKit3
        debug=true,
        sys=1
    })
    gnss.start() --初始化gnss
    gnss.agps() --使用agps辅助定位
    --循环打印解析后的数据,可以根据需要打开对应注释
    while 1 do
        sys.wait(5000)
        log.info("RMC", json.encode(libgnss.getRmc(2) or {}, "7f"))         --解析后的rmc数据
        log.info("GGA", libgnss.getGga(3))                                   --解析后的gga数据
        -- log.info("GLL", json.encode(libgnss.getGll(2) or {}, "7f"))
        -- log.info("GSA", json.encode(libgnss.getGsa(1) or {}, "7f"))
        -- log.info("GSV", json.encode(libgnss.getGsv(2) or {}, "7f"))
        -- log.info("VTG", json.encode(libgnss.getVtg(2) or {}, "7f"))
        -- log.info("ZDA", json.encode(libgnss.getZda(2) or {}, "7f"))
        -- log.info("date", os.date())
        -- log.info("sys", rtos.meminfo("sys"))
        -- log.info("lua", rtos.meminfo("lua"))
    end
end
sys.taskInit(test_gnss)

-- 订阅GNSS状态编码
sys.subscribe("GNSS_STATE", function(event, ticks)
    -- event取值有
    -- FIXED 定位成功
    -- LOSE  定位丢失
    -- ticks是事件发生的时间,一般可以忽略
    log.info("gnss", "state", event, ticks)
    if event == "FIXED" then
        local locStr = libgnss.locStr()
        log.info("gnss", "locStr", locStr)
        -- if locStr then
        --     -- 存入文件,方便下次AGNSS快速定位
        --     io.writeFile("/gnssloc", locStr)
        -- end
    end
end)

-- 用户代码已结束---------------------------------------------
-- 结尾总是这一句
sys.run()
-- sys.run()之后后面不要加任何语句!!!!!
local agps_icoe = {
    version = "1.0.1"
}

local sys = require("sys")

function agps_icoe.setup(opts)
    agps_icoe.opts = opts
    if not agps_icoe.opts.uart_id then
        agps_icoe.opts.uart_id = 2
    end
end

function agps_icoe.start()
    -- 初始化串口
    local gps_uart_id = agps_icoe.opts.uart_id
    local opts = agps_icoe.opts
    -- local write = agps_icoe.writeCmd
    uart.setup(gps_uart_id, 115200)
    -- 是否为调试模式
    if opts.debug then
        libgnss.debug(true)
    end
    if agps_icoe.opts.uart_forward then
        uart.setup(agps_icoe.opts.uart_forward, 115200)
        libgnss.bind(gps_uart_id, agps_icoe.opts.uart_forward)
    else
        libgnss.bind(gps_uart_id)
    end

    -- 是否需要切换定位系统呢?
    if opts.sys then
        if type(opts.sys) == "number" then
            if opts.sys == 1 then
                uart.write(gps_uart_id, "$CFGSYS,H01\r\n")
            elseif opts.sys == 2 then
                uart.write(gps_uart_id, "$CFGSYS,H10\r\n")
            elseif opts.sys == 5 then
                uart.write(gps_uart_id, "$CFGSYS,H101\r\n")
            else
                uart.write(gps_uart_id, "$CFGSYS,H11\r\n")
            end
        end
    end

    if not opts.nmea_ver or opts.nmea_ver == 41 then
        uart.write(gps_uart_id, "$CFGNMEA,h51\r\n") -- 切换到NMEA 4.1
    end

    -- 打开全部NMEA语句
    if opts.rmc_only then
        uart.write(gps_uart_id, "$CFGMSG,0,0,0\r\n")
        sys.wait(20)
        uart.write(gps_uart_id, "$CFGMSG,0,1,0\r\n")
        sys.wait(20)
        uart.write(gps_uart_id, "$CFGMSG,0,2,0\r\n")
        sys.wait(20)
        uart.write(gps_uart_id, "$CFGMSG,0,3,0\r\n")
        sys.wait(20)
        uart.write(gps_uart_id, "$CFGMSG,0,4,1\r\n")
        sys.wait(20)
        uart.write(gps_uart_id, "$CFGMSG,0,5,0\r\n")
        sys.wait(20)
        uart.write(gps_uart_id, "$CFGMSG,0,6,0\r\n")
        sys.wait(20)
        uart.write(gps_uart_id, "$CFGMSG,0,7,0\r\n")
        sys.wait(20)
    elseif agps_icoe.opts.no_nmea then
        uart.write(gps_uart_id, "$CFGMSG,0,0,0\r\n")
        sys.wait(20)
        uart.write(gps_uart_id, "$CFGMSG,0,1,0\r\n")
        sys.wait(20)
        uart.write(gps_uart_id, "$CFGMSG,0,2,0\r\n")
        sys.wait(20)
        uart.write(gps_uart_id, "$CFGMSG,0,3,0\r\n")
        sys.wait(20)
        uart.write(gps_uart_id, "$CFGMSG,0,4,0\r\n")
        sys.wait(20)
        uart.write(gps_uart_id, "$CFGMSG,0,5,0\r\n")
        sys.wait(20)
        uart.write(gps_uart_id, "$CFGMSG,0,6,0\r\n")
        sys.wait(20)
        uart.write(gps_uart_id, "$CFGMSG,0,7,0\r\n")
        sys.wait(20)
    else
        uart.write(gps_uart_id, "$CFGMSG,0,0,1\r\n") -- GGA
        sys.wait(10)
        uart.write(gps_uart_id, "$CFGMSG,0,1,1\r\n") -- GLL
        sys.wait(10)
        uart.write(gps_uart_id, "$CFGMSG,0,2,1\r\n") -- GSA
        sys.wait(10)
        uart.write(gps_uart_id, "$CFGMSG,0,3,1\r\n") -- GSV
        sys.wait(10)
        uart.write(gps_uart_id, "$CFGMSG,0,4,1\r\n") -- RMC
        sys.wait(10)
        uart.write(gps_uart_id, "$CFGMSG,0,5,1\r\n") -- VTG
        sys.wait(10)
        uart.write(gps_uart_id, "$CFGMSG,0,6,1\r\n") -- ZDA
        sys.wait(10)
        -- uart.write(gps_uart_id, "$CFGMSG,0,7,1\r\n") -- GST
        -- sys.wait(10)
    end
end

-- function agps_icoe.writeCmd(cmd)
--     log.info("agps_icoe", "写入指令", cmd:trim())
--     uart.write(agps_icoe.opts.uart_id, cmd)
-- end

function agps_icoe.reboot(mode)
    local cmd = "$RESET,0,"
    if not mode then
        mode = 0
    end
    if mode == 2 then
        cmd = cmd .. "hff\r\n"
    elseif mode == 1 then
        cmd = cmd .. "h01\r\n"
    else
        cmd = cmd .. "h00\r\n"
    end
    uart.write(agps_icoe.opts.uart_id, cmd)
    if mode == 2 then
        agps_icoe.agps_tm = nil
    end
    libgnss.clear()
end

function agps_icoe.stop()
    uart.close(agps_icoe.opts.uart_id)
end

local function do_agps()
    -- 首先, 发起位置查询
    local lat, lng
    if mobile then
        mobile.reqCellInfo(6)
        sys.waitUntil("CELL_INFO_UPDATE", 6000)
        local lbsLoc2 = require("lbsLoc2")
        lat, lng = lbsLoc2.request(5000)
        -- local lat, lng, t = lbsLoc2.request(5000, "bs.openluat.com")
        log.info("lbsLoc2", lat, lng)
        if lat and lng then
            lat = tonumber(lat)
            lng = tonumber(lng)
            log.info("lbsLoc2", lat, lng)
            -- 转换单位
            local lat_dd,lat_mm = math.modf(lat)
            local lng_dd,lng_mm = math.modf(lng)
            lat = lat_dd * 100 + lat_mm * 60
            lng = lng_dd * 100 + lng_mm * 60
        end
    elseif wlan then
        -- wlan.scan()
        -- sys.waitUntil("WLAN_SCAN_DONE", 5000)
    end
    if not lat then
        -- 获取最后的本地位置
        local locStr = io.readFile("/hxxtloc")
        if locStr then
            local jdata = json.decode(locStr)
            if jdata and jdata.lat then
                lat = jdata.lat
                lng = jdata.lng
            end
        end
    end
    -- 然后, 判断星历时间和下载星历
    local now = os.time()
    local agps_time = tonumber(io.readFile("/hxxt_tm") or "0") or 0
    if now - agps_time > 3600 then
        local url = agps_icoe.opts.url
        if not agps_icoe.opts.url then
            if agps_icoe.opts.sys and 2 == agps_icoe.opts.sys then
                -- 单北斗
                url = "http://download.openluat.com/9501-xingli/HXXT_BDS_AGNSS_DATA.dat"
            else
                url = "http://download.openluat.com/9501-xingli/HXXT_GPS_BDS_AGNSS_DATA.dat"
            end
        end
        local code = http.request("GET", url, nil, nil, {dst="/hxxt.dat"}).wait()
        if code and code == 200 then
            log.info("agps_icoe", "下载星历成功", url)
            io.writeFile("/hxxt_tm", tostring(now))
        else
            log.info("agps_icoe", "下载星历失败", code)
        end
    else
        log.info("agps_icoe", "星历不需要更新", now - agps_time)
    end

    local gps_uart_id = agps_icoe.opts.uart_id or 2

    -- 写入星历
    local agps_data = io.readFile("/hxxt.dat")
    if agps_data and #agps_data > 1024 then
        log.info("agps_icoe", "写入星历数据", "长度", #agps_data)
        for offset=1,#agps_data,512 do
            log.info("gnss", "AGNSS", "write >>>", #agps_data:sub(offset, offset + 511))
            uart.write(gps_uart_id, agps_data:sub(offset, offset + 511))
            sys.wait(100) -- 等100ms反而更成功
        end
        -- uart.write(gps_uart_id, agps_data)
    else
        log.info("agps_icoe", "没有星历数据")
        return
    end

    -- 写入参考位置
    -- "lat":23.4068813,"min":27,"valid":true,"day":27,"lng":113.2317505
    if not lat or not lng then
        -- lat, lng = 23.4068813, 113.2317505
        log.info("agps_icoe", "没有GPS坐标", lat, lng)
        return -- TODO 暂时不写入参考位置
    end
    if socket.sntp then
        socket.sntp()
        sys.waitUntil("NTP_UPDATE", 1000)
    end
    local date = os.date("!*t")
    if date.year > 2023 then
        local str = string.format("$AIDTIME,%d,%d,%d,%d,%d,%d,000", date["year"], date["month"], date["day"],
            date["hour"], date["min"], date["sec"])
        log.info("agps_icoe", "参考时间", str)
        uart.write(gps_uart_id, str .. "\r\n")
        sys.wait(20)
    end

    local str = string.format("$AIDPOS,%.7f,%s,%.7f,%s,1.0\r\n",
    lat > 0 and lat or (0 - lat), lat > 0 and 'N' or 'S',
    lng > 0 and lng or (0 - lng), lng > 0 and 'E' or 'W')
    log.info("agps_icoe", "写入AGPS参考位置", str)
    uart.write(gps_uart_id, str)

    -- 结束
    agps_icoe.agps_tm = now
end

function agps_icoe.agps(force)
    -- 如果不是强制写入AGPS信息, 而且是已经定位成功的状态,那就没必要了
    if not force and libgnss.isFix() then return end
    -- 先判断一下时间
    local now = os.time()
    if force or not agps_icoe.agps_tm or now - agps_icoe.agps_tm > 3600 then
        -- 执行AGPS
        log.info("agps_icoe", "开始执行AGPS")
        do_agps()
    else
        log.info("agps_icoe", "暂不需要写入AGPS")
    end
end

function agps_icoe.saveloc(lat, lng)
    if not lat or not lng then
        if libgnss.isFix() then
            local rmc = libgnss.getRmc(3)
            if rmc then
                lat, lng = rmc.lat, rmc.lng
            end
        end
    end
    if lat and lng then
        log.info("待保存的GPS位置", lat, lng)
        local locStr = string.format('{"lat":%7f,"lng":%7f}', lat, lng)
        log.info("agps_icoe", "保存GPS位置", locStr)
        io.writeFile("/hxxtloc", locStr)
    end
end

sys.subscribe("GNSS_STATE", function(event)
    if event == "FIXED" then
        agps_icoe.saveloc()
    end
end)

return agps_icoe

6.2 效果展示

可以看到没有使用 agps 辅助定位需要 31 秒左右才能定位成功。使用 agps 后,注入星历数据后 3s 左右就能定位成功

七、总结

本教程演示了 Air8000 如何使用 AGPS 来进行快速定位,并讲解了 AGPS 的实现原理以及注意事项。

八 、GPS 常见名词解释

[1]GNSS:混合定位,不同于 GPS 定位,狭义上讲的 GPS 系统,单指美国的 24 颗 GPS 卫星以及地面上 1 个主控站、3 个数据注入站和 5 个监测站及作为用户端的 GPS 接收机组成的一整套系统。GNSS 是指通过观测 GNSS 卫星获得坐标系内绝对定位坐标的测量技术。 GNSS 是所有导航定位卫星的总称,凡是可以通过捕获跟踪其卫星信号实现定位的系统,均可纳入 GNSS 系统的范围。国内用户接触最多的应该是美国的 24 颗 GPS 卫星,以及中国的北斗卫星(截至到 2023 年 5 月 17 日 10 时 49 分,中国已有五十六颗北斗导航卫星),其余还有俄罗斯 GLONASS、欧盟 GALILEO、 日本的准天顶卫星系统、印度的 IRNSS(独立的区域导航系统,覆盖印度领土及周边 1500 km 范围内,提供定位精度优于 20 米的服务)等其余定位系统。

[2]冷启动:指在一个陌生的环境下启动 GPS,直到 GPS 芯片和可用卫星联系并且计算出坐标的过程。以下几种情况开机均属冷启动:

  1. 初次开机使用时;
  2. 电池耗尽导致 GPS 芯片内星历信息丢失时;
  3. 关机状态下将接收机移动 1000 公里以上距离。

也就是说,冷启动是通过硬件方式的强制性启动,因为物理距离较远,或者时间间隔很久,GPS 芯片已经把内部的星历信息清除掉,或者内部的星历信息完全失效。GPS 接收机失去卫星参数,或者已经存在的参数和实际接收到卫星参数相差太多,导致 GPS 芯片无法靠星历快速搜星,所以必须从新获得卫星提供的坐标数据。

这也是很多定位器(譬如车载定位器)启动后,搜星时间长、定位耗时久的原因

[3]热启动:指在上次关机的地方没有过多移动过,且距离上次定位时间小于 1 个小时。再次定位时,GPS 芯片通过软件的方式,可以继续使用之前的星历快速搜星,实现秒定位。PS:普通的 GNSS 芯片,星历最长有效期为 12 小时,故此星历过期后,GPS 芯片无法使用星历实现快速定位。

[4]温启动:指距离上次定位时间超过 1 个小时的启动,搜星定位时间介于冷启动和热启动之间的情况。

譬如某时间使用过 GPS 定位实现 3D FIX,GPS 芯片内部生成星历(或者外部灌入 AGPS 数据),那么在 1 小时内启动 GPS 芯片进行定位的行为就属于温启动。启动后,GPS 芯片首先会输出上次的位置信息。因为上次关机前的经纬度和高度已知,但由于关机时间过长,卫星状态发生了变化,之前 3D FIX 时的卫星接受不到了,所以星历中参数中的若干颗卫星已经和 GPS 接收机失去了联系,GPS 芯片需要继续搜星补充位置信息,所以搜星的时间要长于热启动,短于冷启动。

[5]星历:是用于描述太空飞行体位置和速度的表达式———两行式轨道数据系统。卫星、航天器或飞行体一旦进入太空,即被列入 NORAD 卫星星历编号目录。列入 NORAD 卫星星历编号目录的太空飞行体将被终生跟踪。卫星、火箭残骸等飞行体成为太空垃圾时,仍被列入 NORAD 卫星编号目录,直到目标消失。卫星星历以开普勒定律的 6 个轨道参数之间的数学关系确定飞行体的时间、坐标、方位、速度等各项参数,具有极高的精度。卫星星历能精确计算、预测、描绘、跟踪卫星、飞行体的时间、位置、速度等运行状态;能表达天体、卫星、航天器、导弹、太空垃圾等飞行体的精确参数;能将飞行体置于三维的空间;用时间立体描绘天体的过去、现在和将来。卫星星历的时间按世界标准时间(UTC)计算。卫星星历定时更新。

[6]AGPS:辅助全球卫星定位系统(英语:Assisted Global Positioning System,简称:AGPS)指的是一种 GPS 的运行方式。它可以利用地面基地站的资讯,配合传统 GPS 卫星,让定位的速度更快

[7]有源天线:通常对于设备或车载机而言,由于设备与 GPS 接收模块之间往往有距离,考虑到安装的便利性可能会有超过 1 米的距离,在这种情况下我们只能选择有源 GPS 天线,由于天线长度的信号衰减需要进行补偿,一般有两级低噪声放大器(LNA)进行天线前端信号放大,放大后的信号经电缆输出,电缆同步提供 LNA 所需要的直流电压

由于天线收到的信号在有源天线接受头内完成信号接受与天线放大,并且远离 GPS 设备或其他电器设备,干扰源最小,而且安装位置由于天线距离延长安装位置可以选择非常理想的环境,所以实际使用时往往感觉信号较强

[8]无源天线:使用无源 GPS 天线时,由于只有一个陶瓷片接收天空的卫星信号,直接连接到模块的 RF-IN 脚,这种联接方式结构简单,而且标准的 25254 的陶瓷片成本低廉,技术成熟,占空体积小,适合于强调紧凑型空间 GPS 导航产品,蓝牙 GPS,手机 GPS 及其他小型 GPS 消费类产品。

这种天线的布局是从天线的引脚直达模块的 RF-IN 脚,这根导线需要进行 50 欧阻抗匹配,而且在天线附近不能有电磁干扰,对 PCB 的设计及整机的 EMI 设计要求较高,但如果设计得优良的无源天线 GPS 产品同样有非常好的表现效果,而且功耗比较低,无需考虑天线自身的功耗。

[9]半边天以及开拓地带:GPS 卫星运行在距地 36000KM 的轨道上,信号强度相当弱(GPS 卫星的功率有多大?)。GPS 的民用 C/A 码从卫星发出来的时候信号只有 27W 左右,达到地球的时候在-158.5dBW 以上。用对数形式表示可能不直观,换算成十进制等于将近 0.0000000000000001W,相当小。所以,只有室外开阔的、无遮挡、晴好的地方,才能搜到更多的卫星,SNR 值更高(阴天都会有影响哦),GPS 芯片才能更快、更好的实现定位。

半边天一般指楼宇内窗边,打开窗户,只能搜到一半天空的卫星。

[10]定位纠偏:OpenLuat 的所有 GNSS 模块均使用国际标准 WGS-84 坐标系,所以开发者在国内常见地图定位时,会发现与实际情况有几十米甚至上百米的误差。这并非模块问题, 而是国内地图采用了非标坐标系所致。 国内常见地图如高德地图使用 GCJ-02 坐标系, 百度地图使用 BD-09 坐标系,故此开发者需要对模块输出的经纬度进行加偏处理,才能在国内的地图上实现精确定位,坐标转换可在合宙提供的坐标转换网站上直观的展示处理

[11]重捕:是指接收终端在丢失所接收信号状态下,从重新接收到信号开始,至终端设备输出符合定位精度要求的定位结果所需的时间。失锁重捕时间反映了在接收机信号失锁,定位中断后重新恢复定位的速度。失锁重捕时间短的接收机在易中断环境中(如隧道等)的定位性能好,因此失锁重捕时间可以有效评估车载终端的性能

[12]低噪声放大器:主要用于接收信号的前端,放大天线从空中接收到的微弱信号,降低噪声干扰,以供系统解调出所需的信息数据