ROS2 rviz2 dockable panel plugin
I am trying implement rviz2 plugin in ROS2. I have referred user guide from the rviz for the development. Currently there no tutorial available to develop rviz dockable panel in ROS2. Therefore I have referred MoveIt2 and Navigation 2 package for their rviz plugin implementation in ROS2. Here is my code.
demo_widget.h
:
#ifndef DEMO_WIDGET_H
#define DEMO_WIDGET_H
#include <QWidget>
#include <memory>
#include <vector>
#include "ui_pointcloud_controller.h"
#ifndef Q_MOC_RUN
#include <rclcpp/rclcpp.hpp>
#include <std_msgs/msg/string.hpp>
#endif
namespace Ui {
class DemoWidgetUI;
}
namespace prc_demo_panel
{
class DemoWidget : public QWidget
{
Q_OBJECT
public:
DemoWidget(QWidget * parent = 0);
~DemoWidget() override;
public Q_SLOTS:
private Q_SLOTS:
protected:
std::unique_ptr<Ui::DemoWidgetUI> ui_;
private:
rclcpp::Node::SharedPtr _node;
rclcpp::Publisher<std_msgs::msg::String>::SharedPtr _publisher;
};
}
demo_widget.cpp
:
#include <prc_demo_panel/demo_widget.h>
namespace prc_demo_panel
{
DemoWidget::DemoWidget(QWidget *parent): QWidget(parent), ui_(new Ui::DemoWidgetUI)
{
ui_->setupUi(this);
connect(ui_->pushButton_1, &QPushButton::clicked, this, &DemoWidget::buttonOne);
connect(ui_->pushButton_2, &QPushButton::clicked, this, &DemoWidget::buttonTwo);
auto options = rclcpp::NodeOptions().arguments({"--ros-args --remap __node:=dialog_action_client"});
_node = std::make_shared<rclcpp::Node>("_", options);
_publisher = _node->create_publisher<std_msgs::msg::String>("gui_control", 10);
}
}
demo_panel.h
:
#ifndef DEMO_PANEL_H
#define DEMO_PANEL_H
#include <QVBoxLayout>
#include <rviz_common/panel.hpp>
#include <prc_demo_panel/demo_widget.h>
namespace prc_demo_panel
{
class Demo_widget;
class DemoPanel : public rviz_common::Panel
{
Q_OBJECT
public:
explicit DemoPanel(QWidget * parent = 0);
virtual ~DemoPanel();
void onInitialize() override;
void save(rviz_common::Config config) const override;
void load(const rviz_common::Config &conf) override;
private:
DemoWidget *_widget;
};
}
#endif // RVIZ_PANEL_H
demo_panel.cpp
:
#include "prc_demo_panel/demo_panel.h"
#include <QVBoxLayout>
#include <memory>
#include <vector>
#include <utility>
#include <rviz_common/display_context.hpp>
namespace prc_demo_panel
{
DemoPanel::DemoPanel(QWidget * parent) : Panel(parent)
{
_widget = new DemoWidget(parent);
QVBoxLayout * layout = new QVBoxLayout;
layout->addWidget(_widget);
layout->setContentsMargins(10, 10, 10, 10);
setLayout(layout);
}
void DemoPanel::save(rviz_common::Config config) const
{
Panel::save(config);
}
void DemoPanel::load(const rviz_common::Config &conf)
{
Panel::load(conf);
}
void DemoPanel::onInitialize()
{
auto node = getDisplayContext()->getRosNodeAbstraction().lock()->get_raw_node();
}
}
#include <pluginlib/class_list_macros.hpp>
PLUGINLIB_EXPORT_CLASS(prc_demo_panel::DemoPanel, rviz_common::Panel)
CMakeLists.txt
:
cmake_minimum_required(VERSION 3.5)
project(prc_demo_panel)
.
.
.
# find dependencies
find_package(Qt5 REQUIRED COMPONENTS Core Gui Widgets Test Concurrent)
set (THIS_PACKAGE_INCLUDE_DEPENDS
rclcpp
class_loader
pluginlib
Qt5
rviz2
rviz_common
rviz_default_plugins
rviz_rendering
rviz_ogre_vendor
)
include_directories(
include
)
# I prefer the Qt signals and slots to avoid defining "emit", "slots",
# etc because they can conflict with boost signals, so define QT_NO_KEYWORDS here
# e.g. http://muddyazian.blogspot.de/2012/04/getting-qt-app-working-with-boost-using.html
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
#set(CMAKE_AUTORCC ON)
#add_definitions(-DQT_NO_KEYWORDS)
# Define source file
set(${PROJECT_NAME}_SRCS
src/demo_panel.cpp
src/demo_widget.cpp
#src/plugin_init.cpp
)
# Define header file
set(${PROJECT_NAME}_HDRS
include/${PROJECT_NAME}/demo_panel.h
include/${PROJECT_NAME}/demo_widget.h
)
# Define ui file
set(${PROJECT_NAME}_UIS
resource/pointcloud_controller.ui
)
message(STATUS "Generate header for ui with rviz2_QT_VERSION: ${rviz2_QT_VERSION}")
qt5_wrap_ui(${PROJECT_NAME}_UIS_H ${${PROJECT_NAME}_UIS})
foreach(header "${${PROJECT_NAME}_HDRS}")
qt5_wrap_cpp(${PROJECT_NAME}_MOCS ${header})
endforeach()
## Add library is needed in order to generate the header file from ui file.
add_library(${PROJECT_NAME} SHARED
${${PROJECT_NAME}_SRCS}
${${PROJECT_NAME}_UIS_H}
${${PROJECT_NAME}_MOCS}
)
ament_target_dependencies(${PROJECT_NAME} ${THIS_PACKAGE_INCLUDE_DEPENDS})
target_include_directories(${PROJECT_NAME} PUBLIC
${Qt5Widgets_INCLUDE_DIRS}
${OGRE_INCLUDE_DIRS}
)
target_link_libraries(${PROJECT_NAME} rviz_common::rviz_common)
# target_include_directories(${PROJECT_NAME} PUBLIC
# $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
# $<INSTALL_INTERFACE:include>
# )
target_compile_definitions(${PROJECT_NAME} PUBLIC "PLUGINLIB__DISABLE_BOOST_FUNCTIONS")
target_compile_definitions(${PROJECT_NAME} PRIVATE "RVIZ_DEFAULT_PLUGINS_BUILDING_LIBRARY")
pluginlib_export_plugin_description_file(rviz_common demo_plugin ...
Did you ever find a solution to this problem?