当前位置: 首页 > news >正文

mavros和PX4中的海拔高与椭球高转换

飞控高度传感器中一般有两种高度:

  • 海拔高。也称AMSL(Above Mean Sea Level)height或者geoid height或者正高,顾名思义就是指高于当地平均海平面的高度。我猜气压计测得的高度应当就是与海平面相关的。
  • 椭球高。也称ellipsoid height或者大地高。顾名思义就是指相对于WGS84地球标准椭球模型的高度。GPS定位系统普遍采用的WGS84坐标系,给出的高度就是ellipsoid高度。

同一个位置的两种高度值一般可以相差几十米,这是因为当地平均海平面是和地形有关的,凹凸不平没有规律。而ellipsoid height采用的基准是地球标准椭球模型,它的高度值和地形没有关系,只和到地心的距离有关。

下文的mavros指ros1 noetic版本的,ros2版本的我还没研究。

Mavros

mavros/global_position/global话题

此话题发布经纬高,其中高度是ellipsoid height椭球高。其实px4的GLOBAL_POSITION_INT mavlink消息发布的高度是geoid height海拔高度,但是mavros做了转换后再发布到global话题,具体这个转换在:

https://github.com/mavlink/mavros/blob/master/mavros/src/plugins/global_position.cpp#L144-L150

	template<typename MsgT>inline void fill_lla(MsgT &msg, sensor_msgs::NavSatFix::Ptr fix){fix->latitude = msg.lat / 1E7;		// degfix->longitude = msg.lon / 1E7;		// degfix->altitude = msg.alt / 1E3 + m_uas->geoid_to_ellipsoid_height(fix);	// in meters}

geoid_to_ellipsoid_height()就是海拔高转换为椭球高的函数。要进行这个转换,需要知道地球所有地点的平均海拔高,这是一个相当大的数据集。还记得安装mavros的时候需要执行一个install_geographiclib_datasets.sh脚本吗,其实这就是在安装egm96_5库,这个库存放了地球所有地点的平均海拔高模型,并提供每个经纬度点的海拔高和椭球高的差值。实测导入egm96_5库需要额外的18MB内存。

顺便一提,这个话题发布的经纬度只有七位小数精度,因为PX4的GLOBAL_POSITION_INT mavlink消息stream的时候,将经纬度乘了1e7变成了整型,mavros接收mavlink消息后再除了1e7,因此损失了经纬度七位小数之后的精度(大概相当于几厘米)。

下面这段c++代码可以用于海拔高转换为椭球高:

#include <GeographicLib/Geoid.hpp>
#include <memory> // for std::shared_ptr
std::shared_ptr<GeographicLib::Geoid> egm96_5; // This class loads egm96_5 dataset to RAM, it is about 24 MiB.
egm96_5 = std::make_shared<GeographicLib::Geoid>("egm96-5", "", true, true); // Using smallest dataset with 5' grid, // From default location, // Use cubic interpolation, Thread safe
alt_ellipsoid = alt_amsl + GeographicLib::Geoid::GEOIDTOELLIPSOID * (*egm96_5)(lat, lon); // AMSL TO WGS84 altitude

执行代码需要安装egm96,这里借用安装mavros时的脚本:

wget https://gitee.com/shu-peixuan/px4mocap/raw/85b46df9912338f775949903841160c873af4a1d/ROS-install-command/install_geographiclib_datasets.sh
sudo chmod a+x ./install_geographiclib_datasets.sh
sudo ./install_geographiclib_datasets.sh # this step takes some time
rm install_geographiclib_datasets.sh

mavros/global_position/local话题

这个话题发布的是ENU东北天坐标。但它和mavros/local_position/pose还不一定一样。它是由ECEF地球坐标系中的坐标相对于地图原点map origin转换到ENU东北天坐标系。这个地图原点的选取可能是当前点,或者地图点,或者设置的map origin。看看mavros源码吧:

https://github.com/mavlink/mavros/blob/master/mavros/src/plugins/global_position.cpp#L330-L365

/*** @brief Checks if the "map" origin is set.* - If not, and the home position is also not received, it sets the current fix as the origin;* - If the home position is received, it sets the "map" origin;* - If the "map" origin is set, then it applies the rotations to the offset between the origin* and the current local geocentric coordinates.*/
// Current fix to ECEF
map.Forward(fix->latitude, fix->longitude, fix->altitude,map_point.x(), map_point.y(), map_point.z());// Set the current fix as the "map" origin if it's not set
if (!is_map_init && fix->status.status >= sensor_msgs::NavSatStatus::STATUS_FIX) {map_origin.x() = fix->latitude;map_origin.y() = fix->longitude;map_origin.z() = fix->altitude;ecef_origin = map_point; // Local position is zerois_map_init = true;
}
}
catch (const std::exception& e) {
ROS_INFO_STREAM("GP: Caught exception: " << e.what() << std::endl);
}// Compute the local coordinates in ECEF
local_ecef = map_point - ecef_origin;
// Compute the local coordinates in ENU
tf::pointEigenToMsg(ftf::transform_frame_ecef_enu(local_ecef, map_origin), odom->pose.pose.position);/*** @brief By default, we are using the relative altitude instead of the geocentric* altitude, which is relative to the WGS-84 ellipsoid*/
if (use_relative_alt)
odom->pose.pose.position.z = relative_alt->data;odom->pose.pose.orientation = m_uas->get_attitude_orientation_enu();

