px4+vio实现无人机室内定位
文章主要讲述px4 如何利用vins_fusion里程计数据实现在室内定位功能。
文章基于以下软、硬件展开。
| 硬件 | 软件 |
|---|---|
| 机载电脑: Intel NUC | 系统:Ubuntu 20.04 |
| 相机: Intel Realsense D435i | ros:noetic |
| 飞控:Pixhawk 2.4.8 | 固件:PX4 1.14.0 |
完整vins_to_mavros 功能包地址:
https://github.com/rotorcraftman/px4ctrl
随着slam开源技术的普及,px4 要实现室内定位,实现方式很多,如文章使用的vins-fusion等视觉里程计,激光里程计等。
本质上,要实现无人机的室内定位有两个方法:
1.提供室内位置信息
室外可以用gps提供位置信息,实现定位,而室内因为gps没有信号,所以朴素的想法是只要提供位置信息给飞控就可实现像室外gps定位的效果了。
思路:
vio提供里程计—>(/mavros/vision_posion/pose)mavros(mavlink)—>px4
可以看出mavros起到了连接vio和px4的桥梁作用。
2.offboard
外部计算机遵守照MAVLink 协议提供的位置,速度或姿态设定值。 设定值可以由机载计算机上运行的 MAVLink API(例如 MAVSDK (opens new window) 或 MAVROS (opens new window))提供(通常通过串口或 wifi 连接)。
3.光流、UWB等。
接下来详细讲述第一种实现方式,vio以vins_fusion为例。
文章叙述展开方式默认已完成了px4飞控的建立、mavros的安装,未完成的同志可参考上一篇文章:
gazebo11+px4联合仿真测试
一、Pixhawk MAVLink Ports配置
配置Pixhawk Telem2作为与机载电脑数据交互的MAVLINK端口
MAV_1_CONFIG= TELEM 2
MAV_1_MODE = Onboard
SER_TEL2_BAUD = 921600 8N1
设置前参数里可能只有MAV_1_CONFIG,搜不到其他的参数,将MAV_1_CONFIG设置为TELEM 2,然后把飞控重启后其他参数就有了。
Pixhawk 2.4.8硬件,设置为102,参数对应关系如下。

详细参数介绍参见:https://docs.px4.io/main/en/advanced_config/parameter_reference.html
Pixhawk 2.4.8 TELEM1/TELEM2端口设置如下:
| TELEM1 | TELEM2 |
|---|---|
| MAV_0_CONFIG = TELEM 1 | MAV_1_CONFIG = TELEM 2 |
| MAV_0_MODE = Normal | MAV_1_MODE = Onboard |
| MAV_0_RATE= 1200 Bytes/s | MAV_1_RATE= 0 (Half maximum) |
| MAV_0_FORWARD = True | MAV_1_FORWARD = Disabled |
| SER_TEL1_BAUD = 57600 | SER_TEL2_BAUD = 921600 |
详细端口设置参见:https://docs.px4.io/main/en/peripherals/mavlink_peripherals.html
配置好端口后,需要做一根连接机载电脑和Pixhawk TELEM 2 端口的线,我这边直接用一个USB转TTL模块。
Pixhawk TELEM1 / TELEM2 端口线序图如下:
| Pin | Signal | Volt |
|---|---|---|
| 1 (red) | VCC | +5V |
| 2 (blk) | TX (OUT) | +3.3V |
| 3 (blk) | RX (IN) | +3.3V |
| 4 (blk) | CTS (IN) | +3.3V |
| 5 (blk) | RTS (OUT) | +3.3V |
| 6 (blk) | GND | GND |
其它端口详见:https://docs.px4.io/main/en/flight_controller/pixhawk.html#where-to-buy
展示一张做好的端子连接线如下:

在qgc上测试通信是否正常。
qgc-Application Settings-通讯连接-添加,设置如下。

