TDOA定位方法的Fang算法的程序实现(二维)

TDOA定位方法的Fang算法的程序实现(二维)

摘要:

蜂窝无线定位服务(LCS)是一种具有广阔市场前景的移动增值业务,其基本原理是利用现有蜂窝网络,通过对各种位置特征参数,包括到达时间(TOA),到达时间差(TDOA),到达方向(DOA)的测量和估计,从而实现移动用户的定位。
本篇介绍TDOA定位方法的Fang算法及其程序实现。

1、引言:
在各种无线定位系统中,采用的基本定位方法和技术都是相同或者相似的。
从几何角度讲,确定目标在二维或者三维空间的位置可以由两个或者多个曲线在二维或者三维空间内相交得到,以这一标准进行划分,可供选择的定位方法有:
1:圆周定位方法
2:双曲线定位方法
3:方位角测量定位方法
4:混合定位方法
一般,基于电磁波场强和TOA的定位采用的是圆周定位。基于AOA采用的是方位角定位。基于TDOA的定位是采用双曲线定位,混合定位则是基于AOA、TDOA或者其他组合。

2、TDOA双曲线模型
在这里插入图片描述
在这里插入图片描述
根据上面的方程组,进而可以求解得到移动台MS的位置坐标。
不管是哪种TDOA的双曲线算法(熟知的如Chan 或者Fang),在二维平面中,只需要三个基站就可以定位出移动台MS的XY坐标。
如果是三维空间中,需要四个基站才可以定位出MS的XYZ坐标。

3、Fang 算法原理
在这里插入图片描述
在这里插入图片描述
解方程(3.3),可以得到两个X值,,利用有关先验信息如(标签得到两个基站的距离差R21),就可以取到正确的X值。然后利用式(3.2)得到Y值。

4、代码实现

这里我们用C++做程序实现:

这里我们先预设了3个基站、及标签T到基站的距离

//基站1--基站3坐标
double AncLoc[3][3]={
    {0,0,0},                   
    {700,0,0},                 
    {700,740,0},
   // {30,740,300},

};

//标签到3个基站的距离
double T2A_R[3] = {671,506,351};

主函数

int main(int argc, char** argv) {

    FangTDOA Anc;                       //创建对象
    Anc.GetAncData(&AncLoc[0][0],3,3);  //获取基站坐标
    Anc.displayAncData();               //显示基站坐标
    Anc.getRang(&T2A_R[0]);             //获取标签到基站的距离
    Anc.displayATrang();                //显示标签到基站的距离
    Anc.DeviationRang(1);               //计算标签到基站的距离差

    Anc.get3gh();                       //计算得到参数g,h
    Anc.get3def();                      //计算得到参数d,e,f

    Anc.getX();                         //得到X坐标
    Anc.getY();                         //得到Y坐标
    Anc.checkResult();                  //得到最终坐标点

    return 0;
}

主要关键代码:

#include <iostream>
#include <math.h>
#include <cmath>
#include<fstream>
#include<cstdlib>
#include<QString>
#include<FangTDOA.h>

using namespace std;

//Fang TDOA 分为三基站和四基站模式,
//三基站模式下,标签的Z轴的影响,会使得定位的精度变弱。
//四基站模式下,定位精度会比较高。


FangTDOA::FangTDOA()
{
    for (int i = 0; i < 3; ++i)
    {
        for(int j = 0; j<3; ++j)
        {
            AncXYZ[i][j]=0;
        }
    }

    for (int i = 0; i < 3; ++i)
    {
      ATrang[i] = 0;
      devi_R[i] = 0;
    }

   // *sloveX = NULL;
   // *solution = NULL;
    // return 0;

}

FangTDOA::~FangTDOA()
{

 //   return 0;

}


//获取基站坐标
double FangTDOA::GetAncData(double *inputAncDate,const int irows,const int jcolum)
{
    for (int i = 0; i < irows; ++i)
    {
        for(int j = 0; j<jcolum; ++j)
        {
            AncXYZ[i][j]= *(inputAncDate+i*jcolum+j);
        }
    }
    return 0;
}

//显示基站坐标
void FangTDOA::displayAncData()
{
    cout<<"the AncXYZ data is:"<<endl;
    for (int i = 0; i < 3; ++i)
    {
        for(int j = 0; j<3; ++j)
        {
            cout<<setprecision(10)<< AncXYZ[i][j]<<"  ";
        }
           cout<<endl;
    }

}

//获取标签到4个基站的距离
void FangTDOA::getRang(double rang[])
{
    for (int i = 0; i < 3; ++i)
    {
      ATrang[i] = rang[i];
    }
}

void FangTDOA::displayATrang()
{
    cout<<setprecision(10)<< "tag to Anc rang is:  "<<endl;

    for (int i = 0; i < 3 ; ++i)
    {
         cout<<setprecision(10)<< ATrang[i]<<"  ";
    }
    cout<<endl;
}

