Bird
Raised Fist0
ROSframework~20 mins

Visualizing sensor data (laser, camera, IMU) in ROS - Practice Problems & Coding Challenges

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Challenge - 5 Problems
🎖️
Sensor Data Visualization Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
component_behavior
intermediate
2:00remaining
What does this ROS node output when visualizing laser scan data?
Consider a ROS node subscribing to a LaserScan topic and publishing a MarkerArray for visualization. What will be the visible output in RViz if the node publishes a MarkerArray with points corresponding to the laser scan ranges?
ROS
import rospy
from sensor_msgs.msg import LaserScan
from visualization_msgs.msg import Marker, MarkerArray
from geometry_msgs.msg import Point
from math import cos, sin

class LaserVisualizer:
    def __init__(self):
        self.pub = rospy.Publisher('visualization_marker_array', MarkerArray, queue_size=1)
        self.sub = rospy.Subscriber('scan', LaserScan, self.callback)

    def callback(self, msg):
        markers = MarkerArray()
        marker = Marker()
        marker.header = msg.header
        marker.type = Marker.POINTS
        marker.action = Marker.ADD
        marker.scale.x = 0.05
        marker.scale.y = 0.05
        marker.color.a = 1.0
        marker.color.r = 1.0

        for i, r in enumerate(msg.ranges):
            if r < msg.range_max:
                angle = msg.angle_min + i * msg.angle_increment
                x = r * cos(angle)
                y = r * sin(angle)
                p = Point()
                p.x = x
                p.y = y
                p.z = 0
                marker.points.append(p)

        markers.markers.append(marker)
        self.pub.publish(markers)

rospy.init_node('laser_visualizer')
vis = LaserVisualizer()
rospy.spin()
AA 3D mesh of the environment generated from laser points.
BA continuous red line connecting all laser points in order.
CNo visible output because MarkerArray is not supported for laser data.
DA cloud of red points in RViz representing detected obstacles around the robot.
Attempts:
2 left
💡 Hint
Think about how Marker type POINTS displays data in RViz.
📝 Syntax
intermediate
1:30remaining
Which option correctly subscribes to a ROS camera image topic using cv_bridge?
You want to subscribe to the '/camera/image_raw' topic and convert the ROS Image message to an OpenCV image for processing. Which code snippet correctly does this?
ROS
import rospy
from sensor_msgs.msg import Image
from cv_bridge import CvBridge, CvBridgeError
import cv2

class ImageProcessor:
    def __init__(self):
        self.bridge = CvBridge()
        self.sub = rospy.Subscriber('/camera/image_raw', Image, self.callback)

    def callback(self, msg):
        try:
            cv_image = self.bridge.imgmsg_to_cv2(msg, 'bgr8')
            # process cv_image here
        except CvBridgeError as e:
            rospy.logerr(e)

rospy.init_node('image_processor')
proc = ImageProcessor()
rospy.spin()
Acv_image = CvBridge.imgmsg_to_cv2(msg, 'bgr8')
Bcv_image = self.bridge.imgmsg_to_cv2(msg, 'bgr8')
Ccv_image = self.bridge.cv2_to_imgmsg(msg, 'bgr8')
Dcv_image = cv2.imgmsg_to_cv2(msg, 'bgr8')
Attempts:
2 left
💡 Hint
Remember to use the instance method of CvBridge to convert ROS Image to OpenCV image.
🔧 Debug
advanced
2:30remaining
Why does this IMU visualization node fail to update orientation markers in RViz?
Given this ROS node snippet that subscribes to IMU data and publishes an Arrow marker to visualize orientation, why does the arrow not update in RViz?
ROS
def imu_callback(msg):
    marker = Marker()
    marker.header = msg.header
    marker.type = Marker.ARROW
    marker.action = Marker.ADD
    marker.scale.x = 0.5
    marker.scale.y = 0.1
    marker.scale.z = 0.1
    marker.color.a = 1.0
    marker.color.g = 1.0
    marker.pose.orientation = msg.orientation
    pub.publish(marker)

