ROS的一个典型应用场景是:在机器人上安装一台笔记本或单板机,然后在桌面计算机上监视或控制机器人,这时就需要在机器人与桌面计算机之间进行通信。ROS使得多台机器观察同一套话题、服务和参数变得相当容易。
1. 使用 chrony 进行时间同步
ROS网络中的很多消息都带有时间戳,机器之间的时间同步往往很非常关键。一种使计算机保持同步状态的简单方法是在桌面计算机和机器人上同时安装 chrony
数据包。该数据包会保持计算机上的时钟与互联网服务器上的时钟一致,从而使得每台计算机的时间都同步。
安装 chrony
:
$ sudo apt install chrony
安装完成之后,chrony守护进程会自动启动并且开始让计算机与数台互联网服务器直接同步时间。
2. 使用 Zeroconf 进行 ROS 联网
Ubuntu 支持 Zeroconf
技术,允许同一子网下的不同设备通过本地主机名而不是 IP 地址来连接彼此。
使用 hostname
命令来获取所使用设备的短名称,该命令会输出你在 Ubuntu 初始化设置时设置的主机名称。
$ hostname
my_desktop
假设桌面计算机的名称为 my_desktop
,机器人的名称为 my_robot
。则对应的 Zeroconf
名称分别为 my_desktop.local
和 my_robot.local
。
3. 测试连通性
使用ping
命令来确保两台电脑之间基本的连通性。
(1)在桌面计算机上 ping 机器人
$ ping my_robot.local
PING my_robot.local (192.168.1.7) 56(84) bytes of data.
64 bytes from my_robot (192.168.1.7): icmp_seq=1 ttl=64 time=9.06 ms
64 bytes from my_robot (192.168.1.7): icmp_seq=2 ttl=64 time=5.48 ms
64 bytes from my_robot (192.168.1.7): icmp_seq=3 ttl=64 time=1.73 ms
64 bytes from my_robot (192.168.1.7): icmp_seq=4 ttl=64 time=1.77 ms
64 bytes from my_robot (192.168.1.7): icmp_seq=5 ttl=64 time=5.20 ms
64 bytes from my_robot (192.168.1.7): icmp_seq=6 ttl=64 time=4.05 ms
64 bytes from my_robot (192.168.1.7): icmp_seq=7 ttl=64 time=1.55 ms
64 bytes from my_robot (192.168.1.7): icmp_seq=8 ttl=64 time=1.56 ms
64 bytes from my_robot (192.168.1.7): icmp_seq=9 ttl=64 time=5.72 ms
^C
--- my_robot.local ping statistics ---
9 packets transmitted, 9 received, 0% packet loss, time 8011ms
rtt min/avg/max/mdev = 1.552/4.017/9.064/2.455 ms
使用Ctrl+C
命令来终止测试过程。
通常来说,得到的结果应该是0%的丢包率和 5ms 以下的平均延时。
(2)在机器人上 ping 桌面计算机
$ ping my_desktop.local
由于机器人上搭载的计算机往往没有键盘和显示器,可以在桌面计算机上使用
ssh
登录到机器人,然后进行操作。使用以下命令:
$ ssh my_robot.local
4. 设置环境变量
在任何 ROS 网络中,一台设备会被指定为 ROS 主机,它将独自运行 roscore
进程。其他设备必须配置 ROS_MASTER_URI
环境变量来指向 ROS 主机。
假设将机器人作为 ROS 主机,
- 在机器人搭载的计算机上
将它的ROS_HOSTNAME
设置成它的Zeroconf
名,
$ export ROS_HOSTNAME = my_robot.local
然后运行 roscore
进程:
$ roscore
- 在桌面计算机上
将它的ROS_HOSTNAME
设置成它的Zeroconf
名,
$ export ROS_HOSTNAME = my_desktop.local
然后配置ROS_MASTER_URI
环境变量来指向机器人的Zeroconf URI
:
$ export ROS_MASTER_URI = http://my_robot.local:11311
这时,在桌面计算机上也可以看见/rosout
和rosout_agg
话题:
$ rostopic list
/rosout
/rosout_agg
5. 在两台设备上分别运行 ROS 节点
(1)在机器人上(通过 ssh
命令)
运行 turtlesim_node
节点
$ rosrun turtlesim turtlesim_node
[ INFO] [1592031675.400280371]: Starting turtlesim with node name /turtlesim
(2)在桌面计算机上
运行turtle_teleop_key
节点,
$ rosrun turtlesim turtle_teleop_key
Reading from keyboard
---------------------------
Use arrow keys to move the turtle. 'q' to quit.
此时,可以在桌面计算机上控制机器人上小乌龟的运动
后记
使用上述方法进行不同计算机之间的 ROS 通信,有时可行,有时又可不行(roscore
无法运行,会报错"unable to contact my own server ..."
),具体原因不明。
更为可靠的方法
与之前的方法相比,该方法的唯一区别在于:直接使用计算机的 ip 地址,而不是使用 Zeroconf
名称。
具体如下:
- 对于每台计算机,设置其
ROS_HOSTNAME
为它的 ip 地址,即
$ export ROS_HOSTNAME=xxx.xxx.xxx.xxx
- 对于从机(不运行
roscore
进程的计算机),将它的ROS_MASTER_URI
指向主机(运行roscore
进程的计算机),即
$ export ROS_MASTER_URI=http://xxx.xxx.xxx.xxx:11311
联网的不同计算机应处于同一个局域网内,也就是说它们的 ip 地址只有最后一个字段是不一样的。
参考
- 《ROS 入门实例》