Skip to content

Commit a93ae3f

Browse files
committed
rviz_plugin_tutorials: Added sphinx-based tutorial documentation write-up.
1 parent 5bcbab9 commit a93ae3f

17 files changed

+489
-45
lines changed

rviz_plugin_tutorials/CMakeLists.txt

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,29 @@
1+
## BEGIN_TUTORIAL
2+
## This CMakeLists.txt file for rviz_plugin_tutorials builds both the TeleopPanel tutorial and the ImuDisplay tutorial.
3+
##
4+
## First start with some standard ROS stuff.
15
cmake_minimum_required(VERSION 2.4.6)
26
include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake)
3-
4-
# Set the build type. Options are:
5-
# Coverage : w/ debug symbols, w/o optimization, w/ code-coverage
6-
# Debug : w/ debug symbols, w/o optimization
7-
# Release : w/o debug symbols, w/ optimization
8-
# RelWithDebInfo : w/ debug symbols, w/ optimization
9-
# MinSizeRel : w/o debug symbols, w/ optimization, stripped binaries
107
set(ROS_BUILD_TYPE RelWithDebInfo)
11-
128
rosbuild_init()
139

14-
# This plugin includes Qt widgets, so we must include Qt like so:
10+
## This plugin includes Qt widgets, so we must include Qt like so:
1511
find_package(Qt4 COMPONENTS QtCore QtGui REQUIRED)
1612
include(${QT_USE_FILE})
1713

18-
# I prefer the Qt signals and slots to avoid defining "emit", "slots",
19-
# etc because they can conflict with boost signals.
14+
## I prefer the Qt signals and slots to avoid defining "emit", "slots",
15+
## etc because they can conflict with boost signals, so define QT_NO_KEYWORDS here.
2016
add_definitions(-DQT_NO_KEYWORDS)
2117

22-
# Here we specify which header files need to be run through "moc",
23-
# Qt's meta-object compiler.
18+
## Here we specify which header files need to be run through "moc",
19+
## Qt's meta-object compiler.
2420
qt4_wrap_cpp(MOC_FILES
2521
src/drive_widget.h
2622
src/teleop_panel.h
2723
)
2824

