
ROS : Some tips and tricks
December, 2022 Updated on January 21, 2023
Disclaimer: The below topics are relatable to ROS1. It might work in ROS2 also, but I haven't tried ROS2 yet, so not sure about the same.1. Nested File systems
One frustrating thing in ROS, it becomes slow either while launching the gazebo or running a navigation stack or custom nodes. It becomes even more frustrating when we repeatedly test that particular node. It happened to me constantly when I became an intermediate ROS user. When I started my internship, this reduced my work efficiency, where I had to build custom planner plugins and other stuff for the existing navigation stack. So, I started blaming my system configuration even though it looks like this below.
- Dell Inspiron 7591
- RAM: 16 GB
- GeForce GTX 1050 3 GB Max-Q
- 2TB hard drive where I run ubuntu os
- 512 GB SSD for windows
For one year, I thought the hard drive slowed down my system. So, I urged myself to bring another SSD for installation that cost me ₹ 3500, in which I had to re-install ubuntu, ROS and all of the libraries I had previously installed. But surprisingly, the problem persists. However, it did improve the boot time and run some applications like chrome faster than before, but, no improvement on the auto-completion side as well as launching ros nodes. I even tried using the preload package in both cases, but there was no considerable improvement. Also, I have looked for which system process is slowing down my pc using the systemd-analyze
like shown below.
$ systemd-analyze time
$ systemd-analyze blame
But, disabling unwanted systemd units had no effect at all.
So finally, I looked for causes of delay in completing the command when pressed In the gazebo, a common issue is that the simulation always starts with a shadowed scene like the one shown in the figure 1. It is commonly observed in non-Nvidia GPU pc. An easy solution is to disable the shadows in the gazebo by setting shadows false under the Scene in world tab on the panel (see figure 2). Another way to make this work is to set the shadows to 0 in the world file. But this setting only works sometimes; we may have to toggle the shadows from false-true-false. If your pc has an Nvidia graphics card, there is a workaround mentioned in this comment in GitHub. So, according to this, we need to enable Nvidia and use these lines in the file .bashrc. Clock synchronization is often a problem on a remote machine (robot) and systems with dual boots, which causes this clock-skew problem while building and compiling the packages making this build incomplete. To avoid this problem, use the command Possible ways to launch or execute the program files are crontab, startup applications and Systemd. Here, I am not going to discuss which is best for ROS. It depends on various factors and personal experience with these methods, and importantly, I didn't work with crontab, so I won't be discussing the same. Instead, let's start with Startup Applications, the gnome-session manager, where one can explicitly mention which program to execute. You can find this application in the menu (if you have not seen this in your system, install it using So to use this application for your requirements, you need to use the 'add' button, enter the command and some comments for bookkeeping, and reboot. I found this method extremely useful for starting GUI applications. The other best way I found helpful is Systemd. The discussion for auto launch in ROS discourse was beneficial Automatic .launch on OS startup and How do you launch your systems?. This video about Boot to ROS in 7 seconds at ROSCON about minimizing kernel for ROS-specific robots is a good start but takes work to follow. For getting started, the package called robot_systemd has a recipe to use the roslaunch file that can run your programs right after at system boot. Here in this post I will explain how I have used systemd services. Firstly, set up your launch file (see the example below) that runs your program. Use a shell script to run this launch file in your known folder. Then set up your .service file, which looks something like the one below. (all lines are self-explanatory). Remember that the .service file should be located at Then, reload the system configuration using If everything goes correct then you should see the relavant output. We often use the same program to run part of the entire project (the reasons could be anything). So, we use bookkeeping to save the commands in a text file (of course, this is the best method, and even I tend to follow it). The other way to make our commands easy to use are bash aliases. For example, in ROS, we need to use regularly Then I put it in .bash_aliases to use the command after sourcing the .bashrc file. Remember that these lines should be present in the .bashrc file; otherwise, this won't work. Hurray! You can just use compile being in any part of the directory.
and seeing where it took the time (Reminder: use $ set -x
set +x
to revert back). I found out that roslaunch-autocomplete (located in /opt/ros/$ROS_DISTRO/bin
) is the culprit (although it is not the sole reason), which uses a python script to search and display possible outputs below the command. So, when you press the tab-tab for auto-completion, it traverses through all of your directories starting from the beginning letter (if it is no letter, i.e., simply whitespace, it searches through all files within the package). If your ROS workspace looks something like the one below (aka nested folders),
I am sure this is the sole reason for slowing down launching the ros nodes, and auto-completion is the nested filesystem. The best method to tackle this issue is to keep your workspace with a few possible folders nested, or don't keep folders inside another folder and repeat. (The below file structure of folders helped me).
/catkin_ws
..../build
..../devel
..../src
......../package1
......../package2
......../package_parent_1
............/package_child_to_parent_1
................/child1_1
................/[some more]
............/package_child_2_to_parent_1
................/child_2_1
................/[some more]
......../package_parent_2
............/package_child_to_parent_2
................/child2_1_1
................/[some more]
............/package_child_to_parent_2
................/child2_1_2
................/[some more]
......../[some more]
........CMakeLists.txt
Unfortunately, we cannot improve or replace that python script for now, which must be done at the core level of ROS. But the easiest solution is to have packages that are not too nested, as shown above. This method helped me speed up the auto-completion issue and the launching ROS node and whatnot, compiling this extensive list of packages in my workspace. In summary, you don't have a nested filesystem in your ros workspace; instead, you can keep it as straightforward as possible./catkin_ws
..../build
..../devel
..../src
......../package1
......../package2
......../package_parent_1
............/child1_1
............/child1_2
............/[some more]
......../package_parent_2
............/child2_1
............/child2_2
............/[some more]
......../[some more]
........CMakeLists.txt
Reference
2. Gazebo and black shadows
<scene>
<ambient>0.4 0.4 0.4 1</ambient>
<background>0.7 0.7 0.7 1</background>
<shadows>0</shadows>
</scene>
$ sudo prime-select on-demand
Warning: For some reasons the above two lines are not working to make gazebo run in my machine. I will update this blog, if I find out what causing this problem.
# activate offload rendering for OpenGL applications
export __NV_PRIME_RENDER_OFFLOAD=1
export __GLX_VENDOR_LIBRARY_NAME=nvidia
3. Clock Skew Problem
touch *
in the folder that shows this error to change the file timestamps. Reference
4. Auto launch files at startup
sudo apt-get install gnome-startup-applications
). After booting, it runs the commands that you are running the program on a terminal session.<?xml version="1.0"?>
<launch>
<!-- map -->
<arg name="map_file" default"=""$(find husky_nav)/maps/plant_17_09_edited.yaml" />
<node name="map_server" pkg="map_server" type="map_server" args="$(arg map_file)"/>
<!-- amcl -->
<include file="$(find husky_nav)/launch/amcl.launch"/>
<!-- move base -->
<include file="$(find husky_nav)/launch/move_base.launch"/>
<!-- rviz -->
<node name="husky_rviz" pkg="rviz" type="rviz" args="-d $(find husky_nav)/config/move_base_robot.rviz"/>
</launch>
#!/bin/bash
export ROS_HOME=/home/shravista/logs
source /home/shravista/catkin_ws/devel/setup.sh
roslaunch husky_nav stack.launch
/lib/systemd/system
; to do the same, you must edit the file with root permissions.[Unit]
Description=Name_of_the_service
Documentation="Some reference-work to know about this file Here"
After=network-online.target # Add if this service has depend another service which needs to start right after that dependency
Wants=network-online.target
AssertPathExists=/opt/ros
[Service]
Type=simple
SyslogIdentifier=ros_%I
TasksMax=infinity
KillSignal=SIGINT
Environment=ROS_PORT=11311
Environment=ROS_DISTRO=noetic
EnvironmentFile=-/etc/ros/environment
EnvironmentFile=-%h/.ros/environment
# Remember only you can prevent vendor lock
ExecStartPre=/bin/bash -c ' \
if [ -x /bin/netcat ]; then \
for i in {1..10}; do \
sleep 0.2; \
! netcat -z localhost $$ROS_PORT || break; \
done; \
else \
sleep 1; \
fi \
'
ExecStart=/home/shravista/Desktop/auto_launch/stack.bash #files need to be executable
Restart=on-failure
[Install]
WantedBy=multi-user.target
daemon-reload
, followed by enabling and starting your .service file. Now you can check the status of the systemctl service and whether it is running without any issues. Any program, launch file or shell script errors can cause the system to fail. So, make sure that your script file runs correctly. If you don't want to use this service, you can also disable it and delete the file if required.# reload system configuration. do this whenever you change the .service file
sudo systemctl daemon-reload
# enable the .service
sudo systemctl enable stack.service
# start the .service
sudo systemctl start stack.service
# status of your .service
sudo systemctl status stack.service
# if code failed and error is only in the program and modified acordingly then the following command do help
sudo systemctl restart stack.service
5. Bash Aliases
catkin_make
. It becomes irritating when we constantly change the path and repeat it. So one easy-to-go method I have been using is bash aliases, where I turn running this catkin_make at the start of the catkin_ws directory to anywhere with this simple script.alias compile="/home/shravista/catkin_ws/compile.sh"
if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi
Disclaimer : If you feel there is room for improvement in this article and mistakes in delivering the post (grammatical, concept, or technical errors). Please report them to me. I will take the necessary actions at the earliest.