This repository demonstrates the usage of using ROS rqt plugin to design personal UI interface with both cpp and python.
At the moment only cpp version is updated. Python version will be updated on another branch soon.
- Content
- Package Creation
- UI File
- CMakeLists.txt
- package.xml
- plugin.xml
- script/ros_rqt_plugin
- Recompile
- Include Path for Vscode
- Reference
Note that plugin.xml class name should be unique in order for ROS to find it. Or else only the first one that registered is found.
- Create Package
- Create Necessary Folders and Files
- Create UI file with Qt Designer
- Create setup.py
- Create scripts/ros_rqt_plugin (python file
chmod a+x ros_rqt_plugin
) - Update package.xml (remember the export tag)
- Update CMakeFile.txt
- Compile (catkin_make)
- Create and update include/ros_rqt_plugin/ros_rqt_plugin.hpp
- Create and update src/ros_rqt_plugin/ros_rqt_plugin.cpp
- Compile (catkin_make)
- Create launch file (start.launch)
- Create src/ros_rqt_plugin and then touch init.py with chmod a+x (this is for binary installation)
Create your personal ROS RQt plugin with the following command:
catkin_create_pkg ros_rqt_plugin roscpp rospy rqt_gui rqt_gui_cpp rqt_gui_py std_msgs
To create a RQt plugin these are the dependencies that you actually need, the other dependencies included along with the catkin_create_pkg is for this demonstration purpose.
roscpp
rospy
rqt_gui
rqt_gui_cpp
rqt_gui_py
ros_rqt_plugin
├── CMakeLists.txt
├── package.xml
├── plugin.xml
├── setup.py
├── launch
│ └── start.launch
├── resource
│ └── ros_rqt_plugin.ui
├── scripts
│ └── ros_rqt_plugin # Remember to make it executable (chmod a+x ros_rqt_plugin)
├── include
│ └── ros_rqt_plugin
│ └── ros_rqt_plugin.hpp
└── src
└── ros_rqt_plugin
├── ros_rqt_plugin.cpp
└── __init__.py
Create your ui file with Qt 5 Designer
.
For more information, please look at this video.
For the convienience of different Qt version, I have followed the exampl from rqt_template_plugin.
cmake_minimum_required(VERSION 3.0.2)
project(ros_rqt_plugin)
## Compile as C++11, supported in ROS Kinetic and newer
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(catkin REQUIRED COMPONENTS
geometry_msgs
roscpp
rospy
std_msgs
rqt_gui
rqt_gui_cpp
rqt_gui_py
)
# Find qt package
if ("${qt_gui_cpp_USE_QT_MAJOR_VERSION} " STREQUAL "5 ")
find_package(Qt5Widgets REQUIRED)
else ()
find_package(Qt4 COMPONENTS QtCore QtGui REQUIRED)
include(${QT_USE_FILE})
endif ()
## Uncomment this if the package has a setup.py. This macro ensures
## modules and global scripts declared therein get installed
## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
catkin_python_setup()
# Define source file
set(${PROJECT_NAME}_SRCS
src/${PROJECT_NAME}/ros_rqt_plugin.cpp
)
# Define header file
set(${PROJECT_NAME}_HDRS
include/${PROJECT_NAME}/ros_rqt_plugin.hpp
)
# Define ui file
set(${PROJECT_NAME}_UIS
resource/ros_rqt_plugin.ui
)
# Define include directory
set(${PROJECT_NAME}_INCLUDE_DIRECTORIES
include
${CMAKE_CURRENT_BINARY_DIR}
)
catkin_package(
INCLUDE_DIRS include
LIBRARIES ${PROJECT_NAME}
CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs rqt_gui rqt_gui_cpp rqt_gui_py
DEPENDS #system_lib
)
# Obtain qt wrap cpp and qt wrap ui
if ("${qt_gui_cpp_USE_QT_MAJOR_VERSION} " STREQUAL "5 ")
qt5_wrap_cpp(${PROJECT_NAME}_MOCS ${${PROJECT_NAME}_HDRS})
qt5_wrap_ui(${PROJECT_NAME}_UIS_H ${${PROJECT_NAME}_UIS})
else ()
qt4_wrap_cpp(${PROJECT_NAME}_MOCS ${${PROJECT_NAME}_HDRS})
qt4_wrap_ui(${PROJECT_NAME}_UIS_H ${${PROJECT_NAME}_UIS})
endif ()
include_directories(
${${PROJECT_NAME}_INCLUDE_DIRECTORIES}
${catkin_INCLUDE_DIRS}
)
add_library(${PROJECT_NAME}
${${PROJECT_NAME}_SRCS}
${${PROJECT_NAME}_MOCS}
${${PROJECT_NAME}_UIS_H}
)
target_link_libraries(${PROJECT_NAME}
${catkin_LIBRARIES}
)
if ("${qt_gui_cpp_USE_QT_MAJOR_VERSION} " STREQUAL "5 ")
target_link_libraries(${PROJECT_NAME} Qt5::Widgets)
else ()
target_link_libraries(${PROJECT_NAME} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY})
endif ()
# Find class loader
# For more information please visit: http://wiki.ros.org/class_loader
find_package(class_loader)
class_loader_hide_library_symbols(${PROJECT_NAME})
# Install plugin path
install(FILES plugin.xml
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
)
install(TARGETS ${PROJECT_NAME}
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
)
install(PROGRAMS scripts/${PROJECT_NAME}
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
install(PROGRAMS scripts/${PROJECT_NAME}
DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
)
install(DIRECTORY include/${PROJECT_NAME}/
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
)
Do not forget to add export tag correctly.
<?xml version="1.0"?>
<package format="2">
<name>ros_rqt_plugin</name>
<version>0.0.0</version>
<description>The ros_rqt_plugin package</description>
<maintainer email="jianle001@e.ntu.edu.sg">Bruce Chan Jian Le</maintainer>
<license>BSD</license>
<url type="website">https://github.com/BruceChanJianLe/ros-rqt-plugin</url>
<author email="jianle001@e.ntu.edu.sg">Bruce Chan Jian Le</author>
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>rospy</build_depend>
<build_depend>rqt_gui</build_depend>
<build_depend>rqt_gui_cpp</build_depend>
<build_depend>rqt_gui_py</build_depend>
<build_depend>std_msgs</build_depend>
<build_export_depend>roscpp</build_export_depend>
<build_export_depend>rospy</build_export_depend>
<build_export_depend>rqt_gui</build_export_depend>
<build_export_depend>rqt_gui_cpp</build_export_depend>
<build_export_depend>rqt_gui_py</build_export_depend>
<build_export_depend>std_msgs</build_export_depend>
<exec_depend>roscpp</exec_depend>
<exec_depend>rospy</exec_depend>
<exec_depend>rqt_gui</exec_depend>
<exec_depend>rqt_gui_cpp</exec_depend>
<exec_depend>rqt_gui_py</exec_depend>
<exec_depend>std_msgs</exec_depend>
<export>
<rqt_gui plugin="${prefix}/plugin.xml"/>
</export>
</package>
Note that the class name must be unique, else ROS would be able to find it.
<library path="lib/libros_rqt_plugin">
<!-- Note that the class name must be unique, else ROS would be able to find it -->
<!-- The class name also need to follow the "namespace/class_name" convention in order to work properly -->
<class name="ros_rqt_plugin/two_button_plugin" type="ros_rqt_plugin::two_button_plugin" base_class_type="rqt_gui_cpp::Plugin">
<description>
This is an example of two push buttons.
</description>
<qtgui>
<group>
<label>Topics</label>
<icon type="theme">folder</icon>
<statustip></statustip>
</group>
<label>Two Push Example Buttons</label>
<icon type="theme">applications-graphics</icon>
<statustip>This is an example of two push buttons.</statustip>
</qtgui>
</class>
</library>
Explanation:
- library@path: The package-relative path which gets added to sys.path.
- library/class@name: The name of the plugin, which must be unique within a package.
- library/class@type: The concatenated name of the package, module and class, which is used for the import statement. (Form: package.module.class)
- library/class@base_class_type: For Python plugins which use the rospy client library the value is rqt_gui_py::Plugin.
- library/description: The description of the plugin.
- library/qtgui: This tag contains additional optional information about the package. If none are provided, the name of the plugin is used as the label for the plugin in the menu and the description is displayed as a status tip.
- library/qtgui/group (optional, multiple): Enables grouping of plugins. Group tags can contain a label, icon and statustip tag. The groups form a hierarchy of menus where the plugin is added as the leaf. The groups of different plugins are merged based on their label (icons and statustip may be overridden by other plugins when they are defined differently).
- library/qtgui/label: Overrides the label with which the plugin appears in the menu.
- library/qtgui/icon: Defines the icon that should be shown beside the label (depending on the type of attribute).
- library/qtgui/icon@type:
- file (default): the icon value is a package-relative path to an image.
- theme: the icon value names an icon defined by the Icon Naming Specification.
- resource: the icon value names a Qt resource.
- library/qtgui/statustip: Overrides the status tip that is shown when hovering over the plugin label.
This script directory stores a python script that will launch the rqt package.
Please follow the naming convention in order for the package to work properly.
#!/usr/bin/env python
import sys
from rqt_gui.main import Main
main = Main()
sys.exit(main.main(
sys.argv,
# Note to follow the this structure to launch correctly
# 'namespace/class_name'
standalone='ros_rqt_plugin/two_button_plugin'
))
This section inform user when to recompile thier when there's changes.
When changes happen to the following files, please run catkin_make
again.
- plugin.xml
- scripts/ros_rqt_plugin
- include/ros_rqt_plugin/ros_rqt_plugin.hpp
- src/ros_rqt_plugin/ros_rqt_plugin.cpp
To obtain the header for #include <ros_rqt_plugin/ui_ros_rqt_plugin.h>
please include the build folder.
{
"configurations": [
{
"browse": {
"databaseFilename": "",
"limitSymbolsToIncludedHeaders": true
},
"includePath": [
"/usr/include/**",
"${workspaceFolder}/include/**",
"${workspaceFolder}/../../build/**"
],
"name": "ROS",
"compilerPath": "/usr/bin/gcc",
"cStandard": "c11",
"cppStandard": "c++14",
"intelliSenseMode": "gcc-x64"
}
],
"version": 4
Icon error:
UserWarning: icon “/opt/ros/melodic/share/rqt_virtual_joy/resource/input-gaming.png“ not found
Solution:
cd ~/Downloads
git clone https://github.com/aquahika/rqt_virtual_joystick.git
sudo cp -r ~/Downloads/rqt_virtual_joystick/resource /opt/ros/melodic/share/rqt_virtual_joy/
rm -rf ~/Downloads/rqt_virtual_joystick
rqt --standalone package_exe
rqt --list-plugins
-
Video lesson on UI file. link
-
main reference for package. link
-
updated rqt_image_viewer. link
-
older rqt_image_viewer. link
-
rqt plugin examples. link
-
reference to other people github tutorial if you are so incline. link1 link2
-
Two List Selection link
-
Icon list selection in rqt_gui link
-
Useful tutorial link