上一节 :奥特学园ROS笔记--3(122-143节)_echo_gou的博客-CSDN博客
目录
144节
如何关联不同的功能包,繁多的ROS节点应该如何启动?功能包、节点、话题、参数重名时应该如何处理?不同主机上的节点如何通信?
本章主要内容介绍在ROS中上述问题的解决策略(见本章目录),预期达成学习目标也与上述问题对应:
-
掌握元功能包使用语法;
-
掌握launch文件的使用语法;
-
理解什么是ROS工作空间覆盖,以及存在什么安全隐患;
-
掌握节点名称重名时的处理方式;
-
掌握话题名称重名时的处理方式;
-
掌握参数名称重名时的处理方式;
-
能够实现ROS分布式通信。
145、146节 元功能包
在ROS中,提供了一种方式可以将不同的功能包打包成一个功能包,当安装某个功能模块时,直接调用打包后的功能包即可,该包又称之为元功能包(metapackage)。
概念:MetaPackage是Linux的一个文件管理系统的概念。是ROS中的一个虚包,里面没有实质性的内容,但是它依赖了其他的软件包,通过这种方法可以把其他包组合起来,我们可以认为它是一本书的目录索引,告诉我们这个包集合中有哪些子包,并且该去哪里下载。
(146节)实现:
首先新建一个功能包,创建的时候不用填写依赖,因为是一个虚包。
然后修改package.xml(52 53 54 60行):
修改CMakeLists(删除注释,只保留前三行,并且添加第四行):
这样元功能包就创建成功了。
148-155节 launch文件标签
具体查看以下:
4.2 ROS节点管理launch文件 · Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程
<node **** />
和
<node ****>
</node>
是一样的,后者可以在两行中间使用子标签。
148节:<launch>
<launch>
标签是所有 launch 文件的根标签,充当其他标签的容器
1.属性
-
deprecated = "弃用声明"
告知用户当前 launch 文件已经弃用
149节:<node>启动节点
roslaunch 命令不能保证按照 node 的声明顺序来启动节点(节点的启动是多进程的)
150节:<include>:用于重复使用之前编写的xml文件而不需要复制
这里就复用了之前的start_turtle.launch
151节:<remap>用于话题重命名,相当实用
其为 <node>下的子标签
152节:<param>
<param>
标签主要用于在参数服务器上设置参数。参数源可以在标签中通过 value 指定,也可以通过外部文件加载。当在<node>
标签中时,相当于私有命名空间此时会加上相应的前缀如下图3。
param_B前面就有一个前缀(私有命名空间),因为图二中param是放在node中的。
153节:<rosparam>使用的时候是围绕者yaml文件来使用的(导出操作并不会用特别多)
<rosparam>
标签可以从 YAML 文件导入参数,或将参数导出到 YAML 文件,也可以用来删除参数,<rosparam>
标签在<node>
标签中时被视为私有。
下图1为创建的yaml文件
执行上图中导出后生成文件:
(了解)但是这样可能会出现一个问题: 参数服务器中的参数并没有完全导出到这个文件中。这是因为在导出参数之前,往参数服务器中设置参数的这一个步骤可能还没有完成,从而导致导出的参数不完整。这里解决办法是从新建立一个.launch文件,在前一个launch文件执行完之后再去执行新建的launch文件。
154节:<group>
<group>
标签可以对节点分组,具有 ns 属性,可以让节点归属某个命名空间
这里如果不实用group来进行区分命名空间,那么是不允许出现两个重名为my_turtle节点的。
155节:<arg>
标签是用于动态传参,类似于函数的参数,可以增强launch文件的灵活性
可以批量的对参数的值进行修改(上图),同时也可以动态的在命令行执行launch文件的时候对其进行赋值(下图)。
------------重名问题------------
156节 工作空间覆盖
虽然特定工作空间内的功能包不能重名,但是自定义工作空间的功能包与内置的功能包可以重名或者不同的自定义的工作空间中也可以出现重名的功能包,那么调用该名称功能包时,会调用哪一个呢?比如:自定义工作空间A存在功能包 turtlesim,自定义工作空间B也存在功能包 turtlesim,当然系统内置空间也存在turtlesim,如果调用turtlesim包,会调用哪个工作空间中的呢?
这里demo3_ws就是一个工作区间
现在有两个工作空间demo01_ws和demo02_ws两个工作空间,并且两个工作空间下和ros自己三者都有turtelsim这个文件,然后我们在主目录下打开.bashrc文件(用于配置环境变量,配置这个之后就不用每次手动source了),然后在文件末尾加上下图中两行(这两行分别是每个工作空间里面的setup.bash文件的位置)。
然后打开命令行,输入rosrun turtlesim +tab键,就会发现我们补齐的是demo02中的文件。
结论就是如果有重名,我们就会优先使用后刷新的那个环境里面的文件。
158节 节点名称重名-0
在ROS的网络拓扑中,是不可以出现重名的节点的,因为假设可以重名存在,那么调用时会产生混淆,不可以启动重名节点或者同一个节点启动多次,在ROS中如果启动重名节点的话,之前已经存在的节点会被直接关闭。
159节 节点名称重名-1
方式一:启动的时候加入__ns:=xxx
方式二:进行重命名__name:=xxx
160节 节点名称重名-2 launch文件
方式一:名称重映射,name改为了t1
方式二:命名空间,命名空间改为了ergouzi
多次启动一个节点后的节点列表
161节 节点名称重名-3 编码方式实现
(第三章了解过)
c++:
重映射
ros::init(argc,argv,"zhangsan",ros::init_options::AnonymousName);
命名空间
std::map<std::string, std::string> map;
map["__ns"] = "xxxx";
ros::init(map,"wangqiang");
python:
名称别名设置
核心代码:rospy.init_node("lisi",anonymous=True)
执行
会在节点名称后缀时间戳。
162节 ros话题重名-0
在 ROS 中节点终端,不同的节点之间通信都依赖于话题,话题名称也可能出现重复的情况,这种情况下,系统虽然不会抛出异常,但是可能导致订阅的消息非预期的,从而导致节点运行异常。这种情况下需要将两个节点的话题名称由相同修改为不同。
又或者,两个节点是可以通信的,两个节点之间使用了相同的消息类型,但是由于,话题名称不同,导致通信失败。这种情况下需要将两个节点的话题名称由不同修改为相同。
以下例子我们的目的是使用自带的键盘控制节点来对小乌龟进行操作,自带的节点话题是/cmd_vel,乌龟之前一直使用的是/turtlr/cmd_vel节点
163节 ros话题重名-1
话题重命名,下图末尾那一句
164节 ros话题重名-2 launch文件方式
这里只演示将乌龟的话题设置为键盘控制一致
165节 ros话题重名-2 编码方式
ros中可以设置三种不同种类的话题:全局,相对,私有,通过这样的分类可以一定程度上避免重名的问题。
166-168节 ros话题重名-3 c++编码实现
演示准备:
1.初始化节点设置一个节点名称
ros::init(argc,argv,"hello")
2.设置不同类型的话题
3.启动节点时,传递一个 __ns:= xxx
4.节点启动后,使用 rostopic 查看话题信息
全局:
以斜杠开头(也可以设置自己的命名空间),这种情况下和节点(命名空间和名称)没有关系。
代码为创建发布者对象同时创建话题为chatter
这里可以发现,图三的chatter话题名是全局的而不是xxx命名空间下的,因为我们代码中使用的是“/”开头的命名方式,这样就是全局话题。
我们也可以使用自己的命名空间:
此时可以发现(/yyy/chatter)通过代码中添加/yyy来设置自己的命名空间就把之前的/xxx覆盖掉了。
相对:
非斜杠开头
可以发现上图三chatter前面添加了xxx,因为图二中运行的时候添加了namespace,此时就和节点的命名空间看齐。
同时也可以继续累加命名空间(此处加了yyy):
这样就在xxx后面再加上一层yyy的命名空间
私有:
需要创建特定的nodehandle
这样就变成私有的了 ,即chatter编程了hello这个node的私有话题
也可以添加命名空间:
注:全局的优先级更高 (这里书写了私有要用的nodehandle,但是加了/,全局优先级最高,所以还是全局话题)
169节 ros话题重名-3 python编码实现
和c++基本思路等同
170节 ros参数重名-0
关于参数重名的处理,没有重映射实现,为了尽量的避免参数重名,都是使用为参数名添加前缀的方式,实现类似于话题名称,有全局、相对、和私有三种类型之分。
- 全局(参数名称直接参考ROS系统,与节点命名空间平级)
- 相对(参数名称参考的是节点的命名空间,与节点名称平级)
- 私有(参数名称参考节点名称,是节点名称的子级)
设置参数的方式也有三种:
rosrun 命令 171节
launch 文件 172节
编码实现 173节
171节 ros参数重名-1 rosrun命令行方式
这是一种私有的参数
172节 ros参数重名-2 launch文件方式
在4.2节有提到过
173节ros参数重名-3 c++编码方式
使用ros::param
使用nodehandle:
174节ros参数重名-3 python编码方式
175-178节 分布式通信(没看)
ROS是一个分布式计算环境。一个运行中的ROS系统可以包含分布在多台计算机上多个节点。根据系统的配置方式,任何节点可能随时需要与任何其他节点进行通信。
因此,ROS对网络配置有某些要求:
-
所有端口上的所有机器之间必须有完整的双向连接。
-
每台计算机必须通过所有其他计算机都可以解析的名称来公告自己。