模型已经准备完毕,用rviz打开是这样子滴
launch文件首先要明确是什么作用,这个链接具有详细说明
https://www.jianshu.com/p/63a959bfbb96
首先一堆arg变量参数,相当于launch文件的局部变量,只在launch文件内部生效,便于使用变量。
<!-- 设置launch文件的参数 -->
<arg name="world_name" value="$(find mrobot_gazebo)/worlds/playground.world"/>
<arg name="paused" default="false"/>
<arg name="use_sim_time" default="true"/>
<arg name="gui" default="true"/>
<arg name="headless" default="false"/>
<arg name="debug" default="false"/>
接下来是运行gazebo仿真环境, <include file="$(find gazebo_ros)/launch/empty_world.launch">
是调用了另一个launch文件
include的作用:在launch文件中复用其他launch文件可以减少代码编写的工作量,提高文件的简洁性。使用包含元素include在launch文件中可包含其他launch文件中所有的节点和参数。
gazebo下面的这些args都记住就可以,是模式化的东西
<!-- 运行gazebo仿真环境 -->
<include file="$(find gazebo_ros)/launch/empty_world.launch">
<arg name="world_name" value="$(arg world_name)" />
<arg name="debug" value="$(arg debug)" />
<arg name="gui" value="$(arg gui)" />
<arg name="paused" value="$(arg paused)"/>
<arg name="use_sim_time" value="$(arg use_sim_time)"/>
<arg name="headless" value="$(arg headless)"/>
</include>
接下来是加载机器人模型描述参数,param参数:
parameter是运行中的ROS系统使用的数值,存储在参数服务器(parameter server)中,每个活跃的节点都可以通过 ros::param::get 函数来获取parameter的值,用户也可以通过rosparam来获得parameter的值而argument只在启动文件内才有意义他们的值是不能被节点直接获取的。
也就是param是流淌在整个ros系统中的,不像是arg只是局部参数
之前设计的机器人模型mrobot_with_camera.urdf.xacro在这里被加载到ros系统当中
<param name="robot_description" command="$(find xacro)/xacro --inorder '$(find mrobot_gazebo)/urdf/mrobot_with_camera.urdf.xacro'" />
接下来运行关节相关的一系列节点
一个负责发布机器人关节状态的publisher,发布话题用的,是个节点
另一个是发布tf也就是坐标变换关系的publisher,也是发布话题用的,是个节点
<!-- 运行joint_state_publisher节点,发布机器人的关节状态 -->
<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" ></node>
<!-- 运行robot_state_publisher节点,发布tf -->
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" output="screen" >
<param name="publish_frequency" type="double" value="50.0" />
</node>
接下来是在gazebo中加载机器人模型,也就是如果想在gazebo进行仿真,那么这句话是必须的
设置的,是一个节点,用来发布和接受gazebo有关话题
注意这个args里面
-urdf -model 后面跟的是机器人模型的名称,也就是mrobot_body.urdf.xacro文件中的第二行:
<?xml version="1.0"?>n
-param 后面跟着加载机器人模型描述参数那一行命令的名称,也就是机器人的模型文件
这样就把机器人的模型文件与gazebo联系起来了。
<!-- 在gazebo中加载机器人模型-->
<node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen"
args="-urdf -model mrobot -param robot_description"/>
接下来设置在rviz中显示,如何在rviz中显示,见我的另一篇教程
https://blog.csdn.net/weixin_44684139/article/details/104416690
最后附上launch文件的所有代码
<launch>
<!-- 设置launch文件的参数 -->
<arg name="world_name" value="$(find mrobot_gazebo)/worlds/playground.world"/>
<arg name="paused" default="false"/>
<arg name="use_sim_time" default="true"/>
<arg name="gui" default="true"/>
<arg name="headless" default="false"/>
<arg name="debug" default="false"/>
<!-- 运行gazebo仿真环境 -->
<include file="$(find gazebo_ros)/launch/empty_world.launch">
<arg name="world_name" value="$(arg world_name)" />
<arg name="debug" value="$(arg debug)" />
<arg name="gui" value="$(arg gui)" />
<arg name="paused" value="$(arg paused)"/>
<arg name="use_sim_time" value="$(arg use_sim_time)"/>
<arg name="headless" value="$(arg headless)"/>
</include>
<!-- 加载机器人模型描述参数 -->
<param name="robot_description" command="$(find xacro)/xacro --inorder '$(find mrobot_gazebo)/urdf/mrobot_with_camera.urdf.xacro'" />
<!-- 运行joint_state_publisher节点,发布机器人的关节状态 -->
<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" ></node>
<!-- 运行robot_state_publisher节点,发布tf -->
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" output="screen" >
<param name="publish_frequency" type="double" value="50.0" />
</node>
<!-- 在gazebo中加载机器人模型-->
<node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen"
args="-urdf -model mrobot -param robot_description"/>
<!-- 在rviz中显示-->
<node name="rviz" pkg="rviz" type="rviz" args="-d $(find mrobot_gazebo)/config/mrobot_with_camera.rviz" required="true" />
</launch>
简而言之,launch文件是为了同时启动节点管理器(master)和多个节点,实现机器人模型与仿真环境的浑然天成,实现信息在机器人系统中的流动。
补充:
node的三个属性分别为节点名字、程序包名字和 可执行文件的名字。 name属性给节点指派了名称,它将覆盖任何通过调用 ros::init来赋予节点的名称。另外node标签内也可以用过arg设置节点参数值。如果node标签有children标签,就需要显式标签来定义。即末尾为/node>
<node name="node-name" pkg="pkg-name" type="executable-name" />
三个分别为 节点名称、程序包名称、cpp的名字