ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Decawave官方双边测距(一对一)原理介绍及代码实现

2021-10-21 12:00:36  阅读:403  来源: 互联网

标签:Decawave tx dwt 一对一 RX rx ts SYS 测距


Decawave官方双边测距(一对一)原理介绍及代码实现

一、运行平台
运行软件平台:Keil5
运行硬件平台:STM32
开发板型号:UWB-S1学习板
开发板淘宝链接:https://item.taobao.com/item.htm?spm=a1z10.5-c.w4002-23565193320.10.6e6c3f96tF7wds&id=572212584700

二、TOF/单边测距/双边测距概念介绍
Uwb常用测距方法有两种:飞行时间测量(TOF)和到达时间差(TDoA),我们这里将详细介绍飞行时间测量(TOF)的方法。

2.1 TOF
飞行时间测量法(Time of Flight,TOF)是一种双向测距技术,它通过测量两个设备间UWB信号的飞行时间来计算距离(注:所有的双向测距算法并不由DW1000来完成,DW1000仅负责记录下发送/接受数据包的时间戳)。根据UWB数据交互数量可分为:
①单边双向测距
②双边双向测距

2.2 单边双向测距
<单边测距Single-sided Two-WAY Ranging>具体流程:设备A首先向设备B发出一个数据包,并记录下发包时刻Ta1,设备B收到数据包后,记下收包时刻Tb1。之后设备B等待Treply时刻,在Tb2(Tb2 = Tb1 + Treply)时刻,向设备A发送一个数据包,设备A收到数据包后记下Ta2.然后可以算出电磁波在空中的飞行时间Tprop,飞行时间乘以光速即为两个设备间的距离。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

因为设备A和设备B使用各自独立的时钟源,时钟都会有一定的偏差,假设设备A和设备B时钟的实际频率是预期频率的eA和eB倍,那么因为时钟偏差引入的误差error为:
在这里插入图片描述

设备A和B的时钟偏差都会对Tprop值造成影响,并且直接影响我们的测量精度,因为光速是30cm/ns,所以很小的时钟偏差也会对测量结果造成很大影响,而且这种影响是SS测距方式无法避免的。也因此SS测距很少被采用,大部分情况下我们都使用DS测距的方式。
在这里插入图片描述

2.3双边双向测距
<双边测距Double-sided Two-WAY Ranging>具体流程:DS测距在SS测距的基础上增加一次通讯,两次通讯的时间可以互相弥补(因为时间偏移引入的误差)。
在这里插入图片描述
在这里插入图片描述

使用DS测距方式时钟引入的误差为
在这里插入图片描述

假设设备A和设备B的时钟精度是20ppm(很差),1ppm为百万分之一,那么Ka和Kb分别是0.99998或者1.00002,ka和kb分别是设备A、B时钟的实际频率和预期频率的比值。设备A、B相距100m,电磁波的飞行时间是333ns。则因为时钟引入的误差为2033310-9秒,导致测距误差为2.2mm,可以忽略不计了。因此双边测距是最常采用的测距方式(Decawave官方也提供了双边测距的例程)。

三、官方测距代码实现
UWB-S1测距源码(官改)即使用了Decawave官方提供Double-sided two-way代码做基础,下面我们将对源码做详细介绍。

标签/基站模式切换方法如下
①基站模式:node_task(),注释tag_task()
②标签模式:tag_task(),注释node_task()

int main(void)
{
	init();	

//	tag_task();	//标签任务
	node_task();	//基站任务

	for(;;)
	{	
	}
}

3.1 基站/标签统一配置

初始化DW1000设备
dwt_initialise(DWT_LOADUCODE)

配置DW1000标签/基站通信信道的参数
dwt_configure(&config)

设置DW1000天线的延迟
dwt_setrxantennadelay(RX_ANT_DLY);
dwt_settxantennadelay(TX_ANT_DLY);

设置DW1000 LED指示灯与发送接受同步
dwt_setleds(3);

3.2 基站/标签流程
基站/标签流程图如下(图片版权并非作者)
在这里插入图片描述

3.2.1标签发送Poll

dwt_setrxaftertxdelay(POLL_TX_TO_RESP_RX_DLY_UUS);//设置标签发送Poll包后延迟打开接受时间
dwt_setrxtimeout(RESP_RX_TIMEOUT_UUS);//设置接受超时时间
dwt_setpreambledetecttimeout(PRE_TIMEOUT);//设置前导码接受超时时间

dwt_writetxdata(sizeof(tx_poll_msg), tx_poll_msg, 0);//将Poll发送数据写入DW1000准备发送 
dwt_writetxfctrl(sizeof(tx_poll_msg), 0, 1);//设置发送Poll数据长度 

dwt_starttx(DWT_START_TX_IMMEDIATE | DWT_RESPONSE_EXPECTED);//立即打开发送

3.2.2 基站接受Poll

dwt_setpreambledetecttimeout(PRE_TIMEOUT);//设置前导码接受超时时间
dwt_setrxtimeout(0);//清除接受超时
dwt_rxenable(DWT_START_RX_IMMEDIATE);//立即开始接受

dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_TO | SYS_STATUS_ALL_RX_ERR)))
dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG);//清除DW1000接受成功寄存器

dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFL_MASK_1023;//读取DW1000接受数据长度
dwt_readrxdata(rx_buffer, frame_len, 0);//读取DW1000接受数据

3.2.3 基站发送Resp

poll_rx_ts = get_rx_timestamp_u64();//读取接受Poll时间戳值
resp_tx_time = (poll_rx_ts + (POLL_RX_TO_RESP_TX_DLY_UUS * UUS_TO_DWT_TIME)) >> 8;//计算Resp数据包发送时间

dwt_setdelayedtrxtime(resp_tx_time);//设置Resp数据包发送时间
dwt_setrxaftertxdelay(RESP_TX_TO_FINAL_RX_DLY_UUS);//设置基站发送Resp包后延迟打开接受时间
dwt_setrxtimeout(FINAL_RX_TIMEOUT_UUS);//设置接受超时时间

dwt_writetxdata(sizeof(tx_resp_msg), tx_resp_msg, 0);//将Resp发送数据写入DW1000准备发送 
dwt_writetxfctrl(sizeof(tx_resp_msg), 0, 1); //设置发送Resp数据长度
dwt_starttx(DWT_START_TX_DELAYED | DWT_RESPONSE_EXPECTED);//设置延迟发送,

3.2.4 标签接受Resp

dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_TO | SYS_STATUS_ALL_RX_ERR)))
dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG | SYS_STATUS_TXFRS);//清除DW1000接受成功寄存器

dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFLEN_MASK;//读取DW1000接受数据长度
dwt_readrxdata(rx_buffer, frame_len, 0);//读取DW1000接受数据

3.2.5 标签发送Final

poll_tx_ts = get_tx_timestamp_u64();//读取发送Poll时间戳值
resp_rx_ts = get_rx_timestamp_u64();//读取接受Resp时间戳值

final_tx_time = (resp_rx_ts + (RESP_RX_TO_FINAL_TX_DLY_UUS * UUS_TO_DWT_TIME)) >> 8;//计算Final数据包发送时间
dwt_setdelayedtrxtime(final_tx_time);//设置Final数据包发送时间

dwt_writetxdata(sizeof(tx_final_msg), tx_final_msg, 0);//将Final发送数据写入DW1000准备发送 
dwt_writetxfctrl(sizeof(tx_final_msg), 0, 1);//设置发送Final数据长度
ret = dwt_starttx(DWT_START_TX_DELAYED);//设置延迟发送,延迟发送时间为final_tx_time

3.2.6 基站接受Final

dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_TO | SYS_STATUS_ALL_RX_ERR)))
dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG | SYS_STATUS_TXFRS);//清除DW1000接受成功寄存器

dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFLEN_MASK;//读取DW1000接受数据长度
dwt_readrxdata(rx_buffer, frame_len, 0);//读取DW1000接受数据

//开始3.2.7(基站-标签计算距离)

3.2.7 基站计算测距数据

uint32 poll_tx_ts, resp_rx_ts, final_tx_ts;
uint32 poll_rx_ts_32, resp_tx_ts_32, final_rx_ts_32;
double Ra, Rb, Da, Db;
int64 tof_dtu;

resp_tx_ts = get_tx_timestamp_u64();//读取发送Resp时间戳值
final_rx_ts = get_rx_timestamp_u64();//读取接受Final时间戳值

final_msg_get_ts(&rx_buffer[FINAL_MSG_POLL_TX_TS_IDX], &poll_tx_ts);//从标签发来数据中获取Poll发送时间戳
final_msg_get_ts(&rx_buffer[FINAL_MSG_RESP_RX_TS_IDX], &resp_rx_ts);//从标签发来数据中获取Resp接受时间戳
final_msg_get_ts(&rx_buffer[FINAL_MSG_FINAL_TX_TS_IDX], &final_tx_ts);//从标签发来数据中获取Final发送时间戳

poll_rx_ts_32 = (uint32)poll_rx_ts;
resp_tx_ts_32 = (uint32)resp_tx_ts;
final_rx_ts_32 = (uint32)final_rx_ts;
Ra = (double)(resp_rx_ts - poll_tx_ts);
Rb = (double)(final_rx_ts_32 - resp_tx_ts_32);
Da = (double)(final_tx_ts - resp_rx_ts);
Db = (double)(resp_tx_ts_32 - poll_rx_ts_32);
tof_dtu = (int64)((Ra * Rb - Da * Db) / (Ra + Rb + Da + Db));

tof = tof_dtu * DWT_TIME_UNITS;
distance = tof * SPEED_OF_LIGHT;//计算标签与基站距离值

memset(dist_str, 0, sizeof(dist_str));
sprintf(dist_str, "DIST: %3.2f m\n", distance);
port_tx_msg(dist_str,strlen(dist_str));//打印距离参数

标签:Decawave,tx,dwt,一对一,RX,rx,ts,SYS,测距
来源: https://blog.csdn.net/qq_31254149/article/details/120883281

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有