当前位置:   article > 正文

小白PX4无人机仿真—OFFBOARD控制资料汇总_px4 offboard模式

px4 offboard模式

1. 仿真环境搭建

这套仿真环境是基于Ubuntu20.04环境下的ROS1+PX4固件的联合仿真,由于初次接触这方面的仿真环境搭建,几番寻找找到了国内的XTdrone开源无人机仿真平台,跟着这套仿真平台搭建了一个完整的仿真环境,XTdrone这个平台的简介可以参考这个视频:

XTDrone: 基于PX4、ROS和Gazebo的无人机通用仿真平台简介_哔哩哔哩_bilibili

这里再附上XTdrone的gitee链接 :

XTDrone: 基于PX4、ROS和Gazebo的无人机通用仿真平台

对于无人机仿真来说其实本质需要的就是三大部分,ROS环境,MAVROS包,PX4编译环境,ROS提供通讯和Gazebo仿真环境,PX4固件支持linux编译运行,并通过Gazebo仿真出来,还可连接QGC地面站,MAVROS则是ROS和PX4通讯的桥梁,因为PX4只支持mavlink通讯协议,而ROS则是基于话题,服务等通讯机制,所以需要有一个功能包去把话题和服务转换成mavlink协议,这个功能包就是MAVROS。

XTdrone的搭建有两个版本,一个是基于Ubuntu18.04的但由于Ubuntu18.04已经停止维护,所以更推荐基于Ubuntu20.04的版本,其对应的PX4版本也比较新。下面是搭建的官方教程,最好需要有科学上网的环境,不然配置起来很麻烦,另外官方的教程基于Ubuntu20.04可能安装的人并不多,所以坑还是不少的,每个人的坑也不太一样,不过这些坑基本可以从CSDN上找到解决办法。

此处为语雀内容卡片,点击链接查看:仿真平台基础配置(对应PX4 1.13版) · 语雀

当可以运行键盘控制无人机飞行则表明环境搭建成功

2. 上层控制基础介绍

对于上层控制PX4,飞控端的模式是OFFBOARD,在这个模式下,可以通过mavlink协议,对无人机发送期望位置,期望速度,期望加速度来控制无人机,同时可以通过接收mavlink消息来获取无人机当前姿态。下面这个视频系列对这个模式有详细的介绍:

新手入门无人机+PX4+ROS工程应用开发?看这门课就够了 4.无人机offboard控制_哔哩哔哩_bilibili

同时介绍一下mavros功能包,这个功能包所包含的话题和服务种类很多,这里列举几个常用的消息话题:

【精选】ROS系列——mavros功能包中常用话题和服务介绍,包括消息名称、类型、头文件、成员变量、示例代码_mavros/mission/waypoint-CSDN博客

常用的基本上也就是以下这几个

  • mavros/state
  • mavros/local_position/pose
  • mavros/manual_control/control
  • mavros/setpoint_position/local
  • mavros/setpoint_velocity/cmd_vel_unstamped
  • mavros/setpoint_attitude/attitude
  • mavros/cmd/arming
  • mavros/set_mode(谨慎使用)

3. 代码分析

3.1 一键起飞例程运行

第一步需要启动PX4官方的一个仿真launch文件

cd ~/PX4_Firmware
roslaunch px4 mavros_posix_sitl.launch

此时会启动一个Gazebo的仿真环境,如下图所示

再新开一个终端,并运行

rostopic echo /mavros/state

这是用来订阅/mavros/state这一话题,可以实时查看当前无人机状态,如果connected显示的是True的话,则说明仿真运行正常,MAVROS通讯正常。显示的效果如下图所示:

如果安装了地面站的话执行下面指令打开地面站(到软件包对应目录)

./QGroundControl.AppImage 

此时在地面站应该可以看到无人机相关状态信息,随后就进入到了最关键的一步,编写offboard控制节点,这个节点的功能包如果还没创建,可以参考下面这篇文章:

【ROS+Gazebo+px4】打开offboard模式,offboard_node文件内容-CSDN博客

而具体的源码分析,可以参考下面这篇文章:

mavros笔记(一):mavros概述与offboard例程解析_听风南巷的博客-CSDN博客

3.2 代码分析

首先从最开始运行的 mavros_posix_sitl.launch 这一launch文件说起,下面是这个launch文件源码

