日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2024/1/1 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Decawave官方双边测距(一对一)原理介绍及代码实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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官方双边测距(一对一)原理介绍及代码实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。