文章目录
前言
Rviz基于qt编写的可视化界面,是ros的一个可视化工具,用于可视化传感器的数据和状态信息。本文介绍怎样在rviz中添加按钮组件,方便用户操作。
一、代码实现
1.新建功能包
在工作空间下,新建功能包test_rviz_plugin。
cd catkin_ws/src
catkin_create_pkg test_rviz_plugin roscpp rviz
cd ..
catkin_make
2. 具体实现
参考rviz:rviz_plugin_tutorials
2.1 test_rviz_plugin.h
新建TestRvizPlugin类,公共继承rviz::Panel;
virtual void load(const rviz::Config &config)和virtual void save(rviz::Config config) const 重写rviz::Panel中的函数,用于从配置文件加载和保存数据;
void test_callback(); 和 void test2_callback();槽函数,点击按钮后执行的操作函数;
#ifndef PROJECT_TEST_RVIZ_H
#define PROJECT_TEST_RVIZ_H
#include <ros/ros.h>
#include <rviz/panel.h>
#include <QHBoxLayout>
#include <QPushButton>
#include <QString>
namespace test_rviz_plugin{
class TestRvizPlugin :public rviz::Panel{
Q_OBJECT
public:
TestRvizPlugin(QWidget *parent = 0);
virtual void load(const rviz::Config &config);
virtual void save(rviz::Config config) const;
protected Q_SLOTS:
void test_callback();
void test2_callback();
private:
ros::NodeHandle nh_;
QPushButton *test_button_;
QPushButton *test2_button_;
ros::Publisher test_pub_, test2_pub_;
};
}
#endif //PROJECT_TEST_RVIZ_H
2.2 test_rviz_plugin.cpp
最后两行的作用 是告诉插件库这个类。 每个应该由 pluginlib::ClassLoader 加载的类都必须在其.cpp文件中编译这两行,在任何命名空间范围之外。
#include <test_rviz_plugin/test_rviz_plugin.h>
#include <std_msgs/String.h>
namespace test_rviz_plugin{
TestRvizPlugin::TestRvizPlugin(QWidget *parent):Panel(parent)
{
//创建两个按钮---测试按钮和测试按钮2
auto *button_layout = new QHBoxLayout;
test_button_ = new QPushButton(tr("测试按钮"),this);
button_layout->addWidget(test_button_);
test2_button_ = new QPushButton(tr("测试按钮2"),this);
button_layout->addWidget(test2_button_);
setLayout(button_layout);
//信号连接---点击信号发生,连接到槽函数test_callback()
connect(test_button_,SIGNAL(clicked()),this,SLOT(test_callback()));
connect(test2_button_,SIGNAL(clicked()),this,SLOT(test2_callback()));
test_pub_ = nh_.advertise<std_msgs::String>("test_topic",10);
test2_pub_ = nh_.advertise<std_msgs::String>("test2_topic",10);
}
//加载配置数据---必须要有的
void TestRvizPlugin::load(const rviz::Config &config){
Panel::load(config);
}
//将所有配置数据保存到给定的Config对象中。在这里,重要的是要对父类调用save(),以便保存类id和面板名称。---必须要有的
void TestRvizPlugin::save(rviz::Config config) const{
Panel::save(config);
}
void TestRvizPlugin::test_callback()
{
std::string str;
std_msgs::String msg;
msg.data = "test";
ROS_INFO("测试消息发布!");
test_pub_.publish(msg);
}
void TestRvizPlugin::test2_callback()
{
std::string str;
std_msgs::String msg;
msg.data = "test2";
ROS_INFO("测试消息2发布!");
test_pub_.publish(msg);
}
}
#include <pluginlib/class_list_macros.h>
PLUGINLIB_EXPORT_CLASS(test_rviz_plugin::TestRvizPlugin,rviz::Panel)
二、修改配置文件
1.CMakeLists.txt
find_package(catkin REQUIRED COMPONENTS
roscpp
rviz
)
catkin_package(
INCLUDE_DIRS include
)
include_directories(${catkin_INCLUDE_DIRS})
link_directories(${catkin_LIBRARY_DIRS})
## This setting causes Qt's "MOC" generation to happen automatically.
set(CMAKE_AUTOMOC ON)
## This plugin includes Qt widgets, so we must include Qt.
## We'll use the version that rviz used so they are compatible.
if(rviz_QT_VERSION VERSION_LESS "5")
message(STATUS "Using Qt4 based on the rviz_QT_VERSION: ${rviz_QT_VERSION}")
find_package(Qt4 ${rviz_QT_VERSION} EXACT REQUIRED QtCore QtGui)
## pull in all required include dirs, define QT_LIBRARIES, etc.
include(${QT_USE_FILE})
else()
message(STATUS "Using Qt5 based on the rviz_QT_VERSION: ${rviz_QT_VERSION}")
find_package(Qt5 ${rviz_QT_VERSION} EXACT REQUIRED Core Widgets)
## make target_link_libraries(${QT_LIBRARIES}) pull in all required dependencies
set(QT_LIBRARIES Qt5::Widgets)
endif()
## 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.
add_definitions(-DQT_NO_KEYWORDS)
add_library(test_rviz_plugin src/test_rviz_plugin.cpp include/test_rviz_plugin/test_rviz_plugin.h)
add_dependencies(test_rviz_plugin ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(test_rviz_plugin ${QT_LIBRARIES} ${catkin_LIBRARIES})
2.package.xml
添加如下:主要添加编译依赖和执行依赖,以及注册rviz插件
<build_depend>qtbase5-dev</build_depend>
<build_depend>rviz</build_depend>
<exec_depend>libqt5-core</exec_depend>
<exec_depend>libqt5-gui</exec_depend>
<exec_depend>libqt5-widgets</exec_depend>
<exec_depend>rviz</exec_depend>
<export>
<!-- Other tools can request additional information be placed here -->
<rviz plugin="${prefix}/plugin_descriptions.xml"/>
</export>
3.新建插件描述文件
在功能包中,新建.xml文件,以plugin_descriptions.xml为例。path =“lib/libxxx”
标签class中name 、type、base_class_type表示插件名称、类型以及依赖的基类
<library path="lib/libtest_rviz_plugin">
<class name="test_rviz_plugin/TestRvizPlugin"
type="test_rviz_plugin::TestRvizPlugin"
base_class_type="rviz::Panel">
<description>
A panel widget is used to test rviz plugin.
</description>
</class>
</library>
三、查看插件注册及结果
1.插件注册显示
cd catkin_ws
catkin_make
source devel/setup.bash
rospack plugins --attrib=plugin rviz
会在终端打印出rviz的相关插件:
...
test_rviz_plugin /home/robot/catkin_ws/src/test_rviz_plugin/plugin_descriptions.xml
...
2.结果显示
roscore
rviz
打开rviz—Panels—Add New Panel
点击Add New Panel
找到自定义的test_rviz_plugin插件,选中添加即可。
如图所示:
点击测试按钮,结果如图:
放一张效果图~~
四、总结
以上就是在rviz中添加简单的按钮插件过程,和全局路径插件类似,都需要注册插件后才能使用。