这里面的odom就是发布到mavros/global_position/local话题的消息。可以看到它的高度默认是相对高度relative_alt。这个相对高度是由px4的GLOBAL_POSITION_INT mavlink消息发布的,是px4飞控内部对于相对地面/起飞点高度的一个估计。

可以看出,mavros/global_position/local话题没什么用,还不如用mavros/local_position/pose。

mavros/setpoint_raw/global话题

这个话题用于向飞控发布期望的经纬高setpoint,我在四旋翼利用mavros进行GPS坐标指点飞行_/mavros/setpoint_raw/local-CSDN博客一文中已经指出,尽量不要直接用这个话题发送GPS目标位置点,可以用mavros/setpoint_raw/local代替。

如果你非要用这个话题,那么我们看看发送的经纬高setpoint中的高度是什么:

https://github.com/mavlink/mavros/blob/master/mavros/src/plugins/setpoint_raw.cpp#L205-L234

void global_cb(const mavros_msgs::GlobalPositionTarget::ConstPtr &req)
{Eigen::Vector3d velocity, af;float yaw, yaw_rate;tf::vectorMsgToEigen(req->velocity, velocity);tf::vectorMsgToEigen(req->acceleration_or_force, af);// Transform frame ENU->NEDvelocity = ftf::transform_frame_enu_ned(velocity);af = ftf::transform_frame_enu_ned(af);yaw = ftf::quaternion_get_yaw(ftf::transform_orientation_aircraft_baselink(ftf::transform_orientation_ned_enu(ftf::quaternion_from_rpy(0.0, 0.0, req->yaw))));Eigen::Vector3d ang_vel_enu(0.0, 0.0, req->yaw_rate);auto ang_vel_ned = ftf::transform_frame_ned_enu(ang_vel_enu);yaw_rate = ang_vel_ned.z();set_position_target_global_int(req->header.stamp.toNSec() / 1000000,req->coordinate_frame, //代表经纬高采用的坐标系(主要针对高度)req->type_mask,req->latitude * 1e7,req->longitude * 1e7,req->altitude, //直接通过SET_POSITION_TARGET_GLOBAL_INT mavlink消息发给px4了velocity,af,yaw, yaw_rate);
}

这里的经纬高是直接通过SET_POSITION_TARGET_GLOBAL_INT mavlink消息发给px4了,经纬度还乘了1e7变成整型,所以损失了第七位小数之后的经纬值(大概相当于几厘米)。

PX4中是怎么处理SET_POSITION_TARGET_GLOBAL_INT mavlink消息的呢,让我们看看px4 v1.13.3(2023年底)中mavlink_receiver.cpp的代码:

https://github.com/PX4/PX4-Autopilot/blob/v1.13.3/src/modules/mavlink/mavlink_receiver.cpp#L1135-L1256

