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“潜艇”雷达探测其他位置的主要内容,如果未能解决你的问题,请参考以下文章