CSCE 452/752 Robotics and Spatial Intelligence, Fall 2025

Notes on rviz2

When
rviz
does not update its visualization

Problem

In class on October 8, your instructor experienced an unexpected error from
rviz2
in which the visualization in the window did not refresh correctly unless the window was resized. This was accompanied by an error message in the console:
QObject::startTimer: Timers cannot have negative intervals
        

Solution

The error seems to have been caused by a problem in some portion of the persistent settings maintained by
rviz2
. It can be resolved by deleting these persistent settings with a command like this
rm -rv  /.rviz2
        
and restarting
rviz
.

Visualizing
LaserScan
data
rviz

Under normal circumstances, you can use
rviz
to display
LaserScan
data directly, simply by adding a LaserScan display and pointing the new display to the correct topic. If this works in your system, then you can safely ignore this section.
However...

Problem

There seems to be a bug in certain versions of
rviz
which, under certain circumstances, prevents
rviz
from displaying LaserScan data correctly. Symptoms of this bug include:
(Details, in case you are curious: The issue occurs specifically when the
frame_id
of the
LaserScan
is different from the global fixed frame. In that case,
rviz
must use
tf
to look up the most recent transformation between the two frames. If that transformation is changing over time, then
rviz
seems to fail in some cases to look up the most recent transform correctly. Without this transform,
rviz
cannot display the data, because it does not know where the points should appear.)

Solution

The most straightforward way to work around this bug is to publish your laser scan data as a
PointCloud
in addition to is normal
LaserScan
form. The
PointCloud
display seems not to be affected by this bug.
In Python, if you have a
LaserScan
message object, you can construct an equivalent
PointCloud
message using code of this general form:
def laser_scan_to_point_cloud(scan):
    return PointCloud(header=scan.header, points = [ Point32(x=scan.ranges[i]*cos(scan.angle_min+i*scan.angle_increment), y=scan.ranges[i]*sin(scan.angle_min+i*scan.angle_increment), z=0.0) for i in range(len(scan.ranges)) ])
        
Then you can publish this
PointCloud
normally and visualize it in
rviz
using a
PointCloud
display.