前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于RT-Thread os混合定位

基于RT-Thread os混合定位

原创
作者头像
用户8417554
修改2021-03-19 18:06:03
4270
修改2021-03-19 18:06:03
举报
文章被收录于专栏:物联网方向物联网方向

# wayz_iotkit

## 1、介绍

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

### 1.1 目录结构

| 名称 | 说明 |

| ---- | ---- |

| docs | 文档目录 |

| examples | 例子目录,并有相应的一些说明 |

| inc | 头文件目录 |

| src | 源代码目录 |

### 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

- 如何从零开始使用,请参考 [用户手册](docs/user-guide.md)

- 完整的 API 文档,请参考 [API 手册](docs/api.md)

- 详细的示例介绍,请参考 [示例文档](docs/samples.md)

## 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** 软件包,操作界面如下图所示:

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

```shell

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、设备相关初始化

```c

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 建立连接会话前,必须定义一个存储会话内容的结构体,如下所示:

```c

twifi_info *wlan_info;

wlan_info = wifi_param_init(WIFI_SSID, WIFI_PWD);

```

`tdeviec_info` 用于保存注册到平台设备信息,在设备注册使用。用户在使用连接会话前,必须定义一个存储会话内容的结构体,如下所示:

```c

tdeviec_info *dev_info;

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

```

## 设备注册

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

示例代码如下所示:

```c

ret = dev_register_init(wlan_info, dev_info, ACCESS_KEY);

if (ret != DEV_REGISTER_OK)

{

rt_kprintf("\033[31;22mdevice register failure. \033[0m\n");

return ;

}

```

## 填充GNSS、基站信息定位

```c

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`函数是打印位置相关信息

示例代码如下所示:

```c

tlocation_info location = {0};

ret = get_position_info(wlan_info, ACCESS_KEY, RT_NULL, &location);

if (RT_ERROR == ret)

{

rt_kprintf("\033[31;22mthe device failed to obtain latitude and longitude information.\033[0m\n");

}

else

{

location_print(location);

}

```

- 其中`get_position_info`函数第三个参数为填充的`GNSS和基站数据`,相关操作可以参照[示例文档](docs/samples.md)

**打印位置信息结果**

```c

-------------------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为定位频次的设置**

示例代码如下所示:

```c

while (1)

{

ret = get_position_info(wlan_info, ACCESS_KEY, RT_NULL, &location);

if (RT_ERROR == ret)

{

rt_kprintf("\033[31;22mthe device failed to obtain latitude and longitude information.\033[0m\n");

}

else

{

location_print(location);

}

rt_thread_mdelay(POINT_FRQ);

rt_memset(&location, 0, sizeof (location));

}

```

# wayz_iotkit API

```c

/**

* 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 manufacture

*

* @param product: product name

*

* @param SN: product serial numbe

*

* @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 registe

*

* @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 示例程序 #

| 示例程序路径 | 说明 |

| ---- | ---- |

| samples/location_client.c.c | wayz_iotkit 测试例程 |

## 运行示例 ##

## 1、申请ACCESS_KEY

- 需要在平台申请ACCESS_KEY,目前只能提供人工申请的方式

在示例代码中的宏中填写申请的ACCESS_KEY字段,例如:

```c

#define ACCESS_KEY "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

```

## 2、填写wifi、设备相关信息

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

```c

#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、基站数据的填充

```c

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`命令即可调用示例代码

## 示例结果 ##

```c

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": "住宅"}]}

```

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档