GPS 定位信息分析:航向角分析及经纬度坐标转局部XY坐标

GPS 定位信息分析(1)

从下面的数据可知,raw data 的提取和经纬度的计算应该是没问题的

在相同的经纬度下, x 和 y 还会发生变化,显然是不正确的

raw data:3150.93331124	11717.59467080	5.3
latitude: 31.8489	longitude: 117.293	heading_angle: 5.3
raw data:3150.93332581	11717.59468186	59.4
latitude: 31.8489	longitude: 117.293	heading_angle: 59.4
x: 0.0270035	y: 0.017412
---------
raw data:3150.93333013	11717.59468264	81.7
latitude: 31.8489	longitude: 117.293	heading_angle: 81.7
x: 0.03501	y: 0.01864
---------
raw data:3150.93333688	11717.59468779	77.2
latitude: 31.8489	longitude: 117.293	heading_angle: 77.2
x: 0.0475202	y: 0.0267478
---------
raw data:3150.93333483	11717.59468236	89.2
latitude: 31.8489	longitude: 117.293	heading_angle: 89.2
x: 0.0437208	y: 0.0181992
---------
raw data:3150.93334090	11717.59465670	337.7
latitude: 31.8489	longitude: 117.293	heading_angle: 337.7
x: 0.0549707	y: 0.022198
---------

调整输出后在 MATLAB 中处理显示

  • clockwise_pro.txt
  • anticlockwise_pro.txt
  • path_pro.txt

clockwise_pro 和 anticlockwise_pro 有助于分析航向角信息,path 参考意义不大

航向角信息分析

clockwise_pro 航向角信息

在这里插入图片描述

anticlockwise_pro 航向角信息

在这里插入图片描述

GPS 获取的是真北航迹方向,deg

Heading定向是指双天线接收机的主天线(ANT1)与从天线(ANT2)之间构成一个基线向量,确定此基线向量逆时针方向与真北的夹角

首先要明确基线向量与正北方向夹角的大小以及正负关系,分析如下,红色表示正北方向,蓝色表示基线向量,绿色表示航向角(真北航迹方向)

在这里插入图片描述
在这里插入图片描述

正北方向表示 0 度或 360 度位置,非负值,沿正北方向顺时针旋转是角度增加的方向

此时分析 clockwise_pro 和 anticlockwise_pro 的航向角变化结果就比较容易,示意图如下

在这里插入图片描述

以顺时针为例,起始位姿航向角 50 度,顺时针旋转至于正北方向重合,角度一直增大至 360 度

重合后继续顺时针旋转,此时会先从 360 度突变至 0 度,再继续增加

问题分析

1、由于手动安装主从天线,基线向量本身存在夹角,导致航向角始终存在偏差

下图能够说明该问题

在这里插入图片描述

2、GPS 获得的航向角信息是在大地或者正北天坐标系下的,该信息并不可以使用,需要转换到局部坐标系下,涉及到坐标转换的问题

3、基线向量和主从天线有关,接收机 com1 口对应主天线,但仅靠线缆无法区分,本次也没有贴标签注明哪一根接前天线,哪一根接后天线,下次接线若与本次不同可能会有影响

轨迹信息分析

clockwise_pro 轨迹信息

在这里插入图片描述

anticlockwise_pro 轨迹信息

在这里插入图片描述

对于原地旋转而言经纬度信息保持不变,此时在 X 方向和 Y 方向还有如此大的位移,是有问题的


GPS 定位信息分析(2)

对于局部 XY 坐标信息的异常,从公式和编程两方面考虑

XY 坐标计算

公式部分应该没什么问题,主要由“根据经纬度计算两地之间的距离”推得

在这里插入图片描述

查找资料的过程中还发现“大地坐标系与空间直角坐标系的转换”,可以作为储备知识

在这里插入图片描述
在这里插入图片描述

以起始的 GPS 坐标为全局坐标系原点(init_pose),以当前纬度为 X轴,当前经度为 Y 轴

计算目标点 X 坐标时,假设纬度相同,根据经度差计算 X 坐标值

计算目标点 Y 坐标时,假设经度相同,根据纬度差计算 Y 坐标值

在这里插入图片描述

陆师兄 gps_path.cpp 中的代码如下,感觉存在一些问题