<?xml version="1.0"?>
<launch>
    <!-- MAVROS posix SITL environment launch script -->
    <!-- launches MAVROS, PX4 SITL, Gazebo environment, and spawns vehicle -->
    <!-- vehicle pose -->
    <arg name="x" default="0"/>
    <arg name="y" default="0"/>
    <arg name="z" default="0"/>
    <arg name="R" default="0"/>
    <arg name="P" default="0"/>
    <arg name="Y" default="0"/>
    <!-- vehicle model and world -->
    <arg name="est" default="ekf2"/>
    <arg name="vehicle" default="iris"/>
    <arg name="world" default="$(find mavlink_sitl_gazebo)/worlds/empty.world"/>
    <arg name="vehicle_sdf" default="iris"/>
    <arg name="sdf" default="$(find mavlink_sitl_gazebo)/models/$(arg vehicle_sdf)/$(arg vehicle_sdf).sdf"/>

    <!-- gazebo configs -->
    <arg name="gui" default="true"/>
    <arg name="debug" default="false"/>
    <arg name="verbose" default="true"/>
    <arg name="paused" default="false"/>
    <arg name="respawn_gazebo" default="false"/>
    <!-- MAVROS configs -->
    <arg name="fcu_url" default="udp://:24540@localhost:34580"/>
    <arg name="respawn_mavros" default="false"/>
    <!-- PX4 configs -->
    <arg name="interactive" default="true"/>
    <!-- PX4 SITL and Gazebo -->
    <include file="$(find px4)/launch/posix_sitl.launch">
        <arg name="x" value="$(arg x)"/>
        <arg name="y" value="$(arg y)"/>
        <arg name="z" value="$(arg z)"/>
        <arg name="R" value="$(arg R)"/>
        <arg name="P" value="$(arg P)"/>
        <arg name="Y" value="$(arg Y)"/>
        <arg name="world" value="$(arg world)"/>
        <arg name="vehicle" value="$(arg vehicle)"/>
        <arg name="sdf" value="$(arg sdf)"/>
        <arg name="gui" value="$(arg gui)"/>
        <arg name="interactive" value="$(arg interactive)"/>
        <arg name="debug" value="$(arg debug)"/>
        <arg name="verbose" value="$(arg verbose)"/>
        <arg name="paused" value="$(arg paused)"/>
        <arg name="respawn_gazebo" value="$(arg respawn_gazebo)"/>
    </include>
    <!-- MAVROS -->
    <include file="$(find mavros)/launch/px4.launch">
        <!-- GCS link is provided by SITL -->
        <arg name="gcs_url" value=""/>
        <arg name="fcu_url" value="$(arg fcu_url)"/>
        <arg name="respawn_mavros" value="$(arg respawn_mavros)"/>
    </include>
</launch>

<arg>标签在6-11行最开始用于声明一些无人机初始位置和角度的变量,方便后续引入其他launch文件后调用,13-17用于定义世界模型和无人机模型的相关变量,后面根据官方注释的,是对Gazebo,MAVROS,PX4的初始化配置,这里要关注fcu_url这个变量,后续做集群的时候,可能会修改这个变量后面的UDP端口。到了31行,来到了第一个重头戏,这里包含了一个新的launch文件,这个文件的源码如下图所示:

<?xml version="1.0"?>
<launch>
    <!-- Posix SITL environment launch script -->
    <!-- launches PX4 SITL, Gazebo environment, and spawns vehicle -->
    <!-- vehicle pose -->
    <arg name="x" default="0"/>
    <arg name="y" default="0"/>
    <arg name="z" default="0"/>
    <arg name="R" default="0"/>
    <arg name="P" default="0"/>
    <arg name="Y" default="0"/>
    <!-- vehicle model and world -->
    <arg name="est" default="ekf2"/>
    <arg name="vehicle" default="iris"/>
    <arg name="world" default="$(find mavlink_sitl_gazebo)/worlds/empty.world"/>
    <arg name="sdf" default="$(find mavlink_sitl_gazebo)/models/$(arg vehicle)/$(arg vehicle).sdf"/>
    <env name="PX4_SIM_MODEL" value="$(arg vehicle)" />
    <env name="PX4_ESTIMATOR" value="$(arg est)" />

    <!-- gazebo configs -->
    <arg name="gui" default="true"/>
    <arg name="debug" default="false"/>
    <arg name="verbose" default="false"/>
    <arg name="paused" default="false"/>
    <arg name="respawn_gazebo" default="false"/>
    <!-- PX4 configs -->
    <arg name="interactive" default="true"/>
    <!-- PX4 SITL -->
    <arg unless="$(arg interactive)" name="px4_command_arg1" value="-d"/>
    <arg     if="$(arg interactive)" name="px4_command_arg1" value=""/>
    <node name="sitl" pkg="px4" type="px4" output="screen"
        args="$(find px4)/build/px4_sitl_default/etc -s etc/init.d-posix/rcS $(arg px4_command_arg1)" required="true"/>

    <!-- Gazebo sim -->
    <include file="$(find gazebo_ros)/launch/empty_world.launch">
        <arg name="gui" value="$(arg gui)"/>
        <arg name="world_name" value="$(arg world)"/>
        <arg name="debug" value="$(arg debug)"/>
        <arg name="verbose" value="$(arg verbose)"/>
        <arg name="paused" value="$(arg paused)"/>
        <arg name="respawn_gazebo" value="$(arg respawn_gazebo)"/>
    </include>
    <!-- gazebo model -->
    <node name="$(anon vehicle_spawn)" pkg="gazebo_ros" type="spawn_model" output="screen" args="-sdf -file $(arg sdf) -model $(arg vehicle) -x $(arg x) -y $(arg y) -z $(arg z) -R $(arg R) -P $(arg P) -Y $(arg Y)"/>
