基于RT-Thread os实现混合定位介绍

电子说

1.3w人已加入

描述

1、介绍

wayz_iotkit 是上海图趣信息科技有限公司,针对RT-thread开发的能够实现定位功能的物联网组件。在使用传统上定位,如 GPS 等信号的同时,也支持使用基站、Wifi等数据,通过 WAYZ 定位云来进行定位。当前版本已实现支持wifi、gnss、基站定位,其中wifi定位为自动获取定位数据,gnss和基站需要开发者手动填写相关信息,后期会逐步实现对其他信号源的自动采集,进一步提升定位效果。

1.1 目录结构

WLAN技术

1.2 许可证

wayz_iotkit package 遵循 LGPLv2.1 许可,详见 LICENSE 文件。

1.3 依赖

RT-Thread 3.0+
RT-Thread 开发 WLAN 框架
webclient软件包
cJSON软件包

2、如何打开 wayz_iotkit

使用 wayz_iotkit package 需要在 RT-Thread 的包管理器中选择它,具体路径如下:

RT-Thread online packages
IOT - internet of things --->
[*] wayz_iotkit: wayz iot location
(wayz123) wifi ssid
(wayz1234) wifi password
Version (v1.0.0) --->

然后让 RT-Thread 的包管理器自动更新,或者使用 pkgs --update 命令更新包到 BSP 中。

3、使用 wayz_iotkit

4、注意事项
该组件是基于wlan框架上运用的wifi定位,前提条件必须要有wifi芯片
利用该组件时,需要重新开启任务处理,防止内存过小引发堆栈溢出错误
使用指南
这里主要介绍 wayz_iotkit 程序的基本使用流程,并针对使用过程中经常涉及到的结构体和重要 API 进行简要说明。

wayz_iotkit 的基本工作流程如下所示:

初始化 wifi、设备相关信息
将设备注册到平台上
获取定位结果(gcj02和wgs84标准)以及POI信息
menuconfig 配置说明
获取 wayz_iotkit 软件包或者修改用户配置都需要使用 menuconfig。需要用户打开 ENV 工具,并将目录切换到您所用的 BSP 目录,使用 menuconfig 命令打开配置界面。

在 RT-Thread online packages → IOT - internet of things 中选择 wayz_iotkit 软件包,操作界面如下图所示:

详细的配置介绍如下所示:

RT-Thread online packages
IOT - internet of things --->
[*] wayz_iotkit: wayz iot location # 打开 wayz_iotkit 软件包
(wayz123) wifi ssid # wifi 名字
(wayz1234) wifi password # wifi 密码
Version (latest) ---> # 选择软件包版本,默认为最新版本
选择合适的配置项后,使用 pkgs --update 命令下载软件包并更新用户配置。

注:wifi 名字和密码 供软件包切换模式用

工作原理

设备中wifi模块获取周围环境中的wifi信息,组包通过http方式上传到WAYZ定位云平台,云平台进行分析后将经纬度等其他信息一并返回到软件包,软件包通过处理可以得到gcj02和wgs84标准的经纬度,和POI信息。也可以通过传入gnss、基站等相关数据获取定位结果及其POI信息

wifi、设备相关初始化
typedef struct device_info // 设备信息
{
char *dev_name; // 设备名称
char *manufacturer; // 设备制造厂家
char *SN; // 设备序列号
char *product; // 设备所属产品
char *tenant; // 设备所属租户,通常是开放平台的用户 ID
}tdeviec_info;
typedef struct wifi_info // wifi 相关信息
{
char *ssid; // 保存wifi名称
char *passwd; // 保存wifi密码
}twifi_info;
twifi_info 用于保存建立连接的 wifi相关信息,在设备上传周围wifi信息时联网使用。用户在使用 WiFi 建立连接会话前,必须定义一个存储会话内容的结构体,如下所示:

twifi_info *wlan_info;
wlan_info = wifi_param_init(WIFI_SSID, WIFI_PWD);
tdeviec_info 用于保存注册到平台设备信息,在设备注册使用。用户在使用连接会话前,必须定义一个存储会话内容的结构体,如下所示:

tdeviec_info *dev_info;
dev_info = dev_para_init(DEV_NAME, VENDER, PRODUCT, SN, TENANT);

设备注册

应用程序使用dev_register_init函数注册设备到平台。其中ACCESS_KEY需要在平台申请

示例代码如下所示:

ret = dev_register_init(wlan_info, dev_info, ACCESS_KEY);
if (ret != DEV_REGISTER_OK)
{
rt_kprintf("�33[31;22mdevice register failure. �33[0mn");
return ;
}
填充GNSS、基站信息定位
typedef struct gnss_unit
{
uint64_t timestamp; // 数据收集的时间戳(UTC 时间,单位:毫秒)
double lng; // 经度
double lat; // 纬度
float accuracy; // 卫星定位水平精度,单位:米
}tgnss_unit;
typedef struct cell_unit
{
uint64_t timestamp; // 数据收集的时间戳(UTC 时间,单位:毫秒)
uint32_t cell_id; // 小区 ID,当 CDMA 时,为 BID(Base Station ID)
char radio_type[7]; // 基站类型,只能是以下值:gsm, wcdma, lte, cdma
uint32_t mcc; // mobileCountryCode:MCC 码
uint32_t mnc; // mobileNetworkCode:当 CDMA 时,为 SID(System ID)码
uint32_t lac; // locationAreaCode:当 CDMA 时,为 NID(Network ID);
当 LTE 时,为 TAC(Tracking Area code)
}tcell_unit;

通过填充GNSS、基站等数据,传入定位接口即可获取定位结果信息

获取定位结果

应用程序使用get_position_info函数从平台端获取位置信息。其中ACCESS_KEY需要在平台上申请

