SLAM从入门到精通(launch文件学习)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

        大家应该还记得我们在一开始学习ros的时候,如果需要启动一个节点的话,需要首先打开roscore,接着用rosrun打开对应的节点。如果节点比较少的话,这种方法,倒也可以接受,但是节点一多就不太方便了。比如,我们之前在学习slam的时候,需要依次打开gazebo、rviz、slam、rqt等多个节点软件,这就非常麻烦了。所以为了解决这个问题,人们想出了roslaunch的办法,它不但可以帮助我们自动打开roscore,还会自动打开脚本中每一个node节点,还能自由配置参数信息。

        所以,对于我们来说,有必要学习好launch、用好launch。至于怎么学习,个人觉得最好的学习方法就是把曾经用过的launch文件直接拿过来分析就可以了。学完了,直接拿过来当模板修改使用。

1、wpb_simple.launch

<launch><!-- We resume the logic in empty_world.launch, changing only the name of the world to be launched --><include file="$(find gazebo_ros)/launch/empty_world.launch"><arg name="world_name" value="$(find wpr_simulation)/worlds/wpb_simple.world"/><arg name="paused" value="false"/><arg name="use_sim_time" value="true"/><arg name="gui" value="true"/><arg name="recording" value="false"/><arg name="debug" value="false"/></include><!-- Spawn the objects into Gazebo --><node name="bookshelft" pkg="gazebo_ros" type="spawn_model" args="-file $(find wpr_simulation)/models/bookshelft.model -x 3.0 -y 0.2 -z 0 -Y 3.14159 -urdf -model bookshelft" /><node name="bottle" pkg="gazebo_ros" type="spawn_model" args="-file $(find wpr_simulation)/models/bottles/red_bottle.model -x 2.8 -y 0 -z 0.6 -Y 0 -urdf -model red_bottle" /><!-- Spawn a robot into Gazebo --><node name="spawn_urdf" pkg="gazebo_ros" type="spawn_model" args="-file $(find wpr_simulation)/models/wpb_home.model -urdf -model wpb_home" /><!-- Robot Description --><arg name="model" default="$(find wpr_simulation)/models/wpb_home.model"/><param name="robot_description" command="$(find xacro)/xacro $(arg model)" /><node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" /><node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />
</launch>

        内容看上很多,其实大部分都是描述仿真环境的。从一开始的empty_world.launch,到后来的objects、robot都是如此,最后添加了一个robot的详细描述。注意,node就是调用节点的地方,pkg代表包名,type代表node名,次序不重要。

        仿真环境部分,world类似于装修里面的硬装,通常是一些围墙、灯光、地面的设置。objects是软装,书柜、瓶子就是objects。robot代表着人。硬装和软装都ok了之后,robot就可以在里面自由行走了。

2、wpb_gmapping.launch

<launch><!-- 载入 机器人 和 RoboCup@Home 的仿真场景 --><include file="$(find wpr_simulation)/launch/wpb_stage_robocup.launch"/><!-- Gmapping --><node pkg="gmapping" type="slam_gmapping" name="slam_gmapping"/><!-- Rviz --><arg name="rvizconfig" default="$(find wpr_simulation)/rviz/slam.rviz" /><node name="rviz" pkg="rviz" type="rviz" args="-d $(arg rvizconfig)" required="true" /><!-- 手柄控制 --><node respawn="true" pkg="joy" type="joy_node" name="joy_node" ><param name="dev" type="string" value="/dev/input/js0" /><param name="deadzone" value="0.12" /></node><param name="axis_linear" value="1" type="int"/><param name="axis_angular" value="0" type="int"/><param name="scale_linear" value="0.5" type="double"/><param name="scale_angular" value="1" type="double"/><node pkg="wpr_simulation" type="teleop_js_node" name="teleop_js_node"/></launch>

        相比较之前wpb_simple.launch文件,这个wpb_gmapping内容要丰富一些。首先,它嵌套了wpb_stage_robocup.launch的内容。接着启动gmapping和rviz,最后加载joy_node和teleop_js_node。不过印象中,实际调试的时候,最后还是通过rqt_robot_steering来调试的。

        通过观察我们还发现,有些param是放在node里面的,这其实代表了私有参数;还有些param是放在外面的,这代表了公有参数,使用的时候需要稍微注意下。

