Specifying ports to be used by ROS1 node
Objective
I want to use ROS on Docker on macOS as the slave node and connect to the ROS Master in the remote Ubuntu machine.
Problem
When the node running in the macOS publishes the topics, I can see the topics from rostopic list
, but I can’t receive the topic itself. (Nothing show up in rostopic echo topic
executes on Ubuntu machine.)
Why?
Docker container needs to open(expose) the ports used by the ROS nodes by using -p
option when creating the docker container. However, for default settings, ROS node randomly pickup free ports when launching the node. Therefore, I don’t know which port to open when I create the container. (If --net=host
option is working properly on the docker on the mac OS, this problem will not occur.)
ROS node registered itself to the ROS master. This registration process works as long as the ROS master’s port is properly open since the node only has access to ROS master. However, when the listener node subscribes to the topic, the listener node and publisher node start communicating directly. At this time, the publisher node’s port must be open. This is why rostopic list
shows the topics but rostopic echo
not working.
(This picture is not accurate. The nodes also using XML/RPC when start communicating directly. Detail(Japanese): http://ysuga.net/?p=145)
Solution
Step 1
Expose 2 ports(if using 1 node in the container) when creating the docker container. (e.g. docker run -p 45100:45100 -p 45101:45101 ~~~~
)
Step 2
In the docker container, set ROS_IP
(or ROS_HOSTNAME
) to the IP address of the macOS machine and ROS_MASTER_URI
to the Ubuntu machine.
E.g.
export ROS_IP=192.168.10.101
export ROS_MASTER_URI=http://192.168.10.102:11311
Step 3
Specifying the ports to be used by the node when initializing the node.
The document says init_node
takes xmlrpc_port
and tcpros_port
.(http://docs.ros.org/jade/api/rospy/html/rospy.client-module.html)
Example of publisher node in Python.
import rospy
from std_msgs.msg import Stringrospy.init_node("test_node",xmlrpc_port=45100, tcpros_port=45101)
pub = rospy.Publisher("test_pub", String, queue_size=1)
msg = String()
msg.data = "hello world"r = rospy.Rate(10)
while not rospy.is_shutdown():
pub.publish(msg)