场强定位三角定位技术介绍和算法演示

场强定位&三角定位技术介绍

场强定位和三角定位是无线通信领域中用于确定物体位置的两种重要技术。它们在很多应用场景中,如室内导航、智能家居、紧急救援和军事操作等,发挥着关键作用。

### 场强定位(RSSI定位)

场强定位,通常指的是利用无线信号的接收信号强度指示(Received Signal Strength Indicator,RSSI)来估算距离,进而确定物体的位置。RSSI是一种衡量无线信号接收强度的指标,通常以分贝(dBm)为单位。RSSI值随着距离增加而减小,这一特性使其可以用于估算距离。

#### 原理:

- **信号衰减**:无线信号在传播过程中会受到衰减,这种衰减与信号源和接收器之间的距离有关。
- **环境因素**:墙壁、障碍物等会影响信号强度,这些因素需要在定位算法中考虑。

#### 优缺点:

- **优点**:实施简单,成本较低。
- **缺点**:准确度受环境影响较大,容易受到多径效应和干扰的影响。

### 三角定位(Triangulation)

三角定位是一种更为精确的定位技术,它利用了几何学中的三角学原理。通过测量与至少三个已知位置的基站或接入点(AP)之间的距离或角度,可以确定目标物体的准确位置。

#### 原理:

- **角度或距离测量**:通过测量目标与每个基站之间的角度或距离,可以构建几何关系来定位目标。
- **三点定位**:至少需要三个点的数据来形成闭合的三角形,从而准确计算目标位置。

#### 优缺点:

- **优点**:相比RSSI定位,三角定位通常更准确。
- **缺点**:需要至少三个参考点,实施难度和成本较高。

### 结合使用

在实际应用中,场强定位和三角定位经常结合使用。例如,可以先使用RSSI测量与几个AP之间的距离,然后利用这些距离数据通过三角定位计算出目标的精确位置。这种结合利用可以提高定位的准确性,尤其是在复杂的室内环境中。

 

算法演示

 

import java.util.List;
import java.util.Optional;

public class RssiTriangleLocUtil {
    // 三角形的边数
    public static final int SIDES_OF_TRIANGLE = 3;
    // 手机高度,固定为1.5米
    private static final double PHONE_HEIGHT = 1.5d;

    // 场强三角定位主方法
    // rssilocationinfos 是定位点到3个信号最强的AP之间的场强信息集合
    public static Optional<double[]> doRssiLocation(List<RssiLocationInfo> rssiLocationInfos) {
        if (rssiLocationInfos.size() == SIDES_OF_TRIANGLE) {
            // 正常流程
            double[] betweenPointE = calculateBetweenPoint(rssiLocationInfos.get(0), rssiLocationInfos.get(1));
            double[] betweenPointF = calculateBetweenPoint(rssiLocationInfos.get(1), rssiLocationInfos.get(2));
            double[] betweenPointG = calculateBetweenPoint(rssiLocationInfos.get(0), rssiLocationInfos.get(2));
            return Optional.of(calculateHeartPoint(betweenPointE, betweenPointF, betweenPointG));
        } else if (rssiLocationInfos.size() == 2) {
            // 只有两个AP的数据
            return Optional.of(calculateBetweenPoint(rssiLocationInfos.get(0), rssiLocationInfos.get(1)));
        } else if (rssiLocationInfos.size() == 1) {
            // 只有一个AP的数据
            RssiLocationInfo info = rssiLocationInfos.get(0);
            return Optional.of(new double[] {info.getXcoord(), info.getYcoord()});
        } else {
            return Optional.empty();
        }
    }

    // 计算两个AP之间的比例点
    private static double[] calculateBetweenPoint(RssiLocationInfo info1, RssiLocationInfo info2) {
        double distanceA3d = distanceFromPointToApByRssi(info1.getRssi(), info1.getRfFrequency(), info1.getInitialRfPower(), info1.getAttenuationCoefficient());
        double distanceB3d = distanceFromPointToApByRssi(info2.getRssi(), info2.getRfFrequency(), info2.getInitialRfPower(), info2.getAttenuationCoefficient());

        double distanceA2d = convert3DDistanceTo2D(distanceA3d, info1.getApHeight());
        double distanceB2d = convert3DDistanceTo2D(distanceB3d, info2.getApHeight());

        return calculateMidpoint(distanceA2d, distanceB2d, info1.getXcoord(), info1.getYcoord(), info2.getXcoord(), info2.getYcoord());
    }

    // 根据定位点到AP的场强计算3D空间距离
    private static double distanceFromPointToApByRssi(double rssi, double rfFrequency, double initialRfPower, double attenuationCoefficient) {
        return Math.pow(10, (initialRfPower - rssi - 32.4 - 20 * Math.log10(rfFrequency)) / attenuationCoefficient);
    }

    // 利用勾股定理转换3D距离为2D距离
    private static double convert3DDistanceTo2D(double distance3d, double apHeight) {
        return Math.sqrt(Math.max(Math.pow(distance3d, 2) - Math.pow(apHeight - PHONE_HEIGHT, 2), 0));
    }

