ROS2 Humble+ Vulkan GPU C++20 Thread-safe Zero rqt dependency SPECTRA_USE_ROS2

ROS2 Adapter

GPU-accelerated ROS2 visualization, debugging, and analysis. Replaces rqt with a single Vulkan-powered tool — topic monitor, live plotter, bag player/recorder, TF tree, node graph, parameter editor, service caller, and more.

Quick Start — First Plot in 10 Seconds

Goal: go from a live ROS graph to a scrolling GPU plot without installing rqt, PlotJuggler, and RViz separately. Build once, then use either --topics or a checked-in session preset.

  1. Source ROS2 and build spectra-ros
    # One-time setup (Humble example)
    source /opt/ros/humble/setup.bash
    cmake -S . -B build -G Ninja \
      -DSPECTRA_USE_ROS2=ON \
      -DSPECTRA_ROS2_BAG=ON \
      -DCMAKE_BUILD_TYPE=Release
    cmake --build build --target spectra-ros -j$(nproc)
  2. Publish something (terminal 1)
    ros2 topic pub /cmd_vel geometry_msgs/msg/Twist \
      "{ linear: { x: 0.5 } }" --rate 10
  3. Launch and plot (terminal 2)
    # Fastest path — subscribe + plot at startup
    ./build/spectra-ros --topics /cmd_vel:linear.x

    # Or open the default cockpit and drag a field from Topic Monitor
    ./build/spectra-ros

Default layout opens Topic Monitor (left), Plot Area (center), Topic Echo (bottom), and Topic Statistics (right). Select a topic in the monitor — the stats panel shows a hint until you pick a field to plot.

Session presets. Checked-in layouts live under sessions/presets/. Load at startup with --session — no manual dock setup required.
./build/spectra-ros --session sessions/presets/tuning.spectra-ros-session
Zero impact when OFF. When SPECTRA_USE_ROS2=OFF (the default), no ROS2 headers are included and no ROS2 dependencies are required. All adapter code is fully gated behind the CMake option.

Named Workflows & Presets

Each workflow has a session preset, launch file, and QA scenario. See also how Spectra compares to rqt, PlotJuggler, RViz, and Foxglove.

W1 · Live tuning

IMU / PID session

Four IMU axes on a 2×2 grid — acceleration and angular rate.

ros2 launch spectra imu_monitor.launch.py
# or
./build/spectra-ros --session sessions/presets/tuning.spectra-ros-session
W2 · Bag post-mortem

Bag review

Transport bar, bag info, plots, and echo on one timeline.

./build/spectra-ros --bag recording.db3 \
  --session sessions/presets/bag_review.spectra-ros-session
W3 · Bringup

cmd_vel + odom

Commanded vs measured velocity for integrator bringup.

ros2 launch spectra bringup.launch.py
Nav debug

Navigation dashboard

cmd_vel, odom, diagnostics — nav stack at a glance.

ros2 launch spectra nav_dashboard.launch.py

Architecture

The adapter is a self-contained CMake library target (spectra_ros2_adapter) that sits entirely under src/adapters/ros2/. It does not modify the Spectra core library.

ROS2 → Spectra data path

Background executor introspects DDS messages; SPSC ring buffers decouple the Vulkan render thread.

ROS2 adapter data path

ROS2 Thread

  • Ros2Bridge — node lifecycle
  • TopicDiscovery — periodic graph query
  • GenericSubscriber — type-erased subscription
  • MessageIntrospector — runtime field extraction
  • Runs on dedicated background executor thread

Lock-free Ring Buffer

  • SPSC per subscribed field
  • Default depth: 10 000 samples
  • Zero-copy timestamp + value pairs
  • No blocking on render thread

Render Thread

  • RosPlotManager — polls ring buffers
  • Appends to Spectra LineSeries each frame
  • ScrollController — auto-scroll window
  • ImGui panels — all UI rendering
  • Vulkan pipeline — GPU output
Message introspection at runtime. Spectra uses rosidl_typesupport_introspection_cpp to walk any message type's field tree without code generation. Field paths like pose.position.x are resolved at subscribe time and extracted per-message via offset arithmetic.

Panel Overview

All panels are dockable and resizable within the spectra-ros layout. The default layout places the topic monitor on the left, the plot area in the center, the inspector on the right, and the log/bag controls at the bottom.

Phase B

Topic Monitor

  • Tree view grouped by namespace
  • Live Hz / bandwidth (rolling 1 s window)
  • Active (green) / stale (gray) status dots
  • Pub / sub counts per topic
  • Search / filter bar
  • Topic echo: last 100 messages expandable
  • Per-topic statistics: avg/min/max Hz, latency, drop detection

