GPS定位调试方法
一、GPS 工作原理简介
1.1 GPS 技术的发展历程
全球定位系统(GPS)起初由美国国防部开发,用于提供精确的定位和导航信息。随着时间推移,它从军事应用扩展到商业和民间领域,实现了全天候、全球范围内的精确地理位置服务。
1.2 GPS 系统组成
GPS 系统主要由三个部分构成:太空中的卫星群、地面控制站和接收器。卫星负责发送信号,地面控制站监测卫星运行状态并进行数据修正,而接收器则用于接收信号并计算位置信息。
1.3 信号接收与定位计算
GPS 接收器通过与至少四颗卫星的信号进行交差定位,借助卫星轨道数据、时间戳和用户位置等信息,使用三角测量法计算出接收器的精确位置、速度和时间。
二、不同地球坐标系的区别
- WGS-84:是国际标准,GPS 坐标(Google Earth 使用、或者 GPS 模块)
- GCJ-02:中国坐标偏移标准,Google Map、高德、腾讯使用
- BD-09:百度坐标偏移标准,Baidu Map 使用
具体解释:
- WGS-84 坐标系 即地球坐标系,国际上通用的坐标系。 设备一般包含 GPS 芯片或者北斗芯片获取的经纬度为 WGS-84 地理坐标系。谷歌地图采用的是 WGS-84 地理坐标系(中国范围除外,谷歌中国地图采用的是 GCJ-02 地理坐标系。)
- GCJ-02 坐标系 即火星坐标系,WGS-84 坐标系经加密后的坐标系。 出于国家安全考虑,国内所有导航电子地图必须使用国家测绘局制定的加密坐标系统,即将一个真实的经纬度坐标加密成一个不正确的经纬度坐标。
- BD-09 坐标系 即百度坐标系,GCJ-02 坐标系经加密后的坐标系。搜狗坐标系、图吧坐标系等,估计也是在 GCJ-02 基础上加密而成的。
Air8000 使用国际标准 WGS-84 坐标系,所以开发者在国内常见地图定位时,会发现与实际情况有几十米的误差。这并非模块问题, 而是国内地图采用了非标坐标系所致。 国内常见地图如高德地图使用 GCJ-02 坐标系, 百度地图使用 BD-09 坐标系,故此开发者需要对模块输出的经纬度进行加偏处理,才能在国内的地图上实现精确定位。
坐标系纠偏的话参考:http://www.openluat.com/GPS-Offset.html
三、GNSS 报文格式
Air8000 的 GNSS 输出数据报文符合 NMEA-0183 标准格式。
NMEA(National Marine Electronics Association)是美国国家海洋电子协会制定的标准通信协议,旨在解决航海电子设备间的数据互通问题。其核心价值在于通过统一接口规范,实现不同厂商设备(如 GPS、雷达、声呐)的兼容性,提升系统集成效率。
3.1 通用 NMEA 语句类型
3.2 NMEA 语句格式
NMEA 语句格式:"$”为语句起始标志,“,"为域分隔符,“”为校验和标识符,其后面的两位数为校验和,校验和等于$和之间所有字符的按位异或。
NMEA-0183 协议采用 ASCII 码来传递 GPS 定位信息,我们称之为帧。
帧格式形如:$aaccc,ddd,ddd,…,ddd*hh(CR)(LF)
1、“$”:帧命令起始位
2、aaccc:地址域,前两位为识别符(aa),后三位为语句名(ccc)
3、ddd…ddd:数据
4、“*”:校验和前缀(也可以作为语句数据结束的标志)
5、hh:校验和(check sum),$ 与*之间所有字符 ASCII 码的校验和(各字节做异或运算,得到校验和后,再转换 16 进制格式的 ASCII 字符)
6、(CR)(LF):帧结束,回车和换行符
核心语句和字段解析可参考下方扩展知识。
四、Air8000 无法定位情况分析
在使用模组的过程中总会有很多客户遇到无法定位的情况,现在此总结下一般遇到无法定位的情况。
4.1 在室内做 GNSS 定位
为什么开发板不能在室内使用 gps 定位?
为什么手机可以定位,模块无法定位呢?
这究竟是为什么呢?
很多开发者在测试 GPS 的时候,总是发觉无法定位,甚至无法搜星。经过技术支持的解答才明白,只有戒掉懒癌,去室外测试,才能有良好的效果。究其原因,还是 GPS 的原理所致。
以最简单的几何来说,两点确定一条线,三个点确定一个面;那么逆推一下,就是三个点确定一个位置(基站定位的原理);四个点确定精确位置(含高程):
导航卫星不断地向地球发射导航电文(卫星的速度、角速度、空间相对位置等信息)
GPS 芯片收到不同卫星的数据后,进行解算,就能得到当前接收器在地球的绝对位置了。根据三点定位的原理,同时使用 3 颗卫星,可以实现 2D FIX(不含高程);只有同时使用 4 颗或以上的卫星,才能实现 3D FIX(含高程)。
不过凡事都有例外,如果开发者在飘窗进行测试,会搜到卫星,甚至超过 4 颗,但是仍然无法定位。这是为什么呢?这是因为 GPS 天线的“可视角”有限,而这片星域的卫星角度相距太近,间隔太小,无法精确解算,故此无法实现定位。
GPS 卫星运行在距地 36000KM 的轨道上,信号强度相当弱(GPS 卫星的功率有多大?)。GPS 的民用 C/A 码从卫星发出来的时候信号只有 27W 左右,达到地球的时候在-158.5dBW 以上。用对数形式表示可能不直观,换算成十进制等于将近 0.0000000000000001W,相当小。所以,只有室外开阔的、无遮挡、晴好的地方,才能搜到更多的卫星,SNR 值更高(阴天都会有影响哦),GPS 芯片才能更快、更好的实现定位。
而室内是没有 GPS 信号的,所以不论开发者如何调整代码、修正天线,都无法实现 GPS 定位。如果开发者懒癌爆发,不想去室外测试怎么办呢?不用担心,万能的淘宝给大家带来了福音:
不过,有的开发者肯定要反驳我:为什么我的手机在室内就能定位,而且特别准呢?
这个问题的答案很简单,手机使用的是多重定位,如果要单纯的测试手机的 GPS 定位,需要这样做:首先“三清”,仅打开 GPS,然后拔卡,飞行模式,再用专业软件如 GPS Test+ 试一试,你就明白啦~~
这种情况下,室内,手机也是无法定位的。
所以说,手机在室内之所以可以定位,实际上是它不仅使用了 GPS,还使用了很多其他的辅助定位技术,如 LBS(基站定位)、Wi-Fi(wifi 定位)、BLE(蓝牙)等
至此,开发者应该可以明白为什么手机可以定位,而开发板无法定位了。
PS:如果有手机同样的预算,开发板也能做到同样的“室内定位”效果
4.2 天线使用问题
1. 有源/无源天线混淆
有部分开发者经常遇到,自己去了户外,按理说应该在 35S 左右就能定位成功了啊,怎么自己一两分钟都没几颗星,等了 10 多 20 分钟依旧还是定位不成功,同步对比手机,发现差距不止一点点,此时应该先检查 GNSS 天线设计问题,看看自己是不是将有源天线插给了无源天线预留的底座,或者无源天线插给了有源天线预留的底座。注意:Air8000 核心板的 GPS 天线是无源天线。
2. 天线设计问题
更多客户遇到的,不是户外定位不到,而是户外定位速度极其的慢的问题,常见于无源天线(因为无源天线对结构、PCB、走线要求都比较高),如果自己设计没有注意下面几点,是很有可能定位不到/定位极其的慢的。
GPS 天线设计参考下面这篇文章:GPS 天线设计指导 - luatos@air8000 - 合宙模组资料中心
3. GPS 天线选型建议
- 在终端结构空间容许,能够统一保证 GPS 天线面朝上的安装使用状态;并且周边没有大的金属物件遮挡的情况下,建议使用 GPS 陶瓷天线,在空间容许的情况下尽量选择大尺寸的陶瓷天线。
- 在不能保证终端使用状态,且空间受限:比如手机,带定位功能的胸牌;建议使用 FPC 天线
- 在明确终端安装环境恶劣,并且对 GPS 性能有较高要求的;建议使用 GPS 有源天线
- 在不能保证产品安装使用状态,但是空间不受限制,也可以选择类似于 GSM 的外置棒状天线。
4. 对天线厂家的要求
- VSWR:GPS 天线电压驻波比一般要求调到 1.5 左右.
- Efficiency:效率一般要求在 40% 左右
- Average Gain:平均增益要求在-0.5dB
- OTA:一般天线厂大多不具备 GPS 天线 OTA 测试环境,天线调试好后可以以实际测试数据做标准来衡量;一般我们 GPS 实测时要求是:可用于定位卫星颗数大于 6 颗以上,最强的信号在 45 dB/Hz 左右,要有 3 颗卫星信号大于 40 dB/Hz。
4.3 星系切换问题
有很多客户遇到过,模组默认固件,只打开 GNSS 电源,35S 左右就能定位到了,但是切换成单北斗,就需要 2 分钟多甚至更长时间才能定位成功。
首先明确一点,合宙的大多数模组,均使用的单频(L1)GNSS 芯片,所以内部能搜到的北斗卫星,只有 B1C 或者 B1I,这两个频段的北斗卫星,由于北斗卫星为高轨卫星,在同一片区域内,卫星数可能不会很多,实测在我家附近的广场上,单频(L1)GNSS 芯片,只能搜到这几颗北斗卫星
所以,在明确自己是真正需要单北斗/单 GPS 或者其他星系前,尽量不要将模块切换为单星系状态,如果客户对单北斗需求非常明确,建议选择真正的单北斗芯片,杜绝后患,因为很多单北斗应用是需要进实验室过多项认证的,使用多星系 GNSS 芯片,有极大概率过不去单北斗的认证。
4.4 外部干扰源问题
此种情况不能说常见,但是确实客观存在,之前有部分客户就遇到了,在他们公司附近一直定位不到,但是客户放在自己小区前面广场上就能定位成功,查看地图得知,客户的公司附近,有"中国军工"单位,不只是 GNSS 定位不到,偶尔自己的手机 5G/4G 信号也没有,此种情况定位不到的原因不言而喻了。
不过还有少量客户遇到的干扰源还是比较明显,例如只针对 GPS 频段发射的干扰源,此时切换为单北斗模式,即使是单频模组,在部分情况下,还是能够正常定位成功的。
以上四点是最为常见的四种无法定位的情况,如果你使用合宙的 GNSS 模组排除了这四点,依旧无法定位,欢迎你来找合宙,我们将会竭力为您排查您所遇到的问题
五、Air8000 的 GNSS 测试环境
有部分客户,需要测试 Air8000 内部 GNSS 的稳定性,但因为 Air8000 UART2(也就是 GPS 对应的串口)RX 不能直接和外部通讯,只能通过 cat.1 主控给它发指令控制,所以使用合宙提供的测试工具,不能直接测试 100 次或者 1000 次冷热启动,需要使用 LUA 脚本控制模块对接 PC 端测试工具,如果客户只是想看看,CN 值、当前位置,那可以直接接 uart2 的 TX 出来对接 PC 端工具
5.1 软件环境
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 开发板中。
5. GNSS PC 端测试工具:- iNavTool-V4020
5.2 硬件环境
Air8000 核心板
淘宝购买链接:Air8000 核心板淘宝购买链接 ;
核心板使用教程参考:Air8000 核心板使用说明
GPS 天线
上面购买链接可以选择套餐三,里面包含一个 gps 天线。
TTL 转 USB 工具
将设备组装好并连接 USB 数据线,将 TTL 转 USB 连接到 Air8000 的核心板的 uart2 上面。
需要注意的是需要将 TTL 转 USB 的 RX 与核心板的 UART2 RX 连接,TX 与和核心板的 UART2 TX 相连接(这是因为 gps 芯片串口与 cat 1 芯片的串口是交叉相连的,所以 TTL 转 USB 的串口只需和 cat 1 的串口 RX 接 RX,TX 接 TX),连接好后如下图所示:
5.3 测试现象
- 下载好的 GNSS PC 端测试工具为一个压缩包,需要解压后打开如图所示 EXE 文件
打开测试工具后可以看见如下界面:
选择左上角的"打开串口"后,选择对应的端口号以及波特率即可,Air8000 的 gps 对应的波特率为 115200,其他的不用管,默认即可。打开端口后,等待片刻,即可看见模块定位成功输出的位置信息以及其他信息,左上角为 NMEA 原始数据,下面的均为从 NMEA 数据中解析出的各种信息(注:此处地图视图需要电脑链接网络才可找到对应经纬度的坐标),如果没有输出经纬度,则证明 GNSS 未打开,需要检查脚本 GPS 电源是否打开,如果长时间没有定位成功,可以参考上一章“Air8000 无法定位情况分析”进行排查。
如果连接成功,则可以看到下面的现象:
此工具更多操作可见下篇 GNSS 调试工具使用方法详细介绍。
六、NMEA 扩展知识
下面是常用的 NMEA 报文语句格式解析:
/*以下的XX可能为以下三种情况
BD 北斗模式
GP GPS模式
GN 双模模式
BD北斗导航系统,中国
GPS(全球定位系统),美国
GLONASS(全球轨道导航卫星系统),前苏联
Galileo-ENSS(欧洲导航卫星系统,即伽利略计划),欧盟
*/
/*推荐定位信息数据格式 $XXRMC
$GPRMC,030551.000,A,3906.2586,N,11720.3131,E,0.00,138.07,150718,,,A*6B
$XXRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>*hh<CR><LF>
<1> 世界时间UTC时间,hhmmss(时分秒)格式 北京时间(BTC),BTC和UTC差了8个小时
<2> 定位状态,A=有效定位,V=无效定位
<3> 纬度ddmm.mmmm(度分)格式(前面的0也将被传输)
<4> 纬度半球N(北半球)或S(南半球)
<5> 经度dddmm.mmmm(度分)格式(前面的0也将被传输)
<6> 经度半球E(东经)或W(西经)
<7> 地面速率(000.0~999.9节,前面的0也将被传输)
<8> 地面航向(000.0~359.9度,以真北为参考基准,前面的0也将被传输)
<9> UTC日期,ddmmyy(日月年)格式
<10> 磁偏角(000.0~180.0度,前面的0也将被传输)
<11> 磁偏角方向,E(东)或W(西)
<12> 模式指示(仅NMEA0183 3.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效)
*/
/*
当前卫星信息 $XXGGA //GPS定位数据
$GPGGA,030551.000,3906.2586,N,11720.3131,E,1,11,0.9,-6.7,M,0.0,M,,*4B
$XXGGA,(1),(2),(3),(4),(5),(6),(7),(8),(9),M,(10),M,(11),(12)*hh(CR)(LF)
各部分所对应的含义为:
(1)定位UTC时间:05时09分01秒
(2)纬度(格式ddmm.mmmm:即dd度,mm.mmmm分);
(3)N/S(北纬或南纬):北纬39度31.4449分;
(4)经度(格式dddmm.mmmm:即ddd度,mm.mmmm分);
(5)E/W(东经或西经):东经116度43.5123分;
(6)质量因子(0=没有定位,1=实时GPS,2=差分GPS):1=实时GPS;
(7)可使用的卫星数(0~8):可使用的卫星数=07;
(8)水平精度因子(1.0~99.9);水平精度因子=1.4;
(9)天线高程(海平面,-9999.9~99999.9,单位:m);天线高程=76.2m);
(10)大地椭球面相对海平面的高度(-999.9~9999.9,单位:m):-7.0m;
(11)差分GPS数据年龄,实时GPS时无:无; //差分GPS数据期限(RTCMSC-104),最后设立RTCM传送的秒数量
(12)差分基准站号(0000~1023),实时GPS时无:无;
*总和校验域;
hh 总和校验数:65
(CR)(LF)回车,换行。
*/
/*
GPVTG 地面速度信息
$GPVTG,<1>,T,<2>,M,<3>,N,<4>,K,<5>*hh
<1> 以正北为参考基准的地面航向(000~359度,前面的0也将被传输)
<2> 以磁北为参考基准的地面航向(000~359度,前面的0也将被传输)
<3> 地面速率(000.0~999.9节,前面的0也将被传输)
<4> 地面速率(0000.0~1851.8公里/小时,前面的0也将被传输)
<5> 模式指示(仅NMEA0183 3.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效
*/
/*
可见卫星信息 $XXGSV
$XXGSV,<1>,<2>,<3>,<4>,<5>,<6>,<7>,…<4>,<5>,<6>,<7>*hh<CR><LF>
<1> GSV语句的总数 //总的GSV语句电文数;2;
<2> 本句GSV的编号 //当前GSV语句号:1;
<3> 可见卫星的总数(00~12,前面的0也将被传输)
<4> PRN码(伪随机噪声码)(01~32,前面的0也将被传输)
<5> 卫星仰角(00~90度,前面的0也将被传输)
<6> 卫星方位角(000~359度,前面的0也将被传输)
<7> 信噪比(00~99dB,没有跟踪到卫星时为空,前面的0也将被传输)
注:<4>,<5>,<6>,<7>信息将按照每颗卫星进行循环显示,每条GSV语句最多可以显示4颗卫星的信息。其他卫星信息将在下一序列的NMEA0183语句中输出。
*/
/*
当前卫星信息 $XXGSA
$XXGSA,<1>,<2>,<3>,<3>,<3>,<3>,<3>,<3>,<3>,<3>,<3>,<3>,<3>,<3>,<4>,<5>,<6>*hh<CR><LF>
<1> 模式,M=手动,A=自动
<2> 定位类型,1=没有定位,2=2D定位,3=3D定位
<3> PRN码(伪随机噪声码),正在用于解算位置的卫星号(01~32,前面的0也将被传输)。
<4> PDOP位置精度因子(0.5~99.9)
<5> HDOP水平精度因子(0.5~99.9)
<6> VDOP垂直精度因子(0.5~99.9)
字段17:VDOP垂直精度因子(0.5 - 99.9)
字段18:校验值
*/
/*
地理定位信息 $XXGLL
$GPGLL,3906.2586,N,11720.3131,E,030551.000,A,A*5B
$XXGLL,<1>,<2>,<3>,<4>,<5>,<6>,<7>*hh<CR><LF>
<1> 纬度ddmm.mmmm(度分)格式(前面的0也将被传输)
<2> 纬度半球N(北半球)或S(南半球)
<3> 经度dddmm.mmmm(度分)格式(前面的0也将被传输)
<4> 经度半球E(东经)或W(西经)
<5> UTC时间,hhmmss(时分秒)格式
<6> 定位状态,A=有效定位,V=无效定位
<7> 模式指示(仅NMEA0183 3.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效)
*/