cartographer-project/cartographer
Cartographer is a system that provides real-time simultaneous localization and mapping (SLAM) in 2D and 3D across multiple platforms and sensor configurations.
Healthy across all four use cases
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓26+ active contributors
- ✓Apache-2.0 licensed
- ✓CI configured
Show 3 more →Show less
- ✓Tests present
- ⚠Stale — last commit 2y ago
- ⚠Concentrated ownership — top contributor handles 50% of recent commits
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/cartographer-project/cartographer)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/cartographer-project/cartographer on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: cartographer-project/cartographer
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/cartographer-project/cartographer shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across all four use cases
- 26+ active contributors
- Apache-2.0 licensed
- CI configured
- Tests present
- ⚠ Stale — last commit 2y ago
- ⚠ Concentrated ownership — top contributor handles 50% of recent commits
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live cartographer-project/cartographer
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/cartographer-project/cartographer.
What it runs against: a local clone of cartographer-project/cartographer — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in cartographer-project/cartographer | Confirms the artifact applies here, not a fork |
| 2 | License is still Apache-2.0 | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 885 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of cartographer-project/cartographer. If you don't
# have one yet, run these first:
#
# git clone https://github.com/cartographer-project/cartographer.git
# cd cartographer
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of cartographer-project/cartographer and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "cartographer-project/cartographer(\\.git)?\\b" \\
&& ok "origin remote is cartographer-project/cartographer" \\
|| miss "origin remote is not cartographer-project/cartographer (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is Apache-2.0" \\
|| miss "license drift — was Apache-2.0 at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "cartographer/BUILD.bazel" \\
&& ok "cartographer/BUILD.bazel" \\
|| miss "missing critical file: cartographer/BUILD.bazel"
test -f "WORKSPACE" \\
&& ok "WORKSPACE" \\
|| miss "missing critical file: WORKSPACE"
test -f "cartographer/cloud/client/map_builder_stub.h" \\
&& ok "cartographer/cloud/client/map_builder_stub.h" \\
|| miss "missing critical file: cartographer/cloud/client/map_builder_stub.h"
test -f "cartographer/cloud/internal/handlers/add_sensor_data_handler_base.h" \\
&& ok "cartographer/cloud/internal/handlers/add_sensor_data_handler_base.h" \\
|| miss "missing critical file: cartographer/cloud/internal/handlers/add_sensor_data_handler_base.h"
test -f "bazel/repositories.bzl" \\
&& ok "bazel/repositories.bzl" \\
|| miss "missing critical file: bazel/repositories.bzl"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 885 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~855d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/cartographer-project/cartographer"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Cartographer is a real-time SLAM (simultaneous localization and mapping) engine written in C++ that builds 2D and 3D maps while simultaneously estimating a robot's position across multiple sensor configurations and platforms. It combines lidar, IMU, and camera data through a graph-based optimization framework (using Ceres Solver) to produce globally consistent maps in real-time. Monorepo organized as a Bazel workspace: cartographer/ contains core SLAM library (map building, pose estimation, scan matching), with bazel/third_party/ managing 15+ vendored dependencies (Ceres, Eigen, Cairo, GD, Lua). CMAKE and Bazel both supported for builds. Lua scripting embedded for sensor configuration, C++ for core algorithms.
👥Who it's for
Roboticists and autonomous systems engineers building mobile robots (wheeled, UAVs, underwater vehicles) that need to map unknown environments and track their position without GPS, particularly those integrating with ROS 1/ROS 2 stacks via the cartographer_ros wrapper.
🌱Maturity & risk
Production-ready but no longer actively developed—the README explicitly states 'Cartographer is no longer actively maintained' with only rare critical PRs merged. The codebase is mature (2M+ lines of C++, 6+ years old based on README mentioning 2016 copyright) and uses comprehensive CI across Debian variants (bionic, buster, bullseye, focal, jammy). However, development has ceased and the ROS fork (ros2/cartographer) is now the maintained version.
Significant maintenance risk: official development stopped, community has migrated to the ROS fork (ros2/cartographer). The monolithic C++ codebase (2M LOC) with deep dependencies on Ceres, Eigen, and protocol buffers creates high upgrade friction. No indication of active issue triage or PR review velocity—new contributors should expect slow or no response.
Active areas of work
Project is in maintenance-only mode—no active development visible. The README directs users to ros2/cartographer fork for ongoing work. The .github/workflows/ CI runs on 5 Debian versions (bionic, buster, bullseye, focal, jammy) suggesting legacy platform support rather than active feature development.
🚀Get running
git clone https://github.com/cartographer-project/cartographer && cd cartographer && bazel build ... --config=release (see bazel/ and .bazelrc for configuration). For ROS integration, use the maintained fork: git clone https://github.com/ros2/cartographer.
Daily commands: bazel build --config=release cartographer:all (full release build). For development: bazel build cartographer/... (incremental). Lua examples in cartographer/configuration/ demonstrate sensor setups. See Dockerfile.* files for containerized environments (bionic, buster, bullseye, focal, jammy).
🗺️Map of the codebase
cartographer/BUILD.bazel— Root build manifest defining the entire Cartographer library structure, dependencies, and build targets across all modules.WORKSPACE— Bazel workspace configuration declaring external dependencies (Ceres, Eigen, gRPC) critical to the SLAM computation pipeline.cartographer/cloud/client/map_builder_stub.h— Primary client-side abstraction for distributed SLAM processing; entry point for remote map building operations.cartographer/cloud/internal/handlers/add_sensor_data_handler_base.h— Base handler pattern for all sensor data ingestion (LiDAR, IMU, odometry); fundamental to the sensor fusion architecture.bazel/repositories.bzl— Third-party dependency declarations (Cairo, Ceres, Lua) that enable real-time optimization and pose graph manipulation.cartographer-config.cmake.in— CMake configuration template for consumers building against Cartographer; critical for library integration..github/workflows/ci-jammy.yaml— CI/CD pipeline definition showing supported Linux distributions and test matrix for SLAM correctness validation.
🛠️How to make changes
Add a new sensor data handler (e.g., GPS receiver)
- Create handler header in cartographer/cloud/internal/handlers/ following naming convention add_<sensor>_data_handler.h (
cartographer/cloud/internal/handlers/add_gps_data_handler.h) - Inherit from AddSensorDataHandlerBase<> template and implement Handle() method to parse and inject sensor data (
cartographer/cloud/internal/handlers/add_sensor_data_handler_base.h) - Create .cc implementation file; validate sensor timestamp and coordinate frame consistency (
cartographer/cloud/internal/handlers/add_gps_data_handler.cc) - Register handler in the gRPC service dispatch logic (typically in server.cc or routing handler) (
cartographer/cloud/internal/handlers/BUILD.bazel) - Write integration test following pattern from add_imu_data_handler_test.cc; test timestamp ordering and pose integration (
cartographer/cloud/internal/handlers/add_gps_data_handler_test.cc)
Add a new query/getter handler for pose graph data
- Create handler header in cartographer/cloud/internal/handlers/ named get_<data>_handler.h (
cartographer/cloud/internal/handlers/get_landmark_poses_handler.h) - Implement to extract data from PoseGraph (typically via PoseGraphStub) and serialize to protobuf response (
cartographer/cloud/internal/handlers/get_landmark_poses_handler.cc) - Test handler output format and consistency with concurrent SLAM updates (
cartographer/cloud/internal/handlers/get_landmark_poses_handler_test.cc) - Register in gRPC service routing and update MapBuilderStub client if exposing public API (
cartographer/cloud/client/map_builder_stub.h)
Add support for a new platform (OS/architecture)
- Create new GitHub Actions workflow file in .github/workflows/ci-<platform>.yaml with platform-specific dependencies (
.github/workflows/ci-bullseye.yaml) - Add platform-specific Dockerfile in root (e.g., Dockerfile.bullseye) defining build environment (
Dockerfile.bullseye) - Update WORKSPACE and bazel/repositories.bzl with platform-specific dependency versions if needed (
bazel/repositories.bzl) - Add platform variant to CMakeLists.txt and cartographer-config.cmake.in for native CMake builds (
cartographer-config.cmake.in) - Verify all tests pass in CI pipeline; update documentation if platform-specific configuration is required (
.github/workflows/ci-jammy.yaml)
🔧Why these technologies
- Bazel build system — Enables hermetic, reproducible builds across diverse platforms (Linux, macOS, Windows) with precise dependency management; critical for consistent SLAM results.
- gRPC + Protocol Buffers — Provides efficient, language-agnostic RPC for distributed SLAM; allows remote trajectory processing and map queries with low-latency serialization.
- Ceres Solver — Industry-standard non-linear least-squares optimizer; solves the pose graph optimization problem at the heart of SLAM loop-closure refinement.
- Eigen linear algebra library — High-performance matrix operations for geometric transforms, rotation representations, and uncertainty propagation in SLAM calculations.
- Docker + multi-distro CI — Ensures reproducibility across Debian variants (Bionic, Focal, Bullseye, Jammy); critical for user environment compatibility.
⚖️Trade-offs already made
-
Centralized gRPC server architecture for distributed SLAM
- Why: Simplifies pose graph consistency and constraint resolution; avoids multi-master consensus complexity.
- Consequence: Single server becomes bottleneck for very high-frequency sensor streams; requires careful resource management and potential load-balancing.
-
Immutable sensor data handler inheritance hierarchy
- Why: Enforces consistent validation and
- Consequence: undefined
🪤Traps & gotchas
Bazel is the primary build system despite CMakeLists.txt presence—Bazel knowledge required for smooth development. Lua configuration syntax is non-obvious; many runtime errors stem from malformed .lua sensor configs. Graph optimization is CPU-intensive; single-threaded Ceres solver can bottleneck on large pose graphs. Protocol Buffer message definitions scattered across cartographer/mapping/proto/—schema changes require rebuilding. ROS integration requires separate ros2/cartographer fork; using this repo directly with ROS2 is unsupported.
🏗️Architecture
💡Concepts to learn
- Pose Graph Optimization — Cartographer's entire backend solves a pose graph SLAM problem—understanding nodes (poses), edges (measurements), and global optimization is fundamental to the architecture
- Scan Matching (ICP variant) — The frontend repeatedly aligns successive lidar scans to build local maps; this is the real-time bottleneck and critical path
- Loop Closure Detection — Detects when a robot returns to a previously visited location and triggers global map correction; essential for drift correction over long missions
- TSDF (Truncated Signed Distance Function) — Used in 3D scan matching and map representation; efficient sparse voxel representation for real-time 3D SLAM
- Ceres Solver Nonlinear Optimization — Cartographer delegates all pose graph optimization to Ceres; understanding cost functors, loss functions, and convergence criteria is necessary for tuning
- Submap Transformation (local→global) — Cartographer organizes the map into submaps with relative transforms; this hierarchical structure enables incremental mapping and memory efficiency
- Sensor Fusion (lidar + IMU + optional camera) — Multiple sensor streams are probabilistically combined; understanding measurement covariance and temporal synchronization is critical for robustness
🔗Related repos
ros2/cartographer— Official ROS 2 fork and maintained version; users should use this instead of the archived upstream for new developmentros2/cartographer_ros— ROS wrapper library that bridges Cartographer core to ROS 2 message pipelines, IMU/LaserScan topics, and visualizationethz-asl/ceres-solver— Ceres Solver—the nonlinear optimization engine used for graph optimization; understanding its cost functor API is essentialgoogle/protobuf— Protocol Buffers handle serialization of maps, poses, and sensor data throughout Cartographer; proto definitions are in cartographer/mapping/proto/PointCloudLibrary/pcl— Complementary 3D point cloud processing library often used alongside Cartographer for post-processing and visualization
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive CI workflow for ARM64/armv7l cross-platform builds
Cartographer targets 'multiple platforms and sensor configurations' but the current GitHub workflows (.github/workflows/ci-*.yaml) only test on standard x86_64 Linux distributions (bionic, focal, buster, bullseye, jammy). Mobile robotics platforms commonly use ARM architectures. Adding ARM64 CI would catch platform-specific SLAM algorithm issues, alignment problems, and dependency incompatibilities early. This is critical for a SLAM library claiming broad platform support.
- [ ] Create .github/workflows/ci-arm64.yaml using GitHub Actions ARM runners or cross-compilation
- [ ] Test Bazel builds against ARM64 targets (aarch64-linux-gnu toolchain)
- [ ] Verify cartographer/cloud handlers and cartographer core SLAM pipeline compile for ARM
- [ ] Add ARM-specific dependency checks (ensure cairo, ceres, eigen targets ARM in bazel/third_party/)
- [ ] Document ARM build requirements in CONTRIBUTING.md
Add integration tests for cartographer/cloud client-server architecture
The cartographer/cloud/internal/ directory contains multiple handler implementations (add_imu_data_handler, add_fixed_frame_pose_data_handler, add_landmark_data_handler) with corresponding _test.cc files, but there's no end-to-end integration test verifying the full cloud client-server communication pipeline. cartographer/cloud/client/map_builder_stub.cc and trajectory_builder_stub.cc are critical for distributed SLAM but lack documented test coverage for network failures, data serialization, and pose graph synchronization across client-server boundaries.
- [ ] Create cartographer/cloud/integration_test.cc testing map_builder_stub + server roundtrip
- [ ] Add test cases for concurrent trajectory building requests from multiple cloud clients
- [ ] Verify pose graph updates propagate correctly from server to clients (test pose_graph_stub.cc)
- [ ] Test handler data ordering and consistency under network latency simulation
- [ ] Add test for graceful degradation when server becomes unavailable
Add Docker multi-architecture build support and publish to container registry
The repository contains 5 Dockerfiles (Dockerfile.bionic, focal, buster, bullseye, jammy) but no automated Docker image building/publishing in CI. Given Cartographer's use in containerized robotics deployments and the emphasis on multiple platforms, automated multi-arch Docker image builds (amd64, arm64, arm32v7) would dramatically improve adoption. The current manual Dockerfile approach creates maintenance burden and inconsistency.
- [ ] Add .github/workflows/docker-build-push.yaml using docker/build-push-action with buildx for multi-platform builds
- [ ] Configure docker-compose setup for local testing across architectures
- [ ] Create cartographer/docker/entrypoint.sh for standard container image entry point
- [ ] Update RELEASING.rst with Docker image versioning/tagging strategy
- [ ] Add docker build targets to BUILD.bazel files to integrate with existing Bazel-based CI
🌿Good first issues
- Add missing unit tests for cartographer/mapping/internal/scan_matching/tsdf_match_cost_functor.h (file exists but test coverage is sparse based on Bazel BUILD rules lacking test targets)
- Document the Lua configuration schema—cartographer/configuration/ has .lua examples but no formal schema docs; contribute schema reference and migration guide for Lua config v1→v2
- Extend cartographer/io/ to support additional rosbag2 metadata formats; current code reads v1/v2 but v3 support is partially stubbed based on CMake conditionals
⭐Top contributors
Click to expand
Top contributors
- @wohe — 50 commits
- @MichaelGrupp — 14 commits
- @schwoere — 6 commits
- @zjwoody — 3 commits
- @gaschler — 3 commits
📝Recent commits
Click to expand
Recent commits
877157a— Add note for ROS users. (#1941) (kscottz)ef00de2— update rules_boost to latest version (#1898) (Wyverald)9ab5574— Add Debian Bullseye to the install scripts, CI, docs. (#1897) (wohe)1173e80— removed unused param from cmake macro (#1847) (XiaotaoGuo)ca526de— Fix crash caused by setting gravity lower bound (#1893) (hlinhn)dc62634— Remove Debian Stretch from CI. (#1895) (wohe)7b8b29d— Fix CI for Ubuntu 18.04 by disabling gRPC test build for now. (#1891) (wohe)5663e34— Fix typo in trajectory_builder_3d.lua (#1870) (OTL)f76f849— Add Ubuntu 22.04 to the install scripts, CI, docs. (#1888) (wohe)b1b63a3— Add libabsl-dev to the package.xml dependencies. (#1875) (clalancette)
🔒Security observations
Cartographer is a mature SLAM system with reasonable security practices in version control and build systems. However, the cloud/gRPC components lack visible explicit authentication and authorization mechanisms, which is a significant concern for a distributed
- Medium · Multiple Dockerfile configurations without explicit security base images —
Dockerfile.bionic, Dockerfile.buster, Dockerfile.bullseye, Dockerfile.focal, Dockerfile.jammy, Dockerfile.trusty.bazel. The codebase contains multiple Dockerfiles (bionic, bullseye, buster, focal, jammy, trusty) with varying Ubuntu base images. Some of these images (e.g., trusty, bionic) are EOL or approaching EOL and may contain unpatched vulnerabilities. No explicit security scanning or minimal base image strategy (e.g., distroless, alpine) is evident. Fix: 1) Use only currently supported Ubuntu LTS versions (jammy, focal preferred). 2) Consider using minimal base images (distroless, alpine). 3) Implement vulnerability scanning in CI/CD. 4) Pin base image versions explicitly. 5) Regularly update and rebuild images. - Medium · gRPC service exposure without explicit authentication framework —
cartographer/cloud/, Dockerfile.bionic.grpc. The codebase includes gRPC-based cloud services (cartographer/cloud/client, handlers) and a Dockerfile.bionic.grpc variant. gRPC endpoints are exposed but there is no evident explicit authentication/authorization mechanism visible in the file structure (no OAuth, mTLS, or API key validation patterns detected). Fix: 1) Implement TLS/mTLS for gRPC endpoints. 2) Add authentication middleware (OAuth2, JWT, or mutual TLS certificates). 3) Implement rate limiting and request validation. 4) Use gRPC interceptors for security checks. 5) Document security requirements in CONTRIBUTING.md. - Medium · Potential data injection risks in sensor data handlers —
cartographer/cloud/internal/handlers/add_*_data_handler.cc. Multiple handler files (add_*_data_handler.cc) process external sensor data (odometry, IMU, rangefinder, landmarks, fixed frame poses). Without visible input validation patterns, these could be vulnerable to malformed data injection or DoS attacks. Fix: 1) Implement strict input validation for all sensor data. 2) Add boundary checks and type validation. 3) Implement size limits for incoming data. 4) Add fuzzing tests for handler inputs. 5) Use protocol buffers with strict schema validation. - Low · No explicit security configuration documentation —
CONTRIBUTING.md, README.rst, root directory. The CONTRIBUTING.md and README lack security guidelines, vulnerability disclosure process, or security best practices for developers. No SECURITY.md file is evident. Fix: 1) Create a SECURITY.md file with vulnerability reporting process. 2) Add security guidelines to CONTRIBUTING.md. 3) Document secure coding practices for cloud components. 4) Establish security review process for PRs affecting cloud/network code. - Low · Build system dependency management not fully visible —
bazel/repositories.bzl, bazel/third_party/, WORKSPACE. Dependencies are managed through Bazel (bazel/repositories.bzl, bazel/third_party/). Without access to the actual WORKSPACE file and dependency versions, potential supply chain risks cannot be fully assessed. Third-party build files (.BUILD) exist for libraries like ceres, eigen, cairo, but version pinning is not evident. Fix: 1) Pin all third-party dependency versions explicitly. 2) Implement dependency vulnerability scanning in CI/CD. 3) Use dependency lock files or equivalent. 4) Regularly audit and update dependencies. 5) Document all external dependencies with versions. - Low · CI/CD pipeline configuration lacks security scanning —
.github/workflows/, azure-pipelines.yml. GitHub Actions workflows (.github/workflows/ci-*.yaml) and Azure Pipelines (azure-pipelines.yml) are present but their content is not visible. Security scanning tools (SAST, dependency scanning, container scanning) may not be integrated. Fix: 1) Add SAST tools (clang-tidy, cppcheck) to CI pipeline. 2) Integrate dependency vulnerability scanning. 3) Add container image scanning for Dockerfiles. 4) Implement code coverage requirements. 5) Add security-focused linting rules.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.