Phase C

Live Plot Engine

  • Field → LineSeries bridge per subscribed path
  • Drag numeric field from echo panel to axes
  • Right-click: "Plot in new window / current axes / new subplot"
  • Auto-scroll time window (1 s – 3 600 s, default 30 s)
  • Pan/zoom pauses auto-scroll; Home resumes
  • Memory indicator + automatic data pruning
  • Configurable N×M subplot grid with shared X / linked axes

Phase D

Bag Player & Recorder

  • Open .db3 / .mcap bags
  • Transport: play / pause / stop / step / loop
  • Rate control: 0.1× – 10×
  • Scrub bar reuses Spectra TimelineEditor
  • Topic activity bands visualized on timeline
  • Bag recorder: start/stop, auto-split by size/duration
  • Bag info panel: metadata, topic table, drag-and-drop open

Phase F

Node Graph

  • Nodes as boxes, topics as ellipses, edges as arrows
  • Force-directed layout, auto-refresh
  • Filter by namespace
  • Click node → details panel

Phase F

TF Tree Viewer

  • Subscribes /tf + /tf_static
  • Tree view of coordinate frames
  • Transform lookup between any two frames
  • Frame age, stale warning, Hz badge per transform

Phase F

Parameter Editor

  • Discover parameters from any running node
  • Type-aware widgets: checkbox / slider / drag / text
  • Range hints from DescribeParameters
  • Live-edit or staged apply mode
  • Single-level undo per parameter
  • Save / load YAML presets

Phase F

Service Caller

  • List all available services with type display
  • Auto-generated request form from introspection
  • Per-field widgets: checkbox / drag-float / input-text
  • Configurable timeout slider
  • Response JSON viewer + latency badge
  • Call history with replay, copy, import/export

Phase E

Export Tools

  • CSV export: ROS timestamps + field columns
  • Configurable separator, precision, range
  • Clipboard copy as TSV (Ctrl+C on plot)
  • Screenshot (Ctrl+Shift+S) → PNG with timestamp name
  • Video recording via existing Spectra RecordingSession

Phase C

Expression Fields

  • Computed topic streams: sqrt($imu.accel.x^2 + ...)
  • Operators: + − * / ^ sqrt abs sin cos atan2 log exp
  • Expression editor with inline error feedback
  • Save / load named presets
  • Same plot bridge as raw fields

Live Plotting

Subscribing a field creates a LineSeries in the active axes. The render thread polls the ring buffer each frame and appends new samples at zero-copy cost.

Subscribing a Field

In the Topic Echo panel, expand a message type to see its numeric fields. Drag any numeric leaf onto a plot axes or the empty background to create a new series. Right-click for placement options.

Alternatively, use the CLI:

./spectra-ros --topics /imu/data.linear_acceleration.x,/imu/data.angular_velocity.z

Auto-Scroll Window

The X axis tracks [now − window, now] automatically. Configurable range: 1 s – 3 600 s (default 30 s).

  • Pan or zoom → auto-scroll pauses, indicator shown
  • Press Home to resume auto-scroll
  • Data outside 2× the window is pruned to bound memory
  • Current memory usage shown in the status bar

Multi-Subplot Layout

Add subplots from the toolbar (+ button) or by dragging fields to an empty area below existing plots. Each row/column is configurable via the layout dropdown.

  • Shared X axis via AxisLinkManager
  • Shared cursor shows interpolated Y across all linked plots
  • Remove subplot via right-click context menu

Field Addressing

Any scalar-typed field in a ROS2 message can be plotted using dot-separated paths. Arrays index with [N].

# Nested struct field
pose.position.x

# Covariance matrix element
pose.covariance[0]

# IMU angular velocity
angular_velocity.z

Expression Fields

Create computed data streams by combining raw topic fields with math expressions. Expressions are evaluated per-sample on the render thread using the built-in ExpressionEngine.

Syntax

Variables reference topic fields with the $topic.field.path syntax. Multiple topics can be mixed in one expression — values are interpolated to a common timeline.

# IMU linear acceleration magnitude
sqrt($imu.linear_acceleration.x^2
     + $imu.linear_acceleration.y^2
     + $imu.linear_acceleration.z^2)

# Velocity magnitude from Twist
sqrt($cmd_vel.linear.x^2 + $cmd_vel.linear.y^2)

# Convert radians to degrees
$imu.orientation.z * (180.0 / 3.14159)

Supported Operators

CategoryOperators / Functions
Arithmetic+ − * / ^
Comparison< > <= >= == !=
Mathsqrt abs sin cos atan2 log exp
Constantspi e