正常情况下,就可通过TELEM 2连上QGC了。
二、在机载电脑上启动MAVROS
我这里用的是nuc的usb,设备名称:dev/ttyUSB0,按照自己实际情况配置。921600是波特率,就是前面设置的SER_TEL2_BAUD参数,改成设置值就行。
roslaunch mavros px4.launch fcu_url:=serial:=/dev/ttyUSB0:921600 gcs_url:=udp://@172.16.7.210
gcs_url:运行qgc主机的IP地址。
如果不想设置ip,可以设置为以下参数自动寻址。
roslaunch mavros px4.launch fcu_url:=serial:=/dev/ttyUSB0:921600 gcs_url:=udp-b://@
若出现报错
FCU: DeviceError:serial:open: Permission denied
解决方法是给对应的串口权限
sudo chmod 777 /dev/ttyUSB0
三、vins_fusion、mavros建立连接
思考vins_fusion的里程计数据如何发布给px4?
这也是实现室内定位的关键。实现这一步只需将vins_fusion里程计数据以话题 /mavros/vision_pose/pose 发布,mavros 收到/mavros/vision_pose/pose话题后,转化成mavlink通过TELEM 2传给飞控。于是就完成了vins_fusion和px4的连接。
接下来创建发布 /mavros/vision_pose/pose 话题的功能包过程了
1.创建工作空间px4ctrl
mkdir -p px4ctrl/src/
cd px4ctrl/src/
2.创建功能包vins_to_mavros
catkin_create_pkg vins_to_mavros roscpp std_msgs geometry_msgs mavros_msgs nav_msgs tf2_eigen tf
在px4ctrl/src/vins_to_mavros/src/ 目录下创建一个 vins_to_mavros 节点,主要功能:
(1)将 VINS-Fusion 的 body 坐标系在 world 坐标系下为位姿转化为 base_link 在 map 坐标系中的位姿;
(2)将转化后的位姿信息以话题 /mavros/vision_pose/pose 发布。
#include <ros/ros.h>
#include <geometry_msgs/PoseStamped.h>
#include <nav_msgs/Odometry.h>
#include <Eigen/Eigen>Eigen::Vector3d p_mav;
Eigen::Quaterniond q_mav;void vins_callback(const nav_msgs::Odometry::ConstPtr &msg)
{if(msg->header.frame_id == "world"){p_mav = Eigen::Vector3d(msg->pose.pose.position.y, -msg->pose.pose.position.x, msg->pose.pose.position.z);q_mav = Eigen::Quaterniond(msg->pose.pose.orientation.w, msg->pose.pose.orientation.x, msg->pose.pose.orientation.y, msg->pose.pose.orientation.z);Eigen::AngleAxisd roll(M_PI/2,Eigen::Vector3d::UnitX()); // 绕 x 轴旋转 pi / 2Eigen::AngleAxisd pitch(0,Eigen::Vector3d::UnitY());Eigen::AngleAxisd yaw(0,Eigen::Vector3d::UnitZ());Eigen::Quaterniond _q_mav = roll * pitch * yaw;q_mav = q_mav * _q_mav;}
}int main(int argc, char **argv)
{ros::init(argc, argv, "vins_to_mavros");ros::NodeHandle nh("~");ros::Subscriber slam_sub = nh.subscribe<nav_msgs::Odometry>("odom", 100, vins_callback);ros::Publisher vision_pub = nh.advertise<geometry_msgs::PoseStamped>("vision_pose", 10);// the setpoint publishing rate MUST be faster than 2Hzros::Rate rate(20.0);ros::Time last_request = ros::Time::now();while(ros::ok()) {geometry_msgs::PoseStamped vision;vision.pose.position.x = p_mav[0];vision.pose.position.y = p_mav[1];vision.pose.position.z = p_mav[2];vision.pose.orientation.x = q_mav.x();vision.pose.orientation.y = q_mav.y();vision.pose.orientation.z = q_mav.z();vision.pose.orientation.w = q_mav.w();vision.header.stamp = ros::Time::now();vision_pub.publish(vision);ROS_INFO("\nposition:\n x: %.18f\n y: %.18f\n z: %.18f\norientation:\n x: %.18f\n y: %.18f\n z: %.18f\n w: %.18f", \p_mav[0],p_mav[1],p_mav[2],q_mav.x(),q_mav.y(),q_mav.z(),q_mav.w());ros::spinOnce();rate.sleep();}return 0;
}
3.配置 CMakeList.txt 文件
找到相应位置添加
add_executable(vins_to_mavros_node src/vins_to_mavros.cpp)
target_link_libraries(vins_to_mavros_node ${catkin_LIBRARIES})
4.创建vins_to_mavros节点的launch文件
在目录px4ctrl/src/launch/ 创建vins_to_mavros.launch
<launch><node pkg="vins_to_mavros" type="vins_to_mavros_node" name="vins_to_mavros" output="screen"><remap from="~vision_pose" to="/mavros/vision_pose/pose" /><remap from="~odom" to="/vins_estimator/odometry" /></node>
</launch>
5.编译
cd px4ctrl
catkin_make
source devel/setup.bash
6.验证
启动vins_to_mavros节点
roslaunch vins_to_mavros vins_to_mavros.launch
查看话题
rostopic list
显示如下:

PS:此处坐标系转化适配的是Realsense D435i相机,如其它相机需要根据相机imu坐标系与px4坐标系进行相应的转换。
四、联调测试
联调测试的基础是:
1.vins_fusion里程计精度尚可,且具有一定的鲁棒性;
2.px4飞控在自稳模式下手动可控、达到可飞条件。
关于vins_fusion的相关调试参见系列文章:
https://blog.csdn.net/u010196944/article/details/127240169
1.px4飞控设置
将px4定位数据源设置为vinsion,参数EKF2_AID_MASK设置为24,具体如下:

2.在终端依次输入:

此时qgc已连上,可在qgc作如下验证。
Analyze Tools-MAVlink检测,出现了LOCAL_POSITION_NED数据,如下:

验证:
(1)前后左右移动飞机,看看位置是否正确。
(2)前后移动飞机后,放回原位置看位置数据偏差是否大。
验证没问题之后,就可以起飞,通过qgc或者遥控器切换定位模式了。

完结,希望你一切顺利,不“炸鸡”。
参考
1.https://blog.csdn.net/u010196944/article/details/127240169
2.https://docs.px4.io/main/en/
3.https://zhuanlan.zhihu.com/p/364390798
4.https://blog.csdn.net/qq_44998513/article/details/133144421?spm=1001.2014.3001.5502
相关文章:
px4+vio实现无人机室内定位
文章主要讲述px4 如何利用vins_fusion里程计数据实现在室内定位功能。 文章基于以下软、硬件展开。 硬件软件机载电脑: Intel NUC系统:Ubuntu 20.04相机: Intel Realsense D435iros:noetic飞控:Pixhawk 2.4.8固件&am…...
享元模式 rust和java的实现
文章目录 享元模式介绍实现javarust实现代码 rust仓库rust仓库 享元模式 享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应…...
XmlElement注解在Java的数组属性上,以产生多个相同的XML元素
例如,下面这段XML数据,有多个data元素,并且它们级别相同: <?xml version"1.0" encoding"UTF-8"?><request><reqtype>05</reqtype><secret>test</secret><body><userid&…...
SQLServer 数字加千分位 用FORMAT函数强转不管多大位数
问题 CONVERT ( money, CONVERT ( money, CAST ( round( FTP_AMOUNT, 2 ) AS NUMERIC ( 20, 2 ) ) ) 1 ) AS FTP_AMOUNT用的money函数 结果空间不足,无法将 money 值转换为 varchar。 可以强转 select FORMAT(CAST ( round( ‘-8926143870680.62000000’, 2 ) AS N…...
说说mvc和mvvm的区别和联系
mvvm 与mvc mvvm 与mvcmvc和mvvm的区别和联系 举例说明mvvm与mvc MVC是一种用于构建应用程序的架构模式,它也将应用程序的逻辑和界面分离。它由三个主要组件组成: 模型(Model):表示应用程序的数据和业务逻辑。视图&a…...
linux rsyslog综合实战2
本次我们通过rsyslog服务将A节点服务器上的两个(E.g:多个日志也可以)日志(Path:/var/log/245-1.log、245-2.log)实时同步到B节点服务器目录下(Path:/opt/rsyslog/245) 1.rsyslog架构 2.环境信息 环境信息 HostnameIpAddressOS versionModuleNotersyslog1192.168.10.245CentOS…...
AcWing 4. 多重背包问题 I 学习笔记
有 N� 种物品和一个容量是 V� 的背包。 第 i� 种物品最多有 si�� 件,每件体积是 vi��,价值是 wi��。 求解将哪些物品装入背包,可使物…...
解决selenium使用chrome下载文件(如pdf)时,反而打开浏览器的预览界面
文章目录 解决方法完整的配置 解决方法 在初始化浏览器的时候,添加以下配置即可: option webdriver.ChromeOptions()prefs {"profile.managed_default_content_settings.images": 2, # 禁止加载图片# permissions.default.stylesheet: 2, …...
2024年山东省职业院校技能大赛中职组“网络安全”赛项竞赛试题-C
2024年山东省职业院校技能大赛中职组 “网络安全”赛项竞赛试题-C 一、竞赛时间 总计:360分钟 二、竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 A、B模块 A-1 登录安全加固 180分钟 200分 A-2 本地安全策略设置 A-3 流量完整性保护 A-4 …...
基于Python实现用于实时监控和分析 MySQL 服务器的性能指标和相关信息工具源码
MySQL命令行监控工具 - mysqlstat 介绍 mysqlstat 是一个命令行工具,用于实时监控和分析 MySQL 服务器的性能指标和相关信息。 它可以帮助 DBA(数据库管理员)和开发人员定位和解决数据库性能问题。 以下是 mysqlstat 工具的主要功能&#…...
Android 10-13鼠标右键返回功能适配
Android 10-13鼠标右键返回功能适配 文章目录 Android 10-13鼠标右键返回功能适配一、前言二、鼠标右键适配修改1、Android 10 以及更低版本2、Android11 或者更高版本三、总结1、鼠标右键返回功能修改主要代码2、标右键返回修改代码系统源码搜索3、其他 一、前言 Android 原生…...
51单片机/STM32F103/STM32F407学习1_点亮LED灯
目录: 基础知识单片机从0实现单片机GPIO介绍 参考连接: 野火霸天虎教程 https://doc.embedfire.com/products/link/zh/latest/mcu/stm32/ebf_stm32f407_batianhu_v1_v2/download/stm32f407_batianhu_v1_v2.html x.1 基础知识 x.1.1 指针中的取地址&a…...
(Transfer Learning)迁移学习在IMDB上训练情感分析模型
1. 背景 有些场景下,开始的时候数据量很小,如果我们用一个几千条数据训练一个全新的深度机器学习的文本分类模型,效果不会很好。这个时候你有两种选择,1.用传统的机器学习训练,2.利用迁移学习在一个预训练的模型上训练…...
蓝桥杯每日一题2023.11.20
题目描述 “蓝桥杯”练习系统 (lanqiao.cn) 题目分析 方法一:暴力枚举,如果说数字不在正确的位置上也就意味着这个数必须要改变,进行改变记录即可 #include<bits/stdc.h> using namespace std; const int N 2e5 10; int n, a[N], …...
【迅搜02】究竟什么是搜索引擎?正式介绍XunSearch
究竟什么是搜索引擎?正式介绍XunSearch 啥?还要单独讲一下啥是搜索引擎?不就是百度、Google嘛,这玩意天天用,还轮的到你来说? 额,好吧,虽然大家天天都在用,但是我发现&am…...
【Sql】sql server还原数据库的时候,提示:因为数据库正在使用,所以无法获得对数据库的独占访问权。
【问题描述】 sql server 还数据库的时候,提示失败。 点击左下角进度位置,可以得到详细信息: 因为数据库正在使用,所以无法获得对数据库的独占访问权。 【解决方法】 针对数据库先后执行下述语句,获得独占访问权后&a…...
【Go语言实战】(26) 分布式搜索引擎
Tangseng 基于Go语言的搜索引擎 github地址:https://github.com/CocaineCong/tangseng 详细介绍地址:https://cocainecong.github.io/tangseng 这两周我也抽空录成视频发到B站的~ 本来应该10月份就要发了,结果一鸽就鸽到现在hh…...
【理解ARM架构】不同方式点灯 | ARM架构简介 | 常见汇编指令 | C与汇编
🐱作者:一只大喵咪1201 🐱专栏:《理解ARM架构》 🔥格言:你只管努力,剩下的交给时间! 目录 🏀直接操作寄存器点亮LED灯🏀地址空间🏀ARM内部的寄存…...
JS服务端技术—Node.js知识点锦集
【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) https://blog.csdn.net/m0_69908381/article/details/134544523 出自【进步*于辰的博客】 接触Node.js挺长时间了,工作也经常使用…...
界面控件DevExpress WPF流程图组件,完美复制Visio UI!(一)
DevExpress WPF Diagram(流程图)控件帮助用户完美复制Microsoft Visio UI,并将信息丰富且组织良好的图表、流程图和组织图轻松合并到您的下一个WPF项目中。 P.S:DevExpress WPF拥有120个控件和库,将帮助您交付满足甚至…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...
深入理解Optional:处理空指针异常
1. 使用Optional处理可能为空的集合 在Java开发中,集合判空是一个常见但容易出错的场景。传统方式虽然可行,但存在一些潜在问题: // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...
Linux中《基础IO》详细介绍
目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改,实现简单cat命令 输出信息到显示器,你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...
面试高频问题
文章目录 🚀 消息队列核心技术揭秘:从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"?性能背后的秘密1.1 顺序写入与零拷贝:性能的双引擎1.2 分区并行:数据的"八车道高速公路"1.3 页缓存与批量处理…...
一些实用的chrome扩展0x01
简介 浏览器扩展程序有助于自动化任务、查找隐藏的漏洞、隐藏自身痕迹。以下列出了一些必备扩展程序,无论是测试应用程序、搜寻漏洞还是收集情报,它们都能提升工作流程。 FoxyProxy 代理管理工具,此扩展简化了使用代理(如 Burp…...
