outdoor_flight_gazebo.launch源码阅读

简介: 在hector_quadrotor-kinetic-devel里的hector_quadrotor_demo功能包,该功能包应该是可以在gazebo中仿真无人机飞行的。里面的launch文件夹里的launch文件应该可以直接执行相应功能。

在hector_quadrotor-kinetic-devel里的hector_quadrotor_demo功能包,该功能包应该是可以在gazebo中仿真无人机飞行的。里面的launch文件夹里的launch文件应该可以直接执行相应功能。

outdoor_flight_gazebo.launch 代码及include代码阅读

outdoor_flight_gazebo.launch

gazebo启动 world文件加载

包含gazebo的启动与world配置文件 rolling_landscape_120m.launch 具体见rolling_landscape_120m.launch

  <include file="$(find hector_gazebo_worlds)/launch/rolling_landscape_120m.launch"/><!-- 启动gazebo与world配置 -->

启动模型描述

包含 spawn_quadrotor.launch
参数
name="model" value="$(find hector_quadrotor_description)/urdf/quadrotor_hokuyo_utm30lx.gazebo.xacro
name="controllers" value=" controller/attitude controller/velocity controller/position"

  <include file="$(find hector_quadrotor_gazebo)/launch/spawn_quadrotor.launch" >
    <arg name="model" value="$(find hector_quadrotor_description)/urdf/quadrotor_hokuyo_utm30lx.gazebo.xacro"/>
    <arg name="controllers" value="
        controller/attitude
        controller/velocity
        controller/position
        "/>
  </include>

rolling_landscape_120m.launch

由outdoor_flight_gazebo.launch文件包含

这个文件需要自己下载ros的对应package 原工程里没有

以相关参数启动start.launch文件

<?xml version="1.0"?>

<launch>
  <include file="$(find hector_gazebo_worlds)/launch/start.launch">
   <arg name="world" value="$(find hector_gazebo_worlds)/worlds/rolling_landscape_120m.world"/> 
  </include>

</launch>

start.launch

<?xml version="1.0"?>

<launch>
  <arg name="world" default="worlds/empty.world"/> <!-- 设置的默认参数  已由传入参数改变为 $(find hector_gazebo_worlds)/worlds/rolling_landscape_120m.world-->
  <arg name="gui" default="true"/>
  <arg name="args" default=""/>
  
  <param name="/use_sim_time" value="true" /><!-- 全局变量参数 -->

  <node name="gazebo" pkg="gazebo_ros" type="gzserver" args="$(arg world) $(arg args)" respawn="false" output="screen"/>
  
    <!-- start gui -->
  <group if="$(arg gui)">
    <node name="gazebo_gui" pkg="gazebo_ros" type="gzclient" respawn="false" output="screen"/>
  </group>
</launch>

1、本launch 变量定义

其中world参数 已由传入变量该变为 $(find hector_gazebo_worlds)/worlds/rolling_landscape_120m.world

  <arg name="world" default="worlds/empty.world"/> <!-- 设置的默认参数  已由传入参数改变为 $(find hector_gazebo_worlds)/worlds/rolling_landscape_120m.world-->
  <arg name="gui" default="true"/>
  <arg name="args" default=""/>

2、参数服务器参数

  <param name="/use_sim_time" value="true" /><!-- 全局变量参数 -->

3、启动 gazebo_ros 功能包的 gzserver(gazebo服务器)节点 命名为gazebo(后台运算)

加载的world为 world 参数配置的 rolling_landscape_120m.world
args无

<node name="gazebo" pkg="gazebo_ros" type="gzserver" args="$(arg world) $(arg args)" respawn="false" output="screen"/><!-- 启动 gazebo_ros 功能包的 gzserver(gazebo服务器)节点  命名为gazebo(后台运算) -->

此处进行一个launch文件里node标签的详细解析
标准形式
在这里插入图片描述
pkg 和 type 它们分别是:程序包名字和可执行文件的名字。 ros::init() 函数 提供的 name 信息将会被全面的覆盖命名信息(launch文件中node标签里面的name属性)