//初始化if(!init){init_pose.latitude = gps_msg_ptr->latitude;init_pose.longitude = gps_msg_ptr->longitude;init_pose.altitude = gps_msg_ptr->altitude;init = true;}else{//计算相对位置double radLat1 ,radLat2, radLong1,radLong2,delta_lat,delta_long;radLat1 = rad(init_pose.latitude);radLong1 = rad(init_pose.longitude);radLat2 = rad(gps_msg_ptr->latitude);radLong2 = rad(gps_msg_ptr->longitude);//计算xdelta_lat = radLat2 - radLat1;delta_long = 0;double x = 2*asin( sqrt( pow( sin( delta_lat/2 ),2) + cos( radLat1 )*cos( radLat2)*pow( sin( delta_long/2 ),2 ) ));x = x*EARTH_RADIUS*1000;//计算ydelta_lat = 0;delta_long = radLong1  - radLong2;double y = 2*asin( sqrt( pow( sin( delta_lat/2 ),2) + cos( radLat2 )*cos( radLat2)*pow( sin( delta_long/2 ),2 ) ) );y = y*EARTH_RADIUS*1000;//计算zdouble z = gps_msg_ptr->altitude - init_pose.altitude;//发布轨迹ros_path_.header.frame_id = "path";ros_path_.header.stamp = ros::Time::now();  geometry_msgs::PoseStamped pose;pose.header = ros_path_.header;pose.pose.position.x = x;pose.pose.position.y = y;pose.pose.position.z = z;ros_path_.poses.push_back(pose);//ROS_INFO("( x:%0.6f ,y:%0.6f ,z:%0.6f)",x ,y ,z );cout<<x<<","<<y<<","<<z<<endl;state_pub_.publish(ros_path_);}
}

简单调整如下,只是将 X 变为 Y,Y 变为 X,影响不大

        		// 计算xdelta_lat = 0;delta_long = radLong1 - radLong2;           double x = 2 * asin(sqrt(pow(sin(delta_lat / 2), 2) + cos(radLat1) * cos(radLat2) * pow(sin(delta_long / 2), 2)));x = x * EARTH_RADIUS * 1000;cout << "delta_lat: " << delta_lat << "\tdelta_long: " << delta_long << "\tx: " << x << endl;// 计算ydelta_lat = radLat2 - radLat1;delta_long = 0;double y = 2 * asin(sqrt(pow(sin(delta_lat / 2), 2) + cos(radLat2) * cos(radLat2) * pow(sin(delta_long / 2), 2)));y = y * EARTH_RADIUS * 1000;cout << "delta_lat: " << delta_lat << "\tdelta_long: " << delta_long << "\ty: " << y << endl;

XY 坐标误差

另外对于原地旋转经纬度不变情况下存在较大 XY 方向位移的问题,打印过程中各变量分析

      			// 计算相对位置double radLat1, radLat2, radLong1, radLong2, delta_lat, delta_long;radLat1 = rad(init_pose.latitude);radLong1 = rad(init_pose.longitude);radLat2 = rad(latitude);radLong2 = rad(longitude);cout << "radLat1: " << radLat1 << "\tradLong1: " << radLong1 << "\tradLat2: " << radLat2 << "\tradLong2: " << radLong2 << endl;// 计算xdelta_lat = radLat2 - radLat1;delta_long = 0;double x = 2 * asin(sqrt(pow(sin(delta_lat / 2), 2) + cos(radLat1) * cos(radLat2) * pow(sin(delta_long / 2), 2)));x = x * EARTH_RADIUS * 1000;cout << "delta_lat: " << delta_lat << "\tdelta_long: " << delta_long << "\tx: " << x << endl;// 计算ydelta_lat = 0;delta_long = radLong1 - radLong2;double y = 2 * asin(sqrt(pow(sin(delta_lat / 2), 2) + cos(radLat2) * cos(radLat2) * pow(sin(delta_long / 2), 2)));y = y * EARTH_RADIUS * 1000;cout << "delta_lat: " << delta_lat << "\tdelta_long: " << delta_long << "\tx: " << y << endl;cout << "---------" << endl;