Parse errors are shown inline in the expression editor with the offending token highlighted. Presets can be saved and loaded by name.

Bag Player & Recorder

Rosbag2 features are gated behind -DSPECTRA_ROS2_BAG=ON. Both .db3 (SQLite) and .mcap formats are supported.

Opening a Bag

  • CLI: ./spectra-ros --bag /path/to/file.db3
  • Drag-and-drop a .db3 / .mcap file onto the window
  • File → Open Bag… menu
  • Recent bags list in the Bag Info panel

The Bag Info panel shows metadata (duration, topic count, message count, start/end timestamps) and a topic table. Click any topic to plot it immediately.

Transport Controls

  • Play / Pause — Space bar
  • Stop — resets to beginning
  • Step forward / back — one message at a time
  • Seek — click the scrub bar or drag the playhead
  • Rate — 0.1× to 10×, slider in the toolbar
  • Loop — toggle button; restarts at beginning

The scrub bar reuses Spectra's TimelineEditor with per-topic activity bands showing when each topic has messages.

Bag Recorder

Record live topics to a new bag file from within Spectra. The recorder panel lets you select topics, output path, format, and auto-split thresholds.

  • Start / stop recording from toolbar or keyboard shortcut
  • Red indicator dot while recording is active
  • Auto-split by file size (MB) or duration (seconds)
  • Output format: .db3 or .mcap

Headless CSV export (spectra-ros-analyze)

Export numeric bag fields to CSV without the GUI — for CI thresholds and post-run reports. See docs/ci/bag-analysis.md.

./build/spectra-ros-analyze \
  --bag tests/data/ros_bags/imu_snippet \
  --fields /imu/data.linear_acceleration.z \
  --csv /tmp/imu_z.csv

Playback + Live Overlap

Bag messages are fed through the same RosPlotManager pipeline as live subscriptions. You can run a bag alongside live topics simultaneously — the plot series auto-color by source.

Seeking during playback re-inserts all messages from the new position, pruning stale data automatically.

Node Graph

The node graph panel queries the ROS2 graph and renders the full publish/subscribe topology with a force-directed layout.

Layout

  • Nodes shown as labeled rectangles
  • Topics shown as ellipses with colored edges
  • Publisher edges: node → topic (outgoing)
  • Subscriber edges: topic → node (incoming)
  • Auto-refresh every 2 s (configurable)

Interaction

  • Filter by namespace prefix (search bar)
  • Click node → details: pub/sub lists, lifecycle state
  • Drag nodes to pin layout positions
  • Scroll to zoom; middle-drag to pan
  • Reset layout button in toolbar

TF Tree Viewer

Subscribes to /tf and /tf_static and maintains a live frame tree with age tracking.

Frame Tree

  • Hierarchical tree view rooted at world / map
  • Each frame: parent, translation, rotation (RPY), update Hz
  • Age indicator: green (fresh) → yellow (aging) → red (stale)
  • Static transforms shown with a lock icon

Transform Lookup

  • Select source and target frame in dropdown menus
  • Live display of the full transform between any two frames
  • Translation in meters, rotation as quaternion + RPY
  • Stale warning when any intermediate transform exceeds threshold

Parameter Editor

Discover and edit ROS2 node parameters at runtime. Supports all parameter types with range-aware widgets and YAML preset files.

Discovering Parameters

  1. Type or select the target node name in the toolbar
  2. Click Refresh — the editor calls ListParameters → DescribeParameters → GetParameters
  3. Parameters appear in a scrollable 3-column table: Name / Type / Value

Editing

  • Bool → checkbox
  • Integer → slider (if range) or drag field
  • Double → slider (if range) or drag field
  • String → text input
  • Arrays → display with expand tooltip

Live-edit mode: sends SetParameters immediately on change. Apply mode: stages all edits, then sends in one batch via the Apply button.

Undo & Presets

  • Single-level undo per parameter (Ctrl+Z or toolbar button)
  • Save current values as a named YAML preset
  • Load preset → applies saved values to current node
  • YAML format compatible with ros2 param load

Example YAML Preset

## nav2_controller.yaml
ros__parameters:
  max_vel_x: 0.5
  max_vel_theta: 1.0
  min_vel_x: 0.1
  use_sim_time: false

Service Caller

List, introspect, and call any ROS2 service from a generated UI form — no code required.

Workflow

  1. Click Refresh to discover all available services
  2. Select a service from the left pane — the request schema is introspected automatically
  3. Fill in the request form; adjust timeout if needed
  4. Click Call Service — response appears inline