rospy.Subscriber('/imu/data', Imu, imu_callback)
pub = rospy.Publisher('imu_marker', Marker, queue_size=1)
AThe marker lacks a unique id, so RViz treats each publish as a new marker and does not update the existing one.
BThe orientation data from IMU is invalid and causes the marker to not render.
CThe marker scale is too small to be visible in RViz.
DThe publisher is created after the subscriber, causing a race condition.
Attempts:
2 left
💡 Hint
Markers need an id to be updated properly in RViz.
🧠 Conceptual
advanced
2:00remaining
What is the main advantage of using ROS message filters when visualizing synchronized sensor data?
When visualizing data from multiple sensors like laser, camera, and IMU, why is it beneficial to use ROS message_filters ApproximateTimeSynchronizer or TimeSynchronizer?
AThey ensure messages from different topics are processed together with matching timestamps, providing coherent fused visualization.
BThey automatically convert sensor data formats to a common type for visualization.
CThey reduce the bandwidth by compressing sensor messages before visualization.
DThey provide 3D rendering capabilities inside RViz for all sensor types.
Attempts:
2 left
💡 Hint
Think about how sensor data timestamps affect combined visualization.
state_output
expert
3:00remaining
What is the output of this ROS Python node publishing a PointCloud2 message from laser scan data?
This node converts LaserScan ranges to a PointCloud2 message and publishes it. What will be the number of points in the published PointCloud2 message if the laser scan has 360 range readings and 10 of them are out of range (greater than range_max)?
ROS
import rospy
from sensor_msgs.msg import LaserScan, PointCloud2, PointField
import sensor_msgs.point_cloud2 as pc2
from std_msgs.msg import Header
from math import cos, sin

class LaserToPointCloud:
    def __init__(self):
        self.pub = rospy.Publisher('cloud', PointCloud2, queue_size=1)
        self.sub = rospy.Subscriber('scan', LaserScan, self.callback)

    def callback(self, scan):
        points = []
        for i, r in enumerate(scan.ranges):
            if r <= scan.range_max:
                angle = scan.angle_min + i * scan.angle_increment
                x = r * cos(angle)
                y = r * sin(angle)
                points.append([x, y, 0.0])

        header = Header()
        header.stamp = rospy.Time.now()
        header.frame_id = scan.header.frame_id

        fields = [
            PointField('x', 0, PointField.FLOAT32, 1),
            PointField('y', 4, PointField.FLOAT32, 1),
            PointField('z', 8, PointField.FLOAT32, 1)
        ]

        cloud = pc2.create_cloud(header, fields, points)
        self.pub.publish(cloud)

rospy.init_node('laser_to_cloud')
converter = LaserToPointCloud()
rospy.spin()
A360 points in the PointCloud2 message.
B10 points in the PointCloud2 message.
C350 points in the PointCloud2 message.
D350 points plus 10 points with zero coordinates.
Attempts:
2 left
💡 Hint
Points with ranges greater than range_max are excluded from the point list.

Practice

(1/5)
1. What is the primary tool used in ROS to visualize sensor data like laser scans, camera images, and IMU readings?
easy
A. rqt_graph
B. RViz
C. Gazebo
D. rosbag

Solution

  1. Step 1: Identify visualization tools in ROS

    RViz is designed specifically for visualizing sensor data and robot state.
  2. Step 2: Compare with other tools

    Gazebo is for simulation, rqt_graph shows node connections, rosbag records data but does not visualize directly.
  3. Final Answer:

    RViz -> Option B
  4. Quick Check:

    Visualizing sensor data = RViz [OK]
Hint: Remember: RViz = visualize sensor data graphically [OK]
Common Mistakes:
  • Confusing Gazebo (simulation) with RViz (visualization)
  • Thinking rosbag directly shows sensor visuals
  • Mixing rqt_graph with visualization tools
2. Which ROS message type is typically used to represent laser scan data for visualization in RViz?
easy
A. geometry_msgs/Twist
B. sensor_msgs/Image
C. sensor_msgs/Imu
D. sensor_msgs/LaserScan

