Presets
Playback
Parameters
Layers
Model checks
The science
Planar rigid body: m x¨ = −T sinθ + Fgust, m z¨ = T cosθ − m g, I θ¨ = L (TR − TL) − c θ̇, with T = TL + TR, arm L = 0.25 m and I = 0.012 kg m². Rotor thrust follows its command through a first-order lag.
Control is cascaded: altitude PD sets total thrust (with gravity feedforward and 1/cosθ), position PD gives a desired horizontal acceleration that becomes a tilt command θd = −ax/g (limited to 0.5 rad), and the attitude PD τ = Kp(θd − θ) − Kd θ̇ becomes a thrust difference. The attitude loop is the second-order system s² + (Kd/I) s + Kp/I: ωn = √(Kp/I), ζ = Kd / (2√(Kp I)), overshoot exp(−πζ/√(1−ζ²)).
Simplifications: 2D motion only, small linear aerodynamic drag on rotation, no rotor drag torque, perfect state knowledge (no sensor noise or delay), ground contact is a hard floor. The position loop assumes the attitude loop is much faster; slow motors or low Kp break that and the response oscillates.
What to try
- Click a new target and watch the tilt-then-accelerate-then-level pattern.
- Choose Under-damped attitude: the tilt rings and the position loop follows it.
- Choose Slow motors with the aggressive position loop to see the cascade lose stability margin.
- Press the gust button: the controller leans into the wind to recover.