Skip to content

Interpolation API

skelarm.interpolation

From-scratch interpolation for resampling reference trajectories.

A recorded or generated reference trajectory is a finite series of samples (t_i, y_i) that usually does not line up with the controller's time grid, so it must be resampled. This module implements three schemes by hand (no SciPy):

  • linear — piecewise-linear; cheap and shape-preserving, but only C^0.
  • cubic_spline — the natural cubic spline; C^2 with analytic first and second derivatives, the right default for deriving smooth / references.
  • lagrange — the barycentric form of the global Lagrange polynomial; exact for polynomial data but oscillatory for many nodes (Runge), so reserve it for short series.

The series may be a 1-D signal of shape (N,) or a multi-column signal of shape (N, k) (e.g. tip (x, y) or per-joint angles), interpolated column-wise.

See docs/reference/09_trajectory_filtering.md for the theory.

INTERPOLATORS = ('linear', 'cubic_spline', 'lagrange') module-attribute

The supported interpolation method names (the method argument).

interpolate(times, values, query, *, method='cubic_spline')

Resample a sampled series onto new query times.

Parameters:

Name Type Description Default
times ArrayLike

Strictly increasing sample times, shape (N,).

required
values ArrayLike

Sample values, shape (N,) or (N, k).

required
query ArrayLike

Times to evaluate at, a scalar or shape (M,).

required
method str

One of :data:INTERPOLATORS (default "cubic_spline").

'cubic_spline'

Returns:

Type Description
NDArray[float64]

The interpolated values: shape (M,) or () for a 1-D series, or (M, k) / (k,) for a multi-column series.

Raises:

Type Description
ValueError

If method is unknown or the shapes are inconsistent.

Source code in src/skelarm/interpolation.py
def interpolate(
    times: ArrayLike,
    values: ArrayLike,
    query: ArrayLike,
    *,
    method: str = "cubic_spline",
) -> NDArray[np.float64]:
    """Resample a sampled series onto new query times.

    Parameters
    ----------
    times : ArrayLike
        Strictly increasing sample times, shape ``(N,)``.
    values : ArrayLike
        Sample values, shape ``(N,)`` or ``(N, k)``.
    query : ArrayLike
        Times to evaluate at, a scalar or shape ``(M,)``.
    method : str, optional
        One of :data:`INTERPOLATORS` (default ``"cubic_spline"``).

    Returns
    -------
    NDArray[np.float64]
        The interpolated values: shape ``(M,)`` or ``()`` for a 1-D series, or
        ``(M, k)`` / ``(k,)`` for a multi-column series.

    Raises
    ------
    ValueError
        If ``method`` is unknown or the shapes are inconsistent.
    """
    value, _, _ = _evaluate(times, values, query, method=method, order=0)
    return value

resample_with_derivatives(times, values, query, *, method='cubic_spline')

Resample a series and return its value, first, and second time derivatives.

For cubic_spline the derivatives are analytic; for linear and lagrange they fall back to finite differences of the resampled value on the query grid (so pass a reasonably dense, near-uniform query for those methods).

Parameters:

Name Type Description Default
times ArrayLike

As in :func:interpolate.

required
values ArrayLike

As in :func:interpolate.

required
query ArrayLike

As in :func:interpolate.

required
method ArrayLike

As in :func:interpolate.

required

Returns:

Type Description
tuple[NDArray, NDArray, NDArray]

(value, d_dt, d2_dt2), each with the same shape as :func:interpolate would return.

Source code in src/skelarm/interpolation.py
def resample_with_derivatives(
    times: ArrayLike,
    values: ArrayLike,
    query: ArrayLike,
    *,
    method: str = "cubic_spline",
) -> tuple[NDArray[np.float64], NDArray[np.float64], NDArray[np.float64]]:
    """Resample a series and return its value, first, and second time derivatives.

    For ``cubic_spline`` the derivatives are analytic; for ``linear`` and ``lagrange``
    they fall back to finite differences of the resampled value on the query grid (so
    pass a reasonably dense, near-uniform ``query`` for those methods).

    Parameters
    ----------
    times, values, query, method
        As in :func:`interpolate`.

    Returns
    -------
    tuple[NDArray, NDArray, NDArray]
        ``(value, d_dt, d2_dt2)``, each with the same shape as :func:`interpolate`
        would return.
    """
    return _evaluate(times, values, query, method=method, order=2)