manpads-system-launcher-and-rocket
```markdown
What this skill does
```markdown
---
name: manpads-system-launcher-and-rocket
description: Low-cost proof-of-concept MANPADS-style guided rocket and launcher prototype using ESP32, MPU6050, folding fins, canard stabilization, and consumer electronics
triggers:
- manpads rocket launcher
- esp32 flight controller
- guided rocket prototype
- canard stabilization firmware
- mpu6050 rocket imu
- openrocket simulation
- 3d printed rocket launcher
- folding fin rocket design
---
# MANPADS System Launcher and Rocket Skill
> Skill by [ara.so](https://ara.so) — Daily 2026 Skills collection
A proof-of-concept guided rocket and launcher system built with consumer electronics and 3D-printed components. The rocket features folding fins, canard stabilization, an ESP32 flight computer, and an MPU6050 IMU. The launcher integrates GPS, compass, and barometric sensors for orientation and telemetry. Total hardware cost: ~$96.
---
## What It Does
- **Rocket flight computer**: ESP32-based controller reads IMU data, drives canard servos for stabilization, manages ignition sequencing
- **Launcher system**: GPS + compass + barometer integration for target orientation and telemetry
- **Mechanical design**: Fusion 360 CAD for rocket body, folding fins, canard assembly, and launcher tube
- **Simulation**: OpenRocket files for aerodynamic stability analysis and motor selection
- **Firmware**: Arduino/ESP-IDF firmware for both rocket and launcher subsystems
---
## Repository Structure
```
/
├── CAD/ # Fusion 360 .f3d files for rocket and launcher
├── Firmware/
│ ├── Rocket/ # ESP32 flight controller firmware
│ └── Launcher/ # Launcher sensor and telemetry firmware
├── Simulation/ # OpenRocket .ork simulation files
└── Documentation/ # System flow diagrams, BOM, specs
```
---
## Hardware Stack
### Rocket
| Component | Purpose |
|---|---|
| ESP32 | Flight computer / main MCU |
| MPU6050 | 6-DOF IMU (accel + gyro) |
| Micro servos (x2) | Canard fin actuation |
| E-match / igniter | Motor ignition |
| LiPo cell | Power supply |
### Launcher
| Component | Purpose |
|---|---|
| ESP32 | Main controller |
| GPS module (NEO-6M or similar) | Position fix |
| HMC5883L / QMC5883 | Compass / heading |
| BMP280 / MS5611 | Barometric altitude |
| Relay module | Fire control circuit |
---
## Firmware: Rocket Flight Controller
### Core IMU Read + Canard Control Loop (ESP32 / Arduino framework)
```cpp
#include <Wire.h>
#include <MPU6050.h>
#include <ESP32Servo.h>
MPU6050 imu;
Servo canardPitch;
Servo canardYaw;
// PID state
float pitchIntegral = 0, yawIntegral = 0;
float prevPitchErr = 0, prevYawErr = 0;
const float Kp = 1.2f, Ki = 0.01f, Kd = 0.4f;
const int SERVO_CENTER = 90;
const int SERVO_RANGE = 30; // ±30 degrees max deflection
void setup() {
Wire.begin();
imu.initialize();
if (!imu.testConnection()) {
Serial.println("MPU6050 connection failed");
while (1);
}
canardPitch.attach(18); // GPIO18
canardYaw.attach(19); // GPIO19
canardPitch.write(SERVO_CENTER);
canardYaw.write(SERVO_CENTER);
Serial.begin(115200);
}
float pidUpdate(float error, float &integral, float &prevError, float dt) {
integral += error * dt;
float derivative = (error - prevError) / dt;
prevError = error;
return Kp * error + Ki * integral + Kd * derivative;
}
void loop() {
static unsigned long lastTime = micros();
unsigned long now = micros();
float dt = (now - lastTime) / 1e6f;
lastTime = now;
int16_t ax, ay, az, gx, gy, gz;
imu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
// Convert raw gyro to deg/s (MPU6050 default ±250°/s scale)
float pitchRate = gy / 131.0f;
float yawRate = gz / 131.0f;
// Target: zero rotation rate (stabilization mode)
float pitchCmd = pidUpdate(pitchRate, pitchIntegral, prevPitchErr, dt);
float yawCmd = pidUpdate(yawRate, yawIntegral, prevYawErr, dt);
// Clamp and apply
pitchCmd = constrain(pitchCmd, -SERVO_RANGE, SERVO_RANGE);
yawCmd = constrain(yawCmd, -SERVO_RANGE, SERVO_RANGE);
canardPitch.write(SERVO_CENTER + (int)pitchCmd);
canardYaw.write(SERVO_CENTER + (int)yawCmd);
delayMicroseconds(2000); // ~500 Hz loop
}
```
### Complementary Filter for Attitude Estimation
```cpp
// Fuse accelerometer angle with gyro integration
float compFilter(float accelAngle, float gyroRate, float prevAngle, float dt, float alpha = 0.98f) {
return alpha * (prevAngle + gyroRate * dt) + (1.0f - alpha) * accelAngle;
}
float accelPitch(int16_t ax, int16_t ay, int16_t az) {
return atan2f((float)ay, sqrtf((float)ax * ax + (float)az * az)) * RAD_TO_DEG;
}
```
---
## Firmware: Launcher System
### GPS + Compass + Barometer Initialization
```cpp
#include <Wire.h>
#include <TinyGPS++.h>
#include <QMC5883LCompass.h>
#include <Adafruit_BMP280.h>
#include <HardwareSerial.h>
TinyGPSPlus gps;
QMC5883LCompass compass;
Adafruit_BMP280 baro;
HardwareSerial gpsSerial(1); // UART1
void launcherSetup() {
Wire.begin();
gpsSerial.begin(9600, SERIAL_8N1, 16, 17); // RX=GPIO16, TX=GPIO17
compass.init();
compass.setCalibration(-500, 500, -500, 500, -500, 500); // calibrate per unit
if (!baro.begin(0x76)) {
Serial.println("BMP280 not found");
}
baro.setSampling(Adafruit_BMP280::MODE_NORMAL,
Adafruit_BMP280::SAMPLING_X2,
Adafruit_BMP280::SAMPLING_X16,
Adafruit_BMP280::FILTER_X4,
Adafruit_BMP280::STANDBY_MS_500);
}
struct LauncherTelemetry {
double lat, lng;
float altitudeMSL;
float heading;
bool gpsFix;
};
LauncherTelemetry readTelemetry() {
LauncherTelemetry t = {};
// Feed GPS
while (gpsSerial.available()) gps.encode(gpsSerial.read());
t.gpsFix = gps.location.isValid();
if (t.gpsFix) {
t.lat = gps.location.lat();
t.lng = gps.location.lng();
}
t.altitudeMSL = baro.readAltitude(1013.25f); // standard sea-level pressure
compass.read();
t.heading = compass.getAzimuth(); // 0–360 degrees
return t;
}
```
### Fire Control Relay
```cpp
const int RELAY_PIN = 25;
const int ARM_PIN = 26; // physical arm switch
const int LAUNCH_DELAY = 3000; // ms countdown
void fireControlSetup() {
pinMode(RELAY_PIN, OUTPUT);
pinMode(ARM_PIN, INPUT_PULLUP);
digitalWrite(RELAY_PIN, LOW);
}
bool fireLaunch() {
if (digitalRead(ARM_PIN) != LOW) {
Serial.println("System not armed");
return false;
}
Serial.println("FIRE in 3...");
delay(LAUNCH_DELAY);
digitalWrite(RELAY_PIN, HIGH);
delay(500); // e-match pulse duration
digitalWrite(RELAY_PIN, LOW);
Serial.println("Launch complete");
return true;
}
```
---
## OpenRocket Simulation Workflow
1. Open `.ork` file in [OpenRocket](https://openrocket.info/) (free, Java-based)
2. Verify stability margin (target: 1.0–2.0 calibers at launch)
3. Select motor from database matching the prototype's 24mm or 29mm mount
4. Run simulation → check apogee, max velocity, max acceleration
5. Export CSV for post-processing thrust curves
```python
# Parse OpenRocket CSV export
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv("simulation_export.csv", skiprows=5)
df.columns = df.columns.str.strip()
plt.figure(figsize=(10, 4))
plt.plot(df["Time (s)"], df["Altitude (m)"], label="Altitude")
plt.plot(df["Time (s)"], df["Vertical velocity (m/s)"], label="Velocity")
plt.xlabel("Time (s)")
plt.legend()
plt.title("OpenRocket Simulation")
plt.tight_layout()
plt.savefig("sim_plot.png")
```
---
## Configuration
### PID Tuning Constants (Rocket firmware)
```cpp
// Tune these for your specific airframe and motor
const float Kp = 1.2f; // Proportional — increase for faster response
const float Ki = 0.01f; // Integral — increase to correct steady drift
const float Kd = 0.4f; // Derivative — increase to reduce overshoot
```
### MPU6050 Full-Scale Range
```cpp
// In setup(), optionally set higher range for high-G flight
imu.setFullScaleAccelRanRelated in Writing & Docs
jax-development
IncludedUse this skill when the user is writing, debugging, profiling, refactoring, reviewing, benchmarking, parallelising, exporting, or explaining JAX code, or when they mention JAX, jax.numpy, jit, grad, value_and_grad, vmap, scan, lax, random keys, pytrees, jax.Array, sharding, Mesh, PartitionSpec, NamedSharding, pmap, shard_map, Pallas, XLA, StableHLO, checkify, profiler, or the JAX repo. It helps turn NumPy or PyTorch-style code into pure functional JAX, fix tracer/control-flow/shape/PRNG bugs, remove recompiles and host-device syncs, choose transforms and sharding strategies, inspect jaxpr/lowering/IR, and benchmark compiled code correctly.
nature-article-writer
IncludedDrafts, rewrites, diagnostically critiques, and style-calibrates primary research manuscripts for Nature and Nature Portfolio journals. Use when the user wants a Nature-style title, summary paragraph or abstract, introduction, results, discussion, methods, figure legends, presubmission enquiry, cover letter, reviewer response, or when a scientific draft sounds generic, jargon-heavy, structurally weak, or AI-ish and needs precise, broad-reader-friendly prose without inventing data, analyses, or references. Best for primary research articles and letters rather than reviews or press releases unless explicitly adapting one.
deckrd
IncludedDocument-driven framework that derives requirements, specifications, implementation plans, and executable tasks from goals through structured AI dialogue. Use when user says "write requirements", "create spec", "plan implementation", "derive tasks", "structure this feature", "break down into tasks", or "document this module". Also use for reverse engineering existing code into docs (/deckrd rev). Do NOT use for direct code writing — use /deckrd-coder after tasks are generated. Do NOT use when the user only wants to run or fix existing code without planning.
clinical-decision-support
IncludedGenerate professional clinical decision support (CDS) documents for pharmaceutical and clinical research settings, including patient cohort analyses (biomarker-stratified with outcomes) and treatment recommendation reports (evidence-based guidelines with decision algorithms). Supports GRADE evidence grading, statistical analysis (hazard ratios, survival curves, waterfall plots), biomarker integration, and regulatory compliance. Outputs publication-ready LaTeX/PDF format optimized for drug development, clinical research, and evidence synthesis.
handling-sf-data
IncludedSalesforce data operations with 130-point scoring. Use this skill to create, update, delete, bulk import/export, generate test data, and clean up org records using sf CLI and anonymous Apex. TRIGGER when: user creates test data, performs bulk import/export, uses sf data CLI commands, needs data factory patterns for Apex tests, or needs to seed/clean records in a Salesforce org. DO NOT TRIGGER when: SOQL query writing only (use querying-soql), Apex test execution (use running-apex-tests), or metadata deployment (use deploying-metadata).
accelint-ac-to-playwright
IncludedConvert and validate acceptance criteria for Playwright test automation. Use when user asks to (1) review/evaluate/check if AC are ready for automation, (2) assess if AC can be converted as-is, (3) validate AC quality for Playwright, (4) turn AC into tests, (5) generate tests from acceptance criteria, (6) convert .md bullets or .feature Gherkin files to Playwright specs, (7) create test automation from requirements. Handles both bullet-style markdown and Gherkin syntax with JSON test plan generation and validation.