定位算法-三边测距定位

作者:姜小明 @github
日期:2020-09-06
关键字:RANSAC, Multilateral positioning, localization

上一篇文章(《使用RANSAC的鲁棒TDOA Chan定位算法》)中提到,如果我们知道当前位置到各个基站的距离,可以很方便的确定位置。本篇文章我们简短介绍测距定位算法及其实现。

1. 三边测距定位算法简介

利用信号源到各个监测站的距离,最少通过三个监测站,我们就能确定信号的位置,该方法为三边测距定位。如下图,以监测站为中心,距离为半径作圆可以确定信号的位置:

在这里插入图片描述

2. 算法

2.1 算法推导

算法推导如下图(参考知乎-三边测量及多边测量):
在这里插入图片描述

2.2 算法实现

算法实现如下:

bool calculate_pos_with_index_(const Position2D landmarks[], const double distances[], const int effective_landmark_indexes[], int effective_landmark_num, 
        double* x_out, double* y_out) {
    if (is_landmarks_in_one_line(landmarks, effective_landmark_indexes, effective_landmark_num)) {
        printf("all landmarks in one line, cannot locate the position.\n");
        return false;
    }
    int matrix_row_num = effective_landmark_num - 1;
    int coefficient_num = 2;
    // Ax=b
    gsl_matrix* A = gsl_matrix_alloc(matrix_row_num, coefficient_num);
    gsl_matrix* a = gsl_matrix_alloc(matrix_row_num, coefficient_num);
    gsl_vector* b = gsl_vector_alloc(matrix_row_num);
    
    // result
	gsl_vector *sx = gsl_vector_alloc(coefficient_num);

    //Clear data
    gsl_matrix_set_zero(A);
    gsl_vector_set_zero(b);

    int index_last = effective_landmark_indexes[effective_landmark_num - 1];
    for (int i = 0; i < effective_landmark_num - 1; i++) {
        int index_i = effective_landmark_indexes[i];
        gsl_matrix_set(A, i, 0, (landmarks[index_i].x - landmarks[index_last].x) * 2);
        gsl_matrix_set(A, i, 1, (landmarks[index_i].y - landmarks[index_last].y) * 2);
        double bi = landmarks[index_i].x * landmarks[index_i].x - landmarks[index_last].x * landmarks[index_last].x
                        + landmarks[index_i].y * landmarks[index_i].y - landmarks[index_last].y * landmarks[index_last].y
                        + distances[index_last] * distances[index_last] - distances[index_i] * distances[index_i];
        gsl_vector_set(b, i, bi);
    }
    gsl_matrix_memcpy(a, A);
    gsl_vector* tau = gsl_vector_alloc(coefficient_num); //matrix_row_num, coefficient_num
    gsl_vector* residuals = gsl_vector_alloc(matrix_row_num);

    gsl_multifit_linear_workspace *w = gsl_multifit_linear_alloc(matrix_row_num, coefficient_num);
    gsl_multifit_linear_svd(A, w);
    double rcond = gsl_multifit_linear_rcond(w); // reciprocal condition number
    printf("conditional number is:%f\n", 1.0 / rcond);
    if (rcond < 1e-4) {
        printf("conditional number is too large, indicating that the problem is ill-conditioned.\n");
        return false;
    }
    double lambda_gcv = 0.1;
    double chisq, rnorm, snorm;
    gsl_multifit_linear_solve(0.0, A, b, sx, &rnorm, &snorm, w);

    *x_out = gsl_vector_get(sx, 0);
    *y_out = gsl_vector_get(sx, 1);

    gsl_matrix_free(A);
    gsl_matrix_free(a);
    gsl_vector_free(b);
    gsl_vector_free(tau);
    gsl_vector_free(sx);
    gsl_vector_free(residuals);
    return true;
}

3. 项目描述

全部工程代码:github-RANSAC_Locator_using_distances

项目使用C语言实现了三边测距定位算法。和上一篇定位文章类似地,本项目使用了RANSAC思想排除异常点的干扰,获取稳定的解。main.c中包含了一段测试代码。编译方式和gsl库配置方法详见readme.md。

  • 10
    点赞
  • 121
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
TDC-GP22是一种测距算法。TDC代表 Time-to-Digital Converter,即时间到数字转换器。它是一种用于测量信号到达时间的设备。GP22是一种具体型号的TDC。 TDC-GP22测距算法的基本原理是通过测量信号到达时间来计算距离。首先,将待测距离的信号输入到TDC-GP22,它会精确地记录这个信号的到达时间点。然后,将测得的时间转换为数字形式,以便进一步处理。 接下来,我们需要通过一些校准和计算来确定这个时间对应的距离。一种常用的方法是使用已知距离的参照信号进行校准。我们输入一个已知距离的信号并记录其到达时间,然后通过比较这个时间和待测距离的时间来确定两者之间的距离差异。通过多次校准,我们可以建立一个准确的时间和距离的关系模型。 一旦建立了这个模型,我们就可以根据测得的时间来计算相应的距离。我们输入待测距离的信号,TDC-GP22记录其到达时间,然后通过之前建立的模型,将时间转换为距离。 TDC-GP22测距算法的优点是精度高,测量范围广。它可以在微米或亚微米级别进行精确测距,并且适用于不同距离范围的测量需求。 总之,TDC-GP22是一种基于时间测量原理的测距算法。通过记录信号到达时间并进行校准和计算,它能够准确地测量信号的距离,并广泛应用于各种领域,如激光测距、雷达测距等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值