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

[ROS 2]: Add Python bindings #239

Open
wants to merge 4 commits into
base: ros2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 24 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -231,12 +231,6 @@ ament_export_dependencies(geometry_msgs
rviz_ogre_vendor
)
ament_export_include_directories(include)
ament_export_libraries(
${PROJECT_NAME}
${PROJECT_NAME}_remote_control
${PROJECT_NAME}_imarker_simple
${PROJECT_NAME}_gui
)

##########
## TEST ##
Expand All @@ -256,4 +250,28 @@ if (BUILD_TESTING)
)
endif()

####################
## Python binding ##
####################

find_package(Python3 REQUIRED COMPONENTS Interpreter Development)
find_package(pybind11_vendor REQUIRED)
find_package(pybind11 REQUIRED)
find_package(py_binding_tools REQUIRED)

ament_python_install_package(rviz_visual_tools PACKAGE_DIR python/rviz_visual_tools)

pybind11_add_module(pyrviz_visual_tools python/src/rviz_visual_tools.cpp)
target_link_libraries(pyrviz_visual_tools PRIVATE rviz_visual_tools py_binding_tools::py_binding_tools)
ament_target_dependencies(pyrviz_visual_tools pybind11)

install(DIRECTORY python/include/ DESTINATION include/rviz_visual_tools)
install(TARGETS pyrviz_visual_tools
LIBRARY DESTINATION ${PYTHON_INSTALL_DIR}/rviz_visual_tools)
install(PROGRAMS
python/examples/rviz_visual_tools_demo.py
DESTINATION lib/${PROJECT_NAME}
)
ament_export_dependencies(py_binding_tools)

ament_package()
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ To see random shapes generated in Rviz, first launch Rviz:

Then start the RViz Visual Tools demo:

ros2 run rviz_visual_tools rviz_visual_tools_demo
ros2 run rviz_visual_tools rviz_visual_tools_demo # Or rviz_visual_tools_demo.py for the python version

## Code API

Expand Down
2 changes: 2 additions & 0 deletions package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,11 @@
<depend>visualization_msgs</depend>
<depend>std_msgs</depend>
<depend>trajectory_msgs</depend>
<depend>py_binding_tools</depend>

<build_depend>qtbase5-dev</build_depend>
<build_depend>eigen</build_depend>
<build_depend>pybind11_vendor</build_depend>

<build_export_depend>eigen</build_export_depend>
<exec_depend>libqt5-widgets</exec_depend>
Expand Down
145 changes: 145 additions & 0 deletions python/examples/rviz_visual_tools_demo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
#!/usr/bin/env python3
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a note here and in the README that the python demo shows a smaller example of the displayable shapes (compared to the cpp version) in Rviz so users don't think it's missing stuff.


import rviz_visual_tools as rvt
from rclpy.logging import get_logger
from geometry_msgs.msg import Point, Pose, Quaternion
from threading import Thread
import numpy as np
from copy import deepcopy
import rclcpp

LOGGER = get_logger("rviz_visual_tools_demo")

rclcpp.init()
node = rclcpp.Node("rviz_visual_tools_demo")
visual_tools = rvt.RvizVisualTools(node, "world", "/rviz_visual_tools")
visual_tools.load_marker_publisher(True)
visual_tools.delete_all_markers()
visual_tools.enable_batch_publishing(True)

point = Point(x=0.0, y=0.0, z=0.0)

step_x = 0.1

LOGGER.info("Displaying range of colors red->green")
visual_tools.publish_text(
Pose(),
"Shpere-Color-Range",
rvt.Colors.WHITE,
rvt.Scales.XXLARGE,
False,
)
for color in (rvt.Colors.BLACK, rvt.Colors.GREY, rvt.Colors.WHITE, rvt.Colors.RED):
visual_tools.publish_sphere(point, scale=rvt.Scales.XLARGE, color=color)
point.x += step_x
visual_tools.trigger()


LOGGER.info("Displaying Coordinate Axis")
visual_tools.publish_text(
Pose(position=Point(x=0.0, y=-0.2, z=0.0)),
"Coordinate-Axis",
rvt.Colors.WHITE,
rvt.Scales.XXLARGE,
False,
)
visual_tools.publish_axis(Pose(position=Point(x=0.0, y=-0.2, z=0.0)))
visual_tools.publish_axis(
Pose(
position=Point(x=0.25, y=-0.2, z=0.0),
orientation=Quaternion(x=0.0, y=0.0, z=1.0, w=0.0),
)
)
visual_tools.trigger()

