There are nodes that are very useful to start un boot, like for example when we autostart the power management nodes.
First you should create a Launch file for you project such that you are able to orchestrate everything. Check out this tutorial on how to do so in ROS2 humble.
Once you have your launch file, you will have to create a unit file. This file will be used by Systemd to start your nodes. The file msut be placed in /etc/systemd/system
. Please take into account that you will need super-user privileges to do so.
The name of the file is the name of your service, for the sake of the tutorial lets call it yourepicname.service
Here is an example of the file we used to autosatrt the Power Management node in the humanoid robot:
[Unit]
After=network-online.target
Description=ROS2 PIPM services
[Service]
User=pi
Group=pi
ExecStart=/bin/bash -c 'source /home/pi/ros2_arcoslab/install/setup.bash; ros2 launch ros2_mean_well_rpb_1600_driver ros2_pipm.launch.py;'
RemainAfterExit=no
Restart=on-failure
RestartSec=2s
[Install]
WantedBy=default.target
There are some important things that we can take from this file:
After
directive is used to tell systemd what should already be up in order for our node to work. In this case we are telling systemd to start our daemon until network is opperational.User
and Group
directives are very important. This tells systemd to execute the node as the user pi
. We should avoid executing ROS2 nodes as root.WantedBy
directive tells systemd that someone needs this daemon. If we do not include it, then systemd will no start it.We are sourcing the worksapce
setup.bash
file. This is to make sure that all ROS2 variables and libraries are loaded when we launch our project.
Finally you should enable your service:
sudo systemctl enable yourepicname.service
In the particular case of pipm (the raspberry pi that we use for power management) there was a problem that cause the topic to not be discoverable to the rest of the network. It was happening because there were two network interfaces eth0
and eth1
. eth1
is connected to a relay and boots up very quickly, eth0
is conencted to the switch of the humanoid robot and is the one used for communication.
The directive After=network-online.target
became true as soon as eth1
was up, so that started our nodes before eth0
was available. The solution is to force systemd to only care about eth0
.
To do so, you have to edit /lib/systemd/system/systemd-networkd-wait-online.service
.
Change:
ExecStart=/lib/systemd/systemd-networkd-wait-online
To
ExecStart=/lib/systemd/systemd-networkd-wait-online --interface=eth0
Then enable the service. THis will make sure that the directive After=network-online.target
becomes true until eth0
is up.
sudo systemctl enable systemd-networkd-wait-online.service