拓展属性 args
传递参数到节点.,arg参数只在launch文件中合法(相当于局部变量),不直接传给节点,需要通过node中的args属性进行传递.
在这里插入图片描述

拓展属性 respawn
在这里插入图片描述
启动完所有请求启动的节点之后,roslaunch 监测每一个节点,让它们保持正常的运行状态。对于每一个节点,当它终止时,我们可以要求 roslaunch 重新启动它.

拓展属性output
Q: 如何将标准输出信息显示在终端(console)上?
A: 在 node 元素中使用 output 属性:
output=”screen”
在这里插入图片描述

4、启动 gazebo_ros 功能包的 gzclient(gazebo客户端)节点 命名为gazebo_gui(前端显示)

    <!-- start gui -->
  <group if="$(arg gui)">
    <node name="gazebo_gui" pkg="gazebo_ros" type="gzclient" respawn="false" output="screen"/>
  </group>

上面参数配置
所以会启动判断里面的节点

这里对group标签进行一个解释
组(groups)可以通过 判别条件 来启用或禁用节点(nodes):

<group if="0-or-1" /> 
. . . 
</group> 

如果 if 属性的值是 1 , 标签内封闭的元素(elements)会被包含。如果 if 属性 值是 0 ,则 标签内包含的元素会被忽略。 unless 属性的工作方式类似 if 属性,但是含义颠倒:

<group unless="1-or-0" /> 
. . . 
</group> 

至此启动了gazebo ,并加载了相关的world文件。 outdoor_flight_gazebo.launch一条线加载完毕

spawn_quadrotor.launch

=================================================================
启动部分

  <include file="$(find hector_quadrotor_gazebo)/launch/spawn_quadrotor.launch" >
    <arg name="model" value="$(find hector_quadrotor_description)/urdf/quadrotor_hokuyo_utm30lx.gazebo.xacro"/>
    <arg name="controllers" value="
        controller/attitude
        controller/velocity
        controller/position
        "/>
  </include>

================================================================

1、本launch文件变量定义

下面用到的地方再看

  <arg name="name" default="quadrotor"/>
  <arg name="model" default="$(find hector_quadrotor_description)/urdf/quadrotor.gazebo.xacro"/>
  <arg name="controllers" default="
    controller/position
    controller/velocity
    controller/attitude
    "/>
  <arg name="tf_prefix" default="$(optenv ROS_NAMESPACE)"/>

  <arg name="x" default="0.0"/>
  <arg name="y" default="0.0"/>
  <arg name="z" default="0.3"/>

  <arg name="use_ground_truth_for_tf" default="true" />
  <arg name="use_ground_truth_for_control" default="true" />
  <arg name="use_pose_estimation" if="$(arg use_ground_truth_for_control)" default="false"/>
  <arg name="use_pose_estimation" unless="$(arg use_ground_truth_for_control)" default="true"/>

  <arg name="world_frame" default="world"/> <!-- This should actually be "/world". See https://github.com/ros-simulation/gazebo_ros_pkgs/pull/324 -->
  <arg name="base_link_frame" default="$(arg tf_prefix)/base_link"/>

2、参数服务器变量定义

  <!-- send the robot XML to param server -->
  <param name="robot_description" command="$(find xacro)/xacro '$(arg model)' base_link_frame:=$(arg base_link_frame) world_frame:=$(arg world_frame)" />
  <param name="tf_prefix" type="string" value="$(arg tf_prefix)"/> <!-- required for hector_pose_estimation and message_to_tf -->
  <param name="base_link_frame" type="string" value="$(arg base_link_frame)" />
  <param name="base_stabilized_frame" type="string" value="$(arg tf_prefix)/base_stabilized" />
  <param name="base_footprint_frame" type="string" value="$(arg tf_prefix)/base_footprint" />
  <param name="world_frame" type="string" value="$(arg world_frame)" />

3、启动robot_state_publisher(机器人状态发布)节点(发布tf信息)

  • [ ] 先不过多看这个
  <!-- start robot state publisher -->
  <node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher" output="screen" >
    <param name="publish_frequency" type="double" value="50.0" />
  </node>

