If you are not trying to run both an Ethernet and wifi network at the same time, under Ubuntu Linux, for use with Ros2 across multiple computers (e.g., my desktop Mac and my embedded AMD processor), then this article is not for you. Nothing to see here. Go about your business.
If your embedded robot computer is running Ros2 and is using only one network interface, typically the wifi, then launching your robot stack and then going to your desktop to run rviz or teleop_keyboard is a piece of cake. Do what it says in the docs, which is pretty much nothing special.
In my robot, Puck, my main embedded processor, an AMD 3700X is doing the bulk of the work and talks to my house network over wifi. But, and here’s the gotcha, I have two other computers that talk over ethernet to that AMD processor: an Nvidia processor for AI and a custom processor based on the Teensy 4.1 that acts as a sensor processor and system monitor.
For the computer to both talk to wifi and the ethernet, you need to set the “Make available to other users” option in the Details pane of the Wired Network panel.
Then you need to assign a static IP subdomain to devices using the ethernet. Here I say that everything connected to the ethernet bus must have an IP address in the 10.42.0.X subdomain. For example, my custom monitor talks on the IP address of 10.42.0.132 and the AMD processor has an ethernet address of 10.42.0.132 Ignore that the photo below erroneously shows and address of 10.42.0.0 instead of 10.42.0.132. This will set up routing tables automatically so embedded traffic between the 10.0 and 10.42 subdomains can talk to each other.
So far, this is all easy and you can probably find articles that tell you how to get this far. If you run the “ip address” command, you will see that my AMD processor has two network addresses: 10.0.0.48 which is the address when talking over the wlp38s0 wifi interface, and 10.42.0.0 when talking to the enp37s0 ethernet interface (that is wrong here, it should be set to 10.42.0.133, but that’s not important for this article).
As soon as you turn on both the ethernet and wifi interfaces, if you look at the route table, you will see something like this:
The important bit is the ‘link-local’ entry in the routing table. This says that all traffic not specifically directed to 10.0 or 10.42 is to be shuttled off to the enp37s0 device, which is my ethernet device. Now for the meat of this article.
When you start some ros2 node on your embedded Linux on the robot, it advertises itself via multicasting. And, by default, it does so via the link-local route. Which means that, as configured so far, only other ros2 nodes on the embedded AMD processor or devices connected to the ethernet channel of the AMD processor can see each other. The Nvidia and custom processor happily talk with the AMD processor. But my desktop processor, which is on my home's 10.0.0.X wifi subnet, cannot talk to the 10.42.0.X subnet (I won’t go into the magic you can use to slightly get around that limitation). More importantly, the ros2 nodes running on my desktop computer are going to look for multicast traffic on the 10.0.0.X subnet, and that’s not where the AMD processor is sending the multicast network.
So, until you do the right magic, the desktop computer cannot see any ros2 traffic from the AMD processor.
Being at the level of ignorance that I am, but being persistent, I spent many days trying to figure out why the two computers couldn’t talk to each other. If I turned off the ethernet interface on the AMD, everything worked fine. But when I turned the ethernet interface back on, the two computers couldn’t talk to each other via ros2. That clue led me into a maze of twisty little passages, all alike. I had hints that the DDS software used for ros2 networking was using multicast so nodes could talk to each other, but all my attempts to force multicast traffic to be routed through the wifi interface instead the ethernet interface failed.
If you know of magic that might have solved this, I’d love to hear about it.
Now for the magic that worked. If you come across this situation and this magic solves it for you, please send me artwork of Ben Franklin from the government mint, or at least buy me a donut some day.
You need to set the environment variable for CYCLONEDDS_URI. Well, assuming your using the default DDS for the ros2 Galactic distribution. So, here is the magic I have in a shell script that I run to set up my working environment on my embedded computer before I start using ros2. Note that the “wlp38s0” is the name of my wifi interface.