An all-in-one web-based GUI for LiDAR SLAM development with ROS
ROS SLAM WEBUI brings SLAM, localization, data play/record, configuration, and real-time visualization into a single browser-based interface. Instead of running each ROS launch file and tool manually from separate terminals, you can control the full LiDAR SLAM development workflow comfortably from one web GUI on any device (such as Desktop, Tablet, Smartphone).
---Important: To use these features, clone the linked repositories and build them in your ROS2 workspace first.
- LiDAR SLAM — based on FAST-LIO Mapping and Pose Graph Optimization
- Live YAML configuration editing with instant apply
- Inline Live 3D Viewer — auto-shown while mapping, with accumulated map, keyframes/trajectory, and camera follow
- Real-time Analytics Dashboard — sensor Hz, trajectory distance/speed, CPU/RAM usage, per-frame processing time, geometry quality (DOP), and cumulative timing stats
- Save Map Result Viewer — LIO Map / Optimized / Dynamic Object Removal layers, LIO & PGO trajectories with loop-closure overlays, Depth Filter (Eye-Dome Lighting), and Height Clip cross-section
- Real-time Localization — based on FAST-LIO Localization
- Live YAML configuration editing with instant apply
- Inline Live 3D Viewer — auto-shown while running, with camera follow, Top View, and Snapshot
- Real-time Analytics Dashboard — same live metrics as LiDAR SLAM, plus a Map Update Rug showing recent map-update events
- Multi-Session SLAM — based on long_term_mapping
- Map merging (Map 1 / Map 2) and multi-session pose graph optimization
- Optimization Result Viewer — layer legend (Map 1/2, Merge Map 1/2), Check Difference overlays, loop-closure edges, Depth Filter, and Height Clip cross-section
- PlotJuggler-style Real-time Plotting
- Interactive time-series data visualization
- Multi-tab interface for organizing plots
- Drag-and-drop topic selection from tree view
- Auto-save/restore plot configurations
- Zoom, pan, play/pause controls
- Export plots (PNG)
- XY Plot support
- 3D Visualization
- Real-time PointCloud2 and Livox CustomMsg visualization
- Path and odometry display
- TF tree visualization with Fixed Frame support
- Interactive camera controls (Orbit / Top-Down)
- Image topic streaming
- Snapshot export and Fullscreen mode
-
Bag Player
- Play ROS2 bag files with topic filtering
- Timeline control with play/pause/seek
- Variable playback speed (slider)
- Loop mode for continuous replay
- Integration with 3D visualization and Plot
- ROS1 bag support: Auto-detect
.bagfiles, offline convert to ROS2, or direct real-time playback viarosbags - Convert ROS2 bag → ROS1
.bagformat
-
Bag Recorder
- Record live ROS topics to bag files in ROS2 mcap, ROS2 db3, or ROS1
.bagformat - Format selectable via dropdown before recording
- Selective topic recording
- Real-time recording status badge (shows active format)
- Record live ROS topics to bag files in ROS2 mcap, ROS2 db3, or ROS1
-
File Player — Multi-dataset direct playback
- Supports 5 dataset formats selectable via dropdown:
- ConPR: CSV-based trajectory/LiDAR/camera data
- KITTI Raw: Velodyne HDL-64E, 4 cameras (color/gray), IMU/GPS (OXTS), TF
- KAIST Complex Urban: VLP-16 (left/right), SICK LiDAR (back/mid), stereo camera, IMU, GPS, VRS
- MulRan: Ouster OS1-64 LiDAR, radar polar image, IMU, GPS
- HeLiPR: 4 heterogeneous LiDARs (Ouster, Velodyne, Livox Avia, Aeva) selected via
stamp.csvtimeline, xsens IMU (+ magnetic field), inspva GPS, and per-LiDAR ground-truth Odometry/TF (LiDAR_GT/*.txt, priority Ouster > Velodyne > Aeva > Avia)
- Drive/Sequence selection per dataset (scanned from directory)
- Save Bag in ROS2 or ROS1 format
- Playback controls: Loop / Skip stop section / Auto start
- Timeline slider for frame-accurate seeking
- Supports 5 dataset formats selectable via dropdown:
- Latency Monitor — real-time HTTP round-trip measurement
- Sequential 3-ping minimum strategy (avoids self-induced contention)
- Color-coded indicator: 🟢 Green < 50ms / 🟡 Yellow < 150ms / 🔴 Red ≥ 150ms
- Measures every 3 seconds
- Ubuntu: 22.04 or later
- ROS2: Jazzy or later (Desktop Full recommended — includes
rclpy,std_msgs,sensor_msgs,geometry_msgs,nav_msgs,tf2_msgs,rosbag2_py) → Installation Guide - Python: 3.10+ (included with ROS2)
- rosbridge_server: required for 3D Viewer and Plot features
- Browser: any modern browser (Chrome / Firefox recommended)
-
Install rosbridge_server
sudo apt install ros-jazzy-rosbridge-server
-
Install Python dependencies
pip install rosbags ruamel.yaml numpy opencv-python psutil
rosbags: ROS1 bag read/write and format conversion
opencv-python: camera image processing in File Player
psutil(optional): CPU core count / total RAM for the SLAM & Localization Analytics Dashboards — without it, CPU/RAM widgets fall back to defaults -
Clone SLAM-related packages The SLAM & Localization features are based on the following packages:
cd ~/your_workspace/src git clone https://github.com/Kimkyuwon/fast_lio2_mapping_and_localization.git git clone https://github.com/Kimkyuwon/Pose_Graph_Optimization.git git clone https://github.com/Kimkyuwon/long_term_mapping.git
-
Livox LiDAR support Required only if you use a Livox LiDAR sensor. Clone livox_ros_driver2:
git clone https://github.com/Livox-SDK/livox_ros_driver2.git
-
Clone and build ros_slam_webui
git clone https://github.com/Kimkyuwon/ROS-SLAM-WebUI.git cd ~/your_workspace colcon build source install/setup.bash
# Source ROS2 environment
source /opt/ros/jazzy/setup.bash
source ~/your_workspace/install/setup.bash
# Launch the web server (also starts rosbridge_server by default)
ros2 launch ros_slam_webui ros_slam_webui.launch.py
# If rosbridge_server is already running elsewhere, skip launching a duplicate instance:
ros2 launch ros_slam_webui ros_slam_webui.launch.py start_rosbridge:=falseOnce the server starts, you'll see:
[INFO] [ros_slam_webui_node]: ======================================
[INFO] [ros_slam_webui_node]: Web server started on port 8080
[INFO] [ros_slam_webui_node]: Local access: http://localhost:8080
[INFO] [ros_slam_webui_node]: Network access: http://YOUR_IP:8080
[INFO] [ros_slam_webui_node]: ======================================
Open the URL in your web browser. For network access from another device (e.g. tablet or smartphone), the device must be connected to the same Wi-Fi network (AP) as the host machine.
-
Load Configuration
- Click "Config Load" to browse for your SLAM config file
- Default location is auto-detected from
FAST_LIO_Localization_and_Mapping/config/mapping_config.yamlin the same ROS workspace - Edit parameters in real-time using the web interface
-
Start SLAM
- Click "Start SLAM" button
- Monitor real-time terminal output in the web UI
- Green status indicator shows running state
- SLAM Live Viewer appears inline automatically:
- Live-streamed accumulated map (
/PGO_map) plus the current scan, keyframe nodes (/kf_node), LIO/Pose Graph trajectories, and loop-closure lines - Follow button toggles camera tracking of the robot pose
- Top View, Snapshot, and Fullscreen buttons in the bottom-right corner
- Live-streamed accumulated map (
- SLAM Analytics Dashboard appears below the viewer:
- Sensor Frequency (IMU/LiDAR Hz), Trajectory (distance/uptime/avg speed), CPU/RAM usage gauges
- Per-frame Processing Time (stacked area) and Geometry Quality/DOP charts, plus Cumulative Timing Statistics table
- "Full Statistics" toggle expands detailed IESEKF/Feature Matching/Residual/IMU/Keyframe fields
-
Save Map
- Click "Save Map" to trigger pose graph optimization
- Async operation — progress status shown while saving (Live Viewer/Dashboard are hidden during this step)
- Click "Cancel Save Map" to abort if needed
- Map is saved to configured output directory
- Save Map Result Viewer (auto-shown on completion):
- LIO Map (raw), Optimized, and Dynamic Object Removal point cloud layers, toggleable via legend
- LIO / PGO trajectories with Loop Closure edge lines
- Depth Filter (Eye-Dome Lighting shading) and Height Clip (draggable vertical slider for a Z-height cross-section) toolbar buttons
- Top View, Point Size slider, Reset View, Snapshot, and Fullscreen
-
Stop SLAM
- Click "Stop SLAM" button
- Process terminates gracefully (SIGINT → SIGTERM → SIGKILL)
-
Set Inputs
- Click "Set Map 1" and "Set Map 2" to select two map directories
- Click "Set Output" to set output path
-
Run Optimization
- Click "Multi Session Optimization"
- Real-time log stream appears in the status area with spinner
- Click "Cancel" to stop at any time
-
Completion
- Status banner turns green on success, red on failure
- Button label changes to "Exit" after completion — click to reset UI
-
Optimization Result Viewer (auto-shown on completion)
- Inline Three.js 3D viewer shows Map1 / Map2 accumulated point clouds (individually re-projected from each session's scans), the merged Merge Map 1 / Merge Map 2 static map (split by source via intensity), and pose trajectory nodes
- Layer legend: click any legend item to toggle that layer's visibility on/off
- Check Difference: toggle to load and display difference PCD layers — Positive Differences (PD, orange), Negative Differences (ND, purple), First Unexplored area (FirstUE, hot-pink), Second Unexplored area (SecondUE, lime)
- Loop Closure: thick edge lines drawn between non-adjacent pose nodes
- Depth Filter (Eye-Dome Lighting shading) and Height Clip (draggable vertical slider for a Z-height cross-section) toolbar buttons
- Top View toggle, Point Size slider, Reset View button
- Snapshot (📷): exports current 3D view as a high-resolution PNG (2× render scale)
- Fullscreen (⛶): expand viewer to full screen
When you click Start Localization, an inline 3D viewer appears automatically beneath the controls panel.
| Element | Description |
|---|---|
| Display panel (left) | Toggle individual topic layers on/off via checkboxes |
| 3D canvas (right) | Real-time Three.js visualization |
| Follow button | Toggle camera tracking of the robot pose |
| Top View toggle | Switch between perspective and top-down view |
| Snapshot button | Export current 3D view as a PNG |
| Fullscreen button | Expand canvas to full screen |
| Reset View button | Return camera to default position |
Both Start SLAM and Start Localization show a live analytics dashboard beneath their respective viewer, subscribed to the /lio_analytics (fast_lio/msg/LioAnalytics) or /loc_analytics (fast_lio/msg/LocAnalytics) topic:
| Widget | Description |
|---|---|
| Sensor Frequency | IMU / LiDAR message rate (Hz) |
| Trajectory | Cumulative distance, uptime, and average speed |
| CPU / RAM Usage | Gauge + donut charts (via /api/system/info) |
| Per-frame Processing Time | Stacked-area chart of the last 10 seconds |
| Geometry Quality (DOP) | Scan/matching Dilution-of-Precision, lower is better |
| Cumulative Timing Statistics | Mean/Max table per pipeline component |
| Map Update Rug (Localization only) | Canvas strip showing the last 200 map-update events plus an "Initialized" status badge |
| Full Statistics toggle | Expands detailed Scan/Map, Feature Matching, Residual, IESEKF, IMU State, and Keyframe fields |
The Plot feature provides PlotJuggler-style visualization directly in your browser:
-
Navigate to Plot Tab
- Click "Visualization" → "Plot" in the main navigation
-
Browse Topics
- Currently published topics are listed in the tree view (topic → message fields)
- Click a topic to subscribe and expand its message fields
- Ctrl+click to select multiple topics simultaneously
-
Create Plots
- Drag leaf nodes (data fields) from tree to plot area
- Each drag creates a new trace in the plot
- Multiple traces can be added to a single plot
- XY Plot: Ctrl+click to select 2 leaf fields → right-click → "Create XY Plot"
-
Manage Tabs
- Click "+" to create new plot tabs
- Double-click tab title to rename
- Click "×" to close tabs (minimum 1 tab)
- Each tab maintains independent plots
-
Plot Controls
- Play/Pause: Toggle real-time data updates
- t0 Mode: Show relative time from first data point (enabled by default)
- Buffer Time: Adjust visible time window (1-100 seconds)
-
Interact with Plots
- Zoom: Scroll wheel (when paused)
- Auto Scale: Right-click on plot → "Auto Scale"
- Delete Plot: Right-click on trace or legend → "Delete plot"
- Clear Plot: Right-click on plot → "Clear Plot"
- Export PNG: Right-click on plot → "Export as PNG"
- Auto-save: Plot configurations save automatically to browser storage
- Auto-restore: Plots restore after page refresh
-
Filters (right-click on a trace → "Apply Filter")
- Derivative: Rate of change
- Moving Average: Smoothing
- Moving RMS: Root mean square
- Moving Variance: Variance over window
- Scale + Offset: Linear transform (y = scale × x + offset)
-
Enter Bag Name
- Click "Enter Bag Name" to open a file browser dialog
- Type the bag name in the filename field at the bottom
- Click "Save" to confirm — the "Bag Name" field displays the full path (read-only)
-
Select Format
- Use the Format dropdown to choose the output format:
- ROS2 (mcap) — default; single
.mcapfile, fast write, native compression support (ROS2 Iron / Jazzy or later) - ROS2 (db3) — SQLite3 based; classic ROS2 bag format (folder +
.db3+metadata.yaml). Use this if your ROS2 version is older than Iron (e.g. Humble or earlier) - ROS1 (.bag) — direct ROS1
.bagrecording viarosbags;.bagextension is appended to the bag name automatically
- ROS2 (mcap) — default; single
- The Bag Name display updates automatically when switching between ROS1 and ROS2 formats
- Use the Format dropdown to choose the output format:
-
Select Topics
- Click "Select Topic" button
- Choose topics to record from the list (requires bag name to be set first)
- Click "Confirm"
-
Record
- Click "Record" to start recording
- A badge shows the active recording format (ROS1 .bag / ROS2 db3 / ROS2 mcap)
- Click "Stop" to finish recording
- Bag file is saved to the directory selected in step 1
-
Load Bag
- Click "Load Bag File" to open a file browser (starts from your home directory)
- ROS2 bags (
.db3directory or single-file.mcap) and ROS1.bagfiles are all supported - A badge (ROS1 Bag / ROS2 Bag) shows the detected format
-
Select Topics
- Click "Select Topic" to filter which topics to play
- All topics are played by default if none selected
-
Playback
- Click "Play" to start playback
- Use timeline slider for seeking
- Use the speed slider to adjust playback rate (applies to both ROS1 and ROS2 bags)
- Toggle Loop checkbox to replay automatically when finished
- Click "Stop" to stop playback
- ROS1 bag messages are decoded/converted on a background prefetch thread ahead of publishing, keeping playback timing stable even under CPU load (e.g. while SLAM is running concurrently)
-
Format Conversion
- ROS1 bag loaded: "Convert to ROS2" button appears — converts offline using
rosbags-convert - ROS2 bag loaded: "Convert to ROS1" button appears — converts to
.bagformat - Direct playback without conversion is available for both formats
- Conversion always requires at least one topic selected in step 2 — only the Selected Topics are written to the converted bag (
rosbags-convert --include-topic)
- ROS1 bag loaded: "Convert to ROS2" button appears — converts offline using
The File Player supports direct playback of five dataset formats without conversion.
-
Select Dataset Format
- Use the "Dataset" dropdown to choose: ConPR / KITTI Raw / KAIST Complex Urban / MulRan / HeLiPR
-
Load Directory
- Click "Load" to open a file browser (starts from your home directory)
- Navigate to and select the dataset root directory
- For KITTI: select the base directory containing drive folders (
2011_09_26_drive_*) - For KAIST: select the directory containing sequence folders (
urban00,urban01, …) - For MulRan: select the directory containing sequence folders (
Riverside01,KAIST01, …) - For HeLiPR: select the top-level directory containing sequence folders (each with
stamp.csvand aLiDAR/— or flatOuster/Velodyne/Avia/Aeva— layout); both directory layouts used by official HeLiPR releases are auto-detected
-
Select Drive/Sequence (KITTI / KAIST / MulRan / HeLiPR only)
- A dropdown is populated with detected drives or sequences
- Select the desired entry to load it (for HeLiPR, a single detected sequence auto-loads)
-
Play
- Click "▶ Play" to start publishing sensor data to ROS2 topics
- Click "⏸ Pause" to pause; click again to resume
- Use the timeline slider to seek to any position
-
Playback Options
Option Description Loop Restart from beginning when playback reaches the end Skip stop section Skip long gaps between sensor events (on by default) Auto start Begin playback automatically after loading -
Save Bag
- Choose output format — ROS2 (mcap), ROS2 (db3), or ROS1 (.bag) — from the dropdown next to the "Save Bag" button
- Click "Save Bag" to convert the current dataset to a bag file
- Progress bar shows conversion progress
| Dataset | Topics |
|---|---|
| ConPR | /livox/lidar, /camera/image_raw, /imu/data, /gps/fix, /pose |
| KITTI Raw | /kitti/velo/pointcloud, /kitti/camera_*/image_raw, /kitti/imu, /kitti/gps/fix, /tf |
| KAIST Complex Urban | /velodyne_left/points, /velodyne_right/points, /sick_back/points, /sick_mid/points, /stereo/left/image_raw, /imu/data, /gps/fix, /vrs_gps/fix, /tf |
| MulRan | /os1_points, /radar/polar, /imu/data_raw, /gps/fix, /tf |
| HeLiPR | /ouster/points, /velodyne/points, /avia/points (Livox CustomMsg), /aeva/points, /imu/data_raw, /imu/mag, /gps/fix, /gt, /tf |
The 3D Viewer is divided into three panels:
- Displays (left): manage active topic subscriptions and Fixed Frame
- 3D View (center): Three.js canvas
- Views (right): camera type and view controls
Each side panel can be collapsed with the ▶ button.
Click "+ Add" in the Displays panel to open the Add Display dialog.
Select a display type and choose a topic to start visualizing:
| Display Type | ROS Message Type | Description |
|---|---|---|
| PointCloud2 | sensor_msgs/PointCloud2 |
Colored point cloud |
| Path | nav_msgs/Path |
Connected line segments |
| Odometry | nav_msgs/Odometry |
Arrow + optional trajectory trail |
| TF | tf2_msgs/TFMessage |
Coordinate frame axes |
| LivoxLidar | livox_ros_driver2/CustomMsg |
Livox custom point cloud (By Line / Tag Filter) |
| Image | sensor_msgs/Image |
Live video panels below the 3D view |
| LaserScan | sensor_msgs/LaserScan |
2D scan points in 3D space |
Click a display item in the Displays panel to expand its settings:
- PointCloud2 / LivoxLidar
- Color Mode:
Rainbow(field value → gradient),By Line(Livox only),Solid(single color),RGB - Color Field:
intensity,x,y,z,reflectivity, … - Point Size: point rendering size
- Decay Time: seconds before old points are removed (0 = keep latest frame only)
- Color Mode:
- Odometry
- Trajectory: toggle trail on/off, set max trail length
- TF
- Show/hide individual coordinate frames
- Type or select the reference TF frame in the Fixed Frame combo box (default:
map) - Click ▾ to show available TF frames detected at runtime
- TF transformations are applied automatically to all displays
| Action | Control |
|---|---|
| Rotate | Left mouse drag |
| Zoom | Mouse scroll wheel |
| Pan | Right mouse drag |
- Type:
Orbit(free rotation around center) orTopDown(bird's-eye view) - Zero: reset camera to default position
- Select an
Imagetopic via + Add → Image - Image panels appear below the 3D canvas; multiple topics can be displayed simultaneously
- Frames stream via binary WebSocket (port 8081) with GPU-accelerated JPEG decoding
- Resize the image panel by dragging the separator bar
- Snapshot: saves the current 3D view as a PNG file
- Fullscreen (⛶): expands the 3D canvas to full screen; click again or press Escape to exit
- Reset: removes all active displays and clears the scene
The service automatically sets:
ROS_DOMAIN_ID=0
ROS_LOCALHOST_ONLY=1For manual ROS2 commands in other terminals, set the same variables:
export ROS_DOMAIN_ID=0
export ROS_LOCALHOST_ONLY=1
source /opt/ros/jazzy/setup.bashThe web server port (default: 8080) and the PC2 binary WebSocket port (default: 8081, used for PointCloud2/Path/Image streaming) are defined in ros_slam_webui/web_server.py. Update both occurrences to keep them in sync:
# 1. WebGUINode.__init__ — exposed to the frontend via GET /api/server_config
self.web_port = 8080
self.pc2_ws_port = 8081
# 2. main() — actual HTTP server bind port (must match self.web_port above)
web_thread = threading.Thread(target=run_web_server, args=(_ros_node, 8080), daemon=True)The frontend (webui_ports.js) reads the active ports from /api/server_config at page load, so no JavaScript files need to be edited — only the two Python values above.
Then rebuild:
colcon build --packages-select ros_slam_webuiros_slam_webui/
├── ros_slam_webui/
│ ├── web_server.py # Main HTTP server, ROS2 node & binary WebSocket (port 8081)
│ ├── kitti_converter.py # KITTI Raw dataset → ROS2 message converter
│ ├── kaist_converter.py # KAIST Complex Urban dataset → ROS2 message converter
│ ├── mulran_converter.py # MulRan dataset → ROS2 message converter
│ ├── helipr_converter.py # HeLiPR dataset (4 heterogeneous LiDARs + IMU/GPS/GT) → ROS2 message converter
│ └── __init__.py
├── web/
│ ├── index.html # Main web interface
│ └── static/
│ ├── script.js # Main UI logic, API calls & live viewers/dashboards (SlamLiveViewer, SlamResultViewer, Analytics Dashboards, etc.)
│ ├── plot_manager.js # Plotly.js plot management
│ ├── plot_tab_manager.js # Plot tab management
│ ├── plot_tree.js # PlotJuggler-style tree view
│ ├── threejs_display.js # Three.js 3D visualization (general-purpose Display tab)
│ ├── pc2_stream_worker.js # Web Worker for binary PointCloud2 streaming
│ ├── img_stream_worker.js # Web Worker for binary Image streaming (JPEG/GPU decode)
│ ├── latency_ping_worker.js # Web Worker for Latency Monitor round-trip pings
│ ├── webui_ports.js # Reads web/PC2 WS/rosbridge ports from /api/server_config
│ ├── vendor/ # Locally bundled Three.js, roslibjs, Plotly.js (no CDN dependency)
│ └── style.css # UI styling (dark theme)
├── launch/
│ └── ros_slam_webui.launch.py # ROS2 launch configuration
├── package.xml # ROS2 package manifest
├── setup.py # Python package setup
├── README.md # This file
└── LICENSE # Apache 2.0 License
- FAST-LIO Mapping & Localization - LiDAR-Inertial SLAM package with DOP-based scan matching confidence evaluation, supporting both Mapping and Localization modes
- Pose Graph Optimization - LiDAR-based pose graph optimization backend with loop closure detection and dynamic object removal
- long_term_mapping - Multi-session LiDAR SLAM for long-term map maintenance with structural change detection
- ConPR - ConPR dataset format
- KITTI - KITTI Raw dataset
- KAIST Complex Urban - KAIST Urban dataset
- MulRan - MulRan dataset
- HeLiPR - Heterogeneous LiDAR dataset (Ouster/Velodyne/Livox/Aeva) for inter-LiDAR place recognition; converter references HeLiPR-File-Player
- PlotJuggler - Inspiration for plot UI
- Three.js - 3D graphics library
- Plotly.js - Interactive plotting library
- rosbridge_suite - WebSocket interface to ROS
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
The following JavaScript libraries are bundled locally under web/static/vendor/ (no CDN dependency, works fully offline):
| Library | Version | License | Usage |
|---|---|---|---|
| Three.js | 0.128.0 | MIT | 3D rendering |
| Plotly.js | 2.27.0 | MIT | Interactive plots |
| roslibjs | 1.1.0 | BSD-3-Clause | ROS WebSocket bridge |
The following is a separate ROS2 package dependency (not bundled):
| Package | Version | License | Usage |
|---|---|---|---|
| rosbridge_suite | — | BSD-3-Clause | ROS WebSocket server |
The following Python packages are installed separately as runtime dependencies:
| Package | License |
|---|---|
| rosbags | Apache 2.0 |
| ruamel.yaml | MIT |
| numpy | BSD |
| opencv-python | MIT / Apache 2.0 |
- PlotJuggler (LGPL v3.0) — The
PlotJugglerTreecomponent is an independent JavaScript implementation inspired by PlotJuggler's tree-view UI concept. No source code from PlotJuggler is copied or derived. LGPL does not apply to independently re-implemented works. - KITTI / KAIST / MulRan / ConPR — The File Player implements file format parsers for these dataset formats. The dataset files themselves are not included or redistributed; their respective dataset licenses apply only to the data.
Made with ❤️ for the ROS2 community









