SQuAT Plan is a Python library for modeling, optimizing, sampling, and simulating quadrotor trajectories in cluttered environments. It grew from a UCLA MAE 271D course project and is now structured as a reusable planning component for research simulators and higher-level autonomy stacks.
- Nonlinear trajectory optimization through GEKKO, including obstacle constraints and quaternion orientation states.
- A typed, interpolable
Trajectoryobject with safe endpoint sampling. - A validated
QuadrotorModeland boundary-state representation rather than application-specific global configuration. - A deterministic rigid-body simulation harness for offline planner evaluation.
- Existing Matplotlib/RViz demonstrations for visualization environments.
The library is deliberately simulation-only. It does not command an aircraft, provide flight safety guarantees, or implement contact dynamics. For an aerial inspection system, use it for free-flight/pre-contact planning only; keep vehicle control, contact control, and hardware safety interlocks in their own explicitly validated layers.
git clone https://github.com/aaronjs99/squat-plan.git
cd squat-plan
python -m venv .venv
# Windows: .venv\\Scripts\\activate
# macOS/Linux: source .venv/bin/activate
python -m pip install -e .[dev,visualization]Run the unit checks:
python -m unittest discover -s tests -vThe legacy course demonstration remains available through python run.py. ROS/RViz dependencies are optional and must be installed separately on a supported Linux/WSL environment.
import numpy as np
from squatplan import QuadrotorModel, QuadrotorPlant, QuadrotorState
model = QuadrotorModel(
mass_kg=1.5,
inertia_kg_m2=np.diag([0.02, 0.02, 0.04]),
)
state = QuadrotorState(
position_m=[0, 0, 0],
velocity_m_s=[0, 0, 0],
orientation_wxyz=[1, 0, 0, 0],
angular_velocity_rad_s=[0, 0, 0],
)
plant = QuadrotorPlant(model, state)
next_state = plant.step(body_moment_nm=[0, 0, 0], thrust_n=1.5 * 9.81, dt_s=0.01)For optimization, the original dictionary-based TrajOpt interface is kept for compatibility. New callers should use TrajOpt.plan() to receive a typed Trajectory; local GEKKO solving is the default, and hosted solving requires an explicit remote=True solver parameter.
legacypreserves the exact pre-generalization course-projectmaster.masteris the maintained, generalized library surface.- The former
ryanbranch informed the parameterized model, trajectory sampling, simulation, and bounded-solve direction. Its ideas were integrated deliberately rather than copied as an untested application runtime.
Developed originally as a final project for MAE 271D — Control and Trajectory Planning for Autonomous Aerial Systems at UCLA.
- Aaron John Sabu
- Ryan Nemiroff
- Brett T. Lopez (Instructor)
MIT License © 2025, University of California, Los Angeles.