History & JSON

  • All calls logged in the history pane: state / service / latency
  • Replay: click any history entry to re-populate the form
  • Copy response as JSON to clipboard
  • Import / export full call history as JSON
  • Configurable timeout: 0.5 s – 30 s slider

Export Tools

CSV Export

  • Exports all plotted series to a CSV file
  • Columns: timestamp_sec, timestamp_nsec, wall_clock, field values
  • Configurable separator (, ; \t) and decimal precision
  • Export visible range or full history
  • File dialog via File → Export CSV…

Clipboard Copy

  • Ctrl+C on the plot copies selected range as TSV
  • Header row: timestamp columns + series names
  • Union-aligned rows; missing values filled with empty cells
  • Paste directly into Excel, LibreOffice, or Python

Screenshot & Video

  • Ctrl+Shift+S — saves timestamped PNG immediately
  • Tools → Record Video… — opens recording dialog
  • Supports PNG sequence, GIF, and MP4 (via ffmpeg)
  • Configurable FPS, duration, resolution
  • Progress bar + ETA indicator during export

CMake Options

Option Default Description
SPECTRA_USE_ROS2 OFF Enable the ROS2 adapter. Requires ROS2 workspace sourced.
SPECTRA_ROS2_BAG OFF Enable rosbag2 reader/writer/player. Requires rosbag2 packages.
SPECTRA_USE_ROS2 + SPECTRA_USE_FFMPEG Enables MP4 video export from the recording panel.
ROS2 workspace must be sourced before running cmake. Without the sourced environment, find_package(rclcpp) will fail and the adapter will not be built.

CLI Reference

All options can be combined. --topics and --bag can be used together.

FlagExampleDescription
--topics / -t --topics /cmd_vel:linear.x /imu/data:angular_velocity.z Subscribe and plot topic or topic:field_path at startup
--bag / -b --bag /path/to/recording.db3 Open a rosbag immediately on launch
--session / -s --session sessions/presets/tuning.spectra-ros-session Load a .spectra-ros-session preset (plots, panels, layout)
--layout / -l --layout plot-only default, plot-only, monitor, rviz, rviz-plot
--window-s / -w --window-s 60 Auto-scroll time window in seconds (default 30)
--node-name / -n --node-name spectra_debug Override the ROS2 node name (default: spectra_ros)
--rows / --cols --rows 2 --cols 2 Initial subplot grid dimensions
# Example: tuning preset + 60 s scroll window
./spectra-ros \
  --session sessions/presets/tuning.spectra-ros-session \
  --window-s 60

UI Workspace & 3D Studio

spectra-ros uses a single ImGui dockspace with layout presets (Default, Monitor, RViz, RVizPlot, BagReview). Panel layout persists in .spectra-ros-session files under imgui_layout.

  • Plot workflow: expand a topic in Topic Monitor, drag a numeric field onto a subplot (highlight on hover), or double-click a field to plot in <10 s.
  • Topic Echo pin: use Pin to stop auto-following Topic Monitor selection.
  • Topic Statistics: per-series color, width, visibility, and remove controls when the selected topic is plotted.
  • Scene Viewport: Top / Front / Side views, Fit, Measure tool, fixed frame selector in the menu bar.
  • Displays: RViz-style plugins including Grid, TF, markers, point clouds, and OccupancyGrid (nav_msgs/OccupancyGrid).

Run visual QA: spectra_ros_qa_agent --design-review --output-dir /tmp/ros_qa

Keyboard Shortcuts

ShortcutAction
SpacePlay / Pause bag playback
HomeResume auto-scroll (if paused by zoom/pan)
Ctrl+CCopy selected plot range as TSV to clipboard
Ctrl+Shift+SSave screenshot as timestamped PNG
Ctrl+ZUndo last parameter change (Parameter Editor)
Ctrl+KOpen command palette
Ctrl+RRefresh topic list / service list
Ctrl+LToggle legend visibility
Ctrl+GToggle grid on active axes
Ctrl+Shift+AAuto-fit all axes
FAuto-fit active axes

Launch File Examples

Three example launch files are provided under examples/ros2_launch/.

imu_monitor.launch.py

Subscribes to /imu/data (linear acceleration + angular velocity) in a 2-row subplot layout with shared X axis and auto-scrolling 10 s window.

nav_dashboard.launch.py

Navigation stack dashboard — velocity commands, odometry, and costmap diagnostics plotted in a 3-panel layout with the node graph and TF tree visible.

bag_replay.launch.py

Opens a specified rosbag, starts the bag player at 1× speed, and plots all Float64 topics automatically. Accepts the bag path as a launch argument.