latitude: 31.8489	longitude: 117.293	heading_angle: 5.3
latitude: 31.8489	longitude: 117.293	heading_angle: 59.4
radLat1: 0.555868	radLong1: 2.04715	radLat2: 0.555868	radLong2: 2.04715
delta_lat: 4.23824e-09	delta_long: 0	x: 0.0270035
delta_lat: 0	delta_long: -3.21722e-09	x: 0.017412
---------
latitude: 31.8489	longitude: 117.293	heading_angle: 81.7
radLat1: 0.555868	radLong1: 2.04715	radLat2: 0.555868	radLong2: 2.04715
delta_lat: 5.49488e-09	delta_long: 0	x: 0.03501
delta_lat: 0	delta_long: -3.44412e-09	x: 0.01864
---------
latitude: 31.8489	longitude: 117.293	heading_angle: 77.2
radLat1: 0.555868	radLong1: 2.04715	radLat2: 0.555868	radLong2: 2.04715
delta_lat: 7.45837e-09	delta_long: 0	x: 0.0475202
delta_lat: 0	delta_long: -4.94219e-09	x: 0.0267478
---------
latitude: 31.8489	longitude: 117.293	heading_angle: 89.2
radLat1: 0.555868	radLong1: 2.04715	radLat2: 0.555868	radLong2: 2.04715
delta_lat: 6.86205e-09	delta_long: 0	x: 0.0437208
delta_lat: 0	delta_long: -3.36267e-09	x: 0.0181992
---------
latitude: 31.8489	longitude: 117.293	heading_angle: 337.7
radLat1: 0.555868	radLong1: 2.04715	radLat2: 0.555868	radLong2: 2.04715
delta_lat: 8.62774e-09	delta_long: 0	x: 0.0549707
delta_lat: 0	delta_long: 4.10152e-09	x: 0.022198
---------

发现 radLat1 和 radLat2 相等,但是 delta_lat 却一直在变化,经度同理,这是 XY 坐标变化的主因

这里涉及到计算机中小数的表示,浮点数无法被精确表示,虽然 radLat1 和 radLat2 前几位都是 0.555868,但最后的尾部无法始终相同,因此相减后始终存在极小的误差,e-09 级别

round() 函数可以用于保留小数,详见 2022-07-30 C++:round函数用法

在进行角度和弧度转换时限定浮点数精度,调整 cout 输出精度后输出如下

// 角度制转弧度制
double deg2rad(double deg)
{double rad = deg * M_PI / 180.0;// 保留有限小数rad = round(rad * 1000000000) / 1000000000;return rad;
}cout.setf(ios::fixed);cout.precision(9);
/home/redwall/catkin_ws/src/gps_sensor/log/2023-11-10/clockwise.txt
latitude: 31.848888521	longitude: 117.293244513	heading_angle: 5.300000000
latitude: 31.848888763	longitude: 117.293244698	heading_angle: 59.400000000
delta_lat: 0.000000000	delta_long: -0.000000003	x: 0.016236402
delta_lat: 0.000000004	delta_long: 0.000000000	y: 0.025485572
---------
latitude: 31.848888835	longitude: 117.293244711	heading_angle: 81.700000000
delta_lat: 0.000000000	delta_long: -0.000000004	x: 0.021648536
delta_lat: 0.000000005	delta_long: 0.000000000	y: 0.031856965
---------
latitude: 31.848888948	longitude: 117.293244797	heading_angle: 77.200000000
delta_lat: 0.000000000	delta_long: -0.000000005	x: 0.027060668
delta_lat: 0.000000007	delta_long: 0.000000000	y: 0.044599750
---------
latitude: 31.848888914	longitude: 117.293244706	heading_angle: 89.200000000
delta_lat: 0.000000000	delta_long: -0.000000003	x: 0.016236402
delta_lat: 0.000000007	delta_long: 0.000000000	y: 0.044599750
---------
latitude: 31.848889015	longitude: 117.293244278	heading_angle: 337.700000000
delta_lat: 0.000000000	delta_long: 0.000000004	x: 0.021648534
delta_lat: 0.000000008	delta_long: 0.000000000	y: 0.050971144
---------
latitude: 31.848888630	longitude: 117.293243995	heading_angle: 331.400000000
delta_lat: 0.000000000	delta_long: 0.000000009	x: 0.048709202
delta_lat: 0.000000002	delta_long: 0.000000000	y: 0.012742786
---------
latitude: 31.848888411	longitude: 117.293243583	heading_angle: 238.000000000
delta_lat: 0.000000000	delta_long: 0.000000016	x: 0.086594137
delta_lat: -0.000000002	delta_long: 0.000000000	y: 0.012742786
---------
latitude: 31.848888926	longitude: 117.293243262	heading_angle: 269.000000000
delta_lat: 0.000000000	delta_long: 0.000000022	x: 0.119066939
delta_lat: 0.000000007	delta_long: 0.000000000	y: 0.044599750
---------
latitude: 31.848889280	longitude: 117.293242747	heading_angle: 265.900000000
delta_lat: 0.000000000	delta_long: 0.000000031	x: 0.167776140
delta_lat: 0.000000013	delta_long: 0.000000000	y: 0.082828109
---------