Solution

  1. Step 1: Identify message types for sensors

    Laser scan data is published as sensor_msgs/LaserScan in ROS.
  2. Step 2: Match message types to sensors

    Image is for cameras, Imu for inertial data, Twist for robot velocity commands.
  3. Final Answer:

    sensor_msgs/LaserScan -> Option D
  4. Quick Check:

    Laser data = LaserScan message [OK]
Hint: LaserScan message type carries laser data [OK]
Common Mistakes:
  • Choosing Image for laser data
  • Confusing Imu message with laser data
  • Selecting Twist which is for movement commands
3. Given the following ROS Python snippet subscribing to a camera topic, what will be printed when an image message is received?
def callback(data):
    print(f"Received image with height: {data.height}")

sub = rospy.Subscriber('/camera/image_raw', sensor_msgs.msg.Image, callback)
rospy.spin()
medium
A. Received image with height: None
B. Error: 'Image' object has no attribute 'height'
C. Received image with height:
D. No output because callback is never called

Solution

  1. Step 1: Understand the callback function

    The callback prints the height attribute of the Image message received.
  2. Step 2: Confirm Image message has height attribute

    sensor_msgs/Image includes a height field representing image rows.
  3. Final Answer:

    Received image with height: <image height value> -> Option C
  4. Quick Check:

    Image message has height attribute = prints height [OK]
Hint: Image messages have height attribute accessible in callback [OK]
Common Mistakes:
  • Assuming height is None or missing
  • Thinking callback is not triggered
  • Confusing attribute names in Image message
4. You wrote this ROS node to visualize IMU data but get an error:
def imu_callback(msg):
    print(msg.orientation.x)

rospy.Subscriber('/imu/data', sensor_msgs.msg.Imu, imu_callback)
rospy.spin()

What is the likely cause of the error?
medium
A. Missing import of sensor_msgs.msg.Imu
B. IMU topic name is incorrect
C. Orientation field does not have x attribute
D. Callback function signature is wrong

Solution

  1. Step 1: Check for imports

    Using sensor_msgs.msg.Imu requires importing sensor_msgs.msg.Imu before subscribing.
  2. Step 2: Verify topic and callback correctness

    Topic name '/imu/data' and callback signature are correct; orientation.x exists in Imu message.
  3. Final Answer:

    Missing import of sensor_msgs.msg.Imu -> Option A
  4. Quick Check:

    Import Imu message before subscribing [OK]
Hint: Always import message types before subscribing [OK]
Common Mistakes:
  • Assuming topic name is wrong without checking
  • Thinking orientation.x does not exist
  • Using wrong callback parameters
5. You want to visualize laser scan data and camera images simultaneously in RViz. Which of the following steps correctly sets this up?
hard
A. Launch RViz, add LaserScan and Image displays, set topics to /scan and /camera/image_raw respectively
B. Launch Gazebo, add LaserScan and Image plugins, set topics to /laser and /camera/image
C. Use rosbag play with recorded data, RViz auto-detects topics and shows all sensors
D. Write a node to merge laser and camera data into one topic, then visualize in RViz

Solution

  1. Step 1: Understand RViz display setup

    RViz allows adding displays for different sensor types and setting their topics manually.
  2. Step 2: Match topics and displays

    LaserScan display subscribes to /scan, Image display subscribes to /camera/image_raw for camera images.
  3. Step 3: Evaluate other options

    Gazebo is simulation, rosbag does not auto-add displays, merging topics is unnecessary for visualization.
  4. Final Answer:

    Launch RViz, add LaserScan and Image displays, set topics to /scan and /camera/image_raw respectively -> Option A
  5. Quick Check:

    RViz displays + correct topics = visualize sensors [OK]
Hint: Add displays in RViz and set correct sensor topics [OK]
Common Mistakes:
  • Confusing Gazebo with RViz for visualization
  • Expecting rosbag to auto-configure displays
  • Merging topics unnecessarily