# adityapullabhotla/reaction_wheel architecture

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

- Interactive diagram: https://gitdiagram.com/adityapullabhotla/reaction_wheel
- Repository: https://github.com/adityapullabhotla/reaction_wheel
- Video tour (about a minute): https://gitdiagram.com/adityapullabhotla/reaction_wheel/video

## Overview

This Raspberry Pi testbed demonstrates reaction-wheel attitude control in three principal modes: zero-rate disturbance rejection, camera-based target tracking, and motor saturation characterization. Operators run separate scripts for each experiment. Tracking combines camera vision and a cascaded outer/inner control loop, while the saturation test ramps motor PWM and detects diminishing RPM gain. The camera feed provides a browser-visible stream and tracking marker. The graph follows the README and sampled source; unsampled files are represented only where their paths and purpose are supported by the tree or README.

Main entry points: [`src/tracking_graph.py`](https://github.com/adityapullabhotla/reaction_wheel/blob/main/src/tracking_graph.py) (Cascaded Tracker), [`src/tracking_vision.py`](https://github.com/adityapullabhotla/reaction_wheel/blob/main/src/tracking_vision.py) (Vision Tracker), [`src/demo1_graph.py`](https://github.com/adityapullabhotla/reaction_wheel/blob/main/src/demo1_graph.py) (Logged PID Demo), [`data/saturationtest.py`](https://github.com/adityapullabhotla/reaction_wheel/blob/main/data/saturationtest.py) (PWM Ramp Test)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_disturbance["Disturbance Rejection"]
  node_demo["Zero-Rate PID<br/>[demo_1.py]"]
  node_demo_graph["Logged PID Demo<br/>[demo1_graph.py]"]
  node_rejection_plot["Rejection Plot<br/>[demo1_graph.py]"]
end

subgraph group_tracking["Vision Tracking"]
  node_tracking_vision["Vision Tracker<br/>[tracking_vision.py]"]
  node_tracking_cascade["Cascaded Tracker<br/>[tracking_graph.py]"]
  node_live_feed["Live Camera Feed"]
  node_tracking_plot["Tracking Plots<br/>[tracking_graph.py]"]
end

subgraph group_saturation["Saturation Test"]
  node_saturation_test["PWM Ramp Test<br/>[saturationtest.py]"]
  node_sat_plot["Saturation Plot<br/>[saturationtest.py]"]
end

subgraph group_instrumentation["Instrumentation"]
  node_imu_reader["IMU Reader<br/>[imu_data.py]"]
  node_encoder_test["Encoder Test"]
end

node_operator(("Operator"))
node_imu{{"BNO085 IMU"}}
node_motor{{"H-Bridge Motor"}}
node_camera{{"Pi Camera"}}
node_browser(("Stream Viewer"))
node_encoder{{"Quadrature Encoder"}}

node_operator -->|"runs"| node_demo
node_operator -->|"runs"| node_demo_graph
node_operator -->|"runs"| node_tracking_vision
node_operator -->|"runs"| node_tracking_cascade
node_operator -->|"runs"| node_saturation_test
node_operator -->|"runs"| node_imu_reader
node_operator -->|"runs"| node_encoder_test
node_demo -->|"reads gyro"| node_imu
node_demo -->|"drives PWM"| node_motor
node_demo_graph -->|"reads gyro"| node_imu
node_demo_graph -->|"drives PWM"| node_motor
node_demo_graph -->|"generates"| node_rejection_plot
node_tracking_vision -->|"captures frames"| node_camera
node_tracking_vision -.->|"reads gyro"| node_imu
node_tracking_vision -->|"drives PWM"| node_motor
node_tracking_vision -->|"sets camera and marker"| node_live_feed
node_tracking_cascade -->|"captures frames"| node_camera
node_tracking_cascade -->|"reads gyro"| node_imu
node_tracking_cascade -->|"drives PWM"| node_motor
node_tracking_cascade -->|"sets camera and marker"| node_live_feed
node_tracking_cascade -->|"generates"| node_tracking_plot
node_live_feed -->|"captures frames"| node_camera
node_browser -->|"requests stream"| node_live_feed
node_saturation_test -->|"reads gyro"| node_imu
node_saturation_test -->|"ramps PWM"| node_motor
node_saturation_test -->|"generates"| node_sat_plot
node_imu_reader -->|"reads gyro"| node_imu
node_encoder_test -->|"drives PWM"| node_motor
node_encoder_test -->|"reads ticks"| node_encoder

click node_demo "https://github.com/adityapullabhotla/reaction_wheel/blob/main/src/demo_1.py"
click node_demo_graph "https://github.com/adityapullabhotla/reaction_wheel/blob/main/src/demo1_graph.py"
click node_tracking_vision "https://github.com/adityapullabhotla/reaction_wheel/blob/main/src/tracking_vision.py"
click node_tracking_cascade "https://github.com/adityapullabhotla/reaction_wheel/blob/main/src/tracking_graph.py"
click node_live_feed "https://github.com/adityapullabhotla/reaction_wheel/blob/main/src/camera_live_feed.py"
click node_saturation_test "https://github.com/adityapullabhotla/reaction_wheel/blob/main/data/saturationtest.py"
click node_sat_plot "https://github.com/adityapullabhotla/reaction_wheel/blob/main/data/saturationtest.py"
click node_imu_reader "https://github.com/adityapullabhotla/reaction_wheel/blob/main/data/imu_data.py"
click node_encoder_test "https://github.com/adityapullabhotla/reaction_wheel/blob/main/data/motor_encoder_data.py"
click node_tracking_plot "https://github.com/adityapullabhotla/reaction_wheel/blob/main/src/tracking_graph.py"
click node_rejection_plot "https://github.com/adityapullabhotla/reaction_wheel/blob/main/src/demo1_graph.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_demo,node_demo_graph,node_rejection_plot,node_browser toneBlue
class node_tracking_vision,node_tracking_cascade,node_live_feed,node_tracking_plot toneAmber
class node_saturation_test,node_sat_plot toneMint
class node_imu_reader,node_encoder_test toneRose
class node_operator,node_imu,node_motor,node_camera,node_encoder toneIndigo
```

## Components

### Disturbance Rejection

- [Zero-Rate PID](https://github.com/adityapullabhotla/reaction_wheel/blob/main/src/demo_1.py): `src/demo_1.py`
- [Logged PID Demo](https://github.com/adityapullabhotla/reaction_wheel/blob/main/src/demo1_graph.py): `src/demo1_graph.py`
- [Rejection Plot](https://github.com/adityapullabhotla/reaction_wheel/blob/main/src/demo1_graph.py): `src/demo1_graph.py`

### Vision Tracking

- [Vision Tracker](https://github.com/adityapullabhotla/reaction_wheel/blob/main/src/tracking_vision.py): `src/tracking_vision.py`
- [Cascaded Tracker](https://github.com/adityapullabhotla/reaction_wheel/blob/main/src/tracking_graph.py): `src/tracking_graph.py`
- [Live Camera Feed](https://github.com/adityapullabhotla/reaction_wheel/blob/main/src/camera_live_feed.py): `src/camera_live_feed.py`
- [Tracking Plots](https://github.com/adityapullabhotla/reaction_wheel/blob/main/src/tracking_graph.py): `src/tracking_graph.py`

### Saturation Test

- [PWM Ramp Test](https://github.com/adityapullabhotla/reaction_wheel/blob/main/data/saturationtest.py): `data/saturationtest.py`
- [Saturation Plot](https://github.com/adityapullabhotla/reaction_wheel/blob/main/data/saturationtest.py): `data/saturationtest.py`

### Instrumentation

- [IMU Reader](https://github.com/adityapullabhotla/reaction_wheel/blob/main/data/imu_data.py): `data/imu_data.py`
- [Encoder Test](https://github.com/adityapullabhotla/reaction_wheel/blob/main/data/motor_encoder_data.py): `data/motor_encoder_data.py`

### Other components

- **Operator**
- **BNO085 IMU**
- **H-Bridge Motor**
- **Pi Camera**
- **Stream Viewer**
- **Quadrature Encoder**

## Connections

- Operator → Zero-Rate PID: runs
- Operator → Logged PID Demo: runs
- Operator → Vision Tracker: runs
- Operator → Cascaded Tracker: runs
- Operator → PWM Ramp Test: runs
- Operator → IMU Reader: runs
- Operator → Encoder Test: runs
- Zero-Rate PID → BNO085 IMU: reads gyro
- Zero-Rate PID → H-Bridge Motor: drives PWM
- Logged PID Demo → BNO085 IMU: reads gyro
- Logged PID Demo → H-Bridge Motor: drives PWM
- Logged PID Demo → Rejection Plot: generates
- Vision Tracker → Pi Camera: captures frames
- Vision Tracker → BNO085 IMU: reads gyro
- Vision Tracker → H-Bridge Motor: drives PWM
- Vision Tracker → Live Camera Feed: sets camera and marker
- Cascaded Tracker → Pi Camera: captures frames
- Cascaded Tracker → BNO085 IMU: reads gyro
- Cascaded Tracker → H-Bridge Motor: drives PWM
- Cascaded Tracker → Live Camera Feed: sets camera and marker
- Cascaded Tracker → Tracking Plots: generates
- Live Camera Feed → Pi Camera: captures frames
- Stream Viewer → Live Camera Feed: requests stream
- PWM Ramp Test → BNO085 IMU: reads gyro
- PWM Ramp Test → H-Bridge Motor: ramps PWM
- PWM Ramp Test → Saturation Plot: generates
- IMU Reader → BNO085 IMU: reads gyro
- Encoder Test → H-Bridge Motor: drives PWM
- Encoder Test → Quadrature Encoder: reads ticks
