簡單學習:微波定位模塊的測距算法


  UWB是一種無線載波通信技術,利用納秒級的非正弦波窄脈沖傳輸數據,工作頻段在3.25GHZ~6.75GHZ,頻寬典型值為500MHZ或者1GHZ,所以可以獲取亞納米的精確時間(1ns約等於750px)。UWB也可用於傳輸數據,普通幀大約在128字節,擴展幀則能傳輸K級別的數據。

       與普通的通信不同,UWB直接使用數字波形來傳輸數據,而一般的無線通信使用了載波。

  

  通過二者通信的時間戳,我們能利用TOF的方法,來獲得兩個模塊之間的距離。這個算法就是測距算法。

 

  1. 單邊算法:

  

    

我們有兩個模塊,Device A ,DeviceB,他們按照如下流程工作:

  1. deviceA 首先發送一個帶時間戳的幀至 deviceB
  2. deviceB收到幀的同時開始啟動定時T_replay。
  3. DeviceB 發送回應幀,並把定時間隔T_replay附加在幀中。
  4. DeviceA 收到回應幀的同時,計算出發送接收間隔T_round ,並從幀中得到T_replay。

 

  這樣,DeviceA 就得到了計算需要的關鍵數據:T_round ,T_replay。

  而通過計算,就能得到微波在空間中的傳輸時間T_prop

  由於微波是以光速C運行的,進而通過C*T_prop得到傳輸距離,完成測距。

 

  T_prop算法如下:

    T_prop = (Tround - T_replay) /2

 

       T_prop的誤差:

              由於模塊自身的時鍾是有誤差的,所以時間采集也有誤差。我們假定,DeviceA的時鍾誤差為e_a, DeviceB的時鍾誤差為e_b.

              按照資料上看,誤差計算公式是:

                     Error≈ 1/2 * (e_b-e_a) / T_replay

              按照我自己的計算,誤差應該是:

                     Error =  ( e_a*Troud*(1+e_b) – e_b*T_replay*(1+e_a) ) / (Tround(1+e_b) -T_replay*(1+e_a))

         現在還不明白這個誤差公式是怎么推導出來的。

 

  二. 雙邊算法:

    這里用最常用的三次消息法來說明:

    

 

     

  計算距離時,公式如下圖:

       T_prop = (T_ound1*T_ound2 – Treplay1*Treplay2) / ( Tround1 + Tound2 +Treplay1 + Treplay2)

      

  我不嚴謹的分析了下,當T1,T2是一個確定的時間,誤差出現在時間讀數上時:

  T_round1 * T_round2  = T1^2 * e_a*e_b

  Treplay1 * Treplay2 = T2^2 * e_a*e_b

 

       資料上,其誤差公式如下:

       Error = T_prop *(1- (ka+kb)/2)

       其中,ka, kb 時設備A,設備B的運行頻率,接近於1.具體什么含義我也不清楚。

 

  由於確實買看懂誤差公式,所以我使用python來暴力列舉了下,在當設備誤差在(+-0.01),也就是百分之1之內,使用不同的算法,誤差有多大。

       這里涉及到兩個設備,我讓E_a,E_b互相獨立,設定Tround=2400,Treplay = 1800,計算其誤差。

       得到如下對比的誤差圖。,其中X軸是e_a誤差, Y軸是e_b誤差。Z軸是在設備處於e_a,e_b誤差下,測距算法的誤差百分比。

 

  可見,使用DTR(雙邊雙向) 算法,誤差保存在+-1%之間, 而使用STR(單邊)算法,誤差在+-6%之間。

  最后時代碼:

  

import matplotlib.pyplot as plt

from mpl_toolkits.mplot3d import Axes3D

 

ax = plt.figure().add_subplot(111, projection = '3d')
bx = plt.figure().add_subplot(111, projection = '3d')



#單邊算法 求各E_a ,E_b 下的測距誤差,輸入為真實時間
def STR_E(T_round=2400,T_replay=1800):
    for x in range(990,1010):
        for y in range(990,1010):
            x_f = x/1000
            y_f = y /1000
            z_r = (T_round - T_replay)/2
            z_e = (T_round*x_f - T_replay*y_f)/2
            error = (z_e - z_r)/z_r *100
            point = [x_f,y_f,error];
            yield point
            
#雙邊算法 求各E_a ,E_b 下的測距誤差 ,輸入為真實時間            
def DTR_E(T_round=2400,T_replay=1800):
    for x in range(990,1010):
        for y in range(990,1010):
            x_f = x/1000
            y_f = y/1000
            T1_e = T_round*x_f
            T2_e = T_replay*y_f
            T3_e = T_round*y_f
            T4_e = T_replay*x_f
            muti = T1_e*T3_e-T2_e*T4_e
            summ = T1_e+T2_e+T3_e+T4_e
            z_e = muti / summ
            z_r = (T_round - T_replay)/2
            error = (z_e - z_r)/z_r *100
            point = [x_f,y_f,error];
            yield point

#使用生成器,速度很慢           
#for pp  in DTR_E():
    #ax.scatter(pp[0],pp[1],pp[2], c = 'r', marker = '.') #點為紅色三角形

#先把數據寫入列表,然后再顯示,速度快
px=[]
py=[]
pz=[]
for point in DTR_E():
    px.append(point[0])
    py.append(point[1])
    pz.append(point[2])   
ax.scatter(px,py,pz, c = 'r', marker = '.') #點為紅色三角形

pbx=[]
pby=[]
pbz=[]
for point in STR_E():
    pbx.append(point[0])
    pby.append(point[1])
    pbz.append(point[2])   
bx.scatter(pbx,pby,pbz, c = 'r', marker = '.') #點為紅色三角形

#設置坐標軸

ax.set_xlabel('X Label')

ax.set_ylabel('Y Label')

ax.set_zlabel('Z Label')

bx.set_xlabel('X Label')

bx.set_ylabel('Y Label')

bx.set_zlabel('Z Label')


#顯示圖像

plt.show()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM