ROS分布式操作--launch文件启动多个机器上的节点

ROS分布式操作–launch文件启动多个机器上的节点

写在前面:当我们需要启动多个节点的时候,就会用到 l a n c h lanch lanch文件来批量启动,同时还能在 l a u n c h launch launch文件中设置和加载参数,避免了逐个启动节点的麻烦,但是当多个节点分布在不同的主机上的时候,还是需要逐个主机启动对应主机上的节点。其实 l a u n c h launch launch文件也提供了批量启动主机的功能,毕竟 R O S ROS ROS本身就是一个分布式系统,有这个功能也是不意外的。

关于 l a u n c h launch launch文件具体怎么使用,这里就不细说,主要记录一下今天使用 l a u n c h launch launch文件启动网络中多台主机中的节点的操作。

machine标签

l a u n c h launch launch文件的标签中有一个 m a c h i n e machine machine标签,起作用是标识同一网络下的主机,与之对应的,node标签中有一个 m a c h i n e machine machine属性,用于设置节点运行的主机。通过 m a c h i n e machine machine属性的设置,可以远程自动在其他主机上开启其 l a u n c h launch launch进程,并且让节点运行在指定主机上。ros官方文档中对于machine标签属性的描述,常用的几个如下:

  • name: 主机名,node标签指定主机的时候使用该名称
  • address: 设置主机的IP地址,可以使用IP地址、HosrName(即/etc/hosts中设置的ip地址映射)或者域名
  • env-loader: 用于指定远程主机上环境变量配置的shell脚本,脚本中必须设置有运行时需要的全部环境变量的配置,并且以最后一行exec "$@"结尾。这个属性有些复杂,配置起来要绕点路,后面详细说。
  • user: 在远程主机上要使用的用户名
  • password: 对应用户的登陆密码

这样就可以通过再node标签中指定machine标签来启动远程主机了

eg:

<launch>
  <!--这里env.bash文件的文件名是可以自己指定的-->
  <machine name="foo" address="foo-address" user="someone" env-loader="/home/user_name/path/env.bash">
    <env name="LUCKY_NUMBER" value="13" />
  </machine>
  <!--通过machine属性的指定,可以让talker节点运行在主机foo上-->
  <node machine="foo" name="footalker" pkg="test_ros" type="talker.py" />

</launch>

注意事项

如果不出意外的话,其实到这里已经结束了,上面的配置已经可以完成我们的目标,但是现实是残酷的,问题层出,总的来说花费了大半天的时间才解决。

问题1:运行roslaunch启动的时候出现错误,ssh连接不上

首先要说明的是,roslaunch远程启动这个功能,实际上就是借助ssh来实现的,不过它使用的ssh客户端又和我们常规使用的有所区别,加上ros会进行一些条件检查,稍有差池都会导致启动失败。

  • 最难解决的问题是启动最直接报错无法连接,日志提示原因是目标主机未能在known_hosts文件中查找到

    常用ssh的人应该都知道,ssh首次连接一台主机的时候就会将对方的xxxx加入到known_hosts文件中,出现这样的报错提醒就很奇怪了。其原因就是上述所言,ros所用的ssh客户端有猫腻了,它只能识别rsa算法生成的hostkey,所以之前使用ssh而保存的对于ros来说都是无效的。

在这里插入图片描述

解决思路也很简单,重新新生成就好了。具体做法是:

  1. 删除原来的known_hosts文件,rm ~/.ssh/known_hosts
  2. 重新用ssh连接一次目标主机,并指定HostKey的生成算法,ssh username@ip_address -oHostKeyAlgorithms=“ssh-rsa”
  3. 提示会添加hostKey时,输入yes并回车即可
  4. 此时会提示输入一些参数等,都不用管,直接一路回车就行了,连接上之后目的就达到了,此时可以推出ssh连接了。
  5. 此时再次运行roslaunch可以看到ssh连接可以成功创建了

在这里插入图片描述

  • 其次还有个小问题,和上述问题还有点关系。

    具体是这样,当前面的问题解决了,有时候会出现报错xxx主机无法ping通自己这种报错。其原因是因为machine标签中似乎用了hostname来指定address属性,ros在远程启动之前会检查网络的通畅情况,其中一项操作就是ping发起方主机和自身,而这项ping操作使用的地址参数便是address的值。

    这个时候,如果hosts文件中没有做好ip和hostname的映射的话,ros就没办法通过指定的hostname来找到自己的地址,这是会引发无法ping通自己的错误。

在这里插入图片描述

所以主机和从机的hosts文件都需要做好相应的映射,双方的/etc/hosts文件都应该追加两个语句:

master_ip master_hostname
slave_ip slave_hostname

问题2 :env-loader指定的bash脚本不存在(其实就是找不到)

连接成功后,找不到env-loader指定的bash脚本,报错说不存在

在这里插入图片描述

原本按照文档和教程的阐述,我们只要把自己写的shell脚本的完整路径给到env-loader属性即可,
在这里插入图片描述

但是经过实践发现这里只能填写/opt/ros/melodic/setup.bash,其他的值都会出现这个报错。

在这里插入图片描述

查了挺长时间的文档和社区,也没找到这个问题的原因,甚至很多其他成功的博主根本没有提到这个问题。找不到问题的原因解决起来就很麻烦了。为了不耽误时间,我只能绕过解决这个问题,转而用其他方案来解决这个问题了。

具体做法也简单,既然/opt/ros/melodic/setup.bash是可以合法使用的,那么我们将自己配置的shell脚本包含到其中就好了。打开/opt/ros/melodic/setup.bash,在其中最后添加一行:

# shell中source语句相当于C/C++中的include语句
source your_script_path

在这里插入图片描述

通过这种方式,间接执行了自定义的脚本对环境变量进行了设置,从而绕过了env-loader找不到文件的问题。

若有大佬读到这里知道这个问题的直接解决方案,还请评论区不吝赐教,多谢!

参考:http://answers.ros.org/question/244060/roslaunch-ssh-known_host-errors-cannot-launch-remote-nodes/?answer=244064#post-id-244064

https://blog.csdn.net/heroacool/article/details/75228749

  • 24
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值