GPS“潜艇”雷达探测其他位置

Posted

技术标签:

【中文标题】GPS“潜艇”雷达探测其他位置【英文标题】:GPS 'Submarine' Radar Detecting Other location 【发布时间】:2015-05-12 17:07:04 【问题描述】:

假设我有一架无人机和我的手机。我看了看北方,把无人机放在我前面 4 米处。我应该看看雷达,看到无人机在北方。

我的雷达是 256x256 像素,无人机的最大距离是 200 米,大约是 0.002 纬度/经度。

所以,我做了一个简单的测试类来测试我北方的这架无人机。

public static void main(String[] args) 

    BigDecimal droneLat = new BigDecimal(-22.811468333334087077446383773349225521087646484375);
    BigDecimal droneLong = new BigDecimal(-47.04746500000123177187560941092669963836669921875);

    BigDecimal phoneLat = new BigDecimal(-22.81129370000000022855601855553686618804931640625); 
    BigDecimal phoneLong = new BigDecimal(-47.04832809999999909678081166930496692657470703125);

    BigDecimal latDiff = phoneLat.subtract(droneLat);
    BigDecimal longDiff = phoneLong.subtract(droneLong);

    int pixelsLat = degreesToPixels265x265(latDiff.abs());
    int pixelsLong = degreesToPixels265x265(longDiff.abs());

     if (latDiff.compareTo(new BigDecimal(0)) < 0)  // drone > phone means phone is farther to north, phone lat will be lower, it will show lower in radar
           pixelsLat = -pixelsLat;
     
     if (longDiff.compareTo(new BigDecimal(0)) > 0)  // drone > phone means phone is farther to north, phone lat will be lower, it will show lower in radar
           pixelsLong = -pixelsLong;
     

    System.out.println("DiffLat "+latDiff);
    System.out.println("DiffLong "+longDiff);

    System.out.println("Pixels lat = "+pixelsLat);
    System.out.println("Pixels long = "+pixelsLong);


public static int degreesToPixels265x265(BigDecimal n) 
    BigDecimal p1 = n.multiply(new BigDecimal(256/2)); 
    return p1.divide(new BigDecimal(0.002d),2,BigDecimal.ROUND_CEILING).intValue();

Pixels Lat 的总和为 128 以绘制无人机位置,pixelsLong 也是如此。由于无人机在我的北方,像素纬度应该更正吗?

我在这里做一些错误的数学运算来检测绘制这个的真实坐标吗?

非常感谢您的关注!

【问题讨论】:

【参考方案1】:

您要解决的一般问题是“投影”:将球体上的纬度/经度坐标投影到平面(屏幕)上。这是关于如何解决该问题的问题/答案:Converting longitude/latitude to X/Y coordinate

但是如果您不关心解决投影的一般问题,对于任何投影(墨卡托等)并处理非常长的距离(数千英里)和边缘情况(您在靠近北方或南方飞行杆),您可以做一些非常简单的事情:计算点 A(您的位置)和点 B(无人机的位置)的方位和距离。使用该方位和距离,在屏幕上绘制无人机的近似值,该近似值应该可以在几百米范围内正常工作。

要计算距离,请使用Haversine formula:

public static double distance(double lat1, double lon1, double lat2, double lon2) 
    double R = 6372.8; // Radius of the earth in kilometers.
    double dLat = Math.toRadians(lat2 - lat1);
    double dLon = Math.toRadians(lon2 - lon1);
    lat1 = Math.toRadians(lat1);
    lat2 = Math.toRadians(lat2);
    double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
    double c = 2 * Math.asin(Math.sqrt(a));
    return R * c;

并且要计算两点之间的角度(实际上只是初始角度——在球体上,角度会随着您的靠近而变化,但我们是在短距离内进行近似):

public static double bearing(double lat1, double lon1, double lat2, double lon2) 
    double latitude1 = Math.toRadians(lat1);
    double latitude2 = Math.toRadians(lat2);
    double longitude1 = Math.toRadians(lon1);
    double longitude2 = Math.toRadians(lon2);
    double longDiff = longitude2 - longitude1;
    double y = Math.sin(longDiff) * Math.cos(latitude2);
    double x = Math.cos(latitude1) * Math.sin(latitude2) - Math.sin(latitude1) * Math.cos(latitude2) * Math.cos(longDiff);
    return Math.atan2(y, x);

一旦您可以计算距离和方位,您就可以将其映射到您的屏幕上(您正在做的是将极坐标转换为笛卡尔/XY 坐标):

public static void plotLatLon(double droneLat, double droneLon) 
    // Get location from phone geolocation.
    double phoneLat = -22.8112937000;
    double phoneLon = -47.0483281000;
    int width = 256;
    int height = 256;
    // 256 pixels = 400 meters; 200 meters away = edge of screen.
    double scaleFactor = 256.0 / 400.0;

    double bearing = bearing(phoneLat, phoneLon, droneLat, droneLon);
    double distance = distance(phoneLat, phoneLon, droneLat, droneLon);
    System.out.println("Bearing: " + (Math.toDegrees(bearing) + 360.0) % 360.0);
    System.out.println("Distance: " + distance);
    double angle = (Math.PI / 2.0) - bearing;
    int x = (int)(distance * scaleFactor * Math.cos(angle));
    int y = (int)(distance * scaleFactor * Math.sin(angle));
    // Assumes radar coordinate system has (0,0) at the lower left.
    Radar.plotXY(x + width / 2, y + height / 2);

这是我得到的结果:

Bearing: 102.38029388096368
Distance: 90.59766443003579
X: 184
Y: 116

(您的无人机实际上并不在北方;您提供的坐标将其置于东方和稍微南方。)

注意双精度就足够了:"Double precision floats give sub-millimetre precision anywhere on Earth."

您可能还对像 spatial4j 这样的库感兴趣,用于在 Java 中进行地理计算。

【讨论】:

【参考方案2】:

当您向北行驶时,北极的纬度最多增加 90 度。所以是的,你是对的。像素应该更积极。 (我猜你在北美/欧洲?)Read This

但是,我现在正在做一个 GPS 项目,我可以根据经验告诉您,4 米远,远未接近。民用 GPS 接收器没有蜂窝塔的帮助在理想条件下可以达到大约 10 米的精度。使用 GLONASS 可能会更好。

如果您愿意等待,可以购买其中一种: http://store.swiftnav.com

GPS 101:将无人机移到更远的地方,并考虑仅精确到 20 米左右的结果。

【讨论】:

以上是关于GPS“潜艇”雷达探测其他位置的主要内容,如果未能解决你的问题,请参考以下文章

VREP中的二维激光雷达

激光雷达和毫米波雷达

细数激光雷达的那些类型

激光雷达是什么?一文带你读懂激光雷达

自动驾驶离不开的激光雷达,究竟有几种分类?

2201 雷达 | 雷达感应模块的工作原理(人体呼吸探测) 极益科技5.8G | 现在