# paulkemppi/gtsam_fusion architecture

> Architecture diagram of the GitHub repository paulkemppi/gtsam_fusion, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-26). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/paulkemppi/gtsam_fusion
- Repository: https://github.com/paulkemppi/gtsam_fusion

## Overview

gtsam_fusion is a ROS/GTSAM state-estimation package: IMU data drives pose, velocity, and bias prediction, while GPS and/or 6DOF pose measurements constrain drift through incremental ISAM2 optimization. The ROS node supports live topic subscriptions and rosbag playback, converts frames and GPS coordinates, then publishes the fused base pose; optional plotting compares inputs and estimates. The graph follows documented behavior and sampled source, but ROS bag dispatch and some conversion details are only partially excerpted.

Main entry points: [`scripts/gtsam_fusion_ros.py`](https://github.com/paulkemppi/gtsam_fusion/blob/master/scripts/gtsam_fusion_ros.py) (ROS fusion node), [`scripts/gtsam_fusion_core.py`](https://github.com/paulkemppi/gtsam_fusion/blob/master/scripts/gtsam_fusion_core.py) (Fusion core), [`scripts/plots.py`](https://github.com/paulkemppi/gtsam_fusion/blob/master/scripts/plots.py) (Result plots)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_ros["ROS Interface"]
  node_rosnode["ROS fusion node"]
  node_bagreader["Rosbag reader"]
  node_gpsconvert["GPS to ENU"]
  node_frameconvert["Frame transforms"]
  node_output["Pose publisher"]
end

subgraph group_fusion["Fusion Engine"]
  node_fusioncore["Fusion core"]
  node_imuintegrate["IMU preintegration"]
  node_measurements["Measurement factors"]
  node_isam["ISAM2 optimizer"]
  node_estimate["Pose estimate"]
end

subgraph group_tools["Output &amp; Analysis"]
  node_plots["Result plots<br/>[plots.py]"]
end

node_operator(("Operator"))
node_imu(("IMU stream"))
node_gps(("GPS stream"))
node_pose(("6DOF pose stream"))
node_bag["Rosbag input"]
node_gtsam["GTSAM"]
node_rosout(("ROS pose topic"))
node_plotuser(("Plot viewer"))

node_operator -->|"starts"| node_rosnode
node_bag -.->|"provides data"| node_bagreader
node_bagreader -.->|"dispatches messages"| node_rosnode
node_imu -->|"publishes IMU"| node_rosnode
node_gps -.->|"publishes GPS"| node_rosnode
node_pose -.->|"publishes pose"| node_rosnode
node_rosnode -->|"converts GPS"| node_gpsconvert
node_rosnode -->|"transforms frames"| node_frameconvert
node_rosnode -->|"submits measurements"| node_fusioncore
node_fusioncore -->|"preintegrates"| node_imuintegrate
node_fusioncore -->|"adds constraints"| node_measurements
node_fusioncore -->|"updates graph"| node_isam
node_isam -->|"optimizes with"| node_gtsam
node_fusioncore -->|"returns state"| node_estimate
node_rosnode -->|"publishes estimate"| node_output
node_output -->|"publishes pose"| node_rosout
node_rosnode -.->|"sends recorded data"| node_plots
node_plots -.->|"displays charts"| node_plotuser

click node_rosnode "https://github.com/paulkemppi/gtsam_fusion/blob/master/scripts/gtsam_fusion_ros.py"
click node_bagreader "https://github.com/paulkemppi/gtsam_fusion/blob/master/scripts/gtsam_fusion_ros.py"
click node_gpsconvert "https://github.com/paulkemppi/gtsam_fusion/blob/master/scripts/gtsam_fusion_ros.py"
click node_frameconvert "https://github.com/paulkemppi/gtsam_fusion/blob/master/scripts/gtsam_fusion_ros.py"
click node_fusioncore "https://github.com/paulkemppi/gtsam_fusion/blob/master/scripts/gtsam_fusion_core.py"
click node_imuintegrate "https://github.com/paulkemppi/gtsam_fusion/blob/master/scripts/gtsam_fusion_core.py"
click node_measurements "https://github.com/paulkemppi/gtsam_fusion/blob/master/scripts/gtsam_fusion_core.py"
click node_isam "https://github.com/paulkemppi/gtsam_fusion/blob/master/scripts/gtsam_fusion_core.py"
click node_estimate "https://github.com/paulkemppi/gtsam_fusion/blob/master/scripts/gtsam_fusion_core.py"
click node_output "https://github.com/paulkemppi/gtsam_fusion/blob/master/scripts/gtsam_fusion_ros.py"
click node_plots "https://github.com/paulkemppi/gtsam_fusion/blob/master/scripts/plots.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_rosnode,node_bagreader,node_gpsconvert,node_frameconvert,node_output,node_plotuser toneBlue
class node_fusioncore,node_imuintegrate,node_measurements,node_isam,node_estimate toneAmber
class node_plots toneMint
class node_operator,node_imu,node_gps,node_pose,node_bag,node_gtsam,node_rosout toneIndigo
```

## Components

### ROS Interface

- [ROS fusion node](https://github.com/paulkemppi/gtsam_fusion/blob/master/scripts/gtsam_fusion_ros.py): `scripts/gtsam_fusion_ros.py`
- [Rosbag reader](https://github.com/paulkemppi/gtsam_fusion/blob/master/scripts/gtsam_fusion_ros.py): `scripts/gtsam_fusion_ros.py`
- [GPS to ENU](https://github.com/paulkemppi/gtsam_fusion/blob/master/scripts/gtsam_fusion_ros.py): `scripts/gtsam_fusion_ros.py`
- [Frame transforms](https://github.com/paulkemppi/gtsam_fusion/blob/master/scripts/gtsam_fusion_ros.py): `scripts/gtsam_fusion_ros.py`
- [Pose publisher](https://github.com/paulkemppi/gtsam_fusion/blob/master/scripts/gtsam_fusion_ros.py): `scripts/gtsam_fusion_ros.py`

### Fusion Engine

- [Fusion core](https://github.com/paulkemppi/gtsam_fusion/blob/master/scripts/gtsam_fusion_core.py): `scripts/gtsam_fusion_core.py`
- [IMU preintegration](https://github.com/paulkemppi/gtsam_fusion/blob/master/scripts/gtsam_fusion_core.py): `scripts/gtsam_fusion_core.py`
- [Measurement factors](https://github.com/paulkemppi/gtsam_fusion/blob/master/scripts/gtsam_fusion_core.py): `scripts/gtsam_fusion_core.py`
- [ISAM2 optimizer](https://github.com/paulkemppi/gtsam_fusion/blob/master/scripts/gtsam_fusion_core.py): `scripts/gtsam_fusion_core.py`
- [Pose estimate](https://github.com/paulkemppi/gtsam_fusion/blob/master/scripts/gtsam_fusion_core.py): `scripts/gtsam_fusion_core.py`

### Output & Analysis

- [Result plots](https://github.com/paulkemppi/gtsam_fusion/blob/master/scripts/plots.py): `scripts/plots.py`

### Other components

- **Operator**
- **IMU stream**
- **GPS stream**
- **6DOF pose stream**
- **Rosbag input**
- **GTSAM**
- **ROS pose topic**
- **Plot viewer**

## Connections

- Operator → ROS fusion node: starts
- Rosbag input → Rosbag reader: provides data
- Rosbag reader → ROS fusion node: dispatches messages
- IMU stream → ROS fusion node: publishes IMU
- GPS stream → ROS fusion node: publishes GPS
- 6DOF pose stream → ROS fusion node: publishes pose
- ROS fusion node → GPS to ENU: converts GPS
- ROS fusion node → Frame transforms: transforms frames
- ROS fusion node → Fusion core: submits measurements
- Fusion core → IMU preintegration: preintegrates
- Fusion core → Measurement factors: adds constraints
- Fusion core → ISAM2 optimizer: updates graph
- ISAM2 optimizer → GTSAM: optimizes with
- Fusion core → Pose estimate: returns state
- ROS fusion node → Pose publisher: publishes estimate
- Pose publisher → ROS pose topic: publishes pose
- ROS fusion node → Result plots: sends recorded data
- Result plots → Plot viewer: displays charts