4、启动 message_to_tf 节点

功能包里没有该节点(需要自己下载)

该功能包属于开源功能包 message_to_tf
https://github.com/tu-darmstadt-ros-pkg/hector_localization/tree/catkin/message_to_tf
功能包的描述是:

message_to_tf translates pose information from different kind of common_msgs message types to tf. Currently the node supports nav_msgs/Odometry, geometry_msgs/PoseStamped and sensor_msgs/Imu messages as input.
The resulting transform is divided into three subtransforms with intermediate frames for the footprint and the stabilized base frame (without roll and pitch).

message_to_tf 将不同类型的common_msgs(标准信息)信息类型转化为带位置信息的tf信息。当前该节点支持三种信息类型作为输入:
nav_msgs/Odometry(里程计信息)、geometry_msgs/PoseStamped(位置信息)、sensor_msgs/Imu(imu信息)。
结果将转化为三种转换,footprint 坐标系与stabilized 坐标系之间的转换

  <!-- publish state and tf -->
  <node name="ground_truth_to_tf" pkg="message_to_tf" type="message_to_tf" output="screen">
    <param name="odometry_topic" value="ground_truth/state" />
    <param name="frame_id" value="$(arg world_frame)" />
    <param name="tf_prefix" value="$(arg tf_prefix)" if="$(arg use_ground_truth_for_tf)" />
    <param name="tf_prefix" value="$(arg tf_prefix)/ground_truth" unless="$(arg use_ground_truth_for_tf)" />
  </node>
  • [ ] 具体作用之后再看

5、是否用位置估计 (结果不用)(里面内容可以不看)

  <group if="$(arg use_pose_estimation)">
    <node name="pose_estimation" pkg="hector_quadrotor_pose_estimation" type="hector_quadrotor_pose_estimation" output="screen">
      <rosparam file="$(find hector_quadrotor_pose_estimation)/params/simulation.yaml" />
      <param name="nav_frame" value="$(arg tf_prefix)/nav" />
      <param name="publish_world_nav_transform" value="true" />
      <param name="tf_prefix" value="$(arg tf_prefix)" unless="$(arg use_ground_truth_for_tf)" />
      <param name="tf_prefix" value="$(arg tf_prefix)/pose_estimation" if="$(arg use_ground_truth_for_tf)" />
    </node>
  </group>

首先先对group的if后的变量判断是否执行
use_pose_estimation 这个变量是1or0?
之前的参数定义给出

  <arg name="use_ground_truth_for_control" default="true" />
  <arg name="use_pose_estimation" if="$(arg use_ground_truth_for_control)" default="false"/>
  <arg name="use_pose_estimation" unless="$(arg use_ground_truth_for_control)" default="true"/>

由此判断以默认参数执行的话
use_pose_estimation = false

6、通过判断use_ground_truth_for_control 修改参数服务器里的值

  <group if="$(arg use_ground_truth_for_control)">
    <param name="state_topic" value="" />
    <param name="imu_topic" value="" />
  </group>
  <group unless="$(arg use_ground_truth_for_control)">
    <param name="state_topic" value="state" />
    <param name="imu_topic" value="imu" />
  </group>
  <remap from="pose" to="ground_truth_to_tf/pose"  if="$(arg use_ground_truth_for_control)" />

7、加载控制器launch文件controller.launch

  <!-- load controllers -->
  <include file="$(find hector_quadrotor_controllers)/launch/controller.launch">
    <arg name="controllers" value="$(arg controllers)"/>
  </include>

参数:controllers

    <arg name="controllers" value="
        controller/attitude
        controller/velocity
        controller/position
        "/>

8、 controller.launch

1、本launch默认局部参数

与传入参数一样

  <!-- Order is important! -->
  <arg name="controllers" default="
    controller/position
    controller/velocity
    controller/attitude
    "/>
2、向服务器加载控制器与其它相关参数
 <rosparam ns="controller" file="$(find hector_quadrotor_controllers)/params/controller.yaml" />
  <rosparam file="$(find hector_quadrotor_controllers)/params/params.yaml" />
3、启动控制器节点

