# evo: every trajectory format, one metric toolkit

> evo is Michael Grupp's GPL-3.0 Python package for evaluating odometry and SLAM, providing executables and a small library to handle, evaluate and compare trajectory output across TUM, KITTI, EuRoC and ROS or ROS2 bag formats. Absolute and relative pose error metrics, association and alignment options including monocular scale adjustment, plotting from LaTeX to map tiles, and optional Rerun visualization come packaged behind a configurable CLI.

**MichaelGrupp/evo** — Python package for the evaluation of odometry and SLAM

- Repository: https://github.com/MichaelGrupp/evo
- Website: https://michaelgrupp.github.io/evo/
- Stars: 4,322 · Forks: 797
- Language: Python
- License: GPL-3.0
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/michaelgrupp-evo

## One tool for every trajectory format

The package's first advantage is consolidation, common tools for different formats, and the supported list covers the formats the robotics community actually exchanges, TUM trajectory files, KITTI pose files, EuRoC MAV datasets with their csv ground truth and TUM trajectories, and ROS and ROS2 bagfiles carrying geometry_msgs PoseStamped, TransformStamped, PoseWithCovarianceStamped or PointStamped topics, nav_msgs Odometry, or TF messages, with a wiki page documenting the details of each. Before such a tool existed, every benchmark and every dataset shipped its own evaluation scripts, mutually incompatible, and comparing results across them meant format archaeology. evo's positioning against those fragmented tools is the motivation section's first bullet, and the what it is not clause is equally direct, it is not a one to one reimplementation of a particular evaluation protocol tailored to a specific dataset.

## Two metrics, three supporting verbs

The command line surface is five executables installed globally. The two metrics are evo_ape for absolute pose error, how far an estimated trajectory drifts from ground truth at associated points, and evo_rpe for relative pose error, error accumulated over motion segments, the two numbers odometry papers report. Around them, evo_traj analyzes, plots or exports one or more trajectories, evo_res compares one or multiple result files produced by the metric commands, the aggregate step for benchmark tables, and evo_config manipulates global settings and config files. Every command takes --help, tab completion of parameters works on UNIX-like systems through argcomplete, and the CLI is described as powerful and configurable enough to cover many use cases, the interface between the library underneath and the workflows above it.

## Association, alignment, monocular scale

The algorithmic options are where evaluation quality is decided, and evo exposes them rather than hiding defaults. Association, matching estimated poses to reference poses in time, alignment, transforming the estimate into the reference frame before comparison, with or without the scale adjustment that monocular SLAM needs since a single camera cannot recover metric scale, are all configurable. These choices change results more than most implementation details, an unaligned comparison punishes a constant initialization offset, and an unjustified scale adjustment flatters monocular systems, so having them as explicit options makes the evaluation honest and the numbers reproducible. The modular core and tools libraries exist partly for this, custom extensions can build on the same association and alignment machinery rather than reimplementing it.

## The skull warning about pip

The installation section opens with an xkcd joke about Python environment management and then gets serious with a three skull warning, whatever you do, don't use pip install with --user, anything with --break-system-packages, or worst of all sudo pip install. The recommended paths are proper environments, uv or uvx, pipx, venv, or Pixi, with a documented virtualenv recipe for the classic approach. Within that discipline, installation is one line, pip install evo from PyPI, upgrades are pip install --upgrade evo, source installs use pip install --editable in the repository, and Pixi users can pixi add evo or open a dev shell with pixi shell in a clone. Python 3.10 or newer is required, with classifiers running through 3.14. The one line itself, for the record:

```bash
pip install evo
```

and the first plotting command from the example workflow:

```
cd test/data
evo_traj kitti KITTI_00_ORB.txt KITTI_00_SPTAM.txt --ref=KITTI_00_gt.txt -p --plot_mode=xz
```

## Optional upgrades, from Qt to Rerun

Three optional dependencies extend specific capabilities. PyQt6 upgrades plot figures to the enhanced qtagg matplotlib backend, otherwise TkAgg is used, with the switch made after installation through evo_config set plot_backend qtagg, and the practical advice that PyQt6 is a good idea when tkinter installation itself is problematic. contextily adds geographic map tiles to plots of geo-referenced data, placing trajectories on actual maps. And Rerun integration sends data to the rerun viewer, enabled by pip install rerun-sdk plus a --rerun flag on any command, with animated examples in the documentation showing trajectories and error visualizations streaming live. Each is an optional dependency group in the package metadata, gui, geo and rerun, so the base install stays lean.

