Decawave官方双边测距(一对一)原理介绍及代码实现
Decawave官方雙邊測距(一對一)原理介紹及代碼實現(xiàn)
一、運行平臺
 運行軟件平臺:Keil5
 運行硬件平臺:STM32
 開發(fā)板型號:UWB-S1學習板
 開發(fā)板淘寶鏈接: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僅負責記錄下發(fā)送/接受數(shù)據(jù)包的時間戳)。根據(jù)UWB數(shù)據(jù)交互數(shù)量可分為:
 ①單邊雙向測距
 ②雙邊雙向測距
2.2 單邊雙向測距
 <單邊測距Single-sided Two-WAY Ranging>具體流程:設備A首先向設備B發(fā)出一個數(shù)據(jù)包,并記錄下發(fā)包時刻Ta1,設備B收到數(shù)據(jù)包后,記下收包時刻Tb1。之后設備B等待Treply時刻,在Tb2(Tb2 = Tb1 + Treply)時刻,向設備A發(fā)送一個數(shù)據(jù)包,設備A收到數(shù)據(jù)包后記下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官方也提供了雙邊測距的例程)。
三、官方測距代碼實現(xiàn)
 UWB-S1測距源碼(官改)即使用了Decawave官方提供Double-sided two-way代碼做基礎,下面我們將對源碼做詳細介紹。
標簽/基站模式切換方法如下
 ①基站模式:node_task(),注釋tag_task()
 ②標簽模式:tag_task(),注釋node_task()
3.1 基站/標簽統(tǒng)一配置
初始化DW1000設備 dwt_initialise(DWT_LOADUCODE)配置DW1000標簽/基站通信信道的參數(shù) dwt_configure(&config)設置DW1000天線的延遲 dwt_setrxantennadelay(RX_ANT_DLY); dwt_settxantennadelay(TX_ANT_DLY);設置DW1000 LED指示燈與發(fā)送接受同步 dwt_setleds(3);3.2 基站/標簽流程
 基站/標簽流程圖如下(圖片版權并非作者)
 
3.2.1標簽發(fā)送Poll
dwt_setrxaftertxdelay(POLL_TX_TO_RESP_RX_DLY_UUS);//設置標簽發(fā)送Poll包后延遲打開接受時間 dwt_setrxtimeout(RESP_RX_TIMEOUT_UUS);//設置接受超時時間 dwt_setpreambledetecttimeout(PRE_TIMEOUT);//設置前導碼接受超時時間dwt_writetxdata(sizeof(tx_poll_msg), tx_poll_msg, 0);//將Poll發(fā)送數(shù)據(jù)寫入DW1000準備發(fā)送 dwt_writetxfctrl(sizeof(tx_poll_msg), 0, 1);//設置發(fā)送Poll數(shù)據(jù)長度 dwt_starttx(DWT_START_TX_IMMEDIATE | DWT_RESPONSE_EXPECTED);//立即打開發(fā)送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接受數(shù)據(jù)長度 dwt_readrxdata(rx_buffer, frame_len, 0);//讀取DW1000接受數(shù)據(jù)3.2.3 基站發(fā)送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數(shù)據(jù)包發(fā)送時間dwt_setdelayedtrxtime(resp_tx_time);//設置Resp數(shù)據(jù)包發(fā)送時間 dwt_setrxaftertxdelay(RESP_TX_TO_FINAL_RX_DLY_UUS);//設置基站發(fā)送Resp包后延遲打開接受時間 dwt_setrxtimeout(FINAL_RX_TIMEOUT_UUS);//設置接受超時時間dwt_writetxdata(sizeof(tx_resp_msg), tx_resp_msg, 0);//將Resp發(fā)送數(shù)據(jù)寫入DW1000準備發(fā)送 dwt_writetxfctrl(sizeof(tx_resp_msg), 0, 1); //設置發(fā)送Resp數(shù)據(jù)長度 dwt_starttx(DWT_START_TX_DELAYED | DWT_RESPONSE_EXPECTED);//設置延遲發(fā)送,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接受數(shù)據(jù)長度 dwt_readrxdata(rx_buffer, frame_len, 0);//讀取DW1000接受數(shù)據(jù)3.2.5 標簽發(fā)送Final
poll_tx_ts = get_tx_timestamp_u64();//讀取發(fā)送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數(shù)據(jù)包發(fā)送時間 dwt_setdelayedtrxtime(final_tx_time);//設置Final數(shù)據(jù)包發(fā)送時間dwt_writetxdata(sizeof(tx_final_msg), tx_final_msg, 0);//將Final發(fā)送數(shù)據(jù)寫入DW1000準備發(fā)送 dwt_writetxfctrl(sizeof(tx_final_msg), 0, 1);//設置發(fā)送Final數(shù)據(jù)長度 ret = dwt_starttx(DWT_START_TX_DELAYED);//設置延遲發(fā)送,延遲發(fā)送時間為final_tx_time3.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接受數(shù)據(jù)長度 dwt_readrxdata(rx_buffer, frame_len, 0);//讀取DW1000接受數(shù)據(jù)//開始3.2.7(基站-標簽計算距離)3.2.7 基站計算測距數(shù)據(jù)
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();//讀取發(fā)送Resp時間戳值 final_rx_ts = get_rx_timestamp_u64();//讀取接受Final時間戳值final_msg_get_ts(&rx_buffer[FINAL_MSG_POLL_TX_TS_IDX], &poll_tx_ts);//從標簽發(fā)來數(shù)據(jù)中獲取Poll發(fā)送時間戳 final_msg_get_ts(&rx_buffer[FINAL_MSG_RESP_RX_TS_IDX], &resp_rx_ts);//從標簽發(fā)來數(shù)據(jù)中獲取Resp接受時間戳 final_msg_get_ts(&rx_buffer[FINAL_MSG_FINAL_TX_TS_IDX], &final_tx_ts);//從標簽發(fā)來數(shù)據(jù)中獲取Final發(fā)送時間戳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));//打印距離參數(shù)總結
以上是生活随笔為你收集整理的Decawave官方双边测距(一对一)原理介绍及代码实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 传感器课程作业 车载激光雷达
- 下一篇: 使用vue实现分页