location_print函数是打印位置相关信息

示例代码如下所示:

tlocation_info location = {0};
ret = get_position_info(wlan_info, ACCESS_KEY, RT_NULL, &location);
if (RT_ERROR == ret)
{
rt_kprintf("�33[31;22mthe device failed to obtain latitude and longitude information.�33[0mn");
}
else
{
location_print(location);
}

其中get_position_info函数第三个参数为填充的GNSS和基站数据,相关操作可以参照示例文档

打印位置信息结果

-------------------location result-------------------------------
timestamp: 1606293694990
gcj02:
latitude:30.515105
longitude:114.401555
wgs84:
latitude:30.517407914397
longitude:114.396014616712
POI: {"id": "7SkEZdfXQfS","type": "Residential","name": "中建东湖明珠国际公馆","categories":[{"id": 10200,"name": "住宅"}]}
-------------------location result end---------------------------

定位轮询频次

该引用可以通过循环的模式来设置定位频次,其中POINT_FRQ为定位频次的设置

示例代码如下所示:

while (1)
{
ret = get_position_info(wlan_info, ACCESS_KEY, RT_NULL, &location);
if (RT_ERROR == ret)
{
rt_kprintf("�33[31;22mthe device failed to obtain latitude and longitude information.�33[0mn");
}
else
{
location_print(location);
}
rt_thread_mdelay(POINT_FRQ);
rt_memset(&location, 0, sizeof (location));
}
wayz_iotkit API
/**

  • Wifi parameter initialized
  • @param ssid: Wifi name
  • @param passwd: Wifi password
  • @return twifi_info: Dynamic allocation wifi info structure
    */
    twifi_info *wifi_param_init(const char ssid, const char passwd);
    /
  • device parameter initialized
  • @param dev_name: device name
  • @param manufacturer: device manufacturer
  • @param product: product name
  • @param SN: product serial number
  • @param tenant: tenant device
  • @return tdeviec_info: Dynamic allocation device info structure
    */
    tdeviec_info *dev_para_init(const char *dev_name, const char *manufacturer, const char *product,
    const char SN, const char tenant);
    /
  • Wifi station mac address
  • @param data: Wifi station mac address data
  • @return void
    /
    void get_sta_mac_addr(char data);
    /
  • Connected to the Internet to register
  • @param wlan_info: wifi name , wifi passwd
  • @param dev_info: device info ,(dev_name、manufacturer、SN、product、tenant)
  • @param key: Visiting the website key
  • @return =0: wifi connect failure
  • =1: device register success
    
  • =2: device register failure
    

*/
char dev_register_init(twifi_info *wlan_info, tdeviec_info dev_info, char key);
/

  • Get the positioning result function
  • @param wlan_info Wifi related information
  • @param key Visiting the website key
  • @param post_data post gnss and cellulars data, obtain positioning results
  • @param location get location result
  • @return >0: success
  • =0: location failure
    

*/
char get_position_info(twifi_info *wlan_info, char *key, tpost_data post_data, tlocation_info location);
/

  • print location result
  • @param location location info
  • @return void:

*/
void location_print(tlocation_info location);

wayz_iotkit 示例程序

WLAN技术

运行示例

1、申请ACCESS_KEY
需要在平台申请ACCESS_KEY,目前只能提供人工申请的方式
在示例代码中的宏中填写申请的ACCESS_KEY字段,例如:
#define ACCESS_KEY "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

2、填写wifi、设备相关信息
修改将所要连接网络的AP即用户名、密码等;也可以在选择组件时指定wifi相关信息。例如:

ifdef PKG_WAYZ_IOTKIT_WIFI_SSID
define WAYZ_WIFI_SSID PKG_WAYZ_IOTKIT_WIFI_SSID
else
define WAYZ_WIFI_SSID “thread”
endif
ifdef PKG_WAYZ_IOTKIT_WIFI_PASSWORD
define WAYZ_WIFI_PWD PKG_WAYZ_IOTKIT_WIFI_PASSWORD
else
define WAYZ_WIFI_PWD “12345678”
endif
修改设备相关信息,例如:
```c
#define  DEV_NAME       "PANDDRA"      // 设备名称
#define  VENDER         "ALIENTEK"       // 设备生产商
#define  PRODUCT        "FINDU01"       // 设备所属产品
#define  SN             "1234567"       // 产品序列号
#define  TENANT         "WAYZ"           // 设备所属租户,通常是开放平台的用户 ID
3、GNSS、基站数据的填充
tpost_data post_data = {0};                    // 定义上传数据结构体
post_data.gnss.timestamp = 1606729066000;
post_data.gnss.lng = 114.39583641301239;
post_data.gnss.lat = 30.51769862171484;
post_data.gnss.accuracy = 8;
post_data.cellulars.count = 1;
post_data.cellulars.cell[0].timestamp = 1515743846504;
post_data.cellulars.cell[0].cell_id = 149833211;
rt_sprintf(post_data.cellulars.cell[0].radio_type, "%s", "gsm");
post_data.cellulars.cell[0].mcc = 460;
post_data.cellulars.cell[0].mnc = 11;
post_data.cellulars.cell[0].lac = 36558;
// 传入获取定位函数中
get_position_info(wlan_info, ACCESS_KEY, &post_data, &location);
4、在finsh命令行中输入location_test命令即可调用示例代码
示例结果
timestamp: 1606293694990 ms
gcj02:
    latitude:30.515105
    longitude:114.401555
wgs84:
    latitude:30.517407914397
    longitude:114.396014616712
POI: {"id": "7SkEZdfXQfS","type": "Residential","name": "中建东湖明珠国际公馆","categories":[{"id": 10200,"name": "住宅"}]}
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分