3、wpb_corridor_hector.launch

<launch><!-- 载入 机器人 和 长走廊 的仿真场景 --><include file="$(find wpr_simulation)/launch/wpb_stage_corridor.launch"/><!-- Hector --><node pkg="hector_mapping" type="hector_mapping" name="hector_mapping"/><!-- Rviz --><arg name="rvizconfig" default="$(find wpr_simulation)/rviz/corridor.rviz" /><node name="rviz" pkg="rviz" type="rviz" args="-d $(arg rvizconfig)" required="true" /><!-- 运动控制 --><node pkg="rqt_robot_steering" type="rqt_robot_steering" name="rqt_robot_steering"/></launch>

        这个launch文件基本就是大家想要的那种launch文件。它包含了wpb_stage_corridor.launch的嵌套、hector算法、rviz和rqt_robot_steering。其中arg比较有意义,它本身相当于全局变量,供其他param参考使用的。

        另外就是rviz里面的rvizconfig变量,它通过find找到corridor.rviz这个文件,最后被rviz这个node所使用。

4、wpb_navigation.launch

<launch><!-- We resume the logic in empty_world.launch, changing only the name of the world to be launched --><include file="$(find gazebo_ros)/launch/empty_world.launch"><arg name="world_name" value="$(find wpr_simulation)/worlds/robocup_home.world"/><arg name="paused" value="false"/><arg name="use_sim_time" value="true"/><arg name="gui" value="true"/><arg name="recording" value="false"/><arg name="debug" value="false"/></include><!-- Spawn the objects into Gazebo --><node name="bed" pkg="gazebo_ros" type="spawn_model" args="-file $(find wpr_simulation)/models/bed.model -x 5.0 -y -3.9 -z 0 -Y 3.14159 -urdf -model bed" /><node name="sofa" pkg="gazebo_ros" type="spawn_model" args="-file $(find wpr_simulation)/models/sofa.model -x -1.0 -y -3.9 -z 0 -Y 1.57 -urdf -model sofa" /><node name="tea_table" pkg="gazebo_ros" type="spawn_model" args="-file $(find wpr_simulation)/models/tea_table.model -x -2.1 -y -2.2 -z 0 -Y 1.57 -urdf -model tea_table" /><node name="bookshelft" pkg="gazebo_ros" type="spawn_model" args="-file $(find wpr_simulation)/models/bookshelft.model -x 2.0 -y -0.55 -z 0 -Y -1.57 -urdf -model bookshelft" /><node name="kitchen_table" pkg="gazebo_ros" type="spawn_model" args="-file $(find wpr_simulation)/models/table.model -x -3.5 -y 3.7 -z 0 -Y 1.57 -urdf -model kitchen_table" /> <node name="cupboard_0" pkg="gazebo_ros" type="spawn_model" args="-file $(find wpr_simulation)/models/cupboard.model -x -2.0 -y 0.7 -z 0 -Y 1.57 -urdf -model cupboard_0" /><node name="cupboard_1" pkg="gazebo_ros" type="spawn_model" args="-file $(find wpr_simulation)/models/cupboard.model -x -1.3 -y 3.7 -z 0 -Y -1.57 -urdf -model cupboard_1" /> <node name="dinning_table_0" pkg="gazebo_ros" type="spawn_model" args="-file $(find wpr_simulation)/models/table.model -x 1.5 -y 1.5 -z 0 -Y 1.57 -urdf -model dinning_table_0" /><node name="dinning_table_1" pkg="gazebo_ros" type="spawn_model" args="-file $(find wpr_simulation)/models/table.model -x 1.5 -y 2.0 -z 0 -Y 1.57 -urdf -model dinning_table_1" /><node name="dinning_table_2" pkg="gazebo_ros" type="spawn_model" args="-file $(find wpr_simulation)/models/table.model -x 2.7 -y 1.5 -z 0 -Y 1.57 -urdf -model dinning_table_2" /><node name="dinning_table_3" pkg="gazebo_ros" type="spawn_model" args="-file $(find wpr_simulation)/models/table.model -x 2.7 -y 2.0 -z 0 -Y 1.57 -urdf -model dinning_table_3" /><node name="chair_0" pkg="gazebo_ros" type="spawn_model" args="-file $(find wpr_simulation)/models/chair.model -x 1.5 -y 1.2 -z 0 -Y 1.57 -urdf -model chair_0" /><node name="chair_1" pkg="gazebo_ros" type="spawn_model" args="-file $(find wpr_simulation)/models/chair.model -x 1.5 -y 2.3 -z 0 -Y -1.57 -urdf -model chair_1" /><node name="chair_2" pkg="gazebo_ros" type="spawn_model" args="-file $(find wpr_simulation)/models/chair.model -x 2.7 -y 1.2 -z 0 -Y 1.57 -urdf -model chair_2" /><node name="chair_3" pkg="gazebo_ros" type="spawn_model" args="-file $(find wpr_simulation)/models/chair.model -x 2.7 -y 2.3 -z 0 -Y -1.57 -urdf -model chair_3" /><!-- Spawn a robot into Gazebo --><node name="spawn_urdf" pkg="gazebo_ros" type="spawn_model" args="-file $(find wpr_simulation)/models/wpb_home.model -urdf -x -6.0 -y -0.5 -model wpb_home" /><!-- Run the map server --><node name="map_server" pkg="map_server" type="map_server" args="$(find wpr_simulation)/maps/map.yaml"/><!--- Run AMCL --><include file="$(find wpb_home_tutorials)/nav_lidar/amcl_omni.launch" /><!--- Run move base --><node pkg="move_base" type="move_base" respawn="false" name="move_base"  output="screen"><rosparam file="$(find wpb_home_tutorials)/nav_lidar/costmap_common_params.yaml" command="load" ns="global_costmap" /><rosparam file="$(find wpb_home_tutorials)/nav_lidar/costmap_common_params.yaml" command="load" ns="local_costmap" /><rosparam file="$(find wpb_home_tutorials)/nav_lidar/local_costmap_params.yaml" command="load" /><rosparam file="$(find wpb_home_tutorials)/nav_lidar/global_costmap_params.yaml" command="load" /><rosparam file="$(find wpb_home_tutorials)/nav_lidar/local_planner_params.yaml" command="load" /><param name="base_global_planner" value="global_planner/GlobalPlanner" /> <param name="use_dijkstra" value="true"/><param name="base_local_planner" value="wpbh_local_planner/WpbhLocalPlanner" /><param name= "controller_frequency" value="10" type="double"/></node><!-- RViz and TF tree --><arg name="model" default="$(find wpb_home_bringup)/urdf/wpb_home.urdf"/><arg name="gui" default="false" /><arg name="rvizconfig" default="$(find wpr_simulation)/rviz/nav.rviz" /><param name="robot_description" command="$(find xacro)/xacro $(arg model)" /><param name="use_gui" value="$(arg gui)"/><node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher"/><node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" ><rosparam command="load" file="$(find wpb_home_bringup)/config/wpb_home.yaml" /></node><node name="rviz" pkg="rviz" type="rviz" args="-d $(arg rvizconfig)" required="true" /></launch>

        这个是目前为止最复杂的launch文件,不过好在有注释说明,还不算太难理解。从一开始的仿真环境说明gazebo,到后来的map_server、amcl、move_base、rviz和tf等节点工具,内容稍多了一点。这其中和之前不一样的,就是robot_state_publisher和joint_state_publisher两个节点,他们是和gazebo紧密配合一起使用的。

        另外场景搭建的时候,我们也发现环境model和机器人model一般是分开来的。前者用spawn_model,后者用spawn_urdf。毕竟,相比较简单的环境model,urdf还会多一个传感器的插件功能,这才是我们仿真robot所真正在意和关心的。

