UP | HOME

Visualization in ROS

Overview

  • ROS has several tools for interacting graphically with robotic systems.
    • rviz2 is the primary tool for visualizing your robot and its sensor data in 3D
    • rqt is for creating a graphical user interface (GUI) in ROS.
  • Much of this information has not been documented for ROS 2 but it is substantially similar to ROS 1, therefore these notes often refer to ROS 1 documentation.

Rviz2

  • rviz2 is used to visualize data in ROS in a 3D environment
  • In rviz2 you add Display Types to the display and connect them to information that rviz2 receives via ROS messages and parameters.
    • There are many built in Display Types, documented in FEATURES.md

Paths

  • Paths allow you to visualize a series of points that have been visited over time
  • These are visualized with the Path datatype using nav_msgs/Path messages

Visualization Messages

  • The visualization_msgs package contains messages for displaying visual primitives in rviz2 using some Display Types in Rviz2

Markers

  • Markers are the simplest visualization message
  • They let you draw basic shapes at specified locations
    • For example, spheres, cubes, cylinders, lines
  • Markers are drawn by publishing marker messages
    • By default, the Marker display type listens on the visualization_marker topic, but this can be changed in the rviz2 gui or with remapping.
    • Markers have a header field that requires the time. Using node.get_clock().now() for this ensures the Marker will be drawn
    • Be sure to set the alpha (.a) field to be non-zero (e.g. 1) so that the marker is not drawn transparently
  • These C++ tutorials mostly apply to python as well since they are simply setting values in the marker message topic
  • Some important fields are
    • header contains the time at which the marker comes into existence and the frame used to interpret any coordinates
    • ns and id are used to identify the marker. For a given namespace ns each marker has an id. If you send a marker message with an id and ns that already exists, you modify the existing marker
    • type What the shape of the marker is: =visualization_msgs.Marker.{ARROW | CUBE | SPHERE | CYLINDER …}
    • action Lets you either visualization_msgs.Marker.ADD, visualization_msgs.Marker.DELETE, or visualization_msgs.Marker.DELETEALL the markers
    • pose this is the 3D pose of the object, used to set its position and orientation relative to header.frame_id
    • scale used to set the size of the object. By default the markers are 1x1x1 meter.
    • color RGBA (red, green, blue, alpha) color (0 - 1). A common error is forgetting to set the alpha to a non-zero value, otherwise the marker is completely transparent
    • lifetime How long to display the marker before it disappears. Set to 0 for it to last forever (well at least as long as Rviz2 remains open!)
    • frame_locked - Controls behavior of the marker when it's parent frame moves. If this is true then the marker will always be at the same position relative to its parent frame, even if that frame moves after the marker is drawn
    • points and colors, text, mesh_resource are used for some marker types
  • An example of markers is here https://github.com/m-elwin/me495_markers

MarkerArray

  • The MarkerArray message consists of an array of Marker messages
  • This message type lets you publish multiple markers with a single message
  • rviz2 has a DisplayType that can subscribe to a MarkerArray message and visualize all markers in the array
  • If you are sending many markers, it is more efficient to send them as an array

Static Markers

  1. Some markers visualize something that does not move and therefore (in an ideal world) would only be published one time
    • These markers could all be published in a single MarkerArray message, for example
  2. However, if rviz opens after the markers are published, it will not have received the message and will not display the markers
    • It is generally difficult and not a good idea to require one node to start before another in ROS
  3. ROS 1 had a mechanism called a "latching publisher" to help with this issue:
    • The latching publisher remembers the last message it published
    • When a new subscriber connects, that message is sent to the new subscriber
    • For example, if rviz launched after the message is published, it would still receive the message due to the latching
  4. In ROS 2 the Quality of Service (QoS) settings enable emulating the behavior similar to ROS 1
    • The publisher on the topic should have it's "Durability" set to TRANSIENT_LOCAL
    • The subscriber (e.g., the Marker Display in rviz) should also have it's "Durability" set to TRANSIENT_LOCAL
    • When the subscriber connects to the publisher it will receive the last message published
    • The main difference from ROS 1 is that both publisher and subscriber must have matching settings: see ros2 Issue on latching
  5. To set the QoS setting for Durability in python:

    from rclpy.qos import QoSProfile, QoSDurabilityPolicy
    
    # The depth here is what you typically pass in as the 3rd argument to create_publisher
    qos = QoSProfile(depth=10, durability=QoSDurabilityPolicy.TRANSIENT_LOCAL)
    create_publisher(Type, "topic_name", qos)
    
  6. In rviz the Durability policy is selected from a list of options for the marker display widget

InteractiveMarkers

  • Interactive Markers lets users manipulate markers inside Rviz2. Your nodes can then respond to the actions of the user.
  • To use interactive markers, you create an InteractiveMarkerServer
    • This server creates the necessary publishers and subscribers
    • You then provide a callback which gets called whenever the user manipulates the marker in rviz2
    • You can call functions to change the marker in rviz2
  • To learn interactive markers, you should go through at least the first two of these tutorials:
  • An additional example of using interactive markers is here
Plugins
  • Using markers enables you to create complex visualizations by building ROS messages
  • However, marker messages are quite large and using many of them can become slow
  • Fortunately, rviz2 is modular: each of the built-in DisplayTypes is actually a plugin.
  • You can write your own plugins in C++ that contain display logic for your own message types
  • Plugins can also add panels in rviz2 (Panels Tutorial)
  • Plugins can also add tools that change what the mouse does in rviz2 (Tools Tutorial).

rqt

  • Qt is a library for creating graphical user interfaces
  • rqt is a ROS package that enables you to create GUIs using ROS nodes
  • If you create a widget in Qt you can wrap that widget with rqt and use it as part of the ROS user interface
  • Essentially, rqt widgets can be docked and split in a parent window. These configurations can be saved so that others can reproduce your view
  • All built-in rqt plugins can be run with ros2 run
    • Type ros2 run rqt_ then hit tab to see a list of packages.
    • Some of these tools are so useful and popular they have there own shortcuts on the path
      • Type rqt_ then tab to see these. For example
      • rqt_graph - seeing how nodes are connected to each other via topics
      • rqt_console - reading debugging output from ros nodes
      • rqt_logger_level - used to set debugging output level for ROS
      • rqt_plot - plotting message values versus time

rqt_plot

  • rqt_plot is the simplest way to draw real-time time-plots of data from ROS topics
  • You can specify what fields of which topics to plot in the gui or

Author: Matthew Elwin