观察确实主要在 latitude 和 longtitude 的 6 ~ 9 位小数会发生变化,导致 XY 坐标的变化

保留有限的小数可以一定程度上限制数据的抖动,但也会使得 path.txt 无法输出轨迹,比较矛盾

/home/redwall/catkin_ws/src/gps_sensor/log/2023-11-10/path.txt
latitude: 31.848883337	longitude: 117.293247277	heading_angle: 35.900000000
latitude: 31.848883241	longitude: 117.293247357	heading_angle: 49.400000000
delta_lat: 0.000000000	delta_long: 0.000000000	x: 0.000000000
delta_lat: 0.000000000	delta_long: 0.000000000	y: 0.000000000
---------
latitude: 31.848883139	longitude: 117.293247392	heading_angle: 198.800000000
delta_lat: 0.000000000	delta_long: 0.000000000	x: 0.000000000
delta_lat: 0.000000000	delta_long: 0.000000000	y: 0.000000000
---------
latitude: 31.848883027	longitude: 117.293247506	heading_angle: 37.300000000
delta_lat: 0.000000000	delta_long: 0.000000000	x: 0.000000000
delta_lat: 0.000000000	delta_long: 0.000000000	y: 0.000000000
---------
latitude: 31.848883101	longitude: 117.293247264	heading_angle: 359.300000000
delta_lat: 0.000000000	delta_long: 0.000000000	x: 0.000000000
delta_lat: 0.000000000	delta_long: 0.000000000	y: 0.000000000
---------
latitude: 31.848882789	longitude: 117.293247238	heading_angle: 175.200000000
delta_lat: 0.000000000	delta_long: 0.000000000	x: 0.000000000
delta_lat: 0.000000000	delta_long: 0.000000000	y: 0.000000000

问题分析

考虑 GPS 本身的定位精度,以及移动距离过短两方面引起误差的产生

差分定位(Differential GPS,DGPS)是一种通过引入参考站观测数据来提高全球定位系统(GPS)接收机测量精度的技术。通常,差分GPS可以提供亚米级的位置精度,甚至更高,相比于普通的独立GPS。

差分GPS系统的基本原理是,参考站与GPS接收机接收相同的卫星信号,然后比较它们的观测值与已知的准确位置。由于参考站的位置已知,它可以检测到GPS信号由于大气层、电离层等环境因素引起的误差,并将这些误差信息传输给用户设备,从而实现位置精度的提高。

DGPS的精度取决于多个因素,包括:

  1. 基站位置的准确性: 基站的准确位置对差分定位的精度至关重要。
  2. 基站到用户接收机的距离: 基站越接近用户设备,传输的差分校正信息的精度就越高。
  3. 使用的卫星数量和分布: 使用更多的卫星可以提高定位的准确性。
  4. 大气层和电离层的变化: 大气层和电离层的变化会引起GPS信号的传播延迟,这可能影响定位的精度。

总体而言,在适当的条件下,差分GPS可以提供比普通独立GPS更高的位置精度,通常在亚米级别。然而,实际精度可能会受到环境、设备和使用条件的影响。

其实关于 GPS 数据在 Rviz 中显示,2020 年已经有相关技术博客

ROS:GPS坐标序列可视化(在Rviz中显示轨迹)

GPS坐标转换并实时显示轨迹

ROS入门:GPS坐标转换&Rviz显示轨迹

将GPS轨迹,从经纬度WGS-84坐标转换到真实世界xyz坐标系(东北天ENU)下(思路:计算出每个gps坐标相对与第一个坐标的距离(m为单位),比较相邻两点的经纬度变化,赋予位移的方向,然后累加得到轨迹)

陆辉东的代码和博客中几乎一样,应该也是学习借鉴了

对于精度的问题可以参考下面的博客解决

小场景下基于ROS的GPS经纬高度值转换为平面XYZ坐标值,并用RVIZ显示轨迹

在这里插入图片描述
在这里插入图片描述

另外还可以将 GPS 数据在卫星地图中显示,获得比较酷炫的效果

在这里插入图片描述
在这里插入图片描述

ROS下如何将GPS数据在卫星地图显示(两种开源方法)

ROS采集GPS/北斗数据在百度地图中可视化位置

SLAM中将地图映射到谷歌地图上的方法——完美运行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/216662.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【云原生 Prometheus篇】Prometheus的动态服务发现机制

自动发现 一、Prometheus服务发现 理论部分1.1 Prometheus数据采集配置1.2 基于文件的服务发现1.3 基于consul的服务发现1.4 基于 Kubernetes API 的服务发现1.4.1 概念1.4.2 部分配置参数1.4.3 配置模板 二、实例一&#xff1a;部署基于文件的服务发现2.1 创建用于服务发现的文…