5、总结

        对于launch这类脚本的学习,个人建议直接看模板比较好一点,至少说先用起来。这样遇到问题再去找答案,或许效率更高一点。对于仿真环境部分的搭建部分,如果有兴趣可以看一看、学习下。兴趣不大的话,暂时掠过,或者直接复用别人搭建好的仿真环境,这都是可以的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/101952.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

shiro550复现环境搭建

前言 Shiro反序列化漏洞指的是Apache Shiro安全框架中的一个潜在漏洞&#xff0c;该漏洞可能导致攻击者能够通过精心构造的恶意序列化对象来执行任意代码或进行拒绝服务&#xff08;DoS&#xff09;攻击。 这种漏洞的根源是在Shiro的RememberMe功能中&#xff0c;当用户选择“…

C# 实体类转换的两种方式

以下提供两种方式&#xff0c;一种是序列化&#xff0c;一种是泛型反射&#xff1b; 实现功能&#xff1a; 两个实体类数据转换赋值 //学生类 private class Student {public string name { get; set; }public int age { get; set; }public string className { get; set;…

【Node.js】crypto 模块

crypto模块的目的是为了提供通用的加密和哈希算法。用纯JavaScript代码实现这些功能不是不可能&#xff0c;但速度会非常慢。 Nodejs用C/C实现这些算法后&#xff0c;通过cypto这个模块暴露为JavaScript接口&#xff0c;这样用起来方便&#xff0c;运行速度也快。 只要密钥发…

