Skip to main content

Minsnap Trajectories

Simple Python/Numpy implementation of the Minimum Snap Trajectory Generation algorithm.

This package addresses the shortage of turnkey minsnap trajectory generator implementations on PyPI. It implements two of the most time-tested algorithms in this area:

  • Mellinger and Kumar's original Minimum Snap Trajectory Generator [1]

  • Roy and Bry's numerically stable, unconstrained quadratic program [2]

and an important utility in generating quadrotor trajectories:


[1]: D. Mellinger and V. Kumar. Minimum snap trajectory generation and control for quadrotors. In Proc. Int. Conf. on Robotics and Automation, 2011

[2]: C. Richter, A. Bry, and N. Roy. Polynomial trajectory planning for aggressive quadrotor flight in dense indoor environments. In Int. Symposium on Robotics Research, 2013

Get Started

Preliminaries

Use the following convention to import this package

import minsnap_trajectories as ms

Derivatives on position are numbered from 0, as shown below

Orders (# of derivatives) 0 1 2 3 4
Quantity Position Velocity Acceleration Jerk Snap

TLDR

Four key names

  • ms.Waypoint: Time, position, velocity, etc. waypoint. A sequence of this defines the trajectory
  • ms.generate_trajectory: Generates the piecewise-polynomial trajectory
  • ms.compute_trajectory_derivatives: Samples the polynomial for position/velocity/acceleration, etc.
  • ms.compute_quadrotor_trajectory: Directly compute quadrotor state/inputs along the trajectory

Full usage example

Trajectory generated by this example

Define a sequence of position (and optionally velocity, acceleration, higher-order) references

refs = [
    ms.Waypoint(
        time=0.0,
        position=np.array([0.0, 0.0, 10.0]),
    ),
    ms.Waypoint(  # Any higher-order derivatives
        time=8.0,
        position=np.array([10.0, 0.0, 10.0]),
        velocity=np.array([0.0, 5.0, 0.0]),
        acceleration=np.array([0.1, 0.0, 0.0]),
    ),
    ms.Waypoint(  # Potentially leave intermediate-order derivatives unspecified
        time=16.0,
        position=np.array([20.0, 0.0, 10.0]),
        jerk=np.array([0.1, 0.0, 0.2]),
    ),
]

Generate a piecewise polynomial trajectory using Roy and Bry's closed form solution, minimizing jerk (order-3) AND snap (order-4) while constraining position, velocity, etc... up to jerk (orders 0 to 3) to be continuous

polys = ms.generate_trajectory(
    refs,
    degree=8,  # Polynomial degree
    idx_minimized_orders=(3, 4),
    num_continuous_orders=4,  # 4 orders: position, velocity, acceleration, jerk
    algorithm="closed-form",  # Or "constrained"
)

# Inspect the output
t = polys.time_reference
dt = polys.durations
cfs = polys.coefficients

Sample the polynomial trajectory to get position, velocity, acceleration (or higher-order) trajectories

t = np.linspace(0, 16, 100)
#  Sample 3 derivative orders (position, velocity, acceleration) -----v
pva = ms.compute_trajectory_derivatives(polys, t, 3)
position = pva[0, ...]
velocity = pva[1, ...]

num_orders is a count, not an index: pass 4 to also include jerk, 5 for snap, etc.

Or directly generate a quadrotor UAV trajectory

t = np.linspace(0, 15, 100)
states, inputs = ms.compute_quadrotor_trajectory(
    polys,
    t,
    vehicle_mass=1.0, # Quadrotor weight
    yaw="velocity", # Align yaw angle to quadrotor velocity
    drag_params=ms.RotorDragParameters(0.1, 0.2, 1.0),
)

Limitations

Tests are not nearly enough!

Existing tests show that this piecewise polynomial planner behaves identically to two of the more approachable MATLAB-based trajectory generator implementations by icsl-Jeon and symao.

  1. The polynomial planner is not well-guarded against the case when the polynomial planning problem is overconstrained, i.e.

    • The polynomial degree is too low
    • Too many orders of derivatives are constrained to be continuous
  2. The quadrotor trajectory generator is not extensively tested (the rotor-drag effect compensation function is even more so).

Until more extensive tests are available, use the following parameters in polynomial planning (they are the defaults)

  • degree: From 5 to 15
  • idx_minimized_orders: 4 (Minimum snap)
  • num_continuous_orders: 3 (Just keep position/velocity/acceleration continuous)

Migrating to 0.3.0

  • Requires Python 3.10+ (previously 3.11+), and the numpy/scipy floors are low enough to run against the versions Ubuntu 22.04 and ROS 2 Humble ship, so installing no longer replaces a distro-provided numpy or scipy.
  • The closed-form solver now raises ValueError when degree + 1 is less than 2 * num_continuous_orders. It previously returned a trajectory that did not pass through its waypoints. Either raise degree to at least 2 * num_continuous_orders - 1, lower num_continuous_orders, or use algorithm="constrained", which has no such restriction.

Migrating to 0.2.0

  • Requires Python 3.11+.
  • Waypoint is now a frozen dataclass instead of a dict subclass. The constructor signature is unchanged, and all of position, velocity, acceleration, jerk, snap, and time are exposed as attributes (previously jerk and snap were silently dropped from the property accessors). Code that accessed waypoints by dict-key (e.g. wp[0]) must switch to attribute access (e.g. wp.position).
  • The third positional argument to compute_trajectory_derivatives was renamed from order to num_orders to reflect that it counts derivative orders rather than indexing into them. Positional callers are unaffected.

Metadata

Release files for minsnap_trajectories 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for minsnap_trajectories 0.3.0
File Size Uploaded Provenance Actions
minsnap_trajectories-0.3.0.tar.gz 235.2 kB Without provenance Details for minsnap_trajectories-0.3.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for minsnap_trajectories 0.3.0
File Interpreter ABI Platform Actions
minsnap_trajectories-0.3.0-py3-none-any.whl Python 3 none any Details for minsnap_trajectories-0.3.0-py3-none-any.whl

Total release size: 247.9 kB

Release files / minsnap_trajectories-0.3.0.tar.gz

Download URL minsnap_trajectories-0.3.0.tar.gz
Size 235.2 kB
Tags Source
SHA-256 checksum
How to use checksums
b84513c9a70a46607b3401ef17f0c75b4af990b7c2525d52c2e4ac714581a1d3
BLAKE2b-256 checksum
How to use checksums
5cf9e0dfc6fb0ebe18360d02a2423729e1caf58d5cd8ca16eac1f75f0f434f8a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.8

Release files / minsnap_trajectories-0.3.0-py3-none-any.whl

Download URL minsnap_trajectories-0.3.0-py3-none-any.whl
Size 12.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
27426c81437f579b01b59d8d59b86b357848a63350365d519664a057ec230ae7
BLAKE2b-256 checksum
How to use checksums
ed2d622aabc46214ae03c15303e0182bd2bb1b2b7fa5f7de76314e4c3e8ca103
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.8

Security for minsnap_trajectories 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page