RViz writes to incorrect directory when starting using robot_startup
Background
I have an application that requires that I start several RViz windows in a headless ROS environment. The system is required to send image files to some locally networked dumb terminals which can barely but adequately show image files (.jpg). Therefore, I simply take screen snapshots of the RViz displays and send those. This works well, however, I need to run the RViz windows on startup.
Implementation
The ROS noetic system is running on Ubuntu 20.04. I used robotupstart to give me a working skeleton for a systemd service and then modified the core service file to allow displaymanager access
This is my working system.d service file called 'test.service' in /lib/systemd/system
[Unit]
Description="bringup test"
After=network.target
After=display_manager.service
Wants=display_manager.service
[Service]
Type=simple
Environment="XAUTHORITY=/run/user/1000/gdm/Xauthority"
Environment="DISPLAY=:0"
Environment="XDG_RUNTIME_DIR=/home/<my_username>/catkin_ws/tmp"
Environment="/home/<my_username>" # THIS IS THE SOLUTION SOUGHT BY THIS QUESTION
ExecStart=/usr/sbin/test-start
[Install]
WantedBy=multi-user.target
This almost works. journalctl -f -u test.service
lists an error:
Jun 06 21:10:22 aoede test-start[10209]: /opt/ros/noetic/lib/rviz/rviz: line 1: 10220 Aborted (core dumped) $0 $@
Jun 06 21:10:25 aoede dbus-daemon[10259]: [session uid=1000 pid=10257] AppArmor D-Bus mediation is enabled
Jun 06 21:10:28 aoede test-start[10237]: terminate called after throwing an instance of 'boost::filesystem::filesystem_error'
Jun 06 21:10:28 aoede test-start[10237]: what(): boost::filesystem::create_directory: Permission denied: "/.rviz"
Jun 06 21:10:28 aoede test-start[10218]: Aborted (core dumped)
It is trying to write to a directory /.rviz
. When I create this directory myself off the root directory with relaxed permissions it then works correctly and the RViz windows all start. This directory seems to be filled with persistence files for the RViz instances.
I have tried setting XDGRUNTIMEDIR as above but it had no effect. What environment variable should I set, or other way, so that RViz is looking in a more rational place? Also, would appreciate any recommendations on better practices than above.
Asked by James NT on 2021-06-08 00:18:26 UTC
Answers
This is set in the VisualizationFrame::initConfigs()
void VisualizationFrame::initConfigs()
{
home_dir_ = QDir::toNativeSeparators(QDir::homePath()).toStdString();
config_dir_ = (fs::path(home_dir_) / ".rviz").string();
persistent_settings_file_ = (fs::path(config_dir_) / "persistent_settings").string();
default_display_config_file_ = (fs::path(config_dir_) / "default." CONFIG_EXTENSION).string();
...
With the config_dir in this cas ending up as ".rviz" because home_dir is null. home_dir is derived from QDir::homePath() documented here: https://doc.qt.io/qt-5/qdir.html#homePath
This includes the helpful statement:
Under non-Windows operating systems the HOME environment variable is used if it exists, otherwise the path returned by the rootPath().
Which is the answer sought. Without HOME being set QDir::rootPath() will return "/". This environment variable is set after the service is started.
Added environment
Environment="HOME=/home/<my_username>"
to system.d service file
Fixed
Asked by James NT on 2021-06-09 06:20:14 UTC
Comments
I would've expected packages like robot_upstart (which also supports systemd
) to do this already.
Could you not use those?
Asked by gvdhoorn on 2021-06-09 07:40:43 UTC
I did use robot_upstart to create the systemd service files skeleton that I then expanded. The robot_upstart implementation I used (command line) failed with an RViz node because it could not get a graphics context. Hence the additional service entries.
This was my robot_upstart install request which provided the skeleton I used:
rosrun robot_upstart install --job test --user <my_username> --setup ~/catkin_ws/devel/setup.bash --rosdistro noetic --logdir ~/catkin_ws/.ros --provider systemd --symlink <my_package>/launch/test_start.launch
The systemd entries provided by this successfully started all nodes in my launch file except RViz's
Asked by James NT on 2021-06-10 05:53:34 UTC
Comments