location对象详解

location对象详解_window.location.assign_边中之城的博客-CSDN博客

vuex的模块化和namespaced

这里主要是将store里面的index.js这个文件变得更加有条理性一点&#xff0c;使得整个代码看起来比较清晰 主要的变动在于count.vue,person.vue,index.js count.vue <template><div><h1>当前求和为&#xff1a;{{sum}}</h1><h3>当前求和放大10…

制造业单项冠军(国家级、广东省、深圳市)奖励政策及申报对比

制造业单项冠军的头衔含金量极高&#xff0c;是某一细分领域的“领头雁”。下面深科信对“制造业单项冠军”&#xff08;国家级、广东省级、深圳市级&#xff09;的认定标准、奖励政策进行梳理 。 2023年9月25日&#xff0c;工信部办公厅正式发布《关于开展2023年制造业单项冠军…

【TensorFlow2 之012】TF2.0 中的 TF 迁移学习

#012 TensorFlow 2.0 中的 TF 迁移学习 一、说明 在这篇文章中&#xff0c;我们将展示如何在不从头开始构建计算机视觉模型的情况下构建它。迁移学习背后的想法是&#xff0c;在大型数据集上训练的神经网络可以将其知识应用于以前从未见过的数据集。也就是说&#xff0c;为什么…

linux 安装mysql

1、下载mysql安装包 2、创建mysql文件夹 mkdir /usr/local/mysql 3、解压mysql安装包&#xff0c;并将解压出来的文件夹下面的内容全部移动到/usr/local/mysql下 解压 tar zxvf mysql-5.7.39-linux-glibc2.12-x86_64.tar.gz 移动 mv /usr/local/src/mysql-5.7.39-linux-gl…

postgres之pg_dump导出和导入

postgres使用有一段时间了&#xff0c;现记录一下一些常用的命令-导出导入&#xff0c;备以后查询&#xff1a; 1.指定表结构导出 pg_dump --host127.0.0.1 --port5432 --username[用户名] -t[表名1] -t [表名1] --schema-only postgres > F:\db.sql 2.指定表数据的导出…

Vue项目为页面添加水印效果

最近在做项目&#xff0c;有这样要求&#xff0c;需要在指定容器中添加水印&#xff0c;也可不设置容器&#xff0c;如果没有容器&#xff0c;则添加在整个页面中&#xff0c;即body&#xff0c;当接到这个需求的时候我第一想的方法就是用canvas来实现&#xff0c;话不多说搞起…

