moonbitstack/moonmcl/trajectory does not have a README file

    BSpline

    pub(all) struct BSpline {
    degree : Int
    control : Array[Double]
    knots : Array[Double]
    duration : Double
    } derive(
    Debug
    )

    A clamped uniform B-spline over a control polygon.

    The curve is pulled towards the control points without passing through them, which is what makes it the profile for a path that only has to be smooth. The first and last control points are interpolated, so it starts and ends where the polygon does.

    BSpline::duration

    fn BSpline::duration(self : BSpline) -> Double

    BSpline::sample

    BSpline::to_repr

    CubicSpline

    pub(all) struct CubicSpline {
    times : Array[Double]
    positions : Array[Double]
    curvatures : Array[Double]
    } derive(
    Debug
    )

    A natural cubic spline through time-stamped positions, continuous in velocity and acceleration, with zero curvature at both ends.

    CubicSpline::duration

    fn CubicSpline::duration(self : CubicSpline) -> Double

    CubicSpline::sample

    Polynomial

    pub(all) struct Polynomial {
    coefficients : Array[Double]
    duration : Double
    } derive(
    Debug
    )

    A polynomial in time, position = sum(coefficients[i] * t^i).

    A polynomial is the profile to reach for when the boundary conditions are the whole requirement: it matches a position, a velocity and an acceleration at both ends exactly, and it does not care about a jerk limit on the way.

    Polynomial::duration

    fn Polynomial::duration(self : Polynomial) -> Double

    Polynomial::sample

    Scurve

    pub(all) struct Scurve {
    distance : Double
    sign : Double
    duration : Double
    phases : Array[Double]
    jerks : Array[Double]
    starts : Array[(Double, Double, Double)]
    }

    A jerk-limited S-curve.

    Scurve::duration

    fn Scurve::duration(self : Scurve) -> Double

    Scurve::sample

    Synced

    pub(all) struct Synced {
    axes : Array[&
    Trajectory
    ]
    duration : Double
    }

    Several single-axis profiles run together.

    Axes are slowed by sampling them on a stretched clock: axis i is sampled at t * duration_i / duration, and its velocity and acceleration are scaled by the same factor and its square. The path is preserved, the timing is not.

    Synced::axis_sample

    fn Synced::axis_sample(self : Synced, index : Int, t : Double) ->
    Sample

    One axis sampled on the common clock, with its derivatives scaled back to the axis's own time.

    Synced::duration

    fn Synced::duration(self : Synced) -> Double

    Synced::new

    A synchronised set from axes that already have a duration.

    Synced::sample

    Synced::sample_all

    fn Synced::sample_all(self : Synced, t : Double) -> Array[
    Sample
    ]

    Every axis sampled at the same instant.

    Synced::to_repr

    Trapezoid

    pub(all) struct Trapezoid {
    distance : Double
    v_max : Double
    a_max : Double
    start_velocity : Double
    end_velocity : Double
    duration : Double
    ramp_time : Double
    cruise_time : Double
    peak_velocity : Double
    sign : Double
    } derive(
    Debug
    )

    A trapezoidal velocity profile: accelerate, cruise, decelerate.

    It is the cheapest profile that respects a velocity and an acceleration limit, and the one that puts a step in the acceleration at each corner. The boundary velocities may be anything up to the peak the distance allows.

    Trapezoid::duration

    fn Trapezoid::duration(self : Trapezoid) -> Double

    Trapezoid::sample

    b_spline

    fn b_spline(control~ : ArrayView[Double], degree? : Int, duration? : Double) -> BSpline raise
    Refused

    A clamped B-spline of degree over control, running for duration seconds.

    cubic

    fn cubic(start~ : Double, end~ : Double, start_velocity~ : Double, end_velocity~ : Double, duration~ : Double) -> Polynomial raise
    Refused

    A cubic from one boundary state to another over duration.

    A cubic matches the two positions and the two velocities exactly; its acceleration jumps at both ends, which is what a drive without a jerk limit does anyway.

    cubic_spline

    fn cubic_spline(knots~ : ArrayView[(Double, Double)]) -> CubicSpline raise
    Refused

    A natural cubic spline through (time, position) knots, which must be ordered in time.

    quintic

    fn quintic(start~ : Double, end~ : Double, start_velocity~ : Double, start_acceleration~ : Double, end_velocity~ : Double, end_acceleration~ : Double, duration~ : Double) -> Polynomial raise
    Refused

    A quintic from one boundary state to another over duration.

    A quintic also matches the two accelerations, so the acceleration is continuous with whatever profile came before and whatever comes after.

    scurve

    fn scurve(distance~ : Double, v_max~ : Double, a_max~ : Double, j_max~ : Double, start_velocity? : Double, start_acceleration? : Double, end_velocity? : Double, end_acceleration? : Double) -> Scurve raise
    Refused

    An S-curve over distance with the given limits and boundary conditions.

    The start and end accelerations are folded into the first and last ramp, so a motion that is already accelerating keeps its acceleration instead of spending time on coming back to zero. A boundary acceleration outside the limit is refused, and so is a boundary velocity against the direction of travel or above the velocity limit: none of those has a jerk-limited profile that starts from it.

    trapezoid

    fn trapezoid(distance~ : Double, v_max~ : Double, a_max~ : Double, start_velocity? : Double, end_velocity? : Double) -> Trapezoid raise
    Refused

    A trapezoid over distance with the given limits and boundary velocities.

    The boundary velocities are read along the direction of travel: a negative distance with a start velocity of -0.5 means the axis is already moving the way it will go. A velocity against the direction of travel is refused, since the profile would have to reverse inside itself.