    // 计算三角形内心坐标
    private static double[] calculateHeartPoint(double[] pointE, double[] pointF, double[] pointG) {
        double distanceFG = euclideanDistance(pointF, pointG);
        double distanceEG = euclideanDistance(pointE, pointG);
        double distanceEF = euclideanDistance(pointE, pointF);
        double heartX = (distanceFG * pointE[0] + distanceEG * pointF[0] + distanceEF * pointG[0]) / (distanceFG + distanceEG + distanceEF);
        double heartY = (distanceFG * pointE[1] + distanceEG * pointF[1] + distanceEF * pointG[1]) / (distanceFG + distanceEG + distanceEF);
        return new double[]{heartX, heartY};
    }

    // 计算两点间的欧几里得距离
    private static double euclideanDistance(double[] point1, double[] point2) {
        return Math.sqrt(Math.pow(point1[0] - point2[0], 2) + Math.pow(point1[1] - point2[1], 2));
    }

    // 根据两个AP的坐标及定位点距离这两个AP的距离(2D距离),计算两个AP之间的比例中间点
    private static double[] calculateMidpoint(double distanceA2d, double distanceB2d, double xcoordFromAp1, double ycoordFromAp1, double xcoordFromAp2, double ycoordFromAp2) {
        double ratio = distanceA2d / (distanceA2d + distanceB2d + 1e-10); // 添加小量避免除零
        double xGap = xcoordFromAp2 - xcoordFromAp1;
        double yGap = ycoordFromAp2 - ycoordFromAp1;
        double xcoordMiddle = xcoordFromAp1 + xGap * ratio;
        double ycoordMiddle = ycoordFromAp1 + yGap * ratio;
        return new double[]{xcoordMiddle, ycoordMiddle};
    }

    // RssiLocationInfo 类(假设存在),用于存储定位信息
    public static class RssiLocationInfo {
        private double rssi;
        private double rfFrequency;
        private double initialRfPower;
        private double attenuationCoefficient;
        private double xcoord;
        private double ycoord;
        private double apHeight;

        // Getters and setters for the fields
        // ...
    }
}
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/222391.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTML5结构规范

一&#xff0c;getBoundingClientRect&#xff1b; 用于获得页面中某个元素的左&#xff0c;上&#xff0c;右和下分别相对浏览器视窗的位置。 const elTop el.getBoundingClientRect().top;二&#xff0c; Web Worker 当在 HTML 页面中执行脚本时&#xff0c;页面是不可响应的…

使用python脚本部署k8s集群

1.环境规划&#xff1a; 节点IP地址操作系统配置脚本运行节点192.168.174.5centos7.92G2核server192.168.174.150centos7.92G2核client1192.168.174.151centos7.92G2核client2192.168.174.152centos7.92G2 2.运行准备&#xff1a; yum install -y python python-pip pip in…

AI人工智能与云原生:创新科技的完美结合

人工智能&#xff08;AI&#xff09;是当今科技领域的热门话题&#xff0c;而云原生则是一种新兴的软件开发和部署模式。AI人工智能与云原生的结合&#xff0c;为现代技术创新提供了无限的可能性。本文将探讨AI与云原生的关系&#xff0c;并介绍其如何在实际应用中实现协同效应…

微信小程序如何实现WXML和js文件之间的数据交互

在微信小程序中&#xff0c;WXML负责页面结构的描述&#xff0c;而js文件则负责页面的逻辑处理和数据交互。要实现WXML和js文件之间的数据交互&#xff0c;可以通过以下几种方法&#xff1a; JS传输数据到WXML 数据绑定&#xff1a;在WXML中使用{{}}语法将js文件中的数据绑定…

宏景eHR SQL注入漏洞复现

0x01 产品简介 宏景eHR人力资源管理软件是一款人力资源管理与数字化应用相融合&#xff0c;满足动态化、协同化、流程化、战略化需求的软件。 0x02 漏洞概述 宏景eHR app_check_in/get_org_tree.jsp接口处存在SQL注入漏洞&#xff0c;未经过身份认证的远程攻击者可利用此漏洞…

SQL事务管理

事务管理是针对数据库的一组操作。由一条或多条SQL语句组成&#xff0c;这些语句在逻辑上具有强烈的相关性&#xff0c;如果其中一条语句无法执行&#xff0c;那么所有的语句都不会执行。 1 事务管理 原子性 指一个事务必须被视为一个不可分割的最小单元。只有事务中所有的数…

Django、Echarts异步请求、动态更新

前端页面 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>echarts示例</title> <script src"jquery.min.js"></script><script type "text/javascript" src "echarts.m…

什么是PHP的SPL(标准PHP库)?