Unity设计模式——装饰模式

装饰模式&#xff08;Decorator&#xff09;&#xff0c;动态地给一个对象添加一些额外的职责&#xff0c;就增加功能来说&#xff0c;装饰模式比生成子类更为灵活。 Component类&#xff1a; abstract class Component : MonoBehaviour {public abstract void Operation(); …

华为认证 | HCIP-Datacom,这门认证正式发布新版本!

华为认证数通高级工程师HCIP-Datacom-Campus Network Planning and Deployment V1.5&#xff08;中文版&#xff09;自2023年9月28日起&#xff0c;正式在中国区发布。 01 发布概述 基于“平台生态”战略&#xff0c;围绕“云-管-端”协同的新ICT技术架构&#xff0c;华为公司…

互联网性能和可用性优化CDN和DNS

当涉及到互联网性能和可用性优化时&#xff0c;DNS&#xff08;Domain Name System&#xff09;和CDN&#xff08;Content Delivery Network&#xff09;是两个至关重要的元素。它们各自发挥着关键作用&#xff0c;以确保用户能够快速、可靠地访问网站和应用程序。在本文中&…

C++ 指向数组的指针

如果您对 C 指针的概念有所了解&#xff0c;那么就可以开始本章的学习。数组名是指向数组中第一个元素的常量指针。因此&#xff0c;在下面的声明中&#xff1a; double runoobAarray[50];runoobAarray 是一个指向 &runoobAarray[0] 的指针&#xff0c;即数组 runoobAarra…

Java 多线程编程

Java 多线程编程 目录 Java 多线程编程 一个线程的生命周 线程的优先级 创建一个线程 通过实现Runnable接口来创建线程 实例 通过继承Thread来创建线程 实例 Thread 方法 实例 线程的几个主要概念: 多线程的使用 Java给多线程编程提供了内置的支持。一个多线程程序包…

微信小程序项目如何用Hbuild启动,先让对方在微信开发平台将你的微信号添加成开发成员。

微信小程序项目如何用Hbuild启动&#xff0c;先让对方在微信开发平台将你的微信号添加成开发成员。然后在Hbuild官网下载&#xff0c;下载好后运行&#xff0c;点击文件导入项目&#xff0c;然后点击运行&#xff0c;模拟微信小程序&#xff0c;选择微信开发工具的地址&#xf…

【2023美团后端-8】删除字符串的方案,限制不能连续删

小美定义一个字符申是“美丽串”&#xff0c;当且仅当该字符串包含”mei”连续子串。例如”meimei”、“xiaomeichan"都是美丽串&#xff0c;现在小美拿到了一个字符串&#xff0c;她准备删除一些字符&#xff0c;但不能删除两个连续字符。小美希望最终字符串变成美丽串&a…

技巧:训练时Loss剧烈震荡原因汇总

输入数据有误 数据集太少 输入数据为经过标准化&#xff1a;没有经过正则化处理的数据可能存在异常点&#xff0c;或者数据的量纲不一致。可以采用min_max归一化或者z-score标准化 没有选择合理的数据增强没有经过合理的数据增强可能导致训练的时候网络学习的数据不是想要的最…

pyqt---子线程进行gui操作导致界面崩溃

在 PyQt&#xff08;或 Qt 通常&#xff09;中&#xff0c;您不能直接在子线程中执行与 GUI 相关的操作。这可能会导致应用程序崩溃或不可预测的行为。所有与 GUI 相关的操作都应该在主线程中执行。 如果您需要在子线程完成某些操作后显示一个消息框&#xff0c;可以使用 PyQt…

软件工程与计算总结(六)需求分析方法

本贴介绍需求分析方法&#xff0c;涉及到诸多实践性的东西&#xff0c;掌握各种图表的绘制是重中之重~ 一.需求分析基础 1.原因 需求获取中得到的信息仅仅解释了用户对软件系统的理解与期待&#xff0c;使用的是实际业务的表达方式&#xff0c;还不是开发者能够立即加以实现…