DWM1000 多个标签定位讨论 --[蓝点无限]
多标签代码已经基本实现,完成代码可以在论坛上下载
http://bphero.com.cn/forum.php?mod=viewthread&tid=53&fromuid=2
蓝点DWM1000 模块已经打样测试完毕,有兴趣的可以申请购买了,更多信息参见 蓝点论坛

20181125 更新,按照下面的逻辑,已经完成代码,全部代码编译通过,需要后期测试。
1 单个标签定位模式
定位实现基于DWM1000 基础API 实验SS-TWR或者DS-TWR方法,非官方定位源码,官方定位源码使用的是大状态机。
当单个标签定位基本流程是TAG 与ANTHOR0 基于SS/DS-TWR计算距离,然后依次再 ANTHOR1 ANTHOR2计算距离,分别步骤如下图的0 , 1 ,2 ,其中每一步都会有poll、response 以及finnal 多条信息。
而且,通过代码知道,tag 发送一定信息后,会进入等待状态,而anthor0 发送一条信息后也会进入等待状态,但是由于TAG分别与各个ANTHOR通信,所以中间的等待状态不会被破坏。

2 多个标签定位模式
下图是一个多标签定位简图,图中 有两个TAG,3个ANTHOR,其中每个TAG依然单独分别按照顺序与ANTHOR0/1/2 通信

但是会出现如下几种特殊情况需要处理:
1 TAG0 可能和 TAG1 同时给某一个ANCHOR发送信息,这个同时是相对广义的,因为通过代码发现,TAG和ANCHOR 之间测距需要一段时间,交换多条信息后才能实现,假如TAG0 和 ANTHOR已经建立连接,正在交换信息,若TAG1 也发送Poll 信息给ANTHOR0时,ANTHOR0 需要丢弃TAG1 的信息。
处理方法:当ANTHOR 接收到一条Poll信息后,更新目标TAG ID,若后面再接收到信息TAG ID与poll 信息TAG ID一致回复finnal 信息,否则认为冲突不做处理,若连续接收到两条poll 信息,更新目标TAG ID,以最后一次的TAG ID为准。
2 更为严重的是,TAG1 发送的任何信息TAG0都会收到,当然可以和上面一样比较TAG ID后可以丢弃,但是会导致TAG0 退出正常的测距循环(每次TAG 和 ANTHOR 进行测距,多条信息依次发送,当TAG发送一条信息后进入等待状态,若此时收到TAG1的信息,那TAG0就会退出与ANTHOR之间测距),这样的严重后果是,两个TAG相互发送数据,导致每个TAG均不能完成任何依次完成的测距。
处理办法:这个问题有一点类似“多核”问题,需要引入"锁"或者“信号量”的概念,ANTHOR 可以认为是资源。
1 程序初始化,TAG0默认获得"锁"或者“信号量”,与三个ANTHOR 发送信息,测试距离,当测距后。
2 TAG0 发送释放信号量信息,若网络中有其他TAG,收到该信息后,回复给TAG0(只有TAG可以回复该信息),且将TAG ID回复给TAG0,可以扩展其他信息。
3 TAG0 收到信号量请求信息后,发送“信号量”释放信息,“信号量”释放信息包含TAG ID以及其他扩展信息。
4 TAG收到信号量后,与系统中的三个ANTHOR进行数据交换,进行测距,测距完成后,发送释放“信号量”信息
5 TAG0 收到释放信号量信息,回收信号量,并回复给之前TAG
6 TAG0 根据网络状况,决定自己测距,还是继续释放信号量给其他TAG
其它问题:SS-TWR/DS-TWR 都会遇到问题,同一个区域内,如果有多个定位网络,则由于没有进行有效过滤,多个网络如果模式相同,数据相互影响(相同模式:包含射频频率 preamble 等设定相同)
后期需要引入PANID 以及 filter等,将不符合的信息直接在底层就过滤掉。
TAG 共享信号量代码参考
#ifdef TAG
/* Set expected response's delay and timeout. See NOTE 4 and 5 below.
* As this example only handles one incoming frame with always the same delay and timeout, those values can be set here once for all. */
dwt_setrxaftertxdelay(POLL_TX_TO_RESP_RX_DLY_UUS);
dwt_setrxtimeout(RESP_RX_TIMEOUT_UUS); OLED_ShowString(,,"DS TWR TAG:");
OLED_ShowString(,,"Distance:"); if(TAG_ID == MASTER_TAG)
{
Semaphore_Enable = ;
Waiting_TAG_Release_Semaphore = ;
}
else
{
Semaphore_Enable = ;
}
//Master TAG0
while()
{
if(Semaphore_Enable == )
{
//send message to anthor,TAG<->ANTHOR
//measure_distance(); add later
Semaphore_Enable = ;
if(TAG_ID != MASTER_TAG)
{
//send release semaphore to master tag
Semaphore_Release[ALL_MSG_SN_IDX] = frame_seq_nb;
Semaphore_Release[ALL_MSG_TAG_IDX] = TAG_ID;
dwt_writetxdata(sizeof(Semaphore_Release), Semaphore_Release, );
dwt_writetxfctrl(sizeof(Semaphore_Release), ); dwt_starttx(DWT_START_TX_IMMEDIATE );
while (!(dwt_read32bitreg(SYS_STATUS_ID) & SYS_STATUS_TXFRS))
}
} if(TAG_ID == MASTER_TAG)//master tag
{
//statistics tag
if(sum(Semaphore[]) == )
{
for(TAG_INDEX = ; TAG_INDEX <MAX_TAG; TAG_INDEX++)
{
Tag_Statistics[ALL_MSG_SN_IDX] = frame_seq_nb;
Tag_Statistics[ALL_MSG_TAG_IDX] = TAG_INDEX;
dwt_writetxdata(sizeof(Tag_Statistics), Tag_Statistics, );
dwt_writetxfctrl(sizeof(Tag_Statistics), );
dwt_starttx(DWT_START_TX_IMMEDIATE | DWT_RESPONSE_EXPECTED); while (!((status_reg = dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_ERR)))
{ }; if (status_reg & SYS_STATUS_RXFCG)
{
/* Clear good RX frame event and TX frame sent in the DW1000 status register. */
dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG | SYS_STATUS_TXFRS); /* A frame has been received, read it into the local buffer. */
frame_len = dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFLEN_MASK;
if (frame_len <= RX_BUF_LEN)
{
dwt_readrxdata(rx_buffer, frame_len, );
} if (memcmp(rx_buffer, Tag_Statistics_response, ALL_MSG_COMMON_LEN) == )
{
Semaphore[Tag_Statistics_response[TAG_INX]] = ;
}
}
else{
/* Clear RX error events in the DW1000 status register. */
dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_ERR);
}
}
}
//pick one tag ,send Semaphore message
//release to specific tag(TAG ID)
//master tag send release signal,and the specific tag send comfirm message
if(Waiting_TAG_Release_Semaphore == && sum(Semaphore[]) != )
{
for(TAG_INDEX = ; TAG_INDEX <MAX_TAG; TAG_INDEX++)
{
if(Semaphore[TAG_INDEX] == )
{
Master_Release_Semaphore[ALL_MSG_SN_IDX] = frame_seq_nb;
Master_Release_Semaphore[ALL_MSG_TAG_IDX] = TAG_INDEX;
dwt_writetxdata(sizeof(Master_Release_Semaphore), Master_Release_Semaphore, );
dwt_writetxfctrl(sizeof(Master_Release_Semaphore), );
dwt_starttx(DWT_START_TX_IMMEDIATE | DWT_RESPONSE_EXPECTED); while (!((status_reg = dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_ERR)))
{ }; if (status_reg & SYS_STATUS_RXFCG)
{
dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG | SYS_STATUS_TXFRS); frame_len = dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFLEN_MASK;
if (frame_len <= RX_BUF_LEN)
{
dwt_readrxdata(rx_buffer, frame_len, );
} if (memcmp(rx_buffer, Master_Release_Semaphore_comfirm, ALL_MSG_COMMON_LEN) == )
{
//if the tag recive a semaphore, wait release remaphore
Waiting_TAG_Relaease_Semphore = ;
}
}
else//the tag may leave net,clear semaphore
{
Semaphore[TAG_INDEX] = ;
Waiting_TAG_Relaease_Semphore = ;
/* Clear RX error events in the DW1000 status register. */
dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_ERR);
}
break;//only release one semphore once
}
}
}
//Master tag waitting for specific tag send Semaphore Release
if( Waiting_TAG_Relaease_Semphore == )
{
dwt_setrxtimeout();
dwt_rxenable(); while (!((status_reg = dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_ERR)))
{ }; if (status_reg & SYS_STATUS_RXFCG)
{
static uint32 frame_len; dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG);
frame_len = dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFL_MASK_1023;
if (frame_len <= RX_BUFFER_LEN)
{
dwt_readrxdata(rx_buffer, frame_len, );
}
if (memcmp(rx_buffer, Semaphore_Release, ALL_MSG_COMMON_LEN) == )
{
Semaphore[Semaphore_Release[ALL_MSG_TAG_IDX]] = ;
Waiting_TAG_Relaease_Semphore = ;
}
}
else{
/* Clear RX error events in the DW1000 status register. */
dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_ERR);
}
}
//if all tag have serviced by master tag
//master tag can measure the distance
if(sum(Semaphore[]) == )
{
Semaphore_Enable = ;
}
}
else //specific tag
{
dwt_setrxtimeout();
dwt_rxenable(); /* Poll for reception of a frame or error/timeout. See NOTE 7 below. */
while (!((status_reg = dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_ERR)))
{ }; if (status_reg & SYS_STATUS_RXFCG)
{
static uint32 frame_len;
/* Clear good RX frame event in the DW1000 status register. */
dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG); /* A frame has been received, read it into the local buffer. */
frame_len = dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFL_MASK_1023;
if (frame_len <= RX_BUFFER_LEN)
{
dwt_readrxdata(rx_buffer, frame_len, );
} if (memcmp(rx_buffer, Tag_Statistics, ALL_MSG_COMMON_LEN) == )
{
Tag_Statistics_response[ALL_MSG_SN_IDX] = frame_seq_nb;
Tag_Statistics_response[ALL_MSG_TAG_IDX] = TAG_ID;
dwt_writetxdata(sizeof(Tag_Statistics_response), Tag_Statistics_response, );
dwt_writetxfctrl(sizeof(Tag_Statistics_response), ); dwt_starttx(DWT_START_TX_IMMEDIATE );
while (!(dwt_read32bitreg(SYS_STATUS_ID) & SYS_STATUS_TXFRS))
{ };
} if (memcmp(rx_buffer, Master_Release_Semaphore, ALL_MSG_COMMON_LEN) == )
{
Master_Release_Semaphore_comfirm[ALL_MSG_SN_IDX] = frame_seq_nb;
Master_Release_Semaphore_comfirm[ALL_MSG_TAG_IDX] = TAG_ID;
dwt_writetxdata(sizeof(Master_Release_Semaphore_comfirm), Master_Release_Semaphore_comfirm, );
dwt_writetxfctrl(sizeof(Master_Release_Semaphore_comfirm), ); dwt_starttx(DWT_START_TX_IMMEDIATE );
while (!(dwt_read32bitreg(SYS_STATUS_ID) & SYS_STATUS_TXFRS))
{ };
} }
else
{
/* Clear RX error events in the DW1000 status register. */
dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_ERR);
}
}
DWM1000 多个标签定位讨论 --[蓝点无限]的更多相关文章
- DWM1000 多个基站定位讨论 --[蓝点无限]
该篇是之前<DWM1000 多个标签定位讨论 --[蓝点无限]>的续篇 多基站定位也是定位必然,因为有些稍微大一点的场合,或者多个区域(厂区不同房间)定位,往往4个基站会严重不足. DWM ...
- DWM1000 定位操作流程--[蓝点无限]
蓝点DWM1000 模块已经打样测试完毕,有兴趣的可以申请购买了,更多信息参见 蓝点论坛 1烧录HEX文件 使用ST-LINK utility 烧录HEX文件,分别烧录三个基站以及一个标签,烧录基站时 ...
- Python自动化之下拉框,隐藏标签定位 代码&报错解决
python自动化:下拉框定位方法之select标签 style="display: none;" 报错 selenium.common.exceptions.ElementNo ...
- Highmaps网页图表教程之绘图区显示标签显示数据标签定位
Highmaps网页图表教程之绘图区显示标签显示数据标签定位 Highmaps数据标签定位 由于数据标签是和节点一一对应,所以数据标签是依据节点位置进行定位的.本节详细讲解如何对数据标签进行定位. H ...
- DWM1000 三基站一标签定位HEX
蓝点DWM1000 模块已经打样测试完毕,有兴趣的可以申请购买了,更多信息参见 蓝点论坛 HEX 下载链接参见论坛:http://bphero.com.cn/forum.php?mod=viewthr ...
- DWM1000 蓝点无限 PCB样板
蓝点DWM1000 模块已经打样测试完毕,有兴趣的可以申请购买了,更多信息参见 蓝点论坛 正文: 虽然经过一段很长时间的停滞,最近调试成功,可以实现精准测距 和定位. 部分模块正在陆续整理,准备出售一 ...
- 【DWM1000】 非官方开源定位代码bitcraze
蓝点DWM1000 模块已经打样测试完毕,有兴趣的可以申请购买了,更多信息参见 蓝点论坛 正文: 最近关注DWM1000 定位,一方面在看DWM1000 官方提供的代码,也在四处网上找资料看资料. 其 ...
- UWB DWM1000 智能跟踪小车 --[蓝点无限]
蓝点DWM1000 模块已经打样测试完毕,有兴趣的可以申请购买了,更多信息参见 蓝点论坛 UWB 智能跟踪小车:一共三个UWB模块,手持一个,小车上两个. 通过测量小车上两个模块与手持模块之间的距离, ...
- DWM1000 测距原理简单分析 之 SS-TWR代码分析2 -- [蓝点无限]
蓝点DWM1000 模块已经打样测试完毕,有兴趣的可以申请购买了,更多信息参见 蓝点论坛 正文: 首先将SS 原理介绍中的图片拿过来,将图片印在脑海里. 对于DeviceA 和 DeviceB来说,初 ...
随机推荐
- zabbix数据库分表的实现
前提条件是主从同步操作完成(主从同步的前提是两个数据库表结构必须一样) 先看一下mysql配置文件 vi /usr/local/mysql/my.cnf 配置内容:------------------ ...
- Vue(小案例_vue+axios仿手机app)_公共组件(路由组件传参)
一.前言 1.公共轮播图的实现 2.组件传参,公共组件的实现 二.主要内容 1.公共轮播图的实现 (1)分析:当渲染不同的轮 ...
- Shiro 系列 - 基本知识
和 Spring Security 项目一样, Apache Shiro 也是一个被广泛使用安全框架, 它们都能完成认证.授权.会话管理等. 简单对比一下 Apache Shiro 和 Spring ...
- SSH HTTP代理
SSH 连接 参照https://stackoverflow.com/questions/19161960/connect-with-ssh-through-a-proxy 若要使用goflyway连 ...
- [Luogu P1144]最短路计数
emmmm这个题看起来非常复杂,实际上仔细一分析发现到一个点最短路的个数就是所有前驱最短路个数之和.如果在图上表示也就是以1为根的bfs搜索树,一个点的最短路个数等于每一个能够向它扩展的所有点的最短路 ...
- 设置redis服务开机自启动
今天周一,一大早来公司开完会,就听到开发的同学说本地项目起不来了,叫我查下原因.想了下,他们本地项目只跟我们公司的一台内网服务器有关,那台服务器他们要用到的呢,也就只有mysql和redis这两个服务 ...
- Mongodb注入
0x01 Brief Description 作为nosql(not only sql)数据库的一种,mongodb很强大,很多企业也在用到.相对于sql数据库,nosql数据库有以下优点:简单便捷. ...
- SqlServer 语法
四. Ranking 排序与排名是我们最为常用的统计方式,比如对班级的学生根据成员进行排名,或者按照成绩高低把学生划分成若干梯队:比如最好成绩的10名学生属于第一梯队,后10名又 ...
- react-native获取屏幕尺寸
项目中需要获取手机的尺寸 import {Dimensions} from "react-native" var WINDOW = Dimensions.get("win ...
- css :root 选择器
:root css 伪类匹配文档的根元素. 对于 HTML 来说, :root 表示<html>元素,除了优先级更高之外,与 html 选择器相同. 在声明全局 css 变量时 :root ...