diff --git a/mujoco_ros2_control/src/mujoco_simulation.cpp b/mujoco_ros2_control/src/mujoco_simulation.cpp index fc3f058c..965853b2 100644 --- a/mujoco_ros2_control/src/mujoco_simulation.cpp +++ b/mujoco_ros2_control/src/mujoco_simulation.cpp @@ -20,6 +20,7 @@ #include "mujoco_ros2_control/mujoco_simulation.hpp" #include "array_safety.h" #include "mujoco_ros2_control/sim_display_text.hpp" +#include "mujoco_ros2_control_plugins/glfw_platform.hpp" #include #include @@ -555,6 +556,8 @@ bool MujocoSimulation::initialize(rclcpp::Node::SharedPtr node, const std::strin sim_speed_factor_ = sim_speed_factor; headless_ = headless; + mujoco_ros2_control_plugins::prefer_x11_without_wayland_display(); + if (sim_speed_factor_ > 0) { RCLCPP_INFO(get_logger(), "Running the simulation at %.2f percent speed", sim_speed_factor_ * 100.0); diff --git a/mujoco_ros2_control_plugins/include/mujoco_ros2_control_plugins/glfw_platform.hpp b/mujoco_ros2_control_plugins/include/mujoco_ros2_control_plugins/glfw_platform.hpp new file mode 100644 index 00000000..dd9f068d --- /dev/null +++ b/mujoco_ros2_control_plugins/include/mujoco_ros2_control_plugins/glfw_platform.hpp @@ -0,0 +1,42 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef MUJOCO_ROS2_CONTROL_PLUGINS__GLFW_PLATFORM_HPP_ +#define MUJOCO_ROS2_CONTROL_PLUGINS__GLFW_PLATFORM_HPP_ + +#include + +#include + +namespace mujoco_ros2_control_plugins +{ + +/** + * GLFW >= 3.4 built with both Wayland and X11 probes Wayland first unless XDG_SESSION_TYPE says otherwise. Without + * a Wayland compositor (e.g. inside Docker) libwayland prints "XDG_RUNTIME_DIR is invalid or not set" before GLFW + * falls back to X11. Skip the probe when no Wayland display is advertised. Must run before glfwInit(). + * + * Static so that each shared library calls the GLFW it links against; a statically linked GLFW has per-library state. + */ +static inline void prefer_x11_without_wayland_display() +{ +#if GLFW_VERSION_MAJOR > 3 || (GLFW_VERSION_MAJOR == 3 && GLFW_VERSION_MINOR >= 4) + if (std::getenv("WAYLAND_DISPLAY") == nullptr && glfwPlatformSupported(GLFW_PLATFORM_X11)) + { + glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_X11); + } +#endif +} + +} // namespace mujoco_ros2_control_plugins + +#endif // MUJOCO_ROS2_CONTROL_PLUGINS__GLFW_PLATFORM_HPP_ diff --git a/mujoco_ros2_control_plugins/src/camera_plugin.cpp b/mujoco_ros2_control_plugins/src/camera_plugin.cpp index 3a20e2f9..2e1f38da 100644 --- a/mujoco_ros2_control_plugins/src/camera_plugin.cpp +++ b/mujoco_ros2_control_plugins/src/camera_plugin.cpp @@ -19,6 +19,8 @@ #include "camera_plugin.hpp" +#include "mujoco_ros2_control_plugins/glfw_platform.hpp" + namespace mujoco_ros2_control_plugins { @@ -51,6 +53,7 @@ bool CameraPlugin::init(rclcpp::Node::SharedPtr node, const mjModel* model, mjDa // Start the rendering thread process // Try GLFW first, fall back to EGL for headless environments + prefer_x11_without_wayland_display(); if (glfw_init_fn()) { use_egl_ = false;