"); //-->
没有GNSS开发经验也不用怕,本教程专为零基础用户设计,带你快速入门LuatOS exgnss扩展库的实战开发。依托Air8000开发板,从exgnss库的初始化配置(如参数设置、模式选择)讲起,结合典型定位场景的代码示例,逐步讲解定位任务创建、状态监控及数据处理流程,步骤清晰且可复现,让你无需复杂知识储备,即可快速掌握入门技能,实现GNSS开发的速成目标。
一、GNSS 概述
GPS 最先来自美国,1978 年,美国发射了第一颗 GPS 卫星,发明和实践了卫星定位技术。卫星定位技术原理是,覆盖全球的多颗定位卫星连续发射一定频率的无线电信号,移动终端上集成便携式卫星信号接收机,接收机接收卫星信号并测量卫星到终端接收机之间的距离,最终由移动终端利用多颗卫星位置和与这些卫星的距离计算出移动终端的具体位置。后来出现了欧洲的 Galileo、俄罗斯的 GLONASS、中国的北斗等,所以如今的 GPS 实质上是作为一个卫星定位技术体系 GNSS 的代名词,而不是单只美国的 GPS 系统。
GNSS 提供的服务包括定位、授时和导航。定位服务就是 GNSS 终端获得其位置的服务,授时服务就是 GNSS 终端获得正确时间的服务,导航服务是计算 GNSS 终端速度和运动方向的服务。GNSS 不限制终端数,在 GNSS 卫星信号不被阻挡的情况下,在地球上任何地点、任何时间,任何 GNSS 终端都可以得到正确的位置和时间。定位只需要一个条件,那就是能够接收到足够多的卫星信号。因此在室内通常无法定位。
Air8000 作为集成了 4G、Wi-Fi、BLE、GNSS(全球导航卫星系统)等多功能的高性能工业引擎,其内置的 GNSS 模块能够提供稳定、准确的定位服务。
二、演示功能概述
使用 Air8000 开发板,single 示例主要是展示 exgnss 库的三种应用模式,
exgnss.DEFAULT 模式
exgnss.TIMERORSUC 模式
exgnss.TIMER 模式
主要操作为:
1、打开三种应用模式
2、等待 40 秒关闭操作 TIMER 模式
3、然后查询三种应用模式是否处于激活模式
4、等待 10 秒关闭全部应用模式,再次查询三种模式是否处于激活模式
5、然后获取最后一次的定位经纬度数据打印
6、定位成功之后使用 exgnss 库获取 gnss 的 rmc 数据
combination 示例主要展示几种不同的应用场景:
第一种场景是:正常模式,第一步先是通过 tcp_client_main 文件连接服务器,然后第二步模块会配置 GNSS 参数,开启 GNSS 应用,第三步会开启一个 60s 的定时器,定时器每 60s 会打开一个 60sTIMERRORSUC 应用,第四步定位成功之后关闭 GNSS,然后获取 rmc 获取经纬度数据,发送经纬度数据到服务器上。
第二种场景是:低功耗模式,第一步先是通过 tcp_client_main 文件连接服务器,然后第二步模块会配置 GNSS 参数,开启 GNSS 应用,第三步会开启一个 60s 的定时器,定时器每 60s 会进入正常模式,打开一个 60sTIMERRORSUC 应用,第四步定位成功之后关闭 GNSS,然后获取 rmc 获取经纬度数据,发送经纬度数据到服务器上,进入低功耗模式。
第三种场景是:PSM+ 模式,唤醒之后第一步是配置 GNSS 参数,开启 GNSS 应用,第二步定位成功之后关闭 GNSS,然后获取 rmc 获取经纬度数据,拼接唤醒信息和经纬度信息,连接服务器,然后把数据发送数据到服务器上,配置休眠唤醒定时器 ,进入飞行模式,然后进入 PSM+ 模式。
第四种场景是:三轴加速度的应用场景,第一步先是通过 tcp_client_main 文件连接服务器,第二步配置 GNSS 参数,打开内部加速传感器,设置防抖和中断模式,关于中断触发提供了两种方案,有效震动模式和持续震动检测模式,第三步检测到有效震动或者持续震动后,打开 GNSS,每隔 5s 获取 rmc 获取经纬度数据,发送经纬度数据到服务器上。
三、准备硬件环境
本篇教程用 Air8000 开发板来开发调试。
1. Air8000 开发板
2. GNSS 天线
四、准备软件环境
准备好软件环境之后,接下来查看如何烧录项目文件到 Air8000 开发板中,将本篇文章中演示使用的项目文件烧录到 Air8000 开发板中。
五、GNSS 软硬件参考
5.1 API 接口
本教程使用 api 接口
5.2 GNSS 硬件设计
GNSS 在硬件设计中天线部分是比较关键的,可以参考这篇文章:Air8000 GNSS 硬件设计指导;https://docs.openluat.com/air8000/luatos/hardware/design/gnssant/
在开发板上,内置了 3.3V LDO, 用于有源天线供电。因此可以使用外部有源天线直接连接 GNSS 连接器。
注意:目前有源天线供电仅支持 3.3V 有源天线,请注意连接的有源天线的供电范围。
六、代码示例介绍
本文主要提供 2 个 demo 目录,single 和 combination,其中 single 只是对 exgnss 库的三种 GNSS 应用的展示,combination 主要是提供了四种应用场景
noraml:正常功耗模式定位
lowpower:低功耗模式
psm:PSM+ 模式
vibration:三轴加速度传感器触发定位
6.1 exgnss 的三种应用的用法
6.1.1 exgnss 的应用说明
关于 exgnss 库的三种应用说明:

关于应用需要注意的是:使用 exgnss.close()关闭的只是对应的应用,所有应用关闭,gnss 也会关闭,这样做的好处是可以处理不同场景下的不同逻辑,比如服务器下发一条定位指令,定位成功之后关掉,这个时候又下发了一个指令需要长开启定位,这样两种指令就会冲突,需要代码去处理到底是不是要关掉 gnss,这个时候应用的好处就体现出来了,开启 exgnss.TIMERORSUC 第一个应用,定位成功之后关掉对应的应用,同时开启 exgnss.DEFAULT 第二个应用,gnss 就会常开,在应用 1 结束之后,只会对应用进行自动关闭,不会影响到第二个应用,gnss 还会处于常开状态。
关于 agps 辅助定位的逻辑:agps 俗称辅助定位,其逻辑是把星历文件发送给 gnss 芯片,同时发送时间和用基站定位获取的大概位置,然后芯片解析处理,达到快速定位的效果。
exgnss 扩展库的辅助定位功能,我们处理方式是每个小时都会去更新星历,原因是北斗是 1h 一更新,gps 是 4h 一更新,所以取最小值,我们选择了一小时一更新
对于辅助定位需要注意的是,因为辅助定位属于强行把星历文件灌给 gnss 芯片,虽然可以达到快速定位的效果,但是 gnss 芯片实际解析星历需要时间,exgnss 库默认开启了一个 20s 的 gnss 应用,做这个操作是因为,假设开启辅助定位,定位到之后立马关掉 gnss 电源,会导致 gnss 星历解析不完全,这样会影响下次定位为冷启动,冷启动时间大概需要 35s。如果不需要这个逻辑,可以接受冷启动,或者每次都使用辅助定位,可以通过 exgnss.setup()的 auto_open=false 配置添加到配置表里面。
6.1.2 代码讲解
main.lua
主要是为了加载了 exgnss 扩展库,加载 gnss 代码

gnss.lua
主要操作为:
1.开启协程,运行 gnss_fnc 函数,通过 exgnss.setup(gnssotps)配置 gnss 的参数,通过 exgnss.open 开启三种不同的应用
2.等待 40 秒使用 exgnss.close 关闭 TIMER 模式,使用 exgnss.close 需要两个参数,第一个是 exgnss 应用模式,第二个是 tag 标签
3.然后利用 exgnss.is_active 查询三种应用模式是否处于激活模式,查询应用是否处于激活状态同样需要两个参数,第一个是 exgnss 应用模式,第二个是 tag 标签
4.等待 10 秒使用 exgnss.close_all 关闭全部应用模式,再次查询三种模式是否处于激活模式
5.然后使用 xgnss.last_loc 获取最后一次的定位经纬度数据打印
6.定位成功之后使用 subscribe 订阅"GNSS_STATE"消息,根据获取到的值判断是否定位成功,定位成功用 exgnss.rmc 获取 rmc 数据

6.1.3 效果展示





利用纠偏网站进行纠偏:所有的 GNSS 功能的坐标系均使用国际标准 WGS-84 坐标系,所以开发者在国内常见地图定位时,会发现与实际情况有几十米的误差。这并非模块问题, 而是国内地图采用了非标坐标系所致。 国内常见地图如高德地图使用 GCJ-02 坐标系, 百度地图使用 BD-09 坐标系,故此开发者需要对模块输出的经纬度进行加偏处理,才能在国内的地图上实现精确定位。
以下是纠偏网站:
http://old.openluat.com/GPS-Offset.html

6.2 正常功耗模式下的 GNSS 应用
main.lua
主要是支持 4 个场景的切换,每次只能打开一个用于测试,选择对应的功能进行测试