该节点是ROS自带功能包(controller_manager)里的spawner.py文件

  <node name="controller_spawner" pkg="controller_manager" type="spawner" respawn="false" output="screen" args="
    $(arg controllers) --shutdown-timeout 3"/>
  • [ ] 先不管具体作用
4、启动话题中继节点

该节点是ros 自带功能包(topic_tools) 的relay.exe文件
相关介绍再wiki的topic_tools中
作用是将input的topic再换个name发出来 相当于topic中继
lazy是ture的时候 只有订阅时才发送

  <node name="estop_relay" pkg="topic_tools" type="relay" args="/estop estop">
    <param name="lazy" value="true" />
  </node>
  • [ ] 先不管具体作用
5、加载 actions.launch 文件
  <!-- load actions -->
  <include file="$(find hector_quadrotor_actions)/launch/actions.launch" />
6、加载aerodynamic(空气动力学)motor(电机)参数
  <!-- load aerodynamic and motor parameters -->
  <arg name="motors" default="robbe_2827-34_epp1045" />
  <rosparam command="load" file="$(find hector_quadrotor_model)/param/quadrotor_aerodynamics.yaml" />
  <rosparam command="load" file="$(find hector_quadrotor_model)/param/$(arg motors).yaml" />
7、在gazebo中加载机器人模型
  <!-- push robot_description to factory and spawn robot in gazebo -->
  <node name="spawn_robot" pkg="gazebo_ros" type="spawn_model"
        args="-param robot_description
           -urdf
           -x $(arg x)
           -y $(arg y)
           -z $(arg z)
           -model $(arg name)"
        respawn="false" output="screen"/>

9、actions.launch

1、启动位置运动动作节点

该节点是hector_quadrotor_actions(四旋翼无人机动作)功能包里的pose_action执行文件,自己定义的

<node name="pose_action" pkg="hector_quadrotor_actions" type="pose_action" output="screen" />
  • [ ] 具体作用回来再看
2、启动降落运动动作节点

该节点是hector_quadrotor_actions(四旋翼无人机动作)功能包里的landing_action执行文件,自己定义的

<node name="landing_action" pkg="hector_quadrotor_actions" type="landing_action" output="screen" />
  • [ ] 具体作用回来再看
3、启动起飞运动动作节点

该节点是hector_quadrotor_actions(四旋翼无人机动作)功能包里的takeoff_action执行文件,自己定义的

  <node name="takeoff_action" pkg="hector_quadrotor_actions" type="takeoff_action" output="screen" />
  • [ ] 具体作用回来再看

10、加载电机参数与空气动力学参数

  <!-- load aerodynamic and motor parameters -->
  <arg name="motors" default="robbe_2827-34_epp1045" />
  <rosparam command="load" file="$(find hector_quadrotor_model)/param/quadrotor_aerodynamics.yaml" />
  <rosparam command="load" file="$(find hector_quadrotor_model)/param/$(arg motors).yaml" />

11、启动gazebo中机器人描述

  <!-- push robot_description to factory and spawn robot in gazebo -->
  <node name="spawn_robot" pkg="gazebo_ros" type="spawn_model"
        args="-param robot_description
           -urdf
           -x $(arg x)
           -y $(arg y)
           -z $(arg z)
           -model $(arg name)"
        respawn="false" output="screen"/>

12、机器人描述文件

在spawn_quadrotor.launch文件中,参数定义部分给出了模型描述文件
抽取其部分

<arg name="model" default="$(find hector_quadrotor_description)/urdf/quadrotor.gazebo.xacro"/>

 <param name="robot_description" command="$(find xacro)/xacro '$(arg model)' base_link_frame:=$(arg base_link_frame) world_frame:=$(arg world_frame)" />

  <!-- push robot_description to factory and spawn robot in gazebo -->
  <node name="spawn_robot" pkg="gazebo_ros" type="spawn_model"
        args="-param robot_description
           -urdf
           -x $(arg x)
           -y $(arg y)
           -z $(arg z)
           -model $(arg name)"
        respawn="false" output="screen"/>