给虚拟机配置静态id地址

1.令人头大的原因 当连接虚拟机的时候 地址不一会就改变&#xff0c;每次都要重新输入 2.配置虚拟机静态id地址 打开命令窗口执行 : vim /etc/sysconfig/network-scripts/ifcfg-ens33 按下面操作修改 查看自己子网掩码 3.重启网络 命令行输入 systemctl restart netwo…

基于光纤环形激光器的optisystem仿真及其传感应用

近年来&#xff0c;光纤传感器在航空航天领域&#xff0c;工业制造&#xff0c;医疗等领域引起了越来越多的关注&#xff0c;因为他们体积小&#xff0c;结构简单&#xff0c;灵敏度高&#xff0c;抗电磁干扰强&#xff0c;防腐性能好的特点。各种各样的传感器结构被设计出来&a…

[SWPUCTF 2021 新生赛]no_wakeup

直接赋值即可 $a ->admin admin; $a ->passwd wllm; 发现没有绕过&#xff0c;改成大于2的绕过__wakeup 这是因为PHP在反序列化时会检查序列化字符串的长度&#xff0c;如果长度小于等于2&#xff0c;则不会调用__wakeup()方法。

flutter之graphic图表自定义tooltip

renderer graphic中tooltip的TooltipGuide类提供了renderer方法&#xff0c;接收三个参数Size类型&#xff0c;Offset类型&#xff0c;Map<int, Tuple>类型。可查到的文档是真的少&#xff0c;所以只能在源码中扒拉例子&#xff0c;做符合需求的修改。 官方github示例 …

【华为OD题库-038】支持优先级的对列-java

题目 实现一个支持优先级的队列&#xff0c;高优先级先出队列&#xff0c;同优先级时先进先出。 如果两个输入数据和优先级都相同&#xff0c;则后一个数据不入队列被丢弃。 队列存储的数据内容是一个 整数。 输入描述 一组待存入队列的数据(包含内容和优先级)。 输出描述 队列…

【Linux】EVIOCGBIT

EVIOCGBIT(ev, len) 该怎么理解&#xff1f; 我们可以推断出&#xff0c;它是一个宏&#xff0c;它的前两个参数已经确定了&#xff0c;具体的功能由后两个参数(ev,len)来决定。Linux-4.9.88\include\uapi\linux\input.h #define EVIOCGBIT(ev,len) _IOC(_IOC_READ, E, 0x20 …

安卓 Android Studio更换app的图标

大概完成了一个app&#xff0c;在测试机的界面app的icon显示的是默认安卓图标&#xff0c;找了一个简单的更换方法 打开 Androidmanifest.xml 文件&#xff0c;在 application 找到代码 android:icon"mipmap/ic_launcher" 按下Ctrl鼠标左键转到相应位置 如图在背景…

计算机网络四大地址转换(IP,MAC、端口、域名)

计算机网络有四大地址&#xff0c;分别是 ip地址、 MAC地址、域名、端口 计算机网络地址 他们之间是如何转换&#xff0c;通过什么协议转换的 IP地址到MAC地址&#xff0c;通过ARP协议 MAC地址得到IP地址&#xff0c;通过RARP协议 通过域名的到IP地址 是通过DNS查询 端口是…

[ZJCTF 2019]NiZhuanSiWei

虽然有include函数但我们无法直接包含flag因为对file进行了过滤&#xff0c;又看见有反序列化的入口&#xff0c;只是并没有发现可利用的方法&#xff0c;但题目有提示所以尝试将其调出来 php伪协议写入内容 看到file_get_contents函数想到使用data协议&#xff0c;去封装一个…

CANdelaStudio 使用教程2 新建 Interface

文章目录 简述ECU Information1、Supported Interfaces2、Services supported for interfaces 简述 新增 Interface 的话&#xff0c;只能在 CDDT 文件中新增&#xff0c;CDD 文件中只能选择接口 ECU Information 1、Supported Interfaces 创建和编辑ECU应支持的接口 1、…

单片非晶磁性测量系统非晶测量方法

非晶测量方法 单片法是国际主流的非晶测量方法之一&#xff0c;如美标 A932 和日标 H7152 均早已提出了该方法&#xff1b;2014 年 IEC 起草的标准&#xff0c;和我国 2015 年重新修订的 GB/T 19345.1 标准中均明确提出了单片法测量非晶磁性能。单片法与环样法相比&#xff0c…