# tomdoyo/open-command architecture

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

- Interactive diagram: https://gitdiagram.com/tomdoyo/open-command
- Repository: https://github.com/tomdoyo/open-command

## Overview

OpenCommand is a baseball-pitch command tracker: it estimates camera geometry, projects catcher-glove detections into world coordinates, infers a target, and scores each pitch by distance from its actual location to that target. The README documents the stage inputs and outputs, plus validation and comparison capabilities; sampled source confirms the geometry, pose solve, glove filtering, and hierarchical target model. The scoring and validation implementation is only partially sampled, so its documented inputs and outputs are shown without adding unsupported internal call links.

Main entry points: [`src/opencommand.py`](https://github.com/tomdoyo/open-command/blob/main/src/opencommand.py) (Command scoring), [`src/solve_camera_pose.py`](https://github.com/tomdoyo/open-command/blob/main/src/solve_camera_pose.py) (Pose solver), [`src/solve_glove_locations.py`](https://github.com/tomdoyo/open-command/blob/main/src/solve_glove_locations.py) (Glove projection), [`src/target_inference.py`](https://github.com/tomdoyo/open-command/blob/main/src/target_inference.py) (Target inference)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_pose["Camera Pose"]
  node_pose_solver["Pose solver"]
  node_geometry["Geometry &amp; timing<br/>[poselib.py]"]
  node_poses["Camera poses"]
end

subgraph group_glove["Glove Projection"]
  node_glove_solver["Glove projection"]
  node_gloves["World glove locations"]
end

subgraph group_target["Target Inference"]
  node_inference["Target inference"]
  node_targets["Inferred targets"]
end

subgraph group_score["Scoring &amp; Validation"]
  node_scorer["Command scoring<br/>[opencommand.py]"]
  node_scores["Command scores"]
  node_validation["Model validations"]
end

node_operator(("Pipeline operator"))
node_rawtracks["Ball/glove tracks"]
node_zones["Strikezone detections"]
node_pbp["Pitch data"]
node_fangraphs["FanGraphs pitching"]

node_operator -->|"runs stage"| node_pose_solver
node_operator -->|"runs stage"| node_glove_solver
node_operator -->|"runs stage"| node_inference
node_operator -->|"runs stage"| node_scorer
node_rawtracks -->|"reads tracks"| node_pose_solver
node_zones -->|"reads detections"| node_pose_solver
node_pbp -->|"reads pitch data"| node_pose_solver
node_pose_solver -->|"uses geometry"| node_geometry
node_pose_solver -->|"writes poses"| node_poses
node_poses -->|"reads poses"| node_glove_solver
node_rawtracks -->|"reads detections"| node_glove_solver
node_glove_solver -->|"unprojects pixels"| node_geometry
node_glove_solver -->|"writes locations"| node_gloves
node_gloves -->|"reads locations"| node_inference
node_pbp -->|"reads pitch context"| node_inference
node_inference -->|"writes targets"| node_targets
node_targets -->|"reads targets"| node_scorer
node_pbp -->|"reads pitch data"| node_scorer
node_poses -->|"reads poses"| node_scorer
node_fangraphs -->|"reads comparison data"| node_scorer
node_scorer -->|"writes scores"| node_scores
node_scorer -->|"writes validations"| node_validation

click node_pose_solver "https://github.com/tomdoyo/open-command/blob/main/src/solve_camera_pose.py"
click node_geometry "https://github.com/tomdoyo/open-command/blob/main/src/poselib.py"
click node_glove_solver "https://github.com/tomdoyo/open-command/blob/main/src/solve_glove_locations.py"
click node_inference "https://github.com/tomdoyo/open-command/blob/main/src/target_inference.py"
click node_scorer "https://github.com/tomdoyo/open-command/blob/main/src/opencommand.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_pose_solver,node_geometry,node_poses toneBlue
class node_glove_solver,node_gloves toneAmber
class node_inference,node_targets toneMint
class node_scorer,node_scores,node_validation toneRose
class node_operator,node_rawtracks,node_zones,node_pbp,node_fangraphs toneIndigo
```

## Components

### Camera Pose

- [Pose solver](https://github.com/tomdoyo/open-command/blob/main/src/solve_camera_pose.py): `src/solve_camera_pose.py`
- [Geometry & timing](https://github.com/tomdoyo/open-command/blob/main/src/poselib.py): `src/poselib.py`
- **Camera poses**

### Glove Projection

- [Glove projection](https://github.com/tomdoyo/open-command/blob/main/src/solve_glove_locations.py): `src/solve_glove_locations.py`
- **World glove locations**

### Target Inference

- [Target inference](https://github.com/tomdoyo/open-command/blob/main/src/target_inference.py): `src/target_inference.py`
- **Inferred targets**

### Scoring & Validation

- [Command scoring](https://github.com/tomdoyo/open-command/blob/main/src/opencommand.py): `src/opencommand.py`
- **Command scores**
- **Model validations**

### Other components

- **Pipeline operator**
- **Ball/glove tracks**
- **Strikezone detections**
- **Pitch data**
- **FanGraphs pitching**

## Connections

- Pipeline operator → Pose solver: runs stage
- Pipeline operator → Glove projection: runs stage
- Pipeline operator → Target inference: runs stage
- Pipeline operator → Command scoring: runs stage
- Ball/glove tracks → Pose solver: reads tracks
- Strikezone detections → Pose solver: reads detections
- Pitch data → Pose solver: reads pitch data
- Pose solver → Geometry & timing: uses geometry
- Pose solver → Camera poses: writes poses
- Camera poses → Glove projection: reads poses
- Ball/glove tracks → Glove projection: reads detections
- Glove projection → Geometry & timing: unprojects pixels
- Glove projection → World glove locations: writes locations
- World glove locations → Target inference: reads locations
- Pitch data → Target inference: reads pitch context
- Target inference → Inferred targets: writes targets
- Inferred targets → Command scoring: reads targets
- Pitch data → Command scoring: reads pitch data
- Camera poses → Command scoring: reads poses
- FanGraphs pitching → Command scoring: reads comparison data
- Command scoring → Command scores: writes scores
- Command scoring → Model validations: writes validations
