这段时间因为各种事情耽误了,好久没有进行更新了,惭愧!
前段时间在研究cartographer的定位建图模块,在停更的时间主要再研究如何改善定位建图的效果,也有一定的成效,但是缺乏有效的外部传感器去作为全局范围的评价标准,所以把目光放在了GPS上,利用GPS提供的经纬度信息,将其转为平面投影坐标,然后利用GPS的室外测绘信息,比较同个回环下改进前与改进后移动机器人回到原点的能力差距(通过定位距离偏差大小来进行评价)。
为了更好的了解GPS的数据格式,我们先来了解下GPS数据协议,然后了解下ROS中的gps_common功能包,了解gps常用数据格式,方便后面根据相应数据格式进行开发工作。
GPS数据一般采用NMEA-0183协议,该协议是由美国国家海洋电子协会为海用电子设备指定的标准格式,目前已成为GPS导航设备统一的标准协议。
$GPGGA 全球定位数据
$GPGSA 卫星PRN数据
$GPGSV 卫星状态信息
$GPRMC 运输定位数据
$GPVTG 地面速度信息
$GPGLL 大地坐标信息
$GPZDA UTC时间和日期
因为最近在用司南RTK收集GPS数据,收集到的数据格式为GPGGA格式和GPRMC格式。因为接下来我需要在ubuntu系统上写串口驱动解析GPGGA数据格式,所以简单介绍下GPGGA的数据格式。
以实际格式为例进行说明:
$GPGGA,041126.00,3010.9782040,N,12009.2327844,E,2,10,0.5,14.7799,M,0.000,M,1.0,2573*76
看到这么一串数据时,我当时是处于一个头两个大的状态,因为不懂,所以感到心烦。但是当了解GPGGA的数据格式后,看起来就没这么麻烦。
首先是GPGGA代表类型,紧接着:
<1>041126.00表示UTC时间,格式为hhmmss.ss;
<2>3010.9782040表示维度30.109782040度;
<3>N表示纬度半球,N表示北纬,S表示南纬;
<4>12009.2327844表示经度120.092327844度;
<5>E表示经度半球,E表示东经,W表示西经;
<6>2表示GPS状态,0表示未定位,1表示非差分定位,2表示差分定位,3表示无效PPS,4表示固定解,5表示浮点解,6表示正在估算,7表示人工输入固定值,8表示模拟模式,9表示WAAS差分;
<7>10表示正在使用的卫星数量,从00到12;
<8>0.5表示水平精确度,从0.5到99.9;
<9>14.7799表示天线离海平面的高度,范围为-9999.9到9999.9;
<10>M表示高度单位米;
<11>0.000表示大地椭球面相对海平面的高度,范围从-999.9到9999.9;
<12>M表示高度单位米;
<13>1.0表示差分时间,所谓差分时间是指从最近一次接收到差分信号开始的秒数,如果不是差分定位将为空;
<14>2573表示差分参考基站标号;
<15>*76表示校验和,用来判断数据是否正常;
gps_common里面主要有两类数据格式:(1)gps_common::GPSFix;(2)gps_common::GPSStatus。
uint8 COVARIANCE_TYPE_UNKNOWN=0
uint8 COVARIANCE_TYPE_APPROXIMATED=1
uint8 COVARIANCE_TYPE_DIAGONAL_KNOWN=2
uint8 COVARIANCE_TYPE_KNOWN=3
std_msgs/Header header
gps_common/GPSStatus status
float64 latitude
float64 longitude
float64 altitude
float64 track
float64 speed
float64 climb
float64 pitch
float64 roll
float64 dip
float64 time
float64 gdop
float64 pdop
float64 hdop
float64 vdop
float64 tdop
float64 err
float64 err_horz
float64 err_vert
float64 err_track
float64 err_speed
float64 err_climb
float64 err_time
float64 err_pitch
float64 err_roll
float64 err_dip
float64[9] position_covariance
uint8 position_covariance_type
想要具体了解每个参数的意思可以参考ROS Wiki上的说明(链接),这里我是关注float64 latitude、float64 longitude和float64 altitude,分别代表纬度、经度和距离海平面的高度,也是后面需要转换成平面投影坐标的主要数据。
int16 STATUS_NO_FIX=-1
int16 STATUS_FIX=0
int16 STATUS_SBAS_FIX=1
int16 STATUS_GBAS_FIX=2
int16 STATUS_DGPS_FIX=18
int16 STATUS_WAAS_FIX=33
uint16 SOURCE_NONE=0
uint16 SOURCE_GPS=1
uint16 SOURCE_POINTS=2
uint16 SOURCE_DOPPLER=4
uint16 SOURCE_ALTIMETER=8
uint16 SOURCE_MAGNETIC=16
uint16 SOURCE_GYRO=32
uint16 SOURCE_ACCEL=64
std_msgs/Header header
uint16 satellites_used
int32[] satellite_used_prn
uint16 satellites_visible
int32[] satellite_visible_prn
int32[] satellite_visible_z
int32[] satellite_visible_azimuth
int32[] satellite_visible_snr
int16 status
uint16 motion_source
uint16 orientation_source
uint16 position_source
ROS Wiki链接地址(链接),GPSStatus包含在GPSFix数据里面。
安装说明:
gps_common包我上传了资源,属于免费状态,有需要可以自行下载。(链接,审核可能需要点时间)
cd gps_comon
mkdir build
cd build
cmake ..
make
sudo make install
完成安装后只需要在代码中包含头文件:#include
示例:
#include
int main(){
gps_common::GPSFix fix;
// 以经纬度为例
fix.latitude = 30.1483;
fix.longitude = 121.4563;
//...
}