From f5aa87eba791890ca14fdd5ed8ec4f60315f644a Mon Sep 17 00:00:00 2001 From: Crola1702 Date: Sun, 2 Nov 2025 06:32:00 +0000 Subject: [PATCH 1/4] Allow loadDisplayConfig to load yaml config strings Signed-off-by: Crola1702 --- .../rviz_common/visualization_frame.hpp | 2 +- .../src/rviz_common/visualization_frame.cpp | 21 ++++++++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/rviz_common/include/rviz_common/visualization_frame.hpp b/rviz_common/include/rviz_common/visualization_frame.hpp index 151bf346b..ab8102be8 100644 --- a/rviz_common/include/rviz_common/visualization_frame.hpp +++ b/rviz_common/include/rviz_common/visualization_frame.hpp @@ -177,7 +177,7 @@ class RVIZ_COMMON_PUBLIC VisualizationFrame : public QMainWindow, public WindowM * \param path The full path of the config file to load from. */ void - loadDisplayConfig(const QString & path); + loadDisplayConfig(const QString & config_string); // TODO(wjwwood): consider changing this function to raise an exception // when there is a failure, rather than the getErrorMessage() diff --git a/rviz_common/src/rviz_common/visualization_frame.cpp b/rviz_common/src/rviz_common/visualization_frame.cpp index 937d19b5b..8d603d18e 100644 --- a/rviz_common/src/rviz_common/visualization_frame.cpp +++ b/rviz_common/src/rviz_common/visualization_frame.cpp @@ -670,14 +670,16 @@ void VisualizationFrame::markRecentConfig(const std::string & path) updateRecentConfigMenu(); } -void VisualizationFrame::loadDisplayConfig(const QString & qpath) +void VisualizationFrame::loadDisplayConfig(const QString & config_string) { - std::string path = qpath.toStdString(); - QFileInfo path_info(qpath); + std::string path = config_string.toStdString(); + QFileInfo path_info(config_string); std::string actual_load_path = path; - if (!path_info.exists() || path_info.isDir()) { + bool is_loadable_path = (path_info.exists() && !path_info.isDir()); + if (!is_loadable_path) { actual_load_path = package_path_ + "/default.rviz"; - if (!QFile(QString::fromStdString(actual_load_path)).exists()) { + is_loadable_path = QFile(QString::fromStdString(actual_load_path)).exists(); + if (!is_loadable_path) { RVIZ_COMMON_LOG_ERROR_STREAM( "Default display config '" << actual_load_path.c_str() << "' not found. RViz will be very empty at first."); @@ -705,7 +707,12 @@ void VisualizationFrame::loadDisplayConfig(const QString & qpath) YamlConfigReader reader; Config config; + if (is_loadable_path) { reader.readFile(config, QString::fromStdString(actual_load_path)); + } else { // Treat as yaml string content + reader.readString(config, config_string); + } + if (!reader.error()) { try { load(config); @@ -714,11 +721,11 @@ void VisualizationFrame::loadDisplayConfig(const QString & qpath) } } + if (is_loadable_path) { markRecentConfig(path); - setDisplayConfigFile(path); - last_config_dir_ = path_info.absolutePath().toStdString(); + } post_load_timer_->start(1000); } From 0f77886fcf443c22aa4fad2b82834b4cac602b45 Mon Sep 17 00:00:00 2001 From: Crola1702 Date: Sun, 2 Nov 2025 06:33:36 +0000 Subject: [PATCH 2/4] Add LoadConfig service to rviz node Signed-off-by: Crola1702 --- .../rviz_common/visualization_frame.hpp | 10 +++++++ .../src/rviz_common/visualization_frame.cpp | 30 ++++++++++++++++--- rviz_resource_interfaces/CMakeLists.txt | 1 + rviz_resource_interfaces/srv/LoadConfig.srv | 4 +++ 4 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 rviz_resource_interfaces/srv/LoadConfig.srv diff --git a/rviz_common/include/rviz_common/visualization_frame.hpp b/rviz_common/include/rviz_common/visualization_frame.hpp index ab8102be8..c162802f1 100644 --- a/rviz_common/include/rviz_common/visualization_frame.hpp +++ b/rviz_common/include/rviz_common/visualization_frame.hpp @@ -42,6 +42,8 @@ #include // NOLINT: cpplint is unable to handle the include order here #include // NOLINT: cpplint is unable to handle the include order here #include // NOLINT: cpplint is unable to handle the include order here +#include +#include #include "rviz_common/config.hpp" #include "rviz_rendering/render_window.hpp" @@ -83,6 +85,7 @@ class WidgetGeometryChangeDetector; */ class RVIZ_COMMON_PUBLIC VisualizationFrame : public QMainWindow, public WindowManagerInterface { + using LoadConfig = rviz_resource_interfaces::srv::LoadConfig; Q_OBJECT public: @@ -172,6 +175,13 @@ class RVIZ_COMMON_PUBLIC VisualizationFrame : public QMainWindow, public WindowM void savePersistentSettings(); + rclcpp::Service::SharedPtr load_config_service_; + + void + loadDisplayConfigService( + const std::shared_ptr request, + std::shared_ptr response); + /// Load display settings from the given file. /** * \param path The full path of the config file to load from. diff --git a/rviz_common/src/rviz_common/visualization_frame.cpp b/rviz_common/src/rviz_common/visualization_frame.cpp index 8d603d18e..c5191ca73 100644 --- a/rviz_common/src/rviz_common/visualization_frame.cpp +++ b/rviz_common/src/rviz_common/visualization_frame.cpp @@ -61,6 +61,8 @@ #include // NOLINT cpplint cannot handle include order here #include // NOLINT cpplint cannot handle include order here #include // NOLINT cpplint cannot handle include order here +#include +#include #include "rclcpp/clock.hpp" #include "tf2_ros/buffer.hpp" @@ -351,6 +353,14 @@ void VisualizationFrame::initialize( loadDisplayConfig(QString::fromStdString(default_display_config_file_)); } + auto node_abstraction = rviz_ros_node.lock(); + auto node = node_abstraction->get_raw_node(); + load_config_service_ = node->create_service( + node_abstraction->get_node_name() + "/load_config", + std::bind( + &VisualizationFrame::loadDisplayConfigService, this, + std::placeholders::_1, std::placeholders::_2)); + // Periodically process events for the splash screen. QCoreApplication::processEvents(); @@ -670,6 +680,18 @@ void VisualizationFrame::markRecentConfig(const std::string & path) updateRecentConfigMenu(); } +void VisualizationFrame::loadDisplayConfigService( + const std::shared_ptr request, + std::shared_ptr response) +{ + RVIZ_COMMON_LOG_INFO_STREAM( + "Requested loadConfig" << request->config_string.c_str() + ); + loadDisplayConfig(QString::fromStdString(request->config_string)); + response->success = true; + response->message = "Loaded display config."; +} + void VisualizationFrame::loadDisplayConfig(const QString & config_string) { std::string path = config_string.toStdString(); @@ -708,7 +730,7 @@ void VisualizationFrame::loadDisplayConfig(const QString & config_string) YamlConfigReader reader; Config config; if (is_loadable_path) { - reader.readFile(config, QString::fromStdString(actual_load_path)); + reader.readFile(config, QString::fromStdString(actual_load_path)); } else { // Treat as yaml string content reader.readString(config, config_string); } @@ -722,9 +744,9 @@ void VisualizationFrame::loadDisplayConfig(const QString & config_string) } if (is_loadable_path) { - markRecentConfig(path); - setDisplayConfigFile(path); - last_config_dir_ = path_info.absolutePath().toStdString(); + markRecentConfig(path); + setDisplayConfigFile(path); + last_config_dir_ = path_info.absolutePath().toStdString(); } post_load_timer_->start(1000); diff --git a/rviz_resource_interfaces/CMakeLists.txt b/rviz_resource_interfaces/CMakeLists.txt index fca2dc586..5a0534152 100644 --- a/rviz_resource_interfaces/CMakeLists.txt +++ b/rviz_resource_interfaces/CMakeLists.txt @@ -11,6 +11,7 @@ find_package(rosidl_default_generators REQUIRED) rosidl_generate_interfaces(${PROJECT_NAME} "srv/GetResource.srv" + "srv/LoadConfig.srv" ) ament_export_dependencies(rosidl_default_runtime) diff --git a/rviz_resource_interfaces/srv/LoadConfig.srv b/rviz_resource_interfaces/srv/LoadConfig.srv new file mode 100644 index 000000000..db9ac475f --- /dev/null +++ b/rviz_resource_interfaces/srv/LoadConfig.srv @@ -0,0 +1,4 @@ +string config_string +--- +bool success +string message From 39167d9a2d1de822c653b3210ff46e9356af76a7 Mon Sep 17 00:00:00 2001 From: Crola1702 Date: Sun, 2 Nov 2025 06:33:59 +0000 Subject: [PATCH 3/4] Depend on rviz_resource_interfaces Signed-off-by: Crola1702 --- rviz_common/CMakeLists.txt | 3 +++ rviz_common/package.xml | 1 + 2 files changed, 4 insertions(+) diff --git a/rviz_common/CMakeLists.txt b/rviz_common/CMakeLists.txt index 770befd0c..4ab82e206 100644 --- a/rviz_common/CMakeLists.txt +++ b/rviz_common/CMakeLists.txt @@ -44,6 +44,7 @@ find_package(geometry_msgs REQUIRED) find_package(pluginlib REQUIRED) find_package(rclcpp REQUIRED) find_package(resource_retriever REQUIRED) +find_package(rviz_resource_interfaces REQUIRED) find_package(rviz_rendering REQUIRED) find_package(sensor_msgs REQUIRED) find_package(std_msgs REQUIRED) @@ -260,6 +261,7 @@ target_link_libraries(rviz_common PUBLIC tf2::tf2 tf2_ros::tf2_ros yaml-cpp::yaml-cpp + ${rviz_resource_interfaces_TARGETS} ) target_link_libraries(rviz_common PRIVATE @@ -286,6 +288,7 @@ ament_export_dependencies( tf2_ros yaml_cpp_vendor yaml-cpp + rviz_resource_interfaces ) # Export old-style CMake variables diff --git a/rviz_common/package.xml b/rviz_common/package.xml index 8e590bf19..31f50876e 100644 --- a/rviz_common/package.xml +++ b/rviz_common/package.xml @@ -41,6 +41,7 @@ pluginlib rclcpp resource_retriever + rviz_resource_interfaces rviz_ogre_vendor rviz_rendering sensor_msgs From 5531b9e6fcb191f78f7103602bf2abac1a109b97 Mon Sep 17 00:00:00 2001 From: Crola1702 Date: Thu, 6 Nov 2025 04:30:43 +0000 Subject: [PATCH 4/4] Fix cpplint errors and update docs Signed-off-by: Crola1702 --- .../include/rviz_common/visualization_frame.hpp | 11 ++++++----- rviz_common/src/rviz_common/visualization_frame.cpp | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/rviz_common/include/rviz_common/visualization_frame.hpp b/rviz_common/include/rviz_common/visualization_frame.hpp index c162802f1..1f821c316 100644 --- a/rviz_common/include/rviz_common/visualization_frame.hpp +++ b/rviz_common/include/rviz_common/visualization_frame.hpp @@ -36,19 +36,20 @@ #include #include #include +#include #include #include // NOLINT: cpplint is unable to handle the include order here #include // NOLINT: cpplint is unable to handle the include order here #include // NOLINT: cpplint is unable to handle the include order here #include // NOLINT: cpplint is unable to handle the include order here -#include -#include +#include #include "rviz_common/config.hpp" -#include "rviz_rendering/render_window.hpp" #include "rviz_common/window_manager_interface.hpp" #include "rviz_common/ros_integration/ros_node_abstraction_iface.hpp" +#include "rviz_rendering/render_window.hpp" +#include class QAction; class QActionGroup; @@ -182,9 +183,9 @@ class RVIZ_COMMON_PUBLIC VisualizationFrame : public QMainWindow, public WindowM const std::shared_ptr request, std::shared_ptr response); - /// Load display settings from the given file. + /// Load display settings from the configuration string. /** - * \param path The full path of the config file to load from. + * \param config_string Can be path to the config file to load from or a yaml configuration string. */ void loadDisplayConfig(const QString & config_string); diff --git a/rviz_common/src/rviz_common/visualization_frame.cpp b/rviz_common/src/rviz_common/visualization_frame.cpp index c5191ca73..c68a8c15c 100644 --- a/rviz_common/src/rviz_common/visualization_frame.cpp +++ b/rviz_common/src/rviz_common/visualization_frame.cpp @@ -61,10 +61,9 @@ #include // NOLINT cpplint cannot handle include order here #include // NOLINT cpplint cannot handle include order here #include // NOLINT cpplint cannot handle include order here -#include -#include #include "rclcpp/clock.hpp" +#include #include "tf2_ros/buffer.hpp" #include "tf2_ros/transform_listener.hpp" @@ -77,6 +76,7 @@ #include "rviz_common/yaml_config_reader.hpp" #include "rviz_common/yaml_config_writer.hpp" #include "rviz_rendering/render_window.hpp" +#include #include "./env_config.hpp" #include "./failed_panel.hpp"