前言
最近工作上面接触使用GPS的NMEA数据为机器人提供平面坐标定位,根据网上的一些资料对gps原始数据进行了初步的解码,然后简单的转换为xy二维平面坐标
一、GPS数据格式
NMEA数据比较多,选取其中$GNRMC部分来获取当前经纬度信息
$GNRMC数据格式
二、GPS坐标转换二维坐标原理
三、参考代码
1.转换经纬度格式
由于获取的经纬度数据格式为度分格式,所以先把数据转换为度格式
double DM2DDForm(double val)
{
return val = (int)val / 100 + fmod(val , 100) / 60;
}
2.解析通过串口获得的NMEA数据
static uint8_t GNRMCnAlyse(char *buffer)
{
double latitudeTemp, longitudeTemp;
char *pTemp = NULL;
pTemp = strstr(buffer,"$GNRMC");
sscanf(pTemp,"$GNRMC,%f,%c,%lf,%c,%lf,%c,%f, ,%f",
&s_curGpsInfo.utcTime,
&s_curGpsInfo.status,
&latitudeTemp, &s_curGpsInfo.ns,
&longitudeTemp, &s_curGpsInfo.ew,
&s_curGpsInfo.speed, &s_curGpsInfo.azimuthAngle);
s_curGpsInfo.latitude = DM2DDForm(s_curGpsInfo.latitude);
s_curGpsInfo.longitude = DM2DDForm(s_curGpsInfo.longitude);
//校验数据有效性(偷懒没写)
...
return TRUE;
}
3.将经纬度转换为xy平面二维坐标
用了两种不同的转换方式来进行比较,距离实际距离误差都比较大。例如相距10m的A、B两点,使用经纬度转换坐标,误差在±1m左右。仅仅能用于测试,不能进行实际使用。如需实际商业使用,个人感觉使用向量方式作坐标转换比较合理。可参考此文地理坐标(经纬度坐标)和屏幕坐标(xy坐标)间的转换
//使用米勒投影将GPS坐标转换为xy坐标
uint8_t millierConvertion(double lat, double lon, xyPoint *pPos)
{
double L = 6378137 * M_PI * 2;//地球周长
double W = L;// 平面展开后,x轴等于周长
double H = L / 2;// y轴约等于周长一半
double x = lon * M_PI / 180;// 将经度从度数转换为弧度
double y = lat * M_PI / 180;// 将纬度从度数转换为弧度
y = 1.25 * log(tan(0.25 * M_PI + 0.4 * y));// 米勒投影的转换
// 弧度转为实际距离
x = (W / 2) + (W / (2 * M_PI)) * x;
y = (H / 2) - (H / (2 * MILL_CONSTANT)) * y; //MILL_CONSTANT 2.3米勒常数
pPos->x = (int)x;
pPos->y = (int)y;
return TRUE;
}
//简易转换
uint8_t testConvertion(double lat, double lon, xyPoint *pPos)
{
lat = Deg2Rad(lat);
lon = Deg2Rad(lon);
pPos->y = lat * 6378137;
pPos->x = lon * 6378137 * cos(lat);
}
typedef struct
{
float utcTime;
char status;
double latitude; //纬度
double longitude; //经度
char ns;
char ew;
float speed;
float azimuthAngle;
}GpsInfo;
版权声明:本文为weixin_40190472原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。