【ROS2】【源码展示】ROS2中Rviz2增加一个可以实现收发节点双击修改图表等功能的插件panel
使用说明
源代码在这里,本文基于源代码进行功能增加和修改。主要应用Qt中的一些方法,结合ros2中rviz2对增加panel功能的一些封装。实现双击修改图表中的内容,节点的收发,图表根据收到的msg进行更新等功能。代码未进行编译检测,可能存在一些错误。可参考设计思路。
CPP文件
#include "demo_panel/demo_panel.h"
#include "rviz_common/properties/property_tree_widget.hpp"
#include "rviz_common/interaction/selection_manager.hpp"
#include "rviz_common/visualization_manager.hpp"
namespace demo_panel
{
MyPanel::MyPanel(QWidget *parent)
: rviz_common::Panel(parent)
{
auto layout = new QVBoxLayout();
layout->setContentsMargins(0, 0, 0, 0);
auto text = new QLabel("This is a demo");
auto lineEdit = new QLineEdit();
auto radio = new QRadioButton();
tree_ = new QTreeWidget(this);
tree_->setColumnCount(2);
tree_->resize(600, 300);
top_item_ = new QTreeWidgetItem();
top_item_->setText(0, "robot");
tree_->addTopLevelItem(top_item_);
string_leave_ = new QStringList();
string_leave_ << "name" << "leave";
leave_ = new QTreeWidgetItem(top_item_, *string_leave_);
layout->addWidget(text);
layout->addWidget(lineEdit);
layout->addWidget(radio);
layout->addWidget(button_flash_);
layout->addWidget(tree_);
setLayout(layout);
QTimer* publish_timer = new QTimer(this);
connect(tree_, SIGNAL(itemDoubleClicked(QTreeWidgetItem* int)), this, SLOT(openEditor(QTreeWidgetItem* int)));
// connect(tree_, SIGNAL(editingFinished()), this, SLOT(closeEditor()));
connect(button_flash_, SIGNAL(clicked()), this, SLOT(flash()));
publish_timer->start(100);
}
void MyPanel::onInitialize()
{
// tree_widget_->setModel(getDisplayContext()->getSelectionManager()->getPropertyModel());
node_ = rviz_common::Panel::getDisplayContext()->getRosNodeAbstraction().lock()->get_raw_node();
object_info_pub_ = node->create_publisher<Object>("topic", 1);
object_info_sub_ = node->create_subscription<Object>("topic/sub", 1, std::bind(&MyPanel::sub_callback, this, std::placeholders::_1));
}
void MyPanel::openEditor(QTreeWidgetItem* item, int col)
{
item_tmp_ = nullptr;
if(col == 0)
{
item_tmp_ = item;
QLineEdit* lineEdit = new QLineEdit(tree_);
lineEdit->setText(QStringLiteral(" "));
connect(lineEdit, SIGNAL(editingFinished()), this, SLOT(closeEditor()));
tree_->setItemWidget(item_tmp_, 0, lineEdit);
}
}
void MyPanel::closeEditor()
{
if(item_tmp_ != nullptr)
{
QLineEdit* edit = qobject_cast<QLineEdit*>(tree_->itemWidget(item_tmp_, 0));
if(!edit)
{
return;
}
QString text = edit->text();
tree_->removeItemWidget(item_tmp_, 1);
item_tmp_->setText(0, text);
}
}
void MyPanel::flash()
{
leave_->setText(1, QString::number(123, 'd', 2));
}
} // namespace demo_panel
#include <pluginlib/class_list_macros.hpp>
PLUGINLIB_EXPORT_CLASS(demo_panel::MyPanel, rviz_common::Panel)
H文件
#pragma once
#include <QMainWindow>
#include "rviz_common/panel.hpp"
#include <QVBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QRadioButton>
#include <qpushbutton.h>
#include <QTreeWidget>
#include <qtimer.h>
#include <rclcpp/node.hpp>
namespace demo_panel
{
class MyPanel : public rviz_common::Panel // QMainWindow
{
Q_OBJECT
public:
explicit MyPanel(QWidget *parent = nullptr);
void onInitialize() override;
protected Q_SLOTS:
void sub_callback(const object msg);
void publishTopic();
void flash();
void openEditor(QTreeWidgetItem* item, int col);
void closeEditor();
protected:
QPushButton* button_flash_;
QVBoxLayout* layout_;
QTreeWidget* tree_;
QTreeWidgetItem* item_tmp_;
QTreeWidgetItem* top_item_;
QTreeWidgetItem* leave_;
QStringList* string_leave_;
int col_;
rclcpp::Node::SharedPtr node_;
std::shared_ptr<rclcpp::Publisher<Object>> object_info_pub_;
std::shared_ptr<rclcpp::Subscription<Object>> object_info_sub_;
};
} // namespace demo_panel
xml文件
增加如下内容
<class name="demo_panel/MyPanel"
type="demo_panel::MyPanel"
base_class_type="rviz_common::Panel">
<description>
demo_panel
</description>
</class>
CMakeLists.txt文件
对原码中进行了修改,删掉冗余的部分。
cmake_minimum_required(VERSION 3.5)
project(demo_panel LANGUAGES CXX)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rviz_ogre_vendor REQUIRED)
find_package(Qt5 REQUIRED Core Widgets)
set(QT_LIBS Qt5::Widgets)
find_package(pluginlib REQUIRED)
find_package(rclcpp REQUIRED)
find_package(rclcpp_action REQUIRED)
find_package(rviz_default_plugins REQUIRED)
find_package(rviz_assimp_vendor REQUIRED)
find_package(rviz_rendering REQUIRED)
find_package(rviz_common REQUIRED)
ament_package_xml()
set(ROS_DISTRO "ROS 2")
set(OGRE_PLUGIN_PATH "rviz_ogre_vendor")
set(${PROJECT_NAME}_headers_to_moc
include/demo_panel/demo_panel.h
)
foreach(header "${${PROJECT_NAME}_headers_to_moc}")
qt5_wrap_cpp(${PROJECT_NAME}_moc_files "${header}")
endforeach()
set(${PROJECT_NAME}_source_files
src/demo_panel.cpp
)
add_library(${PROJECT_NAME} SHARED
${${PROJECT_NAME}_moc_files}
${${PROJECT_NAME}_source_files}
)
ament_target_dependencies(${PROJECT_NAME}
PUBLIC
pluginlib
rclcpp
rviz_assimp_vendor
rviz_rendering
rviz_common
rclcpp_action
rviz_default_plugins
)
pluginlib_export_plugin_description_file(rviz_common plugin_description.xml)
install(
TARGETS ${PROJECT_NAME}
EXPORT ${PROJECT_NAME}
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
INCLUDES DESTINATION include
)
install(
DIRECTORY include/
DESTINATION include
)
ament_package()