29-
# Here we specify the list of source files, including the output of
30-
# the previous command which is stored in ${MOC_FILES}.
25+
## Here we specify the list of source files, including the output of
26+
## the previous command which is stored in ``${MOC_FILES}``.
3127
set(SOURCE_FILES
3228
src/drive_widget.cpp
3329
src/teleop_panel.cpp
@@ -36,15 +32,23 @@ set(SOURCE_FILES
3632
${MOC_FILES}
3733
)
3834

39-
#set the default path for built executables to the "bin" directory
40-
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
41-
42-
#set the default path for built libraries to the "lib" directory
35+
## Set the default path for built libraries to the "lib" directory
4336
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
4437

45-
# An rviz plugin is just a shared library, so here we declare the
46-
# library and specify the list of source files we collected above.
38+
## An rviz plugin is just a shared library, so here we declare the
39+
## library to be called ``${PROJECT_NAME}`` (which is
40+
## "rviz_plugin_tutorials", or whatever your version of this project
41+
## is called) and specify the list of source files we collected above
42+
## in ``${SOURCE_FILES}``.
4743
rosbuild_add_library(${PROJECT_NAME} ${SOURCE_FILES})
4844

49-
# Link the library
45+
## Link the library with whatever Qt libraries have been defined by
46+
## the ``find_package(Qt4 ...)`` line above.
47+
##
48+
## Although this puts "rviz_plugin_tutorials" (or whatever you have
49+
## called the project) as the name of the library, cmake knows it is a
50+
## library and names the actual file something like
51+
## "librviz_plugin_tutorials.so", or whatever is appropriate for your
52+
## particular OS.
5053
target_link_libraries(${PROJECT_NAME} ${QT_LIBRARIES})
54+
## END_TUTORIAL

rviz_plugin_tutorials/manifest.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<url>http://ros.org/wiki/rviz_plugin_tutorials</url>
1111
<depend package="rviz"/>
1212
<export>
13-
<rviz plugin="${prefix}/plugin_description.xml"/>
13+
<rosdoc config="${prefix}/rosdoc.yaml"/>
14+
<rviz plugin="${prefix}/foo/plugin_description.xml"/>
1415
</export>
1516
</package>

rviz_plugin_tutorials/rosdoc.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- builder: sphinx
2+
sphinx_root_dir: src/doc

rviz_plugin_tutorials/src/doc/conf.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import sys, os
2+
3+
sys.path += [ os.path.abspath( '.' )]
4+
5+
extensions = [ 'sphinx.ext.extlinks',
6+
'rviz_plugin_tutorials.tutorialformatter' ]
7+
8+
# The master toctree document.
9+
master_doc = 'index'
10+
11+
# The suffix of source filenames.
12+
source_suffix = '.rst'
13+
14+
project = u'rviz_plugin_tutorials'
15+
16+
copyright = u'2012, Willow Garage, Inc'
17+
18+
# If true, sectionauthor and moduleauthor directives will be shown in the
19+
# output. They are ignored by default.
20+
show_authors = True
21+
22+
# The name of the Pygments (syntax highlighting) style to use.
23+
pygments_style = 'sphinx'
24+
25+
extlinks = {'svndir': ('https://code.ros.org/svn/ros-pkg/stacks/visualization_tutorials/branches/visualization_tutorials-0.6/rviz_plugin_tutorials/%s', '')}
Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
ImuDisplay
2+
==========
3+
4+
The RViz plugin API and library API are preliminary in Fuerte. We
5+
welcome feedback about how to make them more powerful and easier to
6+
program with. We expect the APIs to change (possibly significantly)
7+
between Fuerte and Groovy.
8+
9+
Overview
10+
--------
11+
12+
This tutorial shows how to write a simple Display plugin for RViz.
13+
14+
RViz does not currently have a way to display sensor_msgs/Imu messages
15+
directly. The code in this tutorial implements a subclass of
16+
rviz::Display to do so.
17+
18+
The source code for this tutorial is in the rviz_plugin_tutorials
19+
package. You can check out the source directly or (if you use Ubuntu)
20+
you can just apt-get install the pre-compiled Debian package like so::
21+
22+
sudo apt-get install ros-fuerte-visualization-tutorials
23+
24+
Here is what the new ImuDisplay output looks like, showing a sequence of
25+
sensor_msgs/Imu messages from the test script:
26+
27+
.. image:: imu_arrows.png
28+
29+
The Plugin Code
30+
---------------
31+
32+
The code for ImuDisplay is in these files:
33+
:svndir:`src/imu_display.h`,
34+
:svndir:`src/imu_display.cpp`,
35+
:svndir:`src/imu_visual.h`, and
36+
:svndir:`src/imu_visual.cpp`.
37+
38+
imu_display.h
39+
^^^^^^^^^^^^^
40+
41+
The full text of imu_display.h is here: :svndir:`src/imu_display.h`
42+
43+
.. tutorial-formatter:: ../imu_display.h
44+
45+
imu_display.cpp
46+
^^^^^^^^^^^^^^^
47+
48+
The full text of imu_display.cpp is here: :svndir:`src/imu_display.cpp`
49+
50+
.. tutorial-formatter:: ../imu_display.cpp
51+
52+
imu_visual.h
53+
^^^^^^^^^^^^
54+
55+
The full text of imu_visual.h is here: :svndir:`src/imu_visual.h`
56+
57+
.. tutorial-formatter:: ../imu_visual.h
58+
59+
imu_visual.cpp
60+
^^^^^^^^^^^^^^
61+
62+
The full text of imu_visual.cpp is here: :svndir:`src/imu_visual.cpp`
63+
64+
.. tutorial-formatter:: ../imu_visual.cpp
65+
66+
Building the Plugin
67+
-------------------
68+
69+
.. tutorial-formatter:: ../../CMakeLists.txt
70+
71+
To build the plugin, just do the normal "rosmake" thing::
72+
73+
rosmake rviz_plugin_tutorials
74+
75+
Exporting the Plugin
76+
--------------------
77+
78+
For the plugin to be found and understood by other ROS packages (in
79+
this case, rviz), it needs a "plugin_description.xml" file. This file
80+
can be named anything you like, as it is specified in the plugin
81+
package's "manifest.xml" file like so:
82+
83+
.. code-block:: xml
84+
85+
<export>
86+
<rviz plugin="${prefix}/plugin_description.xml"/>
87+
</export>
88+
89+
The contents of plugin_description.xml then look like this:
90+
91+
.. code-block:: xml
92+
93+
<library path="lib/librviz_plugin_tutorials">
94+
<class name="rviz_plugin_tutorials/Teleop"
95+
type="rviz_plugin_tutorials::TeleopPanel"
96+
base_class_type="rviz::Panel">
97+
<description>
98+
A panel widget allowing simple diff-drive style robot base control.
99+
</description>
100+
</class>
101+
<class name="rviz_plugin_tutorials/Imu"
102+
type="rviz_plugin_tutorials::ImuDisplay"
103+
base_class_type="rviz::Display">
104+
<description>
105+
Displays direction and scale of accelerations from sensor_msgs/Imu messages.
106+
</description>
107+
</class>
108+
</library>
109+
110+
The first line says that the compiled library lives in
111+
lib/librviz_plugin_tutorials (the ".so" ending is appended by
112+
pluginlib according to the OS). This path is relative to the top
113+
directory of the package:
114+
115+
.. code-block:: xml
116+
117+
<library path="lib/librviz_plugin_tutorials">
118+
119+
The next section is a ``class`` entry describing the TeleopPanel:
120+
121+
.. code-block:: xml
122+
123+
<class name="rviz_plugin_tutorials/Teleop"
124+
type="rviz_plugin_tutorials::TeleopPanel"
125+
base_class_type="rviz::Panel">
126+
<description>
127+
A panel widget allowing simple diff-drive style robot base control.
128+
</description>
129+
</class>
130+
131+
This specifies the name, type, base class, and description of the
132+
class. The *name* field must be a combination of the first two
133+
strings given to the ``PLUGINLIB_DECLARE_CLASS()`` macro in the source
134+
file. It must be the "package" name, a "/" slash, then the "display
135+
name" for the class.
136+
137+
The *type* entry must be the fully-qualified class name, including any
138+
namespace(s) it is inside.
139+
140+
The *base_class_type* is either ``rviz::Panel`` for a panel class, or
141+
``rviz::Display`` for a display class.
142+
143+
The *description* subsection is a simple text description of the
144+
class, which is shown in the class-chooser dialog and in the Displays
145+
panel help area. This section can contain HTML, including hyperlinks,
146+
but the markup must be escaped to avoid being interpreted as XML
147+
markup. For example a link tag might look like: ``&lt;a
148+
href="my-web-page.html"&gt;``.
149+
150+
Trying It Out
151+
-------------
152+
153+
Once your RViz plugin is compiled and exported, simply run rviz normally::
154+
155+
rosrun rviz rviz
156+
157+
and rviz will use pluginlib to find all the plugins exported to it.
158+
159+
Add an ImuDisplay by clicking the "Add" button at the bottom of the
160+
"Displays" panel (or by typing Control-N), then scrolling down through
161+
the available displays until you see "Imu" under your plugin package
162+
name (here it is "rviz_plugin_tutorials").
163+
164+
.. image:: imu_plugin.png
165+
166+
If "Imu" is not in your list of Display Types, look through RViz's
167+
console output for error messages relating to plugin loading. Some common
168+
problems are:
169+
170+
- not having a plugin_description.xml file,
171+
- not exporting it in the manifest.xml file, or
172+
- not properly referencing the library file (like
173+
librviz_plugin_tutorials.so) from plugin_description.xml.
174+
175+
Once you've added the Imu display to RViz, you just need to set the
176+
topic name of the display to a source of sensor_msgs/Imu messages.
177+
178+
If you don't happen to have an IMU or other source of sensor_msgs/Imu
179+
messages, you can test the plugin with a Python script like this:
180+
:svndir:`scripts/send_test_msgs.py`.
181+
182+
The script publishes on the "/test_imu" topic, so enter that.
183+
184+
The script publishes both Imu messages and a moving TF frame
185+
("/base_link" relative to "/map"), so make sure your "Fixed Frame" is
186+
set to "/map".
187+
188+
Finally, adjust the "History Length" parameter of the Imu display to
189+
10 and you should see something like the picture at the top of this
190+
page.
191+
192+
Note: If you use this to visualize messages from an *actual* IMU, the
193+
arrows are going to be huge compared to most robots:
194+
195+
.. image:: real_imu.png
196+
197+
(Note the PR2 robot at the base of the purple arrow.) This is because
198+
the Imu acceleration units are meters per second squared, and gravity
199+
is 9.8 m/s^2, and we haven't applied any scaling or gravity
200+
compensation to the acceleration vectors.
201+
202+
Next Steps
203+
----------
204+
205+
This ImuDisplay is not yet a terribly useful Display class. Extensions to make it more useful might be:
206+
207+
- Add a gravity-compensation option to the acceleration vector.
208+
- Visualize more of the data in the Imu messages.
209+
210+
To add a gravity compensation option, you might take steps like these:
211+
212+
- Add a new ``bool gravity_compensation_on_`` property to ImuDisplay to store whether the option is on or off.
213+
- Add getter and setter functions for it.
214+
- Add a new ``rviz::BoolPropertyWPtr`` to ImuDisplay to show the property in the property editor.
215+
- Add a new ``setGravityCompensation(bool)`` function to
216+
ImuVisual to tell the visual whether to subtract out gravity or not.
217+
- Compute the direction of gravity relative to the Imu frame
218+
orientation (as set in ImuVisual::setFrameOrientation()) and
219+
subtract it from the acceleration vector each time in
220+
ImuVisual::setMessage().
221+
222+
Since ImuVisual takes complete Imu messages as input, adding
223+
visualizations of more of the Imu data only needs modifications to
224+
ImuVisual. Imu data displays might look like:
225+
226+
- orientation: An rviz::Axes object at the Imu reference frame, turned to show the orientation.
227+
- angular_velocity: Maybe a line to show the axis of rotation and a 3D arrow curving around it to show the speed of rotation?
228+
- orientation_covariance: Maybe this is an ellipse at the end of each of the X, Y, and Z axes showing the orientation?
229+
- linear_acceleration_covariance: Maybe this is an ellipsoid at the end of the acceleration arrow?
230+
231+
As all this might be visually cluttered, it may make sense to include boolean options to enable or disable some of them.
14.7 KB
Loading
97.5 KB
Loading
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
RViz Plugin Tutorials
2+
=====================
3+
4+
The RViz plugin API and library API are preliminary in Fuerte. We
5+
welcome feedback about how to make them more powerful and easier to
6+
program with. We expect the APIs to change (possibly significantly)
7+
between Fuerte and Groovy.
8+
9+
The rviz_plugin_tutorials package builds a plugin library for rviz
10+
containing two main classes: ImuDisplay and TeleopPanel.
11+
12+
- :doc:`display_plugin_tutorial` is an example of an rviz::Display
13+
subclass allowing rviz to show data from sensor_msgs::Imu messages.
14+
15+
- :doc:`panel_plugin_tutorial` is an example of an rviz::Panel
16+
subclass which shows a simple control input for sending velocities
17+
to a mobile base.
18+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
TeleopPanel
2+
===========
3+
4+
This is an haitch file:
5+
6+
.. tutorial-formatter:: ../imu_display.h
7+
8+
This is a cpp file:
9+
10+
.. tutorial-formatter:: ../imu_display.cpp
11+
12+
This is the end.
58.3 KB
Loading

rviz_plugin_tutorials/src/doc/rviz_plugin_tutorials/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)