Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add python bindings based on Pyside2 #889

Open
wants to merge 17 commits into
base: rolling
Choose a base branch
from
Open
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ build
lib
*.sublime-workspace
**/.idea/**
*.vscode
3 changes: 3 additions & 0 deletions rviz_common/include/rviz_common/visualization_frame.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ class RVIZ_COMMON_PUBLIC VisualizationFrame : public QMainWindow, public WindowM
{
Q_OBJECT

protected:
explicit VisualizationFrame(QWidget * parent = nullptr);

public:
explicit VisualizationFrame(
ros_integration::RosNodeAbstractionIface::WeakPtr rviz_ros_node, QWidget * parent = nullptr);
Expand Down
24 changes: 24 additions & 0 deletions rviz_common/src/rviz_common/visualization_frame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,30 @@
namespace rviz_common
{

VisualizationFrame::VisualizationFrame(QWidget * parent)
: QMainWindow(parent),
app_(nullptr),
render_panel_(nullptr),
show_help_action_(nullptr),
file_menu_(nullptr),
recent_configs_menu_(nullptr),
toolbar_(nullptr),
manager_(nullptr),
splash_(nullptr),
toolbar_actions_(nullptr),
show_choose_new_master_option_(false),
panel_factory_(nullptr),
add_tool_action_(nullptr),
remove_tool_menu_(nullptr),
initialized_(false),
geom_change_detector_(new WidgetGeometryChangeDetector(this)),
loading_(false),
post_load_timer_(new QTimer(this)),
frame_count_(0),
toolbar_visible_(true)
{
}

VisualizationFrame::VisualizationFrame(
ros_integration::RosNodeAbstractionIface::WeakPtr rviz_ros_node, QWidget * parent)
: QMainWindow(parent),
Expand Down
169 changes: 169 additions & 0 deletions rviz_python_bindings/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
cmake_minimum_required(VERSION 3.17)
project(rviz_python_bindings)

set(shiboken_qt_components
QtCore
QtGui
QtWidgets
)

find_package(ament_cmake REQUIRED)
find_package(ament_cmake_python REQUIRED)
find_package(python_qt_binding REQUIRED)
include(${python_qt_binding_DIR}/shiboken_helper.cmake) #${CMAKE_CURRENT_SOURCE_DIR}/../../python_qt_binding/cmake/shiboken_helper.cmake)#
find_package(Qt5 REQUIRED COMPONENTS Core Gui Widgets)
find_package(rviz_common REQUIRED)
find_package(Python3 COMPONENTS Development)

# name of the library to be generated by shiboken
set(shiboken_bindings_library "rviz_shiboken")
# path to the include wrapper used by shiboken for generation
set(shiboken_include_wrapper "${CMAKE_CURRENT_SOURCE_DIR}/conf/global.hpp")
# path to the typesystem file used by shiboken for generation
set(shiboken_typesystem "${CMAKE_CURRENT_SOURCE_DIR}/conf/typesystem.xml")
# sources generated by shiboken depends on typesystem
set(shiboken_generated_sources
${CMAKE_CURRENT_BINARY_DIR}/${shiboken_bindings_library}/rviz_shiboken_module_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/${shiboken_bindings_library}/rviz_common_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/${shiboken_bindings_library}/rviz_common_visualizerframepy_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/${shiboken_bindings_library}/rviz_common_yamlconfigreader_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/${shiboken_bindings_library}/rviz_common_yamlconfigwriter_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/${shiboken_bindings_library}/rviz_common_config_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/${shiboken_bindings_library}/rviz_common_config_mapiterator_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/${shiboken_bindings_library}/rviz_common_visualizationframe_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/${shiboken_bindings_library}/rviz_common_visualizationmanager_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/${shiboken_bindings_library}/rviz_common_displaygroup_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/${shiboken_bindings_library}/rviz_common_display_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/${shiboken_bindings_library}/rviz_common_viewmanager_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/${shiboken_bindings_library}/rviz_common_paneldockwidget_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/${shiboken_bindings_library}/rviz_common_tool_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/${shiboken_bindings_library}/rviz_common_toolmanager_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/${shiboken_bindings_library}/rviz_common_properties_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/${shiboken_bindings_library}/rviz_common_properties_property_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/${shiboken_bindings_library}/rviz_common_properties_boolproperty_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/${shiboken_bindings_library}/rviz_common_viewcontroller_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/${shiboken_bindings_library}/rviz_rendering_ogrelogging_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/${shiboken_bindings_library}/rviz_rendering_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/${shiboken_bindings_library}/ogre_wrapper.cpp
)

ament_get_recursive_properties(deps_include_dirs _ ${rviz_common_TARGETS})
list(APPEND shiboken_include_dirs
${deps_include_dirs})
message(STATUS "ROS inlcude dirs: ${deps_include_dirs}")
message(STATUS "QT5 inlcude dirs: ${Qt5Core_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS} ${Qt5Gui_INCLUDE_DIRS}")
list(APPEND shiboken_include_dirs
${Qt5Core_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS} ${Qt5Gui_INCLUDE_DIRS}
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)

add_library(rviz_python SHARED
src/visualizer_frame_py.cpp
)

target_include_directories(rviz_python PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
target_compile_options(rviz_python PUBLIC -Wl,--no-undefined)
ament_target_dependencies(rviz_python
rviz_common
Qt5
)

install(TARGETS rviz_python
EXPORT export_rviz_python
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
)


shiboken_generator_ext(
"rviz_shiboken" # TARGET
"${shiboken_include_wrapper}" # INCLUDE WRAPPER
"${shiboken_typesystem}" # TYPSYSTEM
"${CMAKE_CURRENT_BINARY_DIR}" # Working Directory
"${shiboken_generated_sources}" # Generated Sources
"${shiboken_include_dirs}" # INCLUDE DIRS
"${CMAKE_CURRENT_BINARY_DIR}" # BUILD DIR
)

add_library(
${shiboken_bindings_library} MODULE
${shiboken_generated_sources})

shiboken_include_directories(
${shiboken_bindings_library}
"${shiboken_qt_components}")

target_include_directories(
${shiboken_bindings_library} PRIVATE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}
)

target_link_libraries(
${shiboken_bindings_library}
Qt5::Core
Qt5::Gui
Qt5::Widgets
rviz_python
)
ament_target_dependencies(
${shiboken_bindings_library}
rviz_common
)
shiboken_target_link_libraries(${shiboken_bindings_library} ${shiboken_qt_components})



set_target_properties(${shiboken_bindings_library} PROPERTIES
PREFIX "")
set_property(TARGET ${shiboken_bindings_library} PROPERTY OUTPUT_NAME
"${shiboken_bindings_library}.${Python3_SOABI}")

if(WIN32)
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
set_property(TARGET ${shiboken_bindings_library} PROPERTY SUFFIX "_d.pyd")
else()
set_property(TARGET ${shiboken_bindings_library} PROPERTY SUFFIX ".pyd")
endif()
target_link_libraries(
${shiboken_bindings_library}
Python3_LIBRARIES
)
endif()

ament_python_install_package(rviz)
install(TARGETS ${shiboken_bindings_library}
LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/${PYTHON_INSTALL_DIR}/rviz
)


if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
find_package(ament_cmake_pytest REQUIRED)
# the following line skips the linter which checks for copyrights
# comment the line when a copyright and license is added to all source files
set(ament_cmake_copyright_FOUND TRUE)
# the following line skips cpplint (only works in a git repo)
# comment the line when this package is in a git repo and when
# a copyright and license is added to all source files
set(ament_cmake_cpplint_FOUND TRUE)

ament_lint_auto_find_test_dependencies()
endif()

ament_export_include_directories(
include
)
ament_export_libraries(
rviz_python
)
ament_export_targets(
export_rviz_python
)

ament_package()
37 changes: 37 additions & 0 deletions rviz_python_bindings/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# RVIZ Pyhon Bindings

## Usage
To use the python bindings, you need to do the following:

```python
import os
os.environ["QT_API"] = "pyside2"
from rviz import rviz_common
```

Currently only pyside2 is supported. No stubs are generated, so pylance does not work on namespaces.
The following classes are wrapped:
* VisualizationFrame
* Config
* VisualizationManager
* ViewController
* ViewManager
* DisplayGroup
* Display
* PanelDockWidget
* Tool
* ToolManager
* YamlConfigReader
* YamlConfigWriter
* Property
* BoolProperty

## Windows specifics
On windows you will need to install the following dependencies manually:

```
pip install \
--index-url=https://download.qt.io/official_releases/QtForPython/ \
--trusted-host download.qt.io \
shiboken2 pyside2 shiboken2_generator
```
54 changes: 54 additions & 0 deletions rviz_python_bindings/conf/global.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright (c) 2011, Willow Garage, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the Willow Garage, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef PYTHON_GLOBAL_H
#define PYTHON_GLOBAL_H

#include <pyside2_global.h>
#include <QtCore/QtCore>
#include <QtGui/QtGui>
#include <QtWidgets/QtWidgets>
#include <rviz_common/visualization_frame.hpp>
#include <rviz_common/visualization_manager.hpp>
#include <rviz_common/display_group.hpp>
#include <rviz_common/display.hpp>
#include <rviz_common/view_manager.hpp>
#include <rviz_common/tool.hpp>
#include <rviz_common/tool_manager.hpp>
#include <rviz_common/panel_dock_widget.hpp>
#include <rviz_common/properties/bool_property.hpp>
#include <rviz_common/properties/property.hpp>
#include <rviz_python_bindings/visualizer_frame_py.hpp>
#include <rviz_common/yaml_config_reader.hpp>
#include <rviz_common/yaml_config_writer.hpp>
#include <rviz_common/config.hpp>
#include <rviz_common/view_controller.hpp>
#include <rviz_rendering/ogre_logging.hpp>

#endif // PYTHON_GLOBAL_H
35 changes: 35 additions & 0 deletions rviz_python_bindings/conf/typesystem.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version="1.0"?>
<typesystem package="rviz_shiboken">

<load-typesystem name="typesystem_core.xml" generate="no"/>
<load-typesystem name="typesystem_gui.xml" generate="no"/>
<load-typesystem name="typesystem_widgets.xml" generate="no"/>
<namespace-type name="Ogre">
<primitive-type name="Vector3"/>
</namespace-type>
<namespace-type name="rviz_common">
<object-type name="VisualizationFrame"/>
<object-type name="VisualizationManager"/>
<object-type name="ViewManager"/>
<object-type name="DisplayGroup"/>
<object-type name="Display"/>
<object-type name="VisualizerFramePy"/>
<object-type name="PanelDockWidget"/>
<object-type name="Tool"/>
<object-type name="ToolManager"/>
<object-type name="YamlConfigReader"/>
<object-type name="YamlConfigWriter"/>
<object-type name="ViewController"/>
<object-type name="Config">
<enum-type name="Type"/>
<object-type name="MapIterator"/>
</object-type>
<namespace-type name="properties">
<object-type name="Property"/>
<object-type name="BoolProperty"/>
</namespace-type>
</namespace-type>
<namespace-type name="rviz_rendering">
<object-type name="OgreLogging"/>
</namespace-type>
</typesystem>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#ifndef VISUALIZER_FRAME_PY_HPP
#define VISUALIZER_FRAME_PY_HPP

#include "rviz_common/visualization_frame.hpp"
#include "rviz_common/ros_integration/ros_client_abstraction.hpp"
#include "rviz_common/ros_integration/ros_node_abstraction.hpp"

namespace rviz_common
{

class VisualizerFramePy : public VisualizationFrame
{
protected:
std::unique_ptr<rviz_common::ros_integration::RosClientAbstraction> ros_client_abstraction_;

public:
explicit VisualizerFramePy(
QWidget * parent = nullptr);

~VisualizerFramePy()
{
ros_client_abstraction_->shutdown();
}

bool node_ok();

void initialize(const QString & display_config_file = "");
};
}

#endif
Loading