Trajectories
This commit is contained in:
503
docs/TRAJECTORY.md
Normal file
503
docs/TRAJECTORY.md
Normal file
@@ -0,0 +1,503 @@
|
||||
# Trajectory Simulation Guide
|
||||
|
||||
## Overview
|
||||
|
||||
The **Trajectory Simulator** predicts rocket flight paths using physics-based 4th-order Runge-Kutta integration. It accounts for atmospheric drag, gravity, thrust, and user-defined events to compute complete vehicle trajectories from liftoff to landing.
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. **Configure Vehicle**
|
||||
- Import engine (from Engine Designer) or specify manually
|
||||
- Enter vehicle mass (wet & dry), reference area, drag coefficient
|
||||
|
||||
2. **Configure Atmosphere**
|
||||
- Select model (US Standard, exponential)
|
||||
- Set sea-level conditions (temperature, pressure)
|
||||
|
||||
3. **Set Pitch Program**
|
||||
- Vertical hold duration or altitude
|
||||
- Then gravity turn (pitch follows velocity vector)
|
||||
|
||||
4. **Add Events** (optional)
|
||||
- Guidance commands (pitch changes)
|
||||
- Jettison (drop mass during flight)
|
||||
- Markers (annotations)
|
||||
|
||||
5. **Run Simulation**
|
||||
- Click "Run Simulation"
|
||||
- Wait for RK4 integration to complete
|
||||
|
||||
6. **Playback**
|
||||
- Watch animation (1×, 5×, 10× speed)
|
||||
- Scrub timeline to jump to time
|
||||
- Click on plot to jump to position
|
||||
|
||||
---
|
||||
|
||||
## Physics Model
|
||||
|
||||
### State Vector
|
||||
|
||||
At each timestep, we track:
|
||||
```
|
||||
state = [x, y, vx, vy, m]
|
||||
```
|
||||
|
||||
- `x` — downrange distance (m)
|
||||
- `y` — altitude above sea level (m)
|
||||
- `vx` — horizontal velocity (m/s, positive = downrange)
|
||||
- `vy` — vertical velocity (m/s, positive = up)
|
||||
- `m` — vehicle mass (kg)
|
||||
|
||||
### Forces
|
||||
|
||||
**Thrust:**
|
||||
```
|
||||
F_thrust = thrust(t) × cos(pitch_angle) [horizontal component]
|
||||
F_thrust = thrust(t) × sin(pitch_angle) [vertical component]
|
||||
```
|
||||
|
||||
Direction depends on pitch program (see below).
|
||||
|
||||
**Gravity (altitude-dependent):**
|
||||
```
|
||||
g(h) = g0 × (R_earth / (R_earth + h))²
|
||||
```
|
||||
|
||||
Where:
|
||||
- `g0` = 9.81 m/s²
|
||||
- `R_earth` = 6.371×10⁶ m
|
||||
- `h` = altitude (m)
|
||||
|
||||
**Drag:**
|
||||
```
|
||||
F_drag = 0.5 × ρ(h) × v² × Cd × A_ref
|
||||
```
|
||||
|
||||
Opposed to velocity direction:
|
||||
```
|
||||
F_drag_x = -F_drag × (vx / v)
|
||||
F_drag_y = -F_drag × (vy / v)
|
||||
```
|
||||
|
||||
Where `v = √(vx² + vy²)` is total velocity.
|
||||
|
||||
### Atmosphere
|
||||
|
||||
**US Standard Model (default):**
|
||||
- Piecewise linear layers
|
||||
- Troposphere: 0–8500 m (temperature decreases 6.5 K/km)
|
||||
- Stratosphere: 8500–15000 m (isothermal at 216.5 K)
|
||||
- Higher: exponential decay
|
||||
|
||||
**Exponential Model:**
|
||||
```
|
||||
ρ(h) = ρ0 × exp(-h / H)
|
||||
```
|
||||
|
||||
Where:
|
||||
- `ρ0` = sea-level density (1.225 kg/m³)
|
||||
- `H` = scale height (~8500 m)
|
||||
|
||||
**Pressure & Temperature:**
|
||||
- US Standard uses table lookup
|
||||
- Temperature affects gas density (lower T = higher ρ at same P)
|
||||
|
||||
### Equations of Motion
|
||||
|
||||
**Acceleration:**
|
||||
```
|
||||
a_x = (F_thrust_x + F_drag_x) / m
|
||||
a_y = (F_thrust_y + F_drag_y - m×g(h)) / m
|
||||
```
|
||||
|
||||
**Mass Change (during burn):**
|
||||
```
|
||||
dm/dt = -mass_flow_rate
|
||||
```
|
||||
|
||||
Mass only changes during engine burn phase (after liftoff, before MECO).
|
||||
|
||||
### Numerical Integration (RK4)
|
||||
|
||||
The integrator advances state by small timesteps (default: dt = 0.05 s):
|
||||
|
||||
```
|
||||
k1 = derivatives(t, state)
|
||||
k2 = derivatives(t + dt/2, state + k1×dt/2)
|
||||
k3 = derivatives(t + dt/2, state + k2×dt/2)
|
||||
k4 = derivatives(t + dt, state + k3×dt)
|
||||
|
||||
state_new = state + (k1 + 2×k2 + 2×k3 + k4) × dt/6
|
||||
```
|
||||
|
||||
**Accuracy**: RK4 is 4th-order accurate; typical error scales as O(dt⁵).
|
||||
|
||||
**Advantages:**
|
||||
- More accurate than Euler method
|
||||
- Reasonable computational speed
|
||||
- Standard in trajectory software
|
||||
|
||||
**Limitations:**
|
||||
- No adaptive timestep (dt is fixed)
|
||||
- Cannot handle stiff equations
|
||||
- Small dt needed for accuracy (0.01–0.1 s typical)
|
||||
|
||||
---
|
||||
|
||||
## Inputs
|
||||
|
||||
### Vehicle Configuration
|
||||
|
||||
**From Engine Designer (auto-populated if imported):**
|
||||
- `thrust` — engine thrust curve or constant
|
||||
- `isp` — specific impulse (vacuum)
|
||||
- `mdot` — mass flow rate (kg/s)
|
||||
- `burnTime` — engine burn duration (s)
|
||||
- `dryMass` — engine dry mass (kg)
|
||||
|
||||
**Vehicle Properties (manual input):**
|
||||
- `wetMass` — total mass with propellant (kg)
|
||||
- `dryMass` — mass without propellant (kg)
|
||||
- **Note**: Used after engine shutdown
|
||||
- `referenceArea` — cross-sectional area for drag (m²)
|
||||
- `dragCoefficient` — Cd (typically 0.2–0.3 for rockets)
|
||||
- `payloadMass` — payload (kg, contributes to dry mass)
|
||||
|
||||
### Atmospheric Conditions
|
||||
|
||||
- `atmosphereModel` — US Standard or Exponential
|
||||
- `seaLevelTemperature` — T0 (K), default 288.15 K (15°C)
|
||||
- `seaLevelPressure` — P0 (Pa), default 101325 Pa
|
||||
- `windSpeed` — not yet implemented
|
||||
|
||||
### Pitch Program
|
||||
|
||||
**Vertical Hold Phase:**
|
||||
- `pitchStartAlt` — altitude to begin gravity turn (m)
|
||||
- Duration: liftoff until altitude > pitchStartAlt
|
||||
- Pitch angle: 90° (straight up)
|
||||
|
||||
**Gravity Turn Phase:**
|
||||
- Pitch angle follows velocity vector
|
||||
- `pitch = atan2(vy, vx)`
|
||||
- Vehicle points along flight path (min drag)
|
||||
|
||||
**Advanced Programs (future):**
|
||||
- Custom pitch schedule vs. time
|
||||
- Thrust vector control
|
||||
- Angle of attack constraints
|
||||
|
||||
---
|
||||
|
||||
## Outputs
|
||||
|
||||
### Trajectory States
|
||||
|
||||
Array of `state` vectors at each timestep:
|
||||
```javascript
|
||||
[
|
||||
{time: 0, x: 0, y: 0, vx: 0, vy: 0.1, m: 2000},
|
||||
{time: 0.05, x: 0, y: 0.005, vx: 0.2, vy: 15.0, m: 1999.5},
|
||||
...
|
||||
{time: 60, x: 5000, y: 50000, vx: 2000, vy: 0, m: 800}
|
||||
]
|
||||
```
|
||||
|
||||
Total states: ~1200 for 60 second flight (0.05 s dt)
|
||||
|
||||
### Auto-Detected Events
|
||||
|
||||
**Liftoff:**
|
||||
- First time `y > 0` and `vy > 0`
|
||||
- Time, altitude, velocity logged
|
||||
|
||||
**Main Engine Cutoff (MECO):**
|
||||
- When `burnTime` expires
|
||||
- Last time mass changes
|
||||
- Marks end of powered flight
|
||||
|
||||
**Max Q (Dynamic Pressure):**
|
||||
- Maximum value of `q = 0.5 × ρ × v²`
|
||||
- Often a structural design point
|
||||
- Time, altitude, velocity, q value
|
||||
|
||||
**Apogee:**
|
||||
- Highest altitude reached
|
||||
- First time `vy` changes from positive to negative
|
||||
- Last point of ascending flight
|
||||
|
||||
**Landing:**
|
||||
- First time `y ≤ 0` after apogee
|
||||
- Final altitude, downrange, velocity
|
||||
|
||||
### User-Defined Events
|
||||
|
||||
**Guidance (Pitch Command):**
|
||||
```javascript
|
||||
{type: 'guidance', time: 30, pitchAngle: 45}
|
||||
```
|
||||
At t=30s, change pitch to 45° (overrides gravity turn)
|
||||
|
||||
**Jettison (Mass Drop):**
|
||||
```javascript
|
||||
{type: 'jettison', time: 25, massDropped: 50}
|
||||
```
|
||||
Drop 50 kg (e.g., fairings) at t=25s
|
||||
- Reduces drag & inertia
|
||||
- Affects apogee & downrange
|
||||
|
||||
**Marker (Annotation):**
|
||||
```javascript
|
||||
{type: 'marker', time: 15, label: 'Separation'}
|
||||
```
|
||||
Just marks event on timeline; no physics change
|
||||
|
||||
---
|
||||
|
||||
## Workflow: Simulate LOX/RP1 Rocket
|
||||
|
||||
### Step 1: Design Engine
|
||||
1. Go to **Design > Engine**
|
||||
2. LOX/RP1, 200 bar → ~150 kN thrust, 310 s Isp, 60 s burn
|
||||
3. Export JSON
|
||||
|
||||
### Step 2: Design Rocket
|
||||
1. Go to **Design > Rocket**
|
||||
2. Import engine JSON (gets thrust, Isp, burn time)
|
||||
3. Configure tanks (5000 L, tandem)
|
||||
4. Set payload (50 kg)
|
||||
→ **Result**: Wet mass 1550 kg, dry mass 450 kg
|
||||
|
||||
### Step 3: Run Trajectory
|
||||
1. Go to **Design > Trajectory**
|
||||
2. Import rocket JSON (gets wet/dry mass, reference area)
|
||||
3. Import engine JSON (gets thrust, Isp, burn time)
|
||||
4. Set pitch start altitude: 1000 m
|
||||
5. Click "Run Simulation"
|
||||
→ **Result**: ~5000 m downrange, 50 km apogee, 180 s flight time
|
||||
|
||||
### Step 4: Analyze Results
|
||||
- **Plot**: Shows altitude vs. downrange (parabolic path)
|
||||
- **Timeline**: Mark apogee, MECO, Max Q
|
||||
- **Playback**: Watch animation in real time
|
||||
- **Scrub**: Jump to specific times to see position/velocity
|
||||
|
||||
### Step 5: Optimize
|
||||
- Try different masses (remove payload → higher apogee)
|
||||
- Try different pitch programs (start gravity turn later → longer range)
|
||||
- Try jettison events (drop fairings at MECO → save mass)
|
||||
|
||||
---
|
||||
|
||||
## Event System
|
||||
|
||||
### Event Structure
|
||||
|
||||
```javascript
|
||||
{
|
||||
type: 'liftoff' | 'meco' | 'maxQ' | 'apogee' | 'landing' | 'guidance' | 'jettison' | 'marker',
|
||||
time: number, // seconds
|
||||
altitude?: number, // meters
|
||||
downrange?: number, // meters
|
||||
velocity?: number, // m/s
|
||||
label?: string, // display name
|
||||
value?: any // event-specific data
|
||||
}
|
||||
```
|
||||
|
||||
### Auto-Detected Events (Read-Only)
|
||||
|
||||
Computed during simulation; user cannot edit.
|
||||
|
||||
**Liftoff**: `{type: 'liftoff', time: 0.05, altitude: 0.1, velocity: 1.5}`
|
||||
|
||||
**Max Q**: `{type: 'maxQ', time: 5.2, altitude: 1000, q: 50000}`
|
||||
|
||||
**Apogee**: `{type: 'apogee', time: 120, altitude: 50000, velocity: 0}`
|
||||
|
||||
**Landing**: `{type: 'landing', time: 180, altitude: 0, downrange: 5000, velocity: -50}`
|
||||
|
||||
### User Events
|
||||
|
||||
**Guidance Command:**
|
||||
```javascript
|
||||
{type: 'guidance', time: 30, pitchAngle: 45, label: 'Pitch over'}
|
||||
```
|
||||
- Changes pitch at specified time
|
||||
- Overrides gravity turn
|
||||
- Can be used for coast phase burn starts, etc.
|
||||
|
||||
**Jettison:**
|
||||
```javascript
|
||||
{type: 'jettison', time: 25, massDropped: 50, label: 'Fairing separation'}
|
||||
```
|
||||
- Removes mass from trajectory
|
||||
- Affects drag & inertia
|
||||
- Typically after Max Q (fairing drag not needed)
|
||||
|
||||
**Marker:**
|
||||
```javascript
|
||||
{type: 'marker', time: 60, label: 'Engine cutoff'}
|
||||
```
|
||||
- Pure annotation
|
||||
- No physics effect
|
||||
- Useful for documentation
|
||||
|
||||
---
|
||||
|
||||
## 3D Visualization
|
||||
|
||||
### Trajectory Plot
|
||||
|
||||
HTML5 Canvas rendering of flight path:
|
||||
|
||||
**Axes:**
|
||||
- X: downrange (0 to max)
|
||||
- Y: altitude (0 to apogee + margin)
|
||||
- Aspect ratio: ~2:1 (wider than tall)
|
||||
|
||||
**Elements:**
|
||||
- Trajectory curve (light blue line)
|
||||
- Event markers (circles at key points)
|
||||
- Grid (light gray, 10 km spacing)
|
||||
- Labels (altitude, downrange at axis)
|
||||
- Legend (event types & colors)
|
||||
|
||||
**Interactivity:**
|
||||
- Click on plot → jump to that time
|
||||
- Hover on point → show values (alt, range, velocity)
|
||||
- Hover on event marker → show label
|
||||
- Zoom (mousewheel) — not yet implemented
|
||||
|
||||
### 3D Flight Animation
|
||||
|
||||
**Top-down view** showing:
|
||||
- Vehicle model (small rocket symbol or sphere)
|
||||
- Flight path (line from start to current position)
|
||||
- Current altitude/range indicators
|
||||
- Compass heading
|
||||
|
||||
**Implementation:** Canvas 2D or Three.js (current: Canvas)
|
||||
|
||||
---
|
||||
|
||||
## Playback Controls
|
||||
|
||||
### Timeline Bar
|
||||
|
||||
Located below trajectory plot:
|
||||
|
||||
**Play/Pause Button:**
|
||||
- Starts/stops animation
|
||||
- Keyboard: Space bar
|
||||
|
||||
**Speed Selector:**
|
||||
- 1× — real time
|
||||
- 5× — 5× faster
|
||||
- 10× — 10× faster
|
||||
|
||||
**Scrubber (Time Slider):**
|
||||
- Drag to jump to any time
|
||||
- Release to play from that point
|
||||
- Shows current time in seconds
|
||||
|
||||
**Event Timeline:**
|
||||
- Vertical lines at event times
|
||||
- Hover to see event name
|
||||
- Click to jump to event
|
||||
|
||||
### Keyboard Shortcuts
|
||||
|
||||
- **Space**: Play/pause
|
||||
- **→**: Jump forward 10 seconds
|
||||
- **←**: Jump backward 10 seconds
|
||||
- **Home**: Jump to start
|
||||
- **End**: Jump to end
|
||||
|
||||
---
|
||||
|
||||
## Advanced Features
|
||||
|
||||
### Thrust Curves (Future)
|
||||
|
||||
Instead of constant thrust, can import actual thrust vs. time:
|
||||
```javascript
|
||||
{
|
||||
type: 'thrustCurve',
|
||||
data: [
|
||||
{time: 0, thrust: 150000},
|
||||
{time: 5, thrust: 145000},
|
||||
{time: 60, thrust: 0}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Would enable:
|
||||
- Throttling analysis (variable thrust)
|
||||
- Solid rocket motor curves
|
||||
- Multi-engine clustering
|
||||
|
||||
### Stage Separation
|
||||
|
||||
Currently single-stage only. Multi-stage would require:
|
||||
- Stage definition (separate vehicle configs)
|
||||
- Coast phase between stages
|
||||
- Staging logic (when to ignite next stage)
|
||||
- Updated mass calculations
|
||||
|
||||
### Wind Effects
|
||||
|
||||
Could add:
|
||||
- Constant wind (direction, magnitude)
|
||||
- Turbulence (atmospheric gusts)
|
||||
- Wind shear (altitude-dependent)
|
||||
- Affects trajectory & landing site
|
||||
|
||||
### Control Systems
|
||||
|
||||
Could add:
|
||||
- Attitude feedback (pitch control gains)
|
||||
- Stability margin (static/dynamic)
|
||||
- Fin-based control
|
||||
- Thrust vector control (TVC)
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Trajectory looks wrong
|
||||
- Check vehicle mass (should match design)
|
||||
- Verify drag coefficient (0.25 ± 0.05 typical)
|
||||
- Confirm reference area (cross-sectional)
|
||||
- Ensure engine thrust profile is correct
|
||||
|
||||
### Apogee seems too low
|
||||
- Verify engine thrust (check import)
|
||||
- Check mass (try reducing payload)
|
||||
- Ensure Isp is correct (affects delta-v)
|
||||
- Try longer burn time or higher chamber pressure
|
||||
|
||||
### Simulation diverges (NaN values)
|
||||
- Reduce timestep dt (smaller step size)
|
||||
- Check for negative mass (propellant consumed)
|
||||
- Verify atmosphere model (no singularities)
|
||||
- Ensure velocity doesn't exceed sound barrier (should be OK)
|
||||
|
||||
### Playback animation slow
|
||||
- Reduce speed (don't use 10×)
|
||||
- Close other browser tabs
|
||||
- Lower resolution (use simpler plot)
|
||||
- Reduce state vector size (use larger dt)
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- Beard, R. W., & McLain, T. W. (2012). Small unmanned aircraft: Theory and practice. Princeton University Press.
|
||||
- Vallado, D. A., Crawford, P., Hujsa, R., & Kelso, T. S. (2006). Revisiting spacetrack report #3. AIAA/AAS Astrodynamics Specialist Conference.
|
||||
- US Standard Atmosphere 1976. NASA TM-X-74335
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2025-02 | **Status**: Current (v1)
|
||||
Reference in New Issue
Block a user