## Reading ROS bags without ROS

The ROS integration has a pragmatic split worth understanding. Reading ROS bag files works without a ROS installation thanks to the rosbags package installed as a dependency, which handles both ROS 1 and ROS 2 bags on any platform, with one exception, /tf topics need the buffer implementation from actual ROS. Features beyond bag reading, the message types and tooling of a full ROS setup, require a ROS installation, and the project tests against ROS Lyrical, with a Dockerfile.ros-lyrical in the repository for reproducing that environment. The design means most evaluation workflows, load a bag, compare against ground truth, plot, run anywhere Python runs, while only TF-heavy or ROS-native tooling pulls in the robot operating system itself.

## The example workflow in test/data

The documented workflow starts from example trajectories in test/data and shows the two step rhythm. First plotting, evo_traj with the kitti format, two estimated trajectories from ORB and S-PTAM against the ground truth reference, the -p flag to plot and --plot_mode=xz selecting the top-down view, producing the demonstration image of two algorithms' paths overlaid on truth. Second, metrics, evo_ape computing absolute pose error for the same trajectories against KITTI_00_gt.txt as reference, plotting and saving the per-timestep error, the input to any drift analysis. The examples directory extends the same material programmatically, alignment_demo.py, custom_app.py and a rerun_example, and notebooks exist for interactive use, so the learning path runs from shell one liners to library code without a discontinuity.

## Modular, fast, and honest about both

The remaining claims are architectural and measurable. The core and tools libraries are modular for custom extensions, the design that lets the CLI and the examples share one implementation. Speed is claimed against other established Python based tools, with the evidence kept in a performance document rather than asserted in prose, an invitation to check. Output flexibility spans plotting and export including LaTeX plots and Excel tables, the two formats papers and reviewers respectively demand. The repository carries a contrib directory, CI across Linux, macOS, Windows, ROS and ROS2, blame-ignore revisions for a clean history, and there are no GitHub releases, PyPI is the distribution channel, with the last push on 2026-09-08 under GPLv3.

## Conclusion

Use evo whenever trajectory output needs judging, comparing a SLAM run against ground truth, benchmarking algorithms against each other, or preparing publication plots, since its format coverage and metric tooling remove the glue code that otherwise dominates such work. It is not a faithful reproduction of any single dataset's official protocol, the project says so itself, so check against a benchmark's own rules where exact protocol fidelity matters. Install it into a real environment, the project's skull-marked warning against sudo pip is earned, enable PyQt6 or Rerun for better visuals, and read the performance document before trusting speed claims or making your own.

## FAQ

### What is evo in robotics?

evo is a GPL-3.0 Python package for evaluating odometry and SLAM, providing executables and a library to handle, evaluate and compare trajectory output. It supports TUM, KITTI, EuRoC and ROS or ROS2 bag formats, and offers the evo_ape and evo_rpe metrics plus trajectory, result comparison and configuration tools.

### How do you install evo?

Inside a proper environment such as uv, pipx, venv or Pixi, run pip install evo from PyPI, or pip install --editable . from a repository clone, or pixi add evo. The project strongly warns against pip install --user, --break-system-packages and sudo pip install.

### Does evo require a ROS installation?

Not for most work, reading ROS 1 and ROS 2 bag files works without ROS thanks to the rosbags dependency, with the exception of /tf topics which need ROS's buffer implementation. Some ROS-related features do require a ROS installation, tested against ROS Lyrical with a matching Dockerfile in the repository.

## Sources

- [Issues](https://github.com/MichaelGrupp/evo/issues)
- [License: GPL-3.0](https://github.com/MichaelGrupp/evo/blob/master/LICENSE)
- [MichaelGrupp/evo on GitHub](https://github.com/MichaelGrupp/evo)
- [Project website](https://michaelgrupp.github.io/evo/)
- [README](https://github.com/MichaelGrupp/evo/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/michaelgrupp-evo