SPL&#xff08;Standard PHP Library&#xff09;是 PHP 中的标准库&#xff0c;提供了一组用于解决常见问题的接口和类。它包含了一系列的数据结构、算法、迭代器、文件处理、异常处理等组件&#xff0c;使得 PHP 开发者能够更方便地处理各种编程任务。 SPL 提供的主要组件包…

Rancher中使用promtail+loki+grafna收集k8s日志并展示

Rancher中使用promtail+loki+grafna收集k8s日志并展示 根据应用需求和日志数量级别选择对应的日志收集、过滤和展示方式,当日志量不太大,又想简单集中管理查看日志时,可使用promtail+loki+grafna的方式。本文找那个loki和grafana外置在了k8s集群之外。 1、添加Chart Repo …

Pencile - exer

import java.util.HashMap; import java.util.Map;public class TableConverter {public static void main(String[] args) {// 示例输入数据String[] inputData {"line1 col1 A","line2 col3 B","line3 col1 C","line4 col2 D",};//…

云架构的思考4--云上灾备

目录 1 关键指标2 灾备方案3 云上灾备常见模式3.1 “地域”模式3.2 “应用”模式3.3 “数据”模式 4 总结 前几章讲了云上架构、开发等事项&#xff0c;其实灾备也算是架构中的一步&#xff0c;但是这里特意拎出来讲主要有2个原因&#xff0c;其一是因为灾备相对独立且复杂&…

Linux-----5、文件系统

# 文件系统 # 终端的基本操作 ㈠ 打开多个终端 ㈡ 快速清屏 新建标签&#xff1a;command T 新建窗口&#xff1a;command N 关闭标签&#xff1a;command Q 关闭窗口&#xff1a;command W 放大&#xff1a;command 缩小&#xff1a;command - 清屏&#xff…

智慧城市/一网统管建设:人员危险行为检测算法,为城市安全保驾护航

随着人们压力的不断增加&#xff0c;经常会看见在日常生活中由于小摩擦造成的大事故。如何在事故发生时进行及时告警&#xff0c;又如何在事故发生后进行证据搜索与事件溯源&#xff1f;旭帆科技智能视频监控人员危险行为/事件检测算法可以给出答案。 全程监控&#xff0c;有源…

函数节流(js的问题)

函数节流也用到了高阶函数的知识&#xff0c;因为比较重要&#xff0c;所以单开了一个标题。 javascript中的函数在大多数情况下都是由用户主动调用触发的&#xff0c;除非是函数本身的实现不合理。但是在一些少数情况下&#xff0c;函数可能被很频繁的调用&#xff0c;而造成大…

【Linux】多线程编程

目录 1. 线程基础知识 2. 线程创建 3. 线程ID&#xff08;TID&#xff09; 4. 线程终止 5. 线程取消 6. 线程等待 7. 线程分离 8. 线程互斥 8.1 初始化互斥量 8.2 销毁互斥量 8.3 互斥量加锁和解锁 9. 可重入和线程安全 10. 线程同步之条件变量 10.1 初始化条件变…

Qt图像处理-亮度、对比度、灰度、锐化、负片的实现

本文演示Qt中图像的亮度、对比度、灰度、锐化、负片处理实现 一、概述 亮度和对比度原理 图像亮度通俗理解便是图像的明暗程度,数字图像 f(x,y) = i(x,y) r(x, y) ,如果灰度值在[0,255]之间,则 f 值越接近0亮度越低,f 值越接近255亮度越高。而且我们也要把亮度和对比…

Maven下载及安装自用版

Maven下载及安装自用版 可能是Maven用久了。感觉Maven用起来还算顺手&#xff0c;比Gradle要好上手一些。 一、下载 Maven 下载地址 注意下载版本和依赖要求&#xff0c;下载后&#xff0c;解压放在指定的位置;注意安装地址&#xff0c;放在自己规划好的开发环境专用文件夹里…

ubuntu创建apt-mirror本地仓库

首先创建apt-mirror的服务端&#xff0c;也就是存储所有apt-get下载的文件和依赖。大约需要300G&#xff0c;预留400G左右空间就可以开始了。 安装ubuntu省略&#xff0c;用的是ubuntu202204 ubuntu挂载硬盘&#xff08;不需要的可以跳过&#xff09;: #下载挂载工具 sudo apt…

C++类与对象(一)

目录 一&#xff0c;面向过程和面向对象初步认识 二&#xff0c;类的引入 三&#xff0c;类的定义 四&#xff0c;类的访问限定符及封装 五&#xff0c;类的实例化 六&#xff0c;类对象模型 七&#xff0c;this指针 一&#xff0c;面向过程和面向对象初步认识 c语言是面…

使用动画曲线编辑器打造炫酷的3D可视化ACE

前言 在制作3D可视化看板时&#xff0c;除了精细的模型结构外&#xff0c;炫酷的动画效果也是必不可少的。无论是复杂的还是简单的动画效果&#xff0c;要实现100%的自然平滑都是具有挑战性的工作。这涉及到物理引擎的计算和对动画效果的数学建模分析。一般来说&#xff0c;只…