Switching from ROS2’s multicast default to unicast can be a bit tricky, especially if you’re testing. I came up with a way to get it working between to virtualbox virtual machine clones and wanted to share my strategy.
first update and upgrade your apt installation
Starting from a blank ubuntu server 22.04 vm:
sudo apt update && sudo apt full-upgrade -y
sudo apt install ubuntu-desktop-minimal
I also went through the work of removing the firefox snap and its dependencies
sudo apt purge firefox
sudo snap remove --purge firefox
sudo snap remove --purge snap-store
sudo snap remove --purge core20 lxd snapd
sudo snap remove --purge core20
sudo snap remove --purge lxd
sudo snap remove --purge core20
sudo snap remove --purge snapd
snap list
sudo apt remove --autoremove snapd
sudo nano /etc/apt/preferences.d/nosnap.pref
I took down my machine’s ip address
ip a
I did another full upgrade
sudo apt update && sudo apt full-upgrade -y
installed docker…(not necessary)
sudo apt install -y gcc make perl
sudo reboot now
./autorun.sh
sudo reboot now
sudo apt remove docker docker.io containerd runc
sudo apt remove docker*
sudo apt update
sudo apt install -y ca-certificates curl gnupg lsb-release
sudo mkdir -p /etc/apt/keyrings
curl -fsSL <https://download.docker.com/linux/ubuntu/gpg> | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] <https://download.docker.com/linux/ubuntu> $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# sudo apt install docker-compose
sudo service docker start
sudo docker run hello-world
sudo shutdown now
docker pull osrf/ros:galactic-desktop
docker pull osrf/ros:humble-desktop
sudo usermod -a -G docker $USER
sudo shutdown now
docker pull docker pull osrf/ros:humble-desktop
docker pull osrf/ros:humble-desktop
docker run -it --rm osrf/ros:humble-desktop ros2 run demo_nodes_cpp listener
docker run -it --rm osrf/ros:humble-desktop ros2 run demo_nodes_cpp talker
sudo shutdown now
installed ros2, adapting this tutorial and this tutorial for humble
sudo apt install software-properties-common
sudo add-apt-repository universe
sudo apt update && sudo apt install curl -y
sudo curl -sSL <https://raw.githubusercontent.com/ros/rosdistro/master/ros.key> -o /usr/share/keyrings/ros-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] <http://packages.ros.org/ros2/ubuntu> $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
sudo apt update && sudo apt upgrade -y
sudo apt install ros-humble-desktop ros-dev-tools
sudo apt-get install python3-rosdep
sudo apt update && sudo apt install -y \
build-essential \
cmake \
git \
python3-colcon-common-extensions \
python3-flake8 \
python3-pip \
python3-pytest-cov \
python3-rosdep \
python3-setuptools \
python3-vcstool \
wget
sudo rosdep init
rosdep update
I then configured my install, again adapting this tutorial for humble:
echo "export ROS_DOMAIN_ID=0" >> ~/.bashrc
echo "export ROS_LOCALHOST_ONLY=0" >> ~/.bashrc
echo "source /opt/ros/humble/setup.bash" >> .bashrc
and tested in two windows
ros2 run demo_nodes_cpp talker
in another window
ros2 run demo_nodes_cpp listener
I then installed cyclone dds, which is not the default for humble.
I then followed this tutorial, using a modified form of the virtualbox example.
sudo apt install ros-humble-rmw-cyclonedds-cpp
cat <<EOT >> ~/cyclonedds_pc.xml
<CycloneDDS>
<Domain>
<General>
<DontRoute>true</DontRoute>
<AllowMulticast>false</AllowMulticast>
<EnableMulticastLoopback>true</EnableMulticastLoopback>
</General>
<Discovery>
<ParticipantIndex>auto</ParticipantIndex>
<Peers>
<!-- <Peer Address="192.168.xxx.yyy"/>-->
<!-- <Peer Address="192.168.xxx.zzz"/>-->
</Peers>
</Discovery>
</Domain>
</CycloneDDS>
EOT
sudo mv ~/cyclonedds_pc.xml /etc/
echo "export CYCLONEDDS_URI=/etc/cyclonedds_pc.xml" >> ~/.bashrc
echo "export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp" >> ~/.bashrc
source ~/.bashrc
I modified the server’s netplan, according to this post, which helped eliminate getting an identical ip address
sudo nano /etc/netplan/00-installer-config.yaml
from:
# This is the network config written by 'subiquity'
network:
ethernets:
enp0s3:
dhcp4: true
version: 2
to
# This is the network config written by 'subiquity'
network:
ethernets:
enp0s3:
dhcp4: true
dhcp-identifier: mac
version: 2
This config can be modified further as needed, but since I was just getting a demo up and running, I didn’t need to define static ip’s
sudo netplan try
sudo netplan apply
Next, I shutdown the vm and made a linked clone of it
sudo shutdown now
I then started both the original and clone vms and checked my work:
vm 1:
ip a
vm2:
ip a
This should produce different ip addresses for interface enp0s3
I then modified /etc/cyclonedds_pc.xml on both machines, updating the two ip addresses noted above
I closed the terminal windows in each vm and opened new ones in each vm and ran:
vm1:
ros2 run demo_nodes_cpp talker
vm2:
ros2 run demo_nodes_cpp listener
It seems that if you change the cyclone config xml file, those changes will not be seen until terminal windows on both machines are re-opened, or better yet, all machines are rebooted. it seems once the computers are linked, ros retains a memory of what it has connected to in the past.
It also seems that it is sufficient for either one or the other xml file to reflect the other machine’s ip address, regardless of which one is publishing and which one is subscribing.
K I’m not sure if what I described is intended behavior