6.2.1 代码讲解
normal.lua
normal 主要操作:
1.开启协程,运行 gnss_fnc 函数,通过 exgnss.setup(gnssotps)配置 gnss 的参数,然后 require tcp_client_main 文件,连接服务器
2.通过 exgnss.open 开启 exgnss.TIMERORSUC 应用模式,设置的 tag 为 normal,定位时间为 60s,回调函数为 normal_cb,这个模式定位成功之后会关掉 GNSS,然后触发回调函数,回调函数的操作为,通过 exgnss.rmc(0)接口获取 rmc 数据,然后把经纬度拼接成 json 字符串的形式,通过 sys.publish 函数,把数据传给 tcp_client_sender.lua 文件里面处理。
3.用 sys.timerLoopStart()起一个 60s 触发一次的打开 GNSS 定位的定时器,回调函数为 normal_open,回调函数内容和上面开启 exgnss.TIMERORSUC 应用模式一致

6.2.2 效果展示



测试服务器收到消息:

利用纠偏网站进行纠偏:所有的 GNSS 功能的坐标系均使用国际标准 WGS-84 坐标系,所以开发者在国内常见地图定位时,会发现与实际情况有几十米的误差。这并非模块问题, 而是国内地图采用了非标坐标系所致。 国内常见地图如高德地图使用 GCJ-02 坐标系, 百度地图使用 BD-09 坐标系,故此开发者需要对模块输出的经纬度进行加偏处理,才能在国内的地图上实现精确定位。
以下是纠偏网站:
http://old.openluat.com/GPS-Offset.html

6.3 低功耗模式下的 GNSS 应用
6.3.1 代码讲解
lowpower.lua
normal 主要操作:
1.开启协程,运行 gnss_fnc 函数,通过 exgnss.setup(gnssotps)配置 gnss 的参数,然后 require tcp_client_main 文件,连接服务器。
2.通过 exgnss.open 开启 exgnss.TIMERORSUC 应用模式,设置的 tag 为 lowpower,定位时间为 60s,回调函数为 lowpower_cb,这个模式定位成功之后会关掉 GNSS,然后触发回调函数,回调函数的操作为,通过 exgnss.rmc(0)接口获取 rmc 数据,然后把经纬度拼接成 json 字符串的形式,通过 sys.publish 函数,把数据传给 tcp_client_sender.lua 文件里面处理,然后调用 pm.power(pm.WORK_MODE, 1)--进入低功耗模式,pm.power(pm.WORK_MODE,1,1)--wifi 进入低功耗模式。这两个函数主要是为了让模块和 wifi 模块进入低功耗模式。
3.用 sys.timerLoopStart()起一个 60s 触发一次的打开 GNSS 定位的定时器,回调函数为 lower_open,回调函数内容主要是调用 pm.power(pm.WORK_MODE, 0)进入正常模式,然后和上面开启 exgnss.TIMERORSUC 应用模式一致,
然后关闭 USB,节省功耗

6.3.2 效果展示


利用纠偏网站进行纠偏:我们所有的 GNSS 功能的坐标系均使用国际标准 WGS-84 坐标系,所以开发者在国内常见地图定位时,会发现与实际情况有几十米的误差。这并非模块问题, 而是国内地图采用了非标坐标系所致。 国内常见地图如高德地图使用 GCJ-02 坐标系, 百度地图使用 BD-09 坐标系,故此开发者需要对模块输出的经纬度进行加偏处理,才能在国内的地图上实现精确定位。
以下是纠偏网站:
http://old.openluat.com/GPS-Offset.html

6.4 PSM+ 模式下的 GNSS 应用
6.4.1 代码讲解
psm.lua
psm 主要操作:
1.开启协程,运行 gnss_fnc 函数,通过 exgnss.setup(gnssotps)配置 gnss 的参数。
2.通过 exgnss.open 开启 exgnss.TIMERORSUC 应用模式,设置的 tag 为 psm,定位时间为 60s,回调函数为 psm_cb,这个模式定位成功之后会关掉 GNSS,然后触发回调函数,回调函数的操作为,通过 exgnss.rmc(0)接口获取 rmc 数据,获取经纬度并赋值变量,然后使用 sysplus.taskInitEx 开启 TCP 短连接协程,连接服务器发送经纬度消息和唤醒消息内容。
3.发送完毕之后设置定时器,然后进入飞行模式,进入 psm+ 模式

6.4.2 效果展示


利用纠偏网站进行纠偏:我们所有的 GNSS 功能的坐标系均使用国际标准 WGS-84 坐标系,所以开发者在国内常见地图定位时,会发现与实际情况有几十米的误差。这并非模块问题, 而是国内地图采用了非标坐标系所致。 国内常见地图如高德地图使用 GCJ-02 坐标系, 百度地图使用 BD-09 坐标系,故此开发者需要对模块输出的经纬度进行加偏处理,才能在国内的地图上实现精确定位。
以下是纠偏网站:
http://old.openluat.com/GPS-Offset.html

