I'm having trouble making Rviz teleop plugin using Qtcreator. I'm using Noetic and Ubuntu 20.04.
The codes is not complete yet, for now I just want to see teleop GUI on Rviz. I'm using catkin_make_isolated --install
build system
Error message:
[ERROR] [1694503592.866043597]: PluginlibFactory: The plugin for class 'rviz_teleop_plugin/QtTeleopPanel' failed to load. Error: Could not find library corresponding to plugin rviz_teleop_plugin/QtTeleopPanel. Make sure the plugin description XML file has the correct name of the library and that the library actually exists.
files: package name: rviz_teleop_plugin
- CMakeLists.txt
- package.xml
- plugin_description.xml
- src/qt_teleop_ui,cpp
- include/rviz_teleop_plugin/qt_teleop_ui.h
cmake_minimum_required(VERSION 3.0.2)
project(rviz_teleop_plugin)
find_package(catkin REQUIRED COMPONENTS
geometry_msgs
nav_msgs
roscpp
rospy
rviz
sensor_msgs
std_msgs
)
find_package(Qt5 COMPONENTS Core Widgets REQUIRED)
find_package(Qt5Widgets REQUIRED)
find_package(Qt5Core REQUIRED)
find_package(Qt5OpenGL REQUIRED)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(QT_LIBRARIES Qt5::Widgets)
add_definitions(-DQT_NO_KEYWORDS)
catkin_package(
INCLUDE_DIRS include
LIBRARIES rviz_teleop_plugin
CATKIN_DEPENDS geometry_msgs nav_msgs roscpp rospy rviz sensor_msgs std_msgs
# DEPENDS system_lib
)
include_directories(
include
${catkin_INCLUDE_DIRS}
${Qt5Widgets_INCLUDE_DIRS}
)
link_directories(${catkin_LIBRARY_DIRS})
qt5_wrap_cpp(MOC_FILES
include/rviz_teleop_plugin/qt_teleop_ui.h
)
set(SOURCE_FILES
src/qt_teleop_ui.cpp
${MOC_FILES}
)
add_library(${PROJECT_NAME}
${SOURCE_FILES}
)
add_dependencies(rviz_teleop_plugin ${PROJECT_NAME_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(${PROJECT_NAME}
Qt5::Widgets
${QT_LIBRARIES}
${catkin_LIBRARIES}
)
install(TARGETS
${PROJECT_NAME}
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
install(DIRECTORY include/${PROJECT_NAME}/ rviz
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
)
install(FILES plugin_description.xml
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
)
set_target_properties(rviz_teleop_plugin PROPERTIES OUTPUT_NAME "rviz_teleop_plugin")
<?xml version="1.0"?>
<package format="2">
<name>rviz_teleop_plugin</name>
<version>0.0.0</version>
<description>The rviz_teleop_plugin package</description>
<maintainer email="[email protected]">minseojeong</maintainer>
<license>TODO</license>
<buildtool_depend>catkin</buildtool_depend>
<build_depend>geometry_msgs</build_depend>
<build_depend>nav_msgs</build_depend>
<build_depend>roscpp</build_depend>
<build_depend>rospy</build_depend>
<build_depend>rviz</build_depend>
<build_depend>sensor_msgs</build_depend>
<build_depend>std_msgs</build_depend>
<build_depend>qt_gui_cpp</build_depend>
<build_depend>qtbase5-dev</build_depend>
<build_depend>libqt5-core</build_depend>
<build_depend>libqt5-gui</build_depend>
<build_depend>libqt5-widgets</build_depend>
<build_export_depend>geometry_msgs</build_export_depend>
<build_export_depend>nav_msgs</build_export_depend>
<build_export_depend>roscpp</build_export_depend>
<build_export_depend>rospy</build_export_depend>
<build_export_depend>rviz</build_export_depend>
<build_export_depend>sensor_msgs</build_export_depend>
<build_export_depend>std_msgs</build_export_depend>
<build_export_depend>qt_gui_cpp</build_export_depend>
<build_export_depend>qtbase5-dev</build_export_depend>
<build_export_depend>libqt5-core</build_export_depend>
<build_export_depend>libqt5-gui</build_export_depend>
<build_export_depend>libqt5-widgets</build_export_depend>
<exec_depend>geometry_msgs</exec_depend>
<exec_depend>nav_msgs</exec_depend>
<exec_depend>roscpp</exec_depend>
<exec_depend>rospy</exec_depend>
<exec_depend>rviz</exec_depend>
<exec_depend>sensor_msgs</exec_depend>
<exec_depend>std_msgs</exec_depend>
<exec_depend>qt_gui_cpp</exec_depend>
<exec_depend>qtbase5-dev</exec_depend>
<exec_depend>libqt5-core</exec_depend>
<exec_depend>libqt5-gui</exec_depend>
<exec_depend>libqt5-widgets</exec_depend>
<export>
<rviz plugin="${prefix}/plugin_description.xml"/>
</export>
</package>
<!-- <library path="lib/librviz_teleop_plugin"> -->
<library path="install_isolated/lib/librviz_teleop_plugin.so">
<class name="rviz_teleop_plugin/QtTeleopPanel"
type="rviz_teleop_plugin::QtTeleopPanel"
base_class_type="rviz::Panel">
<description>
A Teleop Panel to control the robot.
</description>
<qtgui>
<name>rviz_teleop_plugin/QtTeleopPanel</name>
<class>rviz_teleop_plugin::QtTeleopPanel</class>
<label>Teleop Panel</label>
</qtgui>
</class>
</library>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QApplication>
#include <QtWidgets/QLabel>
#include <QtWidgets/QDoubleSpinBox>
// #include <QtWidgets/QPainter>
// #include <QtWidgets/QLineEdit>
#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMenu>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QWidget>
#include <QtWidgets/QSlider>
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
// #include <rviz/panel.h>
#include "rviz_teleop_plugin/qt_teleop_ui.h"
class QtTeleopPanel;
namespace rviz_teleop_plugin
{
QtTeleopPanel::QtTeleopPanel(QWidget* parent)
: rviz::Panel(parent),
// : QWidget(parent),
nh_("~"),
cmd_vel_pub_(nh_.advertise<geometry_msgs::Twist>("cmd_vel", 1))
{
QVBoxLayout* layout = new QVBoxLayout;
QLabel* X_label = new QLabel("X ::");
QDoubleSpinBox* X_doubleSpinBox = new QDoubleSpinBox;
X_doubleSpinBox->setMaximum(1.0);
X_doubleSpinBox->setSingleStep(0.01);
QLabel* Y_label = new QLabel("Y ::");
QDoubleSpinBox* Y_doubleSpinBox = new QDoubleSpinBox;
Y_doubleSpinBox->setMaximum(1.0);
Y_doubleSpinBox->setSingleStep(0.01);
QPushButton* Send_Button = new QPushButton("Send");
QPushButton* Up_Button = new QPushButton("UP");
QPushButton* Stop_Button = new QPushButton("Stop");
QPushButton* Down_Button = new QPushButton("Down");
QPushButton* Left_Button = new QPushButton("Left");
QPushButton* Right_Button = new QPushButton("Right");
QLabel* Linear_label = new QLabel("Linear vel");
QDoubleSpinBox* Linear_doubleSpinBox = new QDoubleSpinBox;
Linear_doubleSpinBox->setMaximum(1.0);
Linear_doubleSpinBox->setSingleStep(0.01);
QLabel* Angular_label = new QLabel("Angular vel");
QDoubleSpinBox* Angular_doubleSpinBox = new QDoubleSpinBox;
Angular_doubleSpinBox->setMaximum(1.0);
Angular_doubleSpinBox->setSingleStep(0.1);
layout->addWidget(X_label);
layout->addWidget(X_doubleSpinBox);
layout->addWidget(Y_label);
layout->addWidget(Y_doubleSpinBox);
layout->addWidget(Send_Button);
layout->addWidget(Up_Button);
layout->addWidget(Stop_Button);
layout->addWidget(Down_Button);
layout->addWidget(Left_Button);
layout->addWidget(Right_Button);
layout->addWidget(Linear_label);
layout->addWidget(Linear_doubleSpinBox);
layout->addWidget(Angular_label);
layout->addWidget(Angular_doubleSpinBox);
QWidget::setLayout(layout);
QObject::connect(Up_Button, SIGNAL(clicked()), this, SLOT(on_Up_Button_pressed()));
QObject::connect(Down_Button, SIGNAL(clicked()), this, SLOT(on_Down_Button_pressed()));
QObject::connect(Left_Button, SIGNAL(clicked()), this, SLOT(on_Left_Button_pressed()));
QObject::connect(Right_Button, SIGNAL(clicked()), this, SLOT(on_Right_Button_pressed()));
QObject::connect(Stop_Button, SIGNAL(clicked()), this, SLOT(on_Stop_Button_pressed()));
QObject::connect(Send_Button, SIGNAL(clicked(bool)), this, SLOT(on_Send_Button_clicked(bool)));
QObject::connect(X_doubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(on_X_doubleSpinBox_valueChanged(double)));
QObject::connect(Y_doubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(on_Y_doubleSpinBox_valueChanged(double)));
QObject::connect(Linear_doubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(on_Linear_doubleSpinBox_valueChanged(double)));
QObject::connect(Angular_doubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(on_Angular_doubleSpinBox_valueChanged(double)));
}
void QtTeleopPanel::on_Up_Button_pressed()
{
geometry_msgs::Twist cmd_vel;
cmd_vel.linear.x = this->Linear_doubleSpinBox->value();
cmd_vel.angular.z = this->Angular_doubleSpinBox->value();
cmd_vel_pub_.publish(cmd_vel);
}
void QtTeleopPanel::on_Down_Button_pressed()
{
geometry_msgs::Twist cmd_vel;
cmd_vel.linear.x = -this->Linear_doubleSpinBox->value();
cmd_vel.angular.z = -this->Angular_doubleSpinBox->value();
cmd_vel_pub_.publish(cmd_vel);
}
void QtTeleopPanel::on_Left_Button_pressed()
{
geometry_msgs::Twist cmd_vel;
cmd_vel.linear.x = 0.0;
cmd_vel.angular.z = this->Angular_doubleSpinBox->value();
cmd_vel_pub_.publish(cmd_vel);
}
void QtTeleopPanel::on_Right_Button_pressed()
{
geometry_msgs::Twist cmd_vel;
cmd_vel.linear.x = 0.0;
cmd_vel.angular.z = -this->Angular_doubleSpinBox->value();
cmd_vel_pub_.publish(cmd_vel);
}
void QtTeleopPanel::on_Stop_Button_pressed()
{
geometry_msgs::Twist cmd_vel;
cmd_vel.linear.x = 0.0;
cmd_vel.angular.z = 0.0;
cmd_vel_pub_.publish(cmd_vel);
}
void QtTeleopPanel::on_Send_Button_clicked(bool checked)
{
}
void QtTeleopPanel::on_X_doubleSpinBox_valueChanged(double arg1)
{
}
void QtTeleopPanel::on_Y_doubleSpinBox_valueChanged(double arg1)
{
}
void QtTeleopPanel::on_Linear_doubleSpinBox_valueChanged(double arg1)
{
}
void QtTeleopPanel::on_Angular_doubleSpinBox_valueChanged(double arg1)
{
}
} // namespae
#include <pluginlib/class_list_macros.h>
PLUGINLIB_EXPORT_CLASS(rviz_teleop_plugin::QtTeleopPanel, rviz::Panel)
/********************************************************************************
** Form generated from reading UI file 'qt_teleop.ui'
**
** Created by: Qt User Interface Compiler version 5.12.8
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
// #ifndef QT_TELEOP_UI_H
// #define QT_TELEOP_UI_H
#ifndef QT_TELEOP_UI_H
#define QT_TELEOP_UI_H
#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QDoubleSpinBox>
#include <QtWidgets/QLabel>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMenu>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QWidget>
#include <QtWidgets/QSlider>
#include <QtWidgets/QVBoxLayout>
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <rviz/panel.h>
// QT_BEGIN_NAMESPACE
namespace rviz_teleop_plugin
{
// class QtTeleopPanel : public QWidget
class QtTeleopPanel : public rviz::Panel
{
Q_OBJECT
public:
QtTeleopPanel(QWidget *parent = 0);
// ~QtTeleopPanel();
public Q_SLOTS:
void on_Up_Button_pressed();
void on_Down_Button_pressed();
void on_Left_Button_pressed();
void on_Right_Button_pressed();
void on_Stop_Button_pressed();
void on_Send_Button_clicked(bool checked);
void on_X_doubleSpinBox_valueChanged(double arg1);
void on_Y_doubleSpinBox_valueChanged(double arg1);
void on_Linear_doubleSpinBox_valueChanged(double arg1);
void on_Angular_doubleSpinBox_valueChanged(double arg1);
private:
ros::NodeHandle nh_;
ros::Publisher cmd_vel_pub_;
QWidget *centralwidget;
QLabel *X_label;
QDoubleSpinBox *X_doubleSpinBox;
QLabel *Y_label;
QDoubleSpinBox *Y_doubleSpinBox;
QPushButton *Send_Button;
QPushButton *Up_Button;
QPushButton *Stop_Button;
QPushButton *Down_Button;
QPushButton *Left_Button;
QPushButton *Right_Button;
QDoubleSpinBox *Linear_doubleSpinBox;
QLabel *Linear_label;
QLabel *Angular_label;
QDoubleSpinBox *Angular_doubleSpinBox;
QMenuBar *menubar;
QMenu *menuteleop_panel;
QStatusBar *statusbar;
};
} // end namespace
// QT_END_NAMESPACE
#endif // QT_TELEOP_UI_H