本博文将介绍我们基于 SSID 的 Wi-Fi 定位解决方案的工作原理以及如何开始测试。然后,我们将使用 nRF9160 DK、nRF7002 EK和 PPK2 执行并展示实际功耗和准确性测量,以比较 nRF Cloud 提供的不同定位服务的性能。
背景知识
1. Wi-Fi 定位服务
Wi-Fi 定位是一种地理定位功能,可让支持 Wi-Fi 的设备利用附近 Wi-Fi 网络的数据确定自己的大致位置。它的工作原理是检索附近网络的 SSID、BSSID 和信号强度等 Wi-Fi 网络信息,并将这些信息与已知位置的 Wi-Fi 网络数据库进行比较。
Wi-Fi 定位系统包含以下关键组件:
将 MAC 地址等 Wi-Fi 网络信息映射到位置的数据库。该数据库由定位服务提供商维护。
通过查找数据库中的匹配模式并计算信号强度来估计位置的算法。
2. nRF Cloud Wi-Fi 定位服务
通过利用 nRF Cloud 的优化定位算法,基于 Nordic SoC 和 模组的产品可在定位用例中实现高性能和超低功耗。对于 Wi-Fi 定位请求,nRF Cloud 可借助 Wi-Fi 数据库计算设备位置,该数据库包含不同 Wi-Fi 网络的坐标。然后,设备位置将从 nRF Cloud发送到客户云或返回到设备。
3.?nRF70 系列
此外,我们最近还推出了专用于该用例的 nRF7000。这是一款双频 Wi-Fi 配套 IC,不发送数据,但可以进行主动和被动扫描,纯粹用于 Wi-Fi 定位目的。结合我们的 nRF9160 蜂窝物联网模组和 nRF Cloud服务,nRF7000 可通过嗅探本地 Wi-Fi 接入点的 SSID 实现基于 Wi-Fi 的定位服务。
Wi-Fi 定位服务流程
让我们测试一下 nRF Cloud Wi-Fi 定位服务如何在室内环境中工作。
软件:nRF Connect SDK v2.4.2、MFW v1.3.5、nRF Connect for Desktop 中的 Power Profiler 应用程序。
# Add the following lines to the end of prj.conf
CONFIG_LOCATION_LOG_LEVEL_DBG=y
CONFIG_NRF_CLOUD_REST_LOG_LEVEL_DBG=y
CONFIG_REST_CLIENT_LOG_LEVEL_DBG=y
CONFIG_NRF_CLOUD_LOG_LOG_LEVEL_DBG=y
CONFIG_NRF_CLOUD_LOG_LEVEL_DBG=y
步骤 1:扫描 Wi-Fi 接入点信息
在此步骤中,配置 Wi-Fi 定位服务,设备开始扫描附近的 Wi-Fi 接入点。结果显示,设备在奥斯陆Nordic Semiconductor办公楼附近或内找到了 14 个 Wi-Fi 接入点。
- Requesting Wi-Fi location?with?GNSS?and?cellular fallback...
- [00:01:19.903,594] <dbg> location: location_core_config_log: Location configuration:
- [00:01:19.911,682] <dbg> location: location_core_config_log: Methods count:?1
- [00:01:19.919,342] <dbg> location: location_core_config_log: Interval:?0
- [00:01:19.926,605] <dbg> location: location_core_config_log: Timeout:?300000ms
- [00:01:19.934,356] <dbg> location: location_core_config_log: Mode:?0
- [00:01:19.941,223] <dbg> location: location_core_config_log: List of methods:
- [00:01:19.948,913] <dbg> location: location_core_config_log: Method?#0
- [00:01:19.956,146] <dbg> location: location_core_config_log: Method type: Wi-Fi (3)
- [00:01:19.964,660] <dbg> location: location_core_config_log: Timeout:?30000ms
- [00:01:19.972,686] <dbg> location: location_core_config_log: Service: Any (0)
- [00:01:20.044,921] <dbg> location: location_request_info_create: Wi-Fi?and?cellular methods are?not?one after the other?in?method list so they are?not?combined
- [00:01:20.059,448] <dbg> location: location_core_location_get_pos: Requesting location?with?'Wi-Fi'?method
- [00:01:20.069,458] <dbg> location: location_core_location_get_pos: Starting request timer?with?timeout=300000
- [00:01:20.079,711] <dbg> location: location_core_timer_start: Starting timer?with?timeout=30000
- [00:01:20.088,745] <dbg> location: scan_wifi_start: Triggering start of Wi-Fi scanning
- [00:01:24.832,458] <dbg> location: scan_wifi_result_handle: scan result?#1 stored: ssid XXXX, channel 108, mac 24:36:da:16:xx:xx
- [00:01:24.845,184] <dbg> location: scan_wifi_result_handle: scan result?#2 stored: ssid XXXX, channel 108, mac 24:36:da:16:xx:xx
- [00:01:24.858,093] <dbg> location: scan_wifi_result_handle: scan result?#3 stored: ssid XXXX, channel 11, mac 24:36:da:16:xx:xx
- [00:01:24.870,910] <dbg> location: scan_wifi_result_handle: scan result?#4 stored: ssid XXXX, channel 11, mac 24:36:da:16:xx:xx
- [00:01:24.883,483] <dbg> location: scan_wifi_result_handle: scan result?#5 stored: ssid XXXX, channel 1, mac 24:36:da:11:xx:xx
- [00:01:24.896,209] <dbg> location: scan_wifi_result_handle: scan result?#6 stored: ssid XXXX, channel 1, mac 24:36:da:17:xx:xx
- [00:01:24.908,935] <dbg> location: scan_wifi_result_handle: scan result?#7 stored: ssid XXXX, channel 1, mac 24:36:da:17:xx:xx
- [00:01:24.921,417] <dbg> location: scan_wifi_result_handle: scan result?#8 stored: ssid XXXX, channel 64, mac 24:36:da:11:xx:xx
- [00:01:24.933,990] <dbg> location: scan_wifi_result_handle: scan result?#9 stored: ssid XXXX, channel 64, mac 24:36:da:11:xx:xx
- [00:01:24.946,807] <dbg> location: scan_wifi_result_handle: scan result?#10 stored: ssid XXXX, channel 6, mac 8a:5a:85:af:xx:xx
- [00:01:24.959,442] <dbg> location: scan_wifi_result_handle: scan result?#11 stored: ssid XXXX, channel 100, mac 24:36:da:17:xx:xx
- [00:01:24.972,167] <dbg> location: scan_wifi_result_handle: scan result?#12 stored: ssid XXXX, channel 6, mac 34:21:09:48:xx:xx
- [00:01:24.984,649] <dbg> location: scan_wifi_result_handle: scan result?#13 stored: ssid XXXX, channel 132, mac 24:36:da:11:xx:xx
- [00:01:24.997,619] <dbg> location: scan_wifi_result_handle: scan result?#14 stored: ssid XXXX, channel 132, mac 24:36:da:11:xx:xx
- [00:01:25.010,284] <dbg> location: scan_wifi_done_handle: Scan request done?with?14?Wi-Fi Aps
步骤 2:请求 nRF Cloud Wi-Fi 定位
nRF9160 会将 Wi-Fi 接入点信息(包括 MAC 地址、SSID、信号强度和信道)编码为 JSON 文件。然后,JSON 文件将被发送到 nRF Cloud,nRF Cloud 将使用这些数据检查 Wi-Fi 定位数据库,并使用特定算法计算设备位置。结果包含纬度、经度、精确度等信息。有关 API 请求和响应格式,请参阅 nRF Cloud REST API 文档。
- [00:01:25.028,015] <dbg> location: cloud_service_location_get: Cloud service location parameters:
- [00:01:25.037,170] <dbg> location: cloud_service_location_get: Service:?0
- [00:01:25.044,494] <dbg> location: cloud_service_location_get: Timeout:?25060ms
- [00:01:25.052,337] <dbg> location: cloud_service_nrf_pos_get:?Sending positioning?request(REST)
- [00:01:25.160,125] <dbg> nrf_cloud_codec_internal: nrf_cloud_location_req_json_encode: JSON: {"wifi":{"accessPoints":[{"macAddress":"24:36:da:16:xx:xx","ssid":"XXXX","signalStrength":-41,"channel":108},{"macAddress":"24:36:da:16:xx:xx","ssid":"XXXX","signalStrength":-41,"channel":108},{"macAddress":"24:36:da:16:xx:xx","ssid":"XXXX","signalStrength":-48,"channel":11},{"macAddress":"24:36:da:16:xx:xx","ssid":"XXXX","signalStrength":-49,"channel":11},{"macAddress":"24:36:da:11:xx:xx","ssid":"XXXX","signalStrength":-63,"channel":1},{"macAddress":"24:36:da:17:xx:xx","ssid":"XXXX","signalStrength":-70,"channel":1},{"macAddress":"24:36:da:17:xx:xx","ssid":"XXXX","signalStrength":-70,"channel":1},{"macAddress":"24:36:da:11:xx:xx","ssid":"XXXX","signalStrength":-72,"channel":64},{"macAddress":"24:36:da:11:xx:xx","ssid":"XXXX","signalStrength":-72,"channel":64},{"macAddress":"8a:5a:85:af:xx:xx","ssid":"XXXX","signalStrength":-73,"channel":6},{"macAddress":"24:36:da:17:xx:xx","ssid":"XXXX","signalStrength":-75,"channel":100},{"macAddress":"34:21:09:48:xx:xx","ssid":"XXXX","signalStrength":-76,"channel":6},{"macAddress":"24:36:da:11:xx:xx","ssid":"XXXX","signalStrength":-85,"channel":132},{"macAddress":"24:36:da:11:xx:xx","ssid":"XXXX","signalStrength":-85,"channel":132}]}}
- [00:01:25.283,142] <dbg> rest_client: rest_client_request: Requesting destination HOST: api.nrfcloud.com at port?443, URL: /v1/location/ground-fix
- [00:01:25.296,966] <dbg> rest_client: rest_client_request: Payload: {"wifi":{"accessPoints":[{"macAddress":"24:36:da:16:xx:xx","ssid":"XXXX","signalStrength":-41,"channel":108},{"macAddress":"24:36:da:16:xx:xx","ssid":"XXXX","signalStrength":-41,"channel":108},{"macAddress":"24:36:da:16:xx:xx","ssid":"XXXX","signalStrength":-48,"channel":11},{"macAddress":"24:36:da:16:xx:xx","ssid":"XXXX","signalStrength":-49,"channel":11},{"macAddress":"24:36:da:11:xx:xx","ssid":"XXXX","signalStrength":-63,"channel":1},{"macAddress":"24:36:da:17:xx:xx","ssid":"XXXX","signalStrength":-70,"channel":1},{"macAddress":"24:36:da:17:xx:xx","ssid":"XXXX","signalStrength":-70,"channel":1},{"macAddress":"24:36:da:11:xx:xx","ssid":"XXXX","signalStrength":-72,"channel":64},{"macAddress":"24:36:da:11:xx:xx","ssid":"XXXX","signalStrength":-72,"channel":64},{"macAddress":"8a:5a:85:af:xx:xx","ssid":"XXXX","signalStrength":-73,"channel":6},{"macAddress":"24:36:da:17:xx:xx","ssid":"XXXX","signalStrength":-75,"channel":100},{"macAddress":"34:21:09:48:xx:xx","ssid":"XXXX","signalStrength":-76,"channel":6},{"macAddress":"24:36:da:11:xx:xx","ssid":"XXXX","signalStrength":-85,"channel":132},{"macAddress":"24:36:da:11:xx:xx","ssid":"XXXX","signalStrength":-85,"channel":132}]}}[00:01:25.417,358] <dbg> rest_client: rest_client_sckt_connect:?Doing?getaddrinfo()?with?connect addr api.nrfcloud.com port 443
- [00:01:25.435,699] <dbg> rest_client: rest_client_sckt_connect:?getaddrinfo() 52.70.xxx.xxx
- [00:01:25.445,892] <dbg> rest_client: rest_client_sckt_connect: Connecting to api.nrfcloud.com port 443
- +CSCON: 1
- [00:01:26.902,130] <dbg> rest_client: rest_client_http_response_cb: HTTP: All data?received(content/total:?79/328), status: 200 OK
- [00:01:26.914,245] <dbg> rest_client: rest_client_request: API call response len: http status: 200, 79 bytes
- [00:01:26.926,025] <dbg> location: location_core_event_cb_fn: Location acquired successfully:
- [00:01:26.934,844] <dbg> location: location_core_event_cb_fn: method: Wi-Fi(3)
- [00:01:26.942,901] <dbg> location: location_core_event_cb_fn: latitude: 59.920980
- [00:01:26.950,988] <dbg> location: location_core_event_cb_fn: longitude: 10.689317
- [00:01:26.959,136] <dbg> location: location_core_event_cb_fn: accuracy: 15.0 m
- [00:01:26.966,857] <dbg> location: location_core_event_cb_fn: date: 2023-08-31
- [00:01:26.974,609] <dbg> location: location_core_event_cb_fn: time: 13:49:40.035 UTC
- [00:01:26.982,879] <dbg> location: location_core_event_cb_fn: Google maps URL: https://maps.google.com/?q=59.920980,10.689317
- Got location:
- method: Wi-Fi
- latitude: 59.920980
- longitude: 10.689317
- accuracy: 15.0 m
- date: 2023-08-31
- time: 13:49:40.035 UTC
- Google maps URL: https://maps.google.com/?q=59.920980,10.689317
步骤 3:设备进入休眠状态
当 RRC 非活动定时器到期时,nRF9160 将进入 RRC 空闲状态。我将活动定时器 (T3324) 设置为 0 (CONFIG_LTE_PSM_REQ_RAT=“00000000”) 以帮助设备进入 RRC 空闲状态后立即进入 PSM 以节省功耗。RRC 闲置定时器由移动网络运营商配置(此处挪威电信为 5 秒)。如果 MNO 支持快速释放功能 (AS-RAI),设备可通过发送 RAI 通知基站释放它们之间的无线连接,从而立即进入 RRC 空闲状态。这将进一步降低总功耗。您可以从这篇博客中了解有关 RAI 的更多信息:
最大限度延长蜂窝物联网的电池寿命: 对 eDRX、PSM 和 AS-RAI 的分析。
https://www.nordicsemi.cn/blog/maximizing-battery-lifetime-in-cellular-iot-an-analysis-of-edrx-psm-and-as-rai/
准确性:?但在精确度方面,情况恰恰相反。全球导航卫星系统的定位精度高于其他两种系统,而 Wi-Fi 的定位精度则高于蜂窝定位服务。
在为应用选择合适的定位服务时,功耗和准确性是最重要的考虑因素,但您还应考虑室内/室外环境使用、Wi-Fi 和蜂窝网络覆盖等因素,以选择最佳的定位服务或在它们之间进行切换。下表列出了不同 nRF Cloud 定位服务的性能,并根据准确性、延迟和功耗等因素进行了衡量。
为了帮助您了解如何在实践中进行评估,我们对使用不同定位方法时的功耗进行了测量。测量仍然基于 nRF Connect SDK 样本 Cellular: Location。测试地点位于Nordic Semiconductor奥斯陆办公楼的楼顶。
/**
*?@brief?Retrieve location with cellular location service.
*/
staticvoidlocation_cellular_get(void)
{
int err;
structlocation_configconfig;
enumlocation_methodmethods[] = {LOCATION_METHOD_CELLULAR};
location_config_defaults_set(&config,?ARRAY_SIZE(methods), methods);
printk("Requesting cellular location...n");
err =?location_request(&config);
if?(err) {
printk("Requesting location failed, error: %dn", err);
return;
}
location_event_wait();
}
Requesting?cellular location...
Got?location:
method: Cellular
latitude:?59.920624
longitude:?10.689719
accuracy:?1708.0?m
date:?2023-09-04
time:?12:47:23.399?UTC
Google?maps URL: https://maps.google.com/?q=59.920624,10.689719
Got?location:
method: Wi-Fi
latitude:?59.919015
longitude:?10.688577
accuracy:?30.0?m
date:?2023-09-04
time:?12:47:51.753?UTC
Google?maps URL: https://maps.google.com/?q=59.919015,10.688577
低精度模式可让 GNSS 展示较宽松的固定接受标准,以节省功耗。GNSS 定位服务有三种精度模式:低精度、正常精度和高精度。精度越高,设备的耗电量就越大,但根据经验,我们知道所有精度模式的耗电量都高于 Wi-Fi 和蜂窝定位服务。
在 GNSS 定位服务测量中,我们预计即使 GNSS 的低精度模式也会比 Wi-Fi 和蜂窝定位服务提供更好的定位精度,因此在测量中使用了低精度模式,我们可以看到 GNSS 与其他定位服务 “最接近 ”的功耗差异。结果确实证明了这一假设。A-GPS 数据只请求一次,以加快 TTFF 的速度。请注意,只要设备中的历书和星历数据仍然有效,就不需要 A-GPS 请求。
PPK2 测量结果显示,在没有 A-GPS 数据请求过程的情况下,该事件的总电荷量为 316.71mC,日志显示精度为 16.9m。
Got?location:
method: GNSS
latitude:?59.920928
longitude:?10.689040
accuracy:?16.9?m
date:?2023-09-04
time:?12:48:34.586?UTC
Google?maps URL: https://maps.google.com/?q=59.920928,10.689040
结果
请注意,图表中的表格列出了不同定位服务的最佳精度;实际精度在实践中会有所不同。例如,在高楼环绕的城市中,由于反射和建筑物会干扰 GNSS 信号,GNSS 定位服务的精度可能比 Wi-Fi 低。根据应用需求选择正确的定位服务方法并通过测量评估实际定位精度和功耗非常重要。
912