ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

Python Node connection via network

asked 2021-04-23 05:55:22 -0500

Drallert gravatar image

Hi, I would like to publish/subscribe to a series of ROS topics that a specific machine is offering from another machine, being both in the same network. I have done this already using the rosserial_embeddedlinux library, which lets you specify an IP address during the node initialization, however I would also like to be able to do this in Python.

I can't seem to find the correct way to do this, as rospy.init_node does not allow to pass an IP address-like parameter, so I've started to wonder if this is even possible (it probably is, but you never know).

The piece of code I would like to replicate is something like this:

#include <ros.h>
 <...>
ros::NodeHandle nh;
 <...>
nh.initNode("127.0.0.1:11411");

This C++ code allows me to connect to a machine with the IP address specified in nh.initNode's first parameter, but as I already said I can't find the way to do this in Python. The argument list for rospy.init_node is as follows (taken from https://wiki.ros.org/rospy/Overview/I...):

rospy.init_node(name, anonymous=False, log_level=rospy.INFO, disable_signals=False)

Create a new node with the specified name. There are several optional keyword arguments that you may wish to set:

    anonymous=True

        The anonymous keyword argument is mainly used for nodes where you normally expect many of them to be running and don't care about their names (e.g. tools, GUIs). It adds a random number to the end of your node's name, to make it unique. Unique names are more important for nodes like drivers, where it is an error if more than one is running. If two nodes with the same name are detected on a ROS graph, the older node is shutdown. 

    log_level=rospy.INFO

        Set the default log level for publishing log messages to rosout. See Logging. 

    disable_signals=False

        By default, rospy registers signal handlers so that it can exit on Ctrl-C. In some code, you may wish to disable this, including:

            You're not calling init_node() from the Python Main thread. Python only allows signals to be registered from the Main thread.
            You're running rospy within Qt, wxPython or any other GUI toolkit that has its own exit handlers.
            You wish to have your own signal handlers by default.

Is there anyone that could help with this? Thanks a lot in advance.

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
1

answered 2021-04-24 02:54:46 -0500

gvdhoorn gravatar image

updated 2021-04-24 03:11:06 -0500

You seem to be comparing rosserial, which is a custom client library specifically targetting micro-controllers and similar resource constraint systems, with roscpp and rospy, which are full client libraries for ROS 1. rosserial on the one hand and roscpp and rospy on the other do not have feature-parity, nor have they been implemented in the same way.

One major difference is the fact that rosserial is not "stand-alone", but requires an "agent" or "bridge" on the ROS side. That's what the IP you pass to initNode(..) is: the address at which that agent node can be found.

The agent is a full ROS node (ie: using rospy or roscpp), and it proxies for the rosserial client. Without that agent (or server), rosserial clients cannot connect to a ROS system.

I would like to publish/subscribe to a series of ROS topics that a specific machine is offering from another machine, being both in the same network. I have done this already using the rosserial_embeddedlinux library,

I don't believe this does what you think it did.

By default, the rosbridge server will make all topics it can see available to the client, not just those for which publishing nodes run on the same machine (it should be possible to configure the server to relay only certain topics, but by default, it does not impose any such limits).

I can't seem to find the correct way to do this, as rospy.init_node does not allow to pass an IP address-like parameter, so I've started to wonder if this is even possible (it probably is, but you never know).

No, this is not supported (nor in roscpp), as the full client libraries do not implement such a communication pattern: full ROS 1 client libraries will, as part of their initialisation, contact the ROS Master, which then informs them of all registered nodes and topics, regardless of where the nodes which publish them are running (similar to a DNS server). To go even further: ROS allows for location transparency, which makes "where do nodes run?" a non-question.

Even though the Master has an a priori known IP address, you cannot really compare it to how rosserial works. For one thing, the Master is not involved in data exchange between nodes (it's not central broker). It's only role is to provide information on running nodes in a ROS graph.

I would like to publish/subscribe to a series of ROS topics that a specific machine is offering from another machine, being both in the same network.

this seems to be your real question. This can be done, even without rosserial. There are various ways to figure out which topics are published by which nodes, and at which IP addresses they are listening for connections. Note: there is no simple way to figure out which nodes run on which machine I believe. Multi-homed systems complicate this a bit.

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2021-04-23 05:55:22 -0500

Seen: 449 times

Last updated: Apr 24 '21