6.5 运动检测定位模式下的 GNSS 应用
6.5.1 代码讲解
vibration.lua
vibration 主要操作:
1.开启协程,运行 gnss_fnc 函数,通过 exgnss.setup(gnssotps)配置 gnss 的参数,然后 require tcp_client_main 文件,连接服务器,require exvib 扩展库,
2.设置三轴加速度传感器为微小震动模式 exvib.open(1),关于 exvib 的三种模式:

3.8000 内置的三轴加速度传感器的中断触发脚为 gpio.WAKEUP2,设置 gpio 防抖为 100ms,然后设置中断触发
4.代码里面提供了两种触发方式:
第一种是持续震动模式:
加速度传感器震动之后触发中断,中断触发之后使用 exgnss.open 打开定时器,设置 exgnss.DEFAULT 模式,这种模式是一直开启 GNSS,直到调用关闭接口关闭才会关掉,定位成功之后每 5s 上传一次经纬度数据,
假设 10s 内没有再触发震动,则关闭 gnss,等待下一次震动触发
第二种方式是有效震动模式:
震动触发之后计算为一次触发,如果 10s 内触发 5 次有效震动,则开启后续逻辑,如果 10s 内没有触发 5 次,
则判定为无效震动,等待下一次触发,如果是有效震动就使用 exgnss.open 打开定时器,设置 exgnss.DEFAULT 模式,进行定位,
定位成功之后每 5s 上传一次经纬度数据到服务器,有效震动触发之后有 30 分钟的等待时间,在此期间,如果触发有效震动则
不去进行后续逻辑处理,30 分钟时间到了之后,等待下一次有效震动
这两种模式通过打开不同的注释来执行

6.5.2 效果展示
有效中断模式:



有效震动模式:



利用纠偏网站进行纠偏:所有的 GNSS 功能的坐标系均使用国际标准 WGS-84 坐标系,所以开发者在国内常见地图定位时,会发现与实际情况有几十米的误差。这并非模块问题, 而是国内地图采用了非标坐标系所致。 国内常见地图如高德地图使用 GCJ-02 坐标系, 百度地图使用 BD-09 坐标系,故此开发者需要对模块输出的经纬度进行加偏处理,才能在国内的地图上实现精确定位。
以下是纠偏网站:
http://old.openluat.com/GPS

6.6 TCP 部分代码
TCP 部分代码为通用格式内容,里面有对注释的描述,在 GNSS 篇章就不过多对 TCP 的代码做讲解了,如果有需要可以看 TCP 章节
tcp_client_main.lua

tcp_client_reveiver.lua

tcp_client_sender.lua

将定位成功后的经纬度复制到https://www.openluat.com/GPS-Offset.html。可以查看位置信息和坐标系转换后的经纬度。

七、总结
本教程详细介绍了如何使用 exgnss 扩展库搭配 Air8000 的 GNSS 功能,包括硬件连接、软件配置、代码编写等步骤。通过本教程的学习,读者应该能够掌握 exgnss 扩展库功能的基本使用方法,并能够根据实际需求进行扩展和应用。
八、注意事项与常见问题
8.1、GNSS 定位经纬度不准确
1、坐标没有纠偏,参考:http://www.openluat.com/GPS-Offset.html 进行纠偏处理
2、周围有比较高的障碍物,会导致定位误差
3、在开阔地带,正常情况下定位精度只能做到 5 米
4、不能在室内测试,必须到室外测试;如果只能在室内测试,可以淘宝搜索“GNSS 信号转发器”
8.2、Air8000 获取到的经纬度数据是基于什么坐标系
使用国际标准 WGS-84 坐标系,需要自己进行坐标系转换各 GNSS 坐标系说明以及转换方法。
8.3、GPS 天线如何设计
参考:https://docs.openluat.com/air8000/luatos/hardware/design/gnssant/
8.4、可视卫星、可用卫星有什么区别
可视卫星是当前区域,接收条件良好情况下,应该可以收到卫星信号的卫星。
可用卫星是当前已经收到信号并正在使用参与定位的卫星。
8.5、 GGA 和 RMC 应该用哪个
视具体情况而定,建议用 gga,信息相对更全面。
8.6、如何解读 NMEA 报文每个字段的含义
参考:NMEA-0183 协议简介
8.7、车载使用时需要天线引出到车顶上吗
1、挡风玻璃如果没有贴膜或者贴了不含金属材料的膜,可以放在挡风玻璃下,但是 GNSS 信号会有一定衰减,在万不得已的情况下,可以放在挡风玻璃下,最好再实际测试确认一下。 2、挡风玻璃如果贴了含有金属材料的膜,则不能放在挡风玻璃下,必须将天线到车顶。
8.8、如何输出原始 NMEA 数据
可以通过 exgnss.setup()接口的 bind 参数进行绑定。

今天的内容就分享到这里了~
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。