if (target_global_int.coordinate_frame == MAV_FRAME_GLOBAL_INT) {setpoint.z = local_pos.ref_alt - target_global_int.alt; // setpoint.z就是px4具体track的local高度} else if (target_global_int.coordinate_frame == MAV_FRAME_GLOBAL_RELATIVE_ALT_INT) {home_position_s home_position{};_home_position_sub.copy(&home_position);if (home_position.valid_alt) {const float alt = home_position.alt - target_global_int.alt;setpoint.z = alt - local_pos.ref_alt; // setpoint.z就是px4具体track的local高度} else {// home altitude requiredreturn;}} else if (target_global_int.coordinate_frame == MAV_FRAME_GLOBAL_TERRAIN_ALT_INT) {vehicle_global_position_s vehicle_global_position{};_vehicle_global_position_sub.copy(&vehicle_global_position);if (vehicle_global_position.terrain_alt_valid) {const float alt = target_global_int.alt + vehicle_global_position.terrain_alt;setpoint.z = local_pos.ref_alt - alt; // setpoint.z就是px4具体track的local高度} else {// valid terrain alt requiredreturn;}}

原来是和mavlink消息中的coordinate_frame有关,可能是global高度、相对高度或者对地高度。不过这些高度含义其实不那么清晰,具体代表什么还得深挖px4源码。所以再次强调,尽量不要直接用这个话题发送GPS目标位置点。

参考:geoid 理解_egm2008大地水准面模型-CSDN博客

相关文章:

mavros和PX4中的海拔高与椭球高转换

飞控高度传感器中一般有两种高度&#xff1a; 海拔高。也称AMSL&#xff08;Above Mean Sea Level&#xff09;height或者geoid height或者正高&#xff0c;顾名思义就是指高于当地平均海平面的高度。我猜气压计测得的高度应当就是与海平面相关的。椭球高。也称ellipsoid heig…...

洛谷刷题-【入门2】分支结构

目录 1.苹果和虫子 题目描述 输入格式 输出格式 输入输出样例 2.数的性质 题目描述 输入格式 输出格式 输入输出样例 3.闰年判断 题目描述 输入格式 输出格式 输入输出样例 4.apples 题目描述 输入格式 输出格式 输入输出样例 5.洛谷团队系统 题目描述 …...

文件包含技术总结

开发人员一般会把重复使用的函数写到单个文件中&#xff0c;需要使用某个函数时直接调用此文件&#xff0c;而无需再次编写&#xff0c;这中文件调用的过程一般被称为文件包含。 allow_url_fopen On&#xff08;是否允许打开远程文件&#xff09; allow_url_include On&…...

Docker搭建私有仓库

Docker搭建私有仓库 下载docker registry镜像 docker pull docker.io/registry2.registry镜像下载完成后&#xff0c;先创建一个存放镜像的目录。 mkdir -p /data/registry3.启动registry容器 docker run -itd -p 5000:5000 -v /data/registry:/var/lib/registry docker.io…...

【计算机网络】【练习题】【新加坡南洋理工大学】【Computer Control Network】

说明&#xff1a; 仅供学习使用。 一、题目描述 该题目描述一个网络中传播时延&#xff08;Transmission Delay&#xff09;的例子。题目如下&#xff1a; 二、问题解答&#xff08;个人&#xff09; 笔者第3问采用均值不等式求解。标答中采用求导数的方法求极值。似乎均值…...

【学习笔记】CF1349F2 Slime and Sequences (Hard Version)

多项式工业警告&#xff01;&#xff01;&#xff01; 点击看题意 思路来自 这位大佬 。 为什么这么好的题解没人评论。 Part 1 前置知识&#xff1a;拉格朗日反演&#xff08;多项式复合&#xff09;&#xff0c;分式域&#xff08;引入负整数次项&#xff09;。 条件&a…...

HarmonyOS 鸿蒙应用开发( 六、实现自定义弹窗CustomDialog)

自定义弹窗&#xff08;CustomDialog&#xff09;可用于广告、中奖、警告、软件更新等与用户交互响应操作。开发者可以通过CustomDialogController类显示自定义弹窗。具体用法请参考自定义弹窗。 在应用的使用和开发中&#xff0c;弹窗是一个很常见的场景&#xff0c;自定义弹窗…...

# Java NIO(一)FileChannel

Java NIO 1.BIO与NIO的区别 BIO为阻塞IO&#xff0c;NIO为非阻塞IO。 BIONIOJAVA1.4之前Java 1.4之后面向流&#xff1a;以byte为单位处理数据面向块&#xff1a;以块为单位处理数据同步阻塞同步非阻塞无选择器&#xff08;Selector&#xff09; 1.1NIO的核心组成部分 Cha…...

[嵌入式软件][启蒙篇][仿真平台] STM32F103实现串口输出输入、ADC采集

上一篇&#xff1a;[嵌入式软件][启蒙篇][仿真平台] STM32F103实现LED、按键 文章目录 一、串口输出(1) 简介(2) 示例代码(3) 仿真效果 二、串口输入(1) 简介(2) 示例代码(3) 仿真效果 三、ADC采集(1) 简介(2) 采集电压(3) 示例代码&#xff08;电压&#xff09;(4) 仿真效果 …...

Deepin基本环境查看(四)【硬盘/分区、文件系统、硬连接/软连接】

Linux操作系统(Deepin、Ubuntu&#xff09;操作系统中&#xff0c;硬盘分区的管理与Windows操作系统不同&#xff1b; 在Linux系统中维护着一个统一的文件目录体系&#xff0c;而硬盘和分区是以资源的形式由操作系统挂接和调度&#xff1b;此外Linux系统中连接&#xff08;硬连…...

JS之打地鼠案例

需要素材的同学可以私信我 效果图&#xff1a; 上代码&#xff1a; <!DOCTYPE html> <html> <head><meta charset"utf-8"><title></title><style>* {margin: 0;padding: 0;}.box {position: relative;width: 320px;heigh…...

Kubernetes入门

k8s相关基础知识 文章目录 k8s相关基础知识1、Container2、PodPod 与 Container 的不同Pod 其它命令 3、Deployment扩容升级版本Rolling update(滚动更新)存活探针&#xff08;livenessProb&#xff09;就绪探针(readiness) 4、ServiceClusterIPNodePortLoadBalancer 5、Ingres…...

EtherNet/IP开发:C++搭建基础模块,EtherNet/IP源代码

这里是CIP资料的协议层级图&#xff0c;讲解协议构造。 ODVA&#xff08;www.ODVA.org&#xff09;成立于1995年&#xff0c;是一个全球性协会&#xff0c;其成员包括世界领先的自动化公司。结合其成员的支持&#xff0c;ODVA的使命是在工业自动化中推进开放、可互操作的信息和…...

Django(九)

1. 用户登录-Cookie和Session 什么是cookie和session&#xff1f; 发送HTTP请求或者HTTPS请求(无状态&短连接) http://127.0.0.1:8000/admin/list/ https://127.0.0.1:8000/admin/list/http无状态短连接&#xff1a;一次请求响应之后断开连接&#xff0c;再发请求重新连…...

解决Android Studio Unexpected tokens (use ; to separate expressions on the same line)

[TOC](Unexpected tokens (use ; to separate expressions on the same line)) 问题描述&#xff1a;Unexpected tokens (use ; to separate expressions on the same line) 原因&#xff1a;Android Studio 更新到最新的版本之后&#xff0c;gradle工程目录结构发生改变 问…...

【云原生】Docker网络模式和Cgroup资源限制

目录 一、Docker 网络实现原理 二、Docker 的网络模式 #网络模式详解&#xff1a; 第一种&#xff1a;host模式 第二种&#xff1a;bridge模式 第三种&#xff1a;container模式 第四种&#xff1a;none模式 第五种&#xff1a;自定义网络 三、Cgroup资源控制 第一种&a…...

实战:加密传输数据解密

前言 下面将分享一些实际的渗透测试经验&#xff0c;帮助你应对在测试中遇到的数据包内容加密的情况。我们将以实战为主&#xff0c;技巧为辅&#xff0c;进入逆向的大门。 技巧 开局先讲一下技巧&#xff0c;掌握好了技巧&#xff0c;方便逆向的时候可以更加快速的找到关键…...

前端开发提高效率的两大工具

一、浏览器中的开发者工具 怎么启动开发者工具&#xff1f; 在浏览器中按下F12或者鼠标右键点击检查 怎么利用&#xff08;常用的几点&#xff09;&#xff1f; 1、元素 点击标红的图标可以用于在页面选择元素&#xff0c;同时右侧会找到元素在前端代码中的位置 点击下方红…...

探索设计模式的魅力:深入理解面向对象设计的深层原则与思维

如何同时提高一个软件系统的可维护性 和 可复用性是面向对象对象要解决的核心问题。 通过学习和应用设计模式&#xff0c;可以更加深入地理解面向对象的设计理念&#xff0c;从而帮助设计师改善自己的系统设计。但是&#xff0c;设计模式并不能够提供具有普遍性的设计指导原则。…...

【Py/Java/C++三种语言详解】LeetCode每日一题240122【贪心】LeetCode670、最大交换

文章目录 题目链接题目描述解题思路为什么是贪心一个带图的例子 代码pythonjavacpp时空复杂度 华为OD算法/大厂面试高频题算法练习冲刺训练 题目链接 LeetCode670、最大交换 题目描述 给定一个非负整数数组 nums 和一个整数 k &#xff0c;你需要将这个数组分成 k 个非空的连…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...