指明了该文件为
$(find hector_quadrotor_description)/urdf/quadrotor.gazebo.xacro

13、quadrotor.gazebo.xacro

<robot name="quadrotor" xmlns:xacro="http://www.ros.org/wiki/xacro">
    <xacro:include filename="$(find hector_quadrotor_description)/urdf/quadrotor.urdf.xacro" />
    <xacro:include filename="$(find hector_quadrotor_gazebo)/urdf/quadrotor_plugins.gazebo.xacro" />
</robot>
1、quadrotor.urdf.xacro
1、包含quadrotor_base.urdf.xacro文件
    <!-- Included URDF Files -->
    <xacro:include filename="$(find hector_quadrotor_description)/urdf/quadrotor_base.urdf.xacro" />
2、启动 quadrotor_base_macro
    <xacro:quadrotor_base_macro />
2、quadrotor_plugins.gazebo.xacro

包含了四个xacro文件,但是都是宏定义,啥也没干

  <xacro:include filename="$(find hector_quadrotor_gazebo)/urdf/quadrotor_sensors.gazebo.xacro" />
  <xacro:include filename="$(find hector_quadrotor_gazebo)/urdf/quadrotor_controller.gazebo.xacro" />
  <xacro:include filename="$(find hector_quadrotor_gazebo)/urdf/quadrotor_propulsion.gazebo.xacro" />
  <xacro:include filename="$(find hector_quadrotor_gazebo)/urdf/quadrotor_aerodynamics.gazebo.xacro" />
相关实践学习
Docker镜像管理快速入门
本教程将介绍如何使用Docker构建镜像,并通过阿里云镜像服务分发到ECS服务器,运行该镜像。
阿里云资源编排ROS使用教程
资源编排(Resource Orchestration)是一种简单易用的云计算资源管理和自动化运维服务。用户通过模板描述多个云计算资源的依赖关系、配置等,并自动完成所有资源的创建和配置,以达到自动化部署、运维等目的。编排模板同时也是一种标准化的资源和应用交付方式,并且可以随时编辑修改,使基础设施即代码(Infrastructure as Code)成为可能。 产品详情:https://www.aliyun.com/product/ros/
相关文章
|
开发工具
【错误记录】Flutter 插件报错 ( Methods marked with @UiThread must be executed on the main thread. | 更新最新 SDK )(一)
【错误记录】Flutter 插件报错 ( Methods marked with @UiThread must be executed on the main thread. | 更新最新 SDK )(一)
775 0
【错误记录】Flutter 插件报错 ( Methods marked with @UiThread must be executed on the main thread. | 更新最新 SDK )(一)
|
6月前
|
Java Maven 数据库
如何用 APT(Annotation Processing Tool)自动生成代码
如何用 APT(Annotation Processing Tool)自动生成代码
69 0
|
6月前
|
存储 编译器 C++
[√]leak-tracer源码使用到的函数
[√]leak-tracer源码使用到的函数
30 0
|
8月前
UE中创建异步任务编辑器工具(Editor Utility Tasks)
UE中创建异步任务编辑器工具(Editor Utility Tasks)
116 0
UE中创建异步任务编辑器工具(Editor Utility Tasks)
Appium问题解决方案(9)- Original error: Failed to launch Appium Settings app: Condition unmet after 5090 ms
Appium问题解决方案(9)- Original error: Failed to launch Appium Settings app: Condition unmet after 5090 ms
348 0
Appium问题解决方案(9)- Original error: Failed to launch Appium Settings app: Condition unmet after 5090 ms
|
开发工具
【错误记录】Flutter 插件报错 ( Methods marked with @UiThread must be executed on the main thread. | 更新最新 SDK )(二)
【错误记录】Flutter 插件报错 ( Methods marked with @UiThread must be executed on the main thread. | 更新最新 SDK )(二)
276 0
【错误记录】Flutter 插件报错 ( Methods marked with @UiThread must be executed on the main thread. | 更新最新 SDK )(二)
APF model和Fiori launchpad tile的同步问题
APF model和Fiori launchpad tile的同步问题
APF model和Fiori launchpad tile的同步问题