</launch>

对这个源码我们简要过一下,前面其实大差不差,在31行启动了px4这个节点,具体源码我没细看,大致应该是运行PX4固件,后面会加载一个空模型,随后又启动了一个gazebo的仿真节点,大致就是这样,我们书归正传,接着分析mavros_posix_sitl.launch这个文件,32-46行,就是把最开始前面定义的节点,统统都赋值到posix_sitl.launch这个launch文件里的变量中,做了一个嵌套替换,到了49行,又引入了一个新的launch文件,这里我依旧把源码附到下面:

<launch>
	<!-- vim: set ft=xml noet : -->
	<!-- example launch script for PX4 based FCU's -->

	<arg name="fcu_url" default="/dev/ttyACM0:57600" />
	<arg name="gcs_url" default="" />
	<arg name="tgt_system" default="1" />
	<arg name="tgt_component" default="1" />
	<arg name="log_output" default="screen" />
	<arg name="fcu_protocol" default="v2.0" />
	<arg name="respawn_mavros" default="false" />

	<include file="$(find mavros)/launch/node.launch">
		<arg name="pluginlists_yaml" value="$(find mavros)/launch/px4_pluginlists.yaml" />
		<arg name="config_yaml" value="$(find mavros)/launch/px4_config.yaml" />

		<arg name="fcu_url" value="$(arg fcu_url)" />
		<arg name="gcs_url" value="$(arg gcs_url)" />
		<arg name="tgt_system" value="$(arg tgt_system)" />
		<arg name="tgt_component" value="$(arg tgt_component)" />
		<arg name="log_output" value="$(arg log_output)" />
		<arg name="fcu_protocol" value="$(arg fcu_protocol)" />
		<arg name="respawn_mavros" default="$(arg respawn_mavros)" />
	</include>
</launch>

这部分是启动mavros的相关节点,在这里又引入了一个新的launch文件 node.launch,这里依旧把源码附到下面:

<launch>
	<!-- vim: set ft=xml noet : -->
	<!-- base node launch file-->

	<arg name="fcu_url" />
	<arg name="gcs_url" />
	<arg name="tgt_system" />
	<arg name="tgt_component" />
	<arg name="pluginlists_yaml" />
	<arg name="config_yaml" />
	<arg name="log_output" default="screen" />
	<arg name="fcu_protocol" default="v2.0" />
	<arg name="respawn_mavros" default="false" />

	<node pkg="mavros" type="mavros_node" name="mavros" required="$(eval not respawn_mavros)" clear_params="true" output="$(arg log_output)" respawn="$(arg respawn_mavros)">
		<param name="fcu_url" value="$(arg fcu_url)" />
		<param name="gcs_url" value="$(arg gcs_url)" />
		<param name="target_system_id" value="$(arg tgt_system)" />
		<param name="target_component_id" value="$(arg tgt_component)" />
		<param name="fcu_protocol" value="$(arg fcu_protocol)" />

		<!-- load blacklist, config -->
		<rosparam command="load" file="$(arg pluginlists_yaml)" />
		<rosparam command="load" file="$(arg config_yaml)" />
	</node>
</launch>

可以看到,最终最核心的,就是启动mavros这个节点,以及上传一些参数到参数服务器。至此对整个框架有了一个大体的认识。

在运行完launch文件后,此时启动了许多的话题和服务,通过订阅和发布的方式就可以通过话题去控制和监测无人机,常用的控制指令基本都是基于话题的形式,服务相关目前用到的就是模式切换和无人机上锁解锁这两项,对于仿真而言,由于运行时启动的飞机模式是auto模式,此时就需要对其切换成OFFBOARD模式,而切换OFFBOARD模式必须发送大于100条以上的数据才可,在实际飞行中,切记不要在程序中切换飞行模式,切记,后续的offboard控制节点就比较简单了,ROS八股文,订阅消息,发布消息,在上面的CSDN文章也有详细的介绍了。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/393217
推荐阅读
相关标签
  

闽ICP备14008679号