This repository contains a set of scripts and utilities to process and analyze ROS bag files. It converts ROS bags into CSV format, organizes data per topic, generates plots for velocities and trajectories, and computes errors for analysis.
- Overview
- Dependencies
- Folder Structure Created by Script
- User Manual
- Errors and Plots
- Bag File Naming Warning
- Execution Flow Example
- Available Functions
- Notes and Warnings
bagpy
pandas
matplotlib
pyyaml
numpy
scikit-learn
re
glob
Install dependencies with:
pip install bagpy pandas matplotlib pyyaml numpy scikit-learn glob2
Upon running the script, the following structure is created within your specified bag_folder
:
-
csv_files/
- per_run/
- run_0/ (individual run CSV files)
- run_1/
- ... and so on.
- per_topic/
- topic_name_1/
- topic_name_2/
- ... and so on.
- per_run/
-
plots/
- Velocity and trajectory plots generated from CSV files.
-
errors/
- CSV files containing computed position and velocity errors for each run.
- Place your ROS bag files inside a folder (
bag_folder
). - Prepare your configuration file (
config.yaml
) according to your ROS topics. - Include in the same folder as your ROS bags, the .yaml containing the GNSS waypoints of the experiment.
Example config.yaml
structure:
topics:
estimated_position:
name: "lego_loam-odom"
type: "geometry_msgs/PoseStamped"
csv_file: "lego_loam-odom.csv"
trajectory_plan:
name: "move_base-DWAPlannerROS-global_plan"
type: "nav_msgs/Path"
csv_file: "move_base-DWAPlannerROS-global_plan.csv" # it will be the name of the topic.csv
gps_plan:
name: "reach-fix"
type: "gps/points"
csv_file: "reach-fix.csv"
waypoints_coords:
name: "simulation_demo.yaml"
You can use this repository either as a Python library, calling individual functions within your own code, or run it as a standalone script that automatically processes the bag files—handling conversion, plotting, and error calculations in one go.
From the root of the repository, run:
cd scripts/packaged/
Then run the code:
python fullAnalysis.py --bag_folder <path-to-ros-bags> --config_path config.yaml
To use it as a library, there are some obligatory commands, the script must be executed in the following order in main()
:
- load_config
- get_sorted_bag_mapping
- convert_bags_to_csv
- organize_csv_per_topic
- missing functions
This library generates visualizations and numerical evaluations of your robot's performance by comparing ground-truth data with planned or estimated trajectories and velocities.
Errors are calculated along three axes — X, Y, and Z — using the following metrics:
-
RMSE (Root Mean Square Error)
Measures the standard deviation of the differences between predicted and actual values. A lower RMSE indicates better performance. -
Mean Absolute Error (MAE)
The average magnitude of errors in each axis, giving a direct sense of how far off the values are on average. -
Max Absolute Error
The single largest deviation observed for each axis, useful for identifying worst-case behavior.
The following types of errors are computed:
-
Position Error:
Compares estimated robot positions against ground-truth (e.g., from localization vs. odometry). -
Yaw Error (Orientation):
Specifically compares the X component of quaternion orientation to assess heading error.
All errors are saved as CSV files in the errors/
directory and aggregated for all specified runs.
ROS Bag File Format Requirement
This tool requires your ROS bag files to follow the default ROS naming convention, which looks like this:
YYYY-MM-DD-HH-MM-SS.bag
Example:
2025-04-11-13-55-04.bag
Files that do not match this exact format will be ignored during processing.
This naming convention is used to determine the temporal order of the bags (oldest to newest) before assigning them internally asrun_0
,run_1
, etc.Valid:
2024-12-01-08-00-00.bag
Invalid:test_run1.bag
,04112025_13_55_04.bag
,run0.bag
Plots are automatically generated from CSV data and saved in the plots/
folder. These help visually assess the system's behavior and compare it to expectations.
- Trajectory Plots:
- 2D trajectory visualization (X vs. Y) of both real and planned paths.
- Optional offset to origin for alignment and easier visual comparison.
Each plot is saved as a PNG image and named accordingly (e.g., real_velocities_run_0.png
, trajectory_comparison_run_1.png
, etc.).
The following steps illustrate a typical usage of the library by walking through the main()
function. Each function call processes ROS bag data and generates structured outputs, plots, and evaluation metrics.
Load your topic definitions (names, types, and CSV output filenames) from a YAML config file.
topics = load_config("config.yaml")
Loads topic metadata required for all downstream steps.
Sort your bag files in chronological order.
get_sorted_bag_mapping(bag_folder)
Convert .bag
files into individual CSV files, one folder per run.
convert_bags_to_csv(bag_folder, num_bags, topics)
Creates csv_files/per_run/run_X/
folders, each with CSVs for all topics.
Reorganize per-run CSVs into per-topic folders.
organize_csv_per_topic(bag_folder, num_bags, topics)
Creates csv_files/per_topic/topic_name/
folders for analysis.
Below is a summary of the core functions provided by this library. These functions are designed to streamline the process of working with ROS bag files, organizing data, plotting results, and evaluating performance metrics.
-
load_config(config_path)
Loads the YAML configuration file with topic names and types.
Usage:topics = load_config("path/to/config.yaml")
-
get_sorted_bag_mapping(bag_folder
Scans for.bag
files in the folder and returns a dictionary mappingrun_X
file path, sorted by modification time.Usage:
python bag_mapping = get_sorted_bag_mapping("path/to/bag_folder")
-
convert_bags_to_csv(bag_folder, num_bags, topics)
Converts.bag
files into CSV format. Createscsv_files/per_run
with separated CSVs per run.
Usage:convert_bags_to_csv("path/to/bag_folder", 2, topics)
-
organize_csv_per_topic(bag_folder, num_bags, topics)
Organizes CSVs into folders per topic for downstream processing.
Usage:organize_csv_per_topic("path/to/bag_folder", 2, topics)
-
extract_poses_from_csv(input_csv, output_csv)
Parses pose data from complex CSVs (e.g., trajectory plans) and rewrites them into structured format. -
parse_pose_block(pose_block)
Helper to extract position and orientation from raw YAML-style blocks.
- CSV file naming and topic definitions in your configuration file must match exactly, so please do not move or rename any folder or file.
- Some functions issue warnings if expected data or CSV files are missing or incorrectly formatted.