//标签到基站的距离差
void FangTDOA::DeviationRang(int rel)
{
    switch (rel) {
    case 1:
        devi_R[0] = ATrang[0]; // R1
        devi_R[1] = ATrang[1] - ATrang[0] ; // R2-R1
        devi_R[2] = ATrang[2] - ATrang[0] ; //R3-R1
        devi_R[3] = ATrang[3] - ATrang[0] ; //R4-R1
        break;
    case 2:
        devi_R[0] = ATrang[1]; // R1
        devi_R[1] = ATrang[2] - ATrang[1] ; // R2-R1
        devi_R[2] = ATrang[3] - ATrang[1] ; //R3-R1
        devi_R[3] = ATrang[0] - ATrang[1] ; //R4-R1

        break;
    case 3:
        devi_R[0] = ATrang[2]; // R1
        devi_R[1] = ATrang[3] - ATrang[2] ; // R2-R1
        devi_R[2] = ATrang[0] - ATrang[2] ; //R3-R1
        devi_R[3] = ATrang[1] - ATrang[2] ; //R4-R1

        break;
    case 4:
        devi_R[0] = ATrang[3]; // R1
        devi_R[1] = ATrang[0] - ATrang[3] ; // R2-R1
        devi_R[2] = ATrang[1] - ATrang[3] ; //R3-R1
        devi_R[3] = ATrang[2] - ATrang[3] ; //R4-R1

        break;
    default:
        break;
    }
}

void FangTDOA::get3gh()
{
   double temp = 0;
   g = (devi_R[2]* AncXYZ[1][0]/devi_R[1] - AncXYZ[2][0])/AncXYZ[2][1];

       temp = pow(AncXYZ[2][0],2) + pow(AncXYZ[2][1],2) - pow(devi_R[2],2);
       temp = temp + devi_R[2]*devi_R[1]*(1 - pow((AncXYZ[1][0] / devi_R[1]) ,2) ) ;
   h = (temp / 2)/AncXYZ[2][1];

}

void FangTDOA::get3def()
{
    double temp = 0;
    temp = pow((AncXYZ[1][0]/devi_R[1]),2);
    d = - (( 1 - temp)  + g*g);
    e = AncXYZ[1][0]*(1-temp)-2*g*h;
    temp = pow(devi_R[1],2) -pow(AncXYZ[1][0],2);
     temp = pow(temp,2);

    f = (temp/pow(devi_R[1],2))*0.25 - h*h;
}


double FangTDOA::getX()
{

   getfunction2(d,e,f);

  // return sloveX;
}

double FangTDOA::getY()
{

    sloveY[0] = g*sloveX[0]+h;
    sloveY[1] = g*sloveX[1]+h;
}

double FangTDOA::checkResult()
{
    double tempR2 = sqrtf(pow((sloveX[0]-AncXYZ[1][0]),2) + pow(sloveY[0],2));
    double tempR1 = sqrtf(pow(sloveX[0],2)+pow(sloveY[0],2));
    double tempslotR =  fabs((tempR2-tempR1) -devi_R[1]) ;
    if(tempslotR<5)
    {
        finalXYZ[0] = sloveX[0];
        finalXYZ[1] = sloveY[0];
    }
    else
    {
        finalXYZ[0] = sloveX[1];
        finalXYZ[1] = sloveY[1];
    }

    cout<<setprecision(10)<<finalXYZ[0]<< " ";
    cout<<setprecision(10)<<finalXYZ[1]<< " ";
}


结果输出:

在这里插入图片描述
相关参考代码详见附件
//download.csdn.net/download/qq_21291397/12103237

PS:
1、Fang 算法,相对Chan 算法相对复杂,而且对基站的参数有一定的限制,如果基站的坐标可任意设定,这里还需要通过坐标变换(平移和旋转)来实现。
2、三维Fang算法,也可以进一步实现:可以参考下面一片文章:
http://www.doc88.com/p-7724949260733.html,可惜该论文有很多印刷的错误,部分公式的推导也是错误的。但思路可以借鉴。

  • 11
    点赞
  • 111
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
抗非直射传播路径(NLOS)的TDOA(时间差到达)定位算法是指在信号传播过程中存在非直射路径的情况下,通过测量信号到达各个接收器的时间差,实现定位算法。下面是一个简单的示例代码: ```python import numpy as np def TDOA_NLOS(localization_array): # 假设有三个接收器,初始位置已知 receiver1 = np.array([0, 0]) receiver2 = np.array([1, 0]) receiver3 = np.array([0, 1]) # 信号传播速度为光速 c = 299792458 # 测量到达三个接收器的时间 t1 = localization_array[0] t2 = localization_array[1] t3 = localization_array[2] # 构建矩阵方程 Ax = b A = np.array([[2*(receiver1[0]-receiver2[0]), 2*(receiver1[1]-receiver2[1])], [2*(receiver1[0]-receiver3[0]), 2*(receiver1[1]-receiver3[1])], [2*c*(t2-t1), 2*c*(t3-t1)]]) b = np.array([c**2*(t1**2-t2**2+receiver1[0]**2-receiver2[0]**2+receiver1[1]**2-receiver2[1]**2), c**2*(t1**2-t3**2+receiver1[0]**2-receiver3[0]**2+receiver1[1]**2-receiver3[1]**2), 0]) # 使用最小二乘法求解矩阵方程 x = np.linalg.lstsq(A, b, rcond=None)[0] return x # 在主程序中调用定位函数 localization_array = np.array([1.5, 2.0, 2.5]) localization_result = TDOA_NLOS(localization_array) print("目标位置为:", localization_result) ``` 这段代码的主要思路是通过构建一个线性方程组,将三个接收器的位置和到达时间差关系转化为一个矩阵方程,然后使用最小二乘法求解方程组,得出目标的位置坐标。注意代码中的坐标单位为米,时间单位为秒。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值