如何从零开始实现TDOA技术的 UWB 精确定位系统(2)
这是一个系列文章《如何从零开始实现TDOA技术的 UWB 精确定位系统》第2部分。
重要提示(劝退说明):
Q:做这个定位系统需要基础么?
A:文章不是写给小白看的,需要有电子技术和软件编程的基础
Q:你的这些硬件/软件是开源的吗?
A:不是开源的。这一系列文章是授人以“渔”,而不是授人以“鱼”。文章中我会介绍怎么实现UWB定位系统,告诉你如何克服难点,但不会直接把PCB的Gerber文件给你去做板子,不会把软件的源代码给你,不会把编译好的固件给你。我不会给你任何直接的结果,我只是告诉你方法。
Q:我个人对UWB定位很兴趣,可不可以做出一个定位系统?
A:如果是有很强的硬件/软件背景,并且有大量的时间,当然可以做得出来。文章就是写给你看的!
Q:我是商业公司,我想把UWB定位系统搞成一个商业产品。
A:当然可以。这文章也是写给你看的。如果你想自己从头构建整个系统,看了我的文章后,只需要画电路打板;构思软件结构再编码。就这样,所有的难点我都会在文中提到,并介绍了解决方法。你不需要招人来做算法研究。如果你想省事省时间,可以直接购买我们的电路图(AD工程文件),购买我们的软件源代码,然后快速进入生产环节。(网站: https://uwbhome.top)
基站固件设计-时钟同步
时钟同步原理
我们在前面已经说过,对于TDOA技术来说,各个基站需要有统一的时间,这是一个难点。时钟怎么同步呢?
假设一个定位区域有A/B/C/D四个基站,我们另外再把拿一个基站CS作为时钟源,定期发送时钟同步包。这个时钟同步包的结构如下:
typedef struct ieee154_broadcast_clock_sync_frame {
uint8_t frameCtrl[2]; // 0, 2, frame control bytes 00-01: 0x01 (Frame Type 0x01=date), 0xC8 (0xC0=src extended address 64 bits, 0x08=dest address 16 bits)
uint8_t seq8; // 2, 1, sequence_number 02
uint8_t panID[2]; // 3, 2, PAN ID 03-04
uint8_t destAddr[2]; // 5, 2, 0xFFFF
uint8_t sourceAddr[8]; // 7, 8, 64Bits EUI地址
uint8_t messageType; //15, 1, Message Type = RTLS_MSG_TYPE_CLOCK_SYNC
uint8_t seq64[8]; //16, 8, 发出的测距消息序号, 比 seq8 有更大的最大值
uint8_t timeStamp[8]; //24, 8, 时间戳
uint8_t fcs[2]; //32, 2
} BROADCAST_CLOCK_SYNC_MESSAGE;
这是一个DW1000的典型的UWB数据包。这是一个广播类型的包,其中有几个重要字段,timeStamp这是时间戳,也就是A基站发送这个包的时刻。
当,A/B/C/D四个基站收到这个同步包后,记下这个时间戳和收到这个包的时刻(本地时间戳),这样,我们就有两个时间戳了。
过一会,CS再发一个同步包。某个基站例如B基站收到后,再记录下CS基站的远程时间戳和本地收到的时候戳,又得到两个时间戳。
假设CS发出这两个包之间间隔100ms,也就是两个同步发送时间间隔100ms。那么在正常情况下,B基站收到这两个包时,本地的时间间隔应该也是100ms。实际上并不是!
因为两个基站的DWM1000使用的晶振会因为各种原因,频率并不会完全相同,总会有一些差异。
两个基站之间的时钟差异是多少呢?
deta = (ST2 - ST1) - (RT2 - RT1)。其中 deta 是差异,ST2是第二个包的发送时间,ST1是第一个包的发送时间,RT2是第二个包的接收时间,RT是第一个包的接收时间。
差异率是 Ratio = deta / (ST2-ST1)
这样,开始时间知道了,时钟的差异率也知道了。我们就可以把任意一个本地时间戳转换为以CS为准的时间戳。
当某一个标签发出UWB定位数据包时,A/B/C/D四个基站都收到这个包,A/B/C/D把收到时的本地时间戳转换为以CS的时间为基准的标准时间戳,大家都把这个时间戳送到定位引擎,定位引擎得到4个时间,根据它们的差,就可以计算出标签的坐标了。
看到这里,你心应该会有一个疑问。CS发出的同步数据包的发送时刻,是UWB数据包离开CS内的DW1000芯片的一个闸门那一刻。UWB信号然后经过了芯片内部线路,再经过发射天线发射到空中,到达B基站的天线,在B基站的天线内部传输,经过一些芯片内部线路,到达B基站中的DW1000的那个接收闸门,那个时刻是接收到的时刻。这个过程需要不少时间,这个时间怎么得到?在DW1000芯片的手册中有介绍,我们要考虑发射天线延迟/接收天线延迟。
回答是,不用管它。
我们假设,B基站的DW1000与天线之间通过一条长长的射频电缆连接,时钟同步包到达B基站的天线后,再经过长长的电缆才到DW1000芯片。当然,标签发出的定位数据包也一样,到达B基站的天线后,再经过长长的电缆才到DW1000芯片。假设电缆增加一段,导致无线电波要在电缆中多跑1ms,当然,时钟同步包和定位包都要多花1ms在路上。如果我们在计算B基站接收时钟同步包时的时间戳时把这1ms考虑进去,那么在定位引擎计算时间差的时候,要把标签的定位包多花的这1ms扣出。所以这两个包在电缆中所花的时间,在计算公式中会被抵消。
在安装基站时,我们关心“基站安装在哪个位置”,其实并不真的关心基站的位置,而是关心基站天线的位置。天线的位置才是最重要的。时钟同步包到达天线,定位数据包到达天线,基站本身在哪里并不重要。
这也是TDOA的优势之一,不用关心天线延迟,不需像TOF基站和TOF标签那样,在出厂前要做天线延迟标定。
上述的分析,是在使用单独的基站作为时钟源的场景下。我们最初的系统就是使用单独的时钟源。时钟源的硬件和固件与正常的基站完全相同,根据配置作为时钟源还是作为普通基站。作为时钟源的时候,功能只有一个,就是定期发送时钟同步包,时钟源的DW1000只发射不接收;作为普通基站的时候,接收时钟源发出的时钟同步包和标签发出的定位包,普通基站的DW1000只接收不发射。后来,为了降低成本,我们把两个功能合并,普通基站既可以作为基站又可以作为时钟源,平时处于接收状态,定期切换到发射状态发送一个时钟同步包后立即又切换回接收状态。这样,可以节省一个单独的时钟源。
如果基站同时作为时钟源,那么作为时钟源的这个基站,它的天线延迟在计算时就会有影响。对于时钟同步包来说,它是发射延迟;对于定位数据包来说,它是接收延迟。DW1000内部发射延迟和接收延迟差异不大,计算时可以忽略不计。但是,如果有外接PA/LNA,发射和接收经过的路线差异比较大,就需要考虑到这个异常了。
我们最初设计整个系统时,曾经考虑整个系统使用统一的时间。大的定位区域,可以划分为多个小的定位区域。我们可以部署一个根时钟,各个区域有一个分时钟,从根时钟同步时间,逐级同步时钟就OK。
然而事情不是这么简单,最主要的问题是误差。时钟之间的误差我们是无法排除的。
例如,根时钟R的时间同步到A1/B1,然后A1同步到A2,B1同步到B2。然后我们会发现A2和B2之间的误差会比较大。因为时钟同步本身就有误差,多级同步会导致误差积累,最后的误差越来越大。
最后,我们发现整个系统统一时间意义不大,只需要某个小的定位区域内的几个基站之间统一时间就可以了。
细心的同学肯定注意到,前面定义的时钟同步包结构中,一个字段seq64。这是一个64位整数。DW1000芯片内部定义有一个8位的seq,放在帧控制字段后。我们发现,1个字节表达数据包序列号,最多只能256个,很快就会回卷。有时,我们关心更大时间尺度内的数据包,就无法分辨了。所以,我们单独设置了一个64位的数据包序列号。
另外,DW1000的时间戳的有效数据是40位,其单位约为15.6ps。
后期,精益求精的考虑,我们新定义了一个精练一些的时钟同步包。
typedef struct ieee154_broadcast_mini_clock_sync_frame {
uint8_t frameCtrl[2]; // 0, 2: frame control bytes 00-01: 0x01 (Frame Type 0x01=date), 0xC8 (0xC0=src extended address 64 bits, 0x08=dest address 16 bits)
uint8_t seq8; // 2, 1: sequence_number 02
uint8_t panID[2]; // 3, 2: PAN ID 03-04
uint8_t destAddr[2]; // 5, 2: 0xFFFF
uint8_t sourceAddr[8]; // 7, 8: 64 Bits EUI地址
uint8_t messageType; // 15,1: Message Type = RTLS_MSG_TYPE_MINI_CLOCK_SYNC
uint8_t seq32_3[3]; // 16,3: 发出的测距消息序号的高 24 位,即高 3 字节
uint8_t timeStamp[5]; // 19,5: 时间戳, 40 Bits
uint8_t fcs[2]; // 24,2:
} BROADCAST_MINI_CLOCK_SYNC_MESSAGE; // 以上合计 26 字节
seq没有必要搞成64位,32位足够了,前面有一个seq8,那么后面只需要3个字节就可以了,所以把seq64改为seq32_3;时间戳的有效位只有40位,所以不需要使用64位。
新的时钟同步包大小由34个字节减小到26个字节。
因为无线信号本质上是广播,同一时刻空中只能有一个声音,如果出现其它的声音,就是干扰。所以,我们要尽可能的减小信道的占用,传送的数据包越小,占用的时间越短。可以腾出时间,以容纳更多的标签;并且,数据包占用信道的时间越短,被干扰的几率也就越小。
基站共用-与多个时钟源同步时钟
因为UWB业务的定义就是近场无线通信,几乎所有国家的无线电管理部门对UWB的信号功率都有严格限制,不允许大功率发射。因为UWB占用的带宽太宽了,如果功率大了,它就变成干扰源了。
原厂DW1000最大功率发射时,以850K的速率通讯时,覆盖范围大约200米~300米范围。实际上,这个最功率是超标的。如果按照无线电管理局要求的信号强度,通讯距离大概会在20米以内。
无论如何,当我们要对一个很大的区域进行定位,经常需要把它划分为多个小的定位区域。我们假设有一个100米x100米的区域,划分为4块25米x25米的4个区域。假设每个区域使用4个基站,那么4个区域就需要4x4=16个基站。
如果基站可以共用,定位区域边缘的基站可以供相邻的区域共用,那么我们只需要有“田”字的每个顶点安装一个基站,只需要3*3=9个基站就可以了。
使用尽量少的基站,可以减少用户的投资,也减小项目施工难度。
前面我们所述的时钟同步,基站可以多记录几个时钟源的时间戳,就可以达到与多个时钟源同步时间的效果。
typedef struct tag_ClockSource_Sync_Info {
uint8_t clockSourceId[8];
double factor;
double lastFactors[CLOCKSOURCE_SYNC_INFO_LAST_FACTOR_NUM];
int64_t offset;
int64_t localStartTime;
int64_t lastSyncTime;
SAMPLE_KALMAN_FILTER_PARAMETER kfp;
SAMPLE_RC_FILTER_PARAMETER rfp;
double ppm;
double lastFactorAcc[CLOCKSOURCE_SYNC_INFO_LAST_FACTOR_NUM];
double factorAcc;
} CLOCKSOURCE_SYNC_INFO;
上面这个结构是记录了某个时钟源的时钟同步数据。
#define CLOCKSOURCE_SYNC_INFO_NUM 15 // 记录 15 个时钟源的同步信息
CLOCKSOURCE_SYNC_INFO clockSourceSyncInfo[CLOCKSOURCE_SYNC_INFO_NUM];
上面这个数组记录多个时钟源的数据。
具体允许与多少个时钟源同步,这与MCU的RAM有关。在现实中,其实也不会有太多的区域共用同一个基站,15个基本上不同能了。
时钟同步的干扰因素
如果每次收到时钟同步包时,都计算时钟的差异率,那么会发现它一直在变化。我们期望得到一个稳定的,至少一段时间内变化不大的差异率。但是,这不可能!有太多“干扰”因素。
晶振的频率变化
DW1000的晶振是时钟的源头。对晶振的频率生产影响的因素很多,温度湿度变化/电压变化都会影响晶振的频率。晶振两端的pad电容的容量变化,也会对频率产生影响(有些电路就是通过调整这两个pad电容的容量来调整电路的频率),温度湿度电压的变化对这两个电容也会产生影响。
DW1000的Datasheet中建议“Crystal (38.4 MHz +/-10ppm)”,“TCXO (optional use in Anchor nodes. 38.4 MHz)”。DWM1000模组把DW1000芯片封装在一个铁盒子中,对晶振频率的稳定是有一定好处的,因为在铁盒子中有一定的保温效果,可以让晶振的温度不会快速受到空气流动的影响。
其实,频率不准并不可怕。频率偏差再大,我们也可以通过计算校准。我们怕的是无规律的快速变化。
无线电波传输速度的变化
无线电波在空气中传输,空气作为介质,是不稳定的。空气的温度/湿度/气压等都会影响无线电波在空气中的传输速度。
曾经有一次,我把开发板固定在三角架上,放在我办公桌旁边,我在观察时钟同步差异率的变化。刚好有一位同事从旁边路过,我马上看到曲线发生剧烈变化。这也是我在前面基站电路设计部分强调外壳很重要的原因。
保持时钟同步稳定性
因为影响时钟同步差异的因素很多,所以我们要想办法保持稳定。有几个办法:
缩短时钟同步周期。我们把时钟同步周期设定为250ms。较短的时钟同步周期,可以保持当前的时钟同步数据较新,与最新的各种影响因素匹配。
卡尔曼滤波或者其他方法滤波。总体上,频率的变化是类似正态分布的一些随机点:频率有一个总体的变化趋势,如果我们时钟的差异率画出来,它是总体上是一条逐步变化的曲线,但是每次计算出来的点,并不在正好落在曲线上,而是在曲线附近。我们可以使用滤器得到曲线上的值。
使用滤波的效果很在限,最重要的还是缩短时钟同步周期。因为通过滤波器得到的值,并不是真的实际情况,而是一个理想值。比如,因为空气温度变化导致电波从时钟到基站的传输速度变化了,我们得出一个排除这个影响的值,但实际上这个值意义不大。因为标签发出的定位包的速度也一样会受到影响,应该一道排除空气变化影响才行,如果只对时钟同步排除,而标签发出的定位包不排除,那么计算结果肯定会有较大的偏差。
原来打算基站固件设计写一篇就搞定,结果发现仅是时钟同步就写了这么多内容。看来要写的东西还是有点多。慢慢写吧。
如何从零开始实现TDOA技术的 UWB 精确定位系统(2)的更多相关文章
- 关于精准UWB人员定位系统解决方案
WB技术, 目前主要应用在室内定位.人员定位系统等定位领域.近年来被应用在无线定位和雷达测距应用中,因此作为民用雷达和民用测距取得了较快的发展.而今天,我们主要要来介绍的产品就是UWB技术的芯片DW1 ...
- 浅谈UWB(超宽带)室内定位技术(转载)
技术背景 随着无线通信技术的发展和数据处理能力的提高,基于位置的服务成为最有前途的互联网业务之一.无论移动在室内还是室外环境下,快速准确地获得移动终端的位置信息和提供位置服务的需求变得日益迫切.通信和 ...
- [转帖]新iPhone的黑科技:UWB技术揭秘
新iPhone的黑科技:UWB技术揭秘 http://blog.nsfocus.net/iphone-black-technology-uwb-technology-revealed/ 阅读: ...
- 基于UWB技术的DW1000芯片简单解析
近些年来随着物联网和机器人技术的大发展,精确定位技术的热度也随之攀升.目前精确定位的技术有很多,如基于wifi.RFID.zigbee.超声波.UWB等技术都可以实现精准定位.由于技术的不同,精度也不 ...
- 【硬件模块】UWB介绍
From: https://liudongdong1.github.io/ UWB超宽带定位技术属于无线定位技术的一种.无线定位技术是指用来判定移动用户位置的测量方法和计算方法,即定位算法.目前最常用 ...
- 位置指纹(LF)定位技术简介-室内定位
信号的多径传播对环境具有依赖性,呈现出非常强的特殊性.对于每个位置而言,该位置上信道的多径结构是惟一的,终端发射的无线电渡经过反射和折射,产生与周围环境密切相关的特定模式的多径信号,这样的多径 ...
- 一个「学渣」从零开始的Web前端自学之路
从 13 年专科毕业开始,一路跌跌撞撞走了很多弯路,做过餐厅服务员,进过工厂干过流水线,做过客服,干过电话销售可以说经历相当的“丰富”. 最后的机缘巧合下,走上了前端开发之路,作为一个非计算机专业且低 ...
- Linux基础介绍【第九篇】
服务器添加3块磁盘的体系结构 [root@oldboylinux test]# free -m total used free shared buffers cached M ...
- OpenCASCADE Conic to BSpline Curves-Circle
OpenCASCADE Conic to BSpline Curves-Circle eryar@163.com Abstract. The conic sections and circles pl ...
- css精灵
○ css 精灵(Sprites)技术利用photoshop将图片整合,然后用background-images,background-position,background-repeat技术,对图片 ...
随机推荐
- POWERBI_1分钟学会_连续上升或下降指标监控
一:数据源 模拟数据为三款奶茶销量的日销售数据源,日期是23.8.24-23.8.31.A产品为连续7天,日环比下降,B产品为连续3天,日环比下降,C产品为连续2天,日环比下降. 二:建立基础度量值 ...
- 前端三件套系例之CSS——CSS是什么、CSS3语法、css代码书写位置(引入方式)、css选择器
文章目录 1.CSS是什么 2.CSS3语法 2.1 CSS实例 2.2 CSS注释 3.css代码书写位置(引入方式) 3-1 行间式 3-2 内联式 3-3 外联式 总结 3 css选择器 1.基 ...
- MySQL系列之MHA高可用——主从复制架构演变介绍、高可用MHA、管理员在高可用架构维护的职责
文章目录 1. 主从复制架构演变介绍 1.1 基本结构 1.2 高级应用架构演变 1.2.1 高性能架构 1.2.2 高可用架构 2. 高可用MHA ***** 2.1 架构工作原理 2.2 架构介绍 ...
- 俄罗斯版IDM安装与破解以及解决B站视频网站不弹出下载浮窗
IDM 全称 Internet Download Manager,是一款非常优秀的多线程下载和视频嗅探工具,不仅可以显著提高文件下载速度,配合IDM浏览器扩展插件,还可以嗅探并下载YouTube.知乎 ...
- TIM-有感BLDC转速解析
TIM-有感BLDC转速解析 1.基本概念解析 霍尔传感器的原理:通电线圈产生的磁场会使得转子所在位置会产生磁场,其中离得最近的霍尔传感器的磁场最强,进而导致最近霍尔传感器会产生最大的电压信号,这个最 ...
- 算法修养--A*寻路算法
A*寻路算法 广度优先算法 广度优先算法搜索以广度做未优先级进行搜索. 从起点开始,首先遍历起点周围邻近的点,然后再遍历已经遍历过的点邻近的点,逐步的向外扩散,直到找到终点. 这种算法就像洪水(Flo ...
- CF276C
题目简化和分析: 属于一种贪心思维,我们想如果要使得和最大,那么就必须保证最大的数乘的次数越多越好,并且排序没有限制,快速累加每个位置出现的次数,所以应该使用线段树差分. 然后排序最大乘最大累加. S ...
- 一个vuepress配置问题,引发的js递归算法思考
前言 这两天在尝试用语雀+ vuepress + github 搭建个人博客. 小破站地址 :王天的 web 进阶之路 语雀作为编辑器,发布文档推送 github,再自动打包部署,大概流程如下. 问题 ...
- 最新 2023.2 版本 WebStorm 永久破解教程,WebStorm 破解补丁永久激活(亲测有效)
最近 jetbrains 官方发布了 2023.2 版本的 IDEA,之前的激活方法并不支持这个新的版本. 下面是最新的激活教程,激活步骤和之前是类似的,只是换用了不同的补丁文件. 本教程支持 Jet ...
- 使用Python批量发送个性化邮件
前言 在现代工作环境中,我们经常需要向多个收件人发送个性化的邮件.通过使用Python编程语言,我们可以自动化这个过程,从Excel文件中读取收件人和相关数据,并发送定制的邮件. 首先,导入所需的库: ...