英文:
Direction from gps coordinates
问题
我正在做一个基于嵌入式系统的交通灯管理项目。我正在使用一个三路交叉口作为示例。其中一个GPS坐标将是固定的(即交通信号的坐标),另一个将是特定移动车辆(比如救护车)来自任何方向的坐标。有没有办法我可以从GPS坐标中找出它是从哪个方向接近交通信号?
我考虑在每个交叉口使用RFID标签,以便如果救护车或其他紧急车辆到达,它可以感应到并将信号发送给交通灯管理系统。
英文:
I'm making a project which is based on traffic light management using embedded system. I'm using a Three way junction for this example. 1 gps coordinate will be fixed (i.e., of the traffic signal) and the other will be of the particular moving vehicle (lets say ambulance) coming from any direction. is there any way i can find out which direction it is approaching the traffic signal from the gps coordinates?
i considered using an RFID Tag at each junctions so that if an ambulance or any other emergency vehicle arrives, it can sense it and send the signal to the traffic light managing system
答案1
得分: 1
以下是翻译的内容:
有两种常见的方法;Haversine 和 Rhumb Line 公式。 这两种方法都在 http://www.movable-type.co.uk/scripts/latlong.html 中有描述。 对于短距离来说,你使用哪一种方法都没有太大差别。
这两种公式都可以计算距离和方位角。 例如,Haversine 公式用于计算方位角的部分如下:
θ = atan2( sin Δλ ⋅ cos φ2 , cos φ1 ⋅ sin φ2 − sin φ1 ⋅ cos φ2 ⋅ cos Δλ )
其中
φ1
, λ1
是起始点, φ2
, λ2
是终点(Δλ 是经度差值 - λ2 - λ1
)。
所以在代码中:
#include <math.h>
double bearing_degrees( double lat1, double lon1,
double lat2, double lon2 )
{
double delta_lon = lon2 - lon1 ;
double cos_lat2 = cos( lat2 ) ;
double y = sin( delta_lon ) * cos_lat2 ;
double x = cos( lat1 ) * sin( lat2 ) -
sin( lat1 ) * cos_lat2 * cos( delta_lon ) ;
double bearing_rad = atan2( y, x ) ;
// 转换为度数
return fmod(bearing_rad * 180.0f / M_PI + 360.0f, 360.0f ) ;
}
在基于 AVR 的 Arduino 上和基于 ARM 的 Due 上,浮点数计算会占用大量计算资源和代码空间。而且在没有 FPU 的情况下,最好避免使用浮点数计算。但在这种情况下很难避免。此外,虽然使用 float
可以在内存和计算上更高效,但由于精度只有六个有效数字,对于这个应用程序来说不够精确,因为距离只是地球周长的一小部分。要解析到小于2米,需要至少有5位小数,这需要8个有效数字。double
具有15位有效数字,因此更适合这个应用。
英文:
There are two common methods; Haversine and Rhumb Line formulae. Both are described at http://www.movable-type.co.uk/scripts/latlong.html. For short distances it does not really make any difference which you use.
Both formulae yield distance and bearing. The Haversine formula for the bearing component for example:
θ = atan2( sin Δλ ⋅ cos φ2 , cos φ1 ⋅ sin φ2 − sin φ1 ⋅ cos φ2 ⋅ cos Δλ )
where
φ1
,λ1
is the start point, φ2
,λ2
the end point (Δλ
is the difference in longitude - λ2 - λ1
).
So in code:
#include <math.h>
double bearing_degrees( double lat1, double lon1,
double lat2, double lon2 )
{
double delta_lon = lon2 - lon1 ;
double cos_lat2 = cos( lat2 ) ;
double y = sin( delta_lon ) * cos_lat2 ;
double x = cos( lat1 ) * sin( lat2 ) -
sin( lat1 ) * cos_lat2 * cos( delta_lon ) ;
double bearing_rad = atan2( y, x ) ;
// Degrees
return fmod(bearing_rad * 180.0f / M_PI + 360.0f, 360.0f ) ;
}
The use of floating point math is computationally and code space heavy on an AVR based Arduino and even on an ARM based Due, with no FPU, floating-point math is generally best avoided, but in this case it is hard to avoid. Moreover whilst using float
would be both memory and computationally more efficient, with only six significant figures of precision, it will not be accurate enough for this application, where the distances are tiny fractions of an earth-circumference. You need 5 decimal places of a degree to resolve to < 2 metres, which would require 8 significant figures. double
is good for 15 significant figures.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论