LOGGER.info("Displaying Arrows")
visual_tools.publish_text(
Pose(position=Point(x=0.0, y=-0.4, z=0.0)),
"Arrows",
rvt.Colors.WHITE,
rvt.Scales.XXLARGE,
False,
)
visual_tools.publish_x_arrow(
Pose(
position=Point(x=0.0, y=-0.4, z=0.0),
orientation=Quaternion(x=0.0, y=0.0, z=0.0, w=1.0),
)
)
visual_tools.publish_y_arrow(
Pose(
position=Point(x=0.25, y=-0.4, z=0.0),
orientation=Quaternion(x=0.0, y=0.0, z=0.0, w=1.0),
)
)
visual_tools.publish_z_arrow(
Pose(
position=Point(x=0.5, y=-0.4, z=0.0),
orientation=Quaternion(x=0.0, y=0.0, z=0.0, w=1.0),
)
)
visual_tools.trigger()

cuboid_max_size = 0.075
cuboid_min_size = 0.01
point1 = Point(x=0.0, y=-0.6, z=0.0)
LOGGER.info("Displaying Rectangular Cuboid")
visual_tools.publish_text(
Pose(position=point1), "Cuboid", rvt.Colors.WHITE, rvt.Scales.XXLARGE, False
)
for i in np.linspace(0, 1.0, 10):
point2 = deepcopy(point1)
point2.x += i * cuboid_max_size + cuboid_min_size
point2.y += i * cuboid_max_size + cuboid_min_size
point2.z += i * cuboid_max_size + cuboid_min_size
visual_tools.publish_cuboid(point1, point2, color=rvt.Colors.RAND)
point1.x += step_x
visual_tools.trigger()

line_max_size = 0.075
line_min_size = 0.01
point1 = Point(x=0.0, y=-0.8, z=0.0)
LOGGER.info("Displaying Lines")
visual_tools.publish_text(
Pose(position=point1), "Line", rvt.Colors.WHITE, rvt.Scales.XXLARGE, False
)
for i in np.linspace(0, 1.0, 10):
point2 = deepcopy(point1)
point2.x += i * line_max_size + line_min_size
point2.y += i * line_max_size + line_min_size
point2.z += i * line_max_size + line_min_size
visual_tools.publish_line(point1, point2, color=rvt.Colors.RAND)
point1.x += step_x
visual_tools.trigger()

LOGGER.info("Displaying Cylinder")
visual_tools.publish_cylinder(
Pose(position=Point(x=0.0, y=0.2, z=0.0)), color=rvt.Colors.RAND
)
visual_tools.trigger()

LOGGER.info("Displaying Cone")
visual_tools.publish_cone(
Pose(position=Point(x=0.0, y=0.4, z=0.0)),
angle=np.pi,
color=rvt.Colors.RAND,
scale=0.1,
)
visual_tools.trigger()

LOGGER.info("Displaying Planes")
plane_pose = Pose(position=Point(x=0.0, y=0.6, z=0.0))
visual_tools.publish_xy_plane(plane_pose, color=rvt.Colors.RED, scale=0.1)
visual_tools.publish_xz_plane(plane_pose, color=rvt.Colors.GREEN, scale=0.1)
visual_tools.publish_yz_plane(plane_pose, color=rvt.Colors.BLUE, scale=0.1)
visual_tools.trigger()

LOGGER.info("Displaying Labeled Coordinate Axis")
visual_tools.publish_axis_labeled(Pose(position=Point(x=0.0, y=0.8, z=0.0)), "MyAxis")
visual_tools.trigger()

LOGGER.info("Displaying Path")
visual_tools.publish_path(
[Point(x=0.0, y=1.0, z=0.0), Point(x=0.2, y=1.0, z=0.0), Point(x=0.4, y=1.1, z=0.0)]
)
visual_tools.trigger()
6 changes: 6 additions & 0 deletions python/rviz_visual_tools/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from rviz_visual_tools.pyrviz_visual_tools import (
Scales,
Colors,
EulerConvention,
RvizVisualTools,
)
Empty file.
Loading
Loading