Skip to content

API Reference

Complete API documentation for all InterpolatePy classes, functions, and data structures.

Overview

InterpolatePy is organized into the following modules:

Spline Interpolation

CubicSpline

interpolatepy.CubicSpline

CubicSpline(
    t_points: list[float] | ndarray,
    q_points: list[float] | ndarray,
    v0: float = 0.0,
    vn: float = 0.0,
    debug: bool = False,
)

Cubic spline trajectory planning implementation.

This class implements the cubic spline algorithm described in the document. It generates a smooth trajectory passing through specified waypoints with continuous velocity and acceleration profiles.

Parameters:

Name Type Description Default
t_points list or ndarray

List or array of time points (t0, t1, ..., tn)

required
q_points list or ndarray

List or array of position points (q0, q1, ..., qn)

required
v0 float

Initial velocity at t0. Default is 0.0

0.0
vn float

Final velocity at tn. Default is 0.0

0.0
debug bool

Whether to print debug information. Default is False

False

Attributes:

Name Type Description
t_points ndarray

Array of time points

q_points ndarray

Array of position points

v0 float

Initial velocity

vn float

Final velocity

debug bool

Debug flag

n int

Number of segments (n = len(t_points) - 1)

t_intervals ndarray

Time intervals between consecutive points

velocities ndarray

Velocities at each waypoint

coefficients ndarray

Polynomial coefficients for each segment

Notes

The cubic spline ensures C2 continuity (continuous position, velocity, and acceleration) across all waypoints.

Examples:

>>> import numpy as np
>>> # Define waypoints
>>> t_points = [0, 1, 2, 3]
>>> q_points = [0, 1, 0, 1]
>>> # Create spline
>>> spline = CubicSpline(t_points, q_points)
>>> # Evaluate at specific time
>>> spline.evaluate(1.5)
>>> # Plot the trajectory
>>> spline.plot()

Parameters:

Name Type Description Default
t_points list or ndarray

List or array of time points (t0, t1, ..., tn)

required
q_points list or ndarray

List or array of position points (q0, q1, ..., qn)

required
v0 float

Initial velocity at t0. Default is 0.0

0.0
vn float

Final velocity at tn. Default is 0.0

0.0
debug bool

Whether to print debug information. Default is False

False

Raises:

Type Description
ValueError

If t_points and q_points have different lengths If t_points are not strictly increasing

evaluate

evaluate(t: float | ndarray) -> float | ndarray

Evaluate the spline at time t.

Parameters:

Name Type Description Default
t float or ndarray

Time point or array of time points

required

Returns:

Type Description
float or ndarray

Position(s) at the specified time(s)

Examples:

>>> # Evaluate at a single time point
>>> spline.evaluate(1.5)
>>> # Evaluate at multiple time points
>>> spline.evaluate(np.linspace(0, 3, 100))

evaluate_velocity

evaluate_velocity(t: float | ndarray) -> float | ndarray

Evaluate the velocity at time t.

Parameters:

Name Type Description Default
t float or ndarray

Time point or array of time points

required

Returns:

Type Description
float or ndarray

Velocity at the specified time(s)

Examples:

>>> # Evaluate velocity at a single time point
>>> spline.evaluate_velocity(1.5)
>>> # Evaluate velocity at multiple time points
>>> spline.evaluate_velocity(np.linspace(0, 3, 100))

evaluate_acceleration

evaluate_acceleration(
    t: float | ndarray,
) -> float | ndarray

Evaluate the acceleration at time t.

Parameters:

Name Type Description Default
t float or ndarray

Time point or array of time points

required

Returns:

Type Description
float or ndarray

Acceleration at the specified time(s)

Examples:

>>> # Evaluate acceleration at a single time point
>>> spline.evaluate_acceleration(1.5)
>>> # Evaluate acceleration at multiple time points
>>> spline.evaluate_acceleration(np.linspace(0, 3, 100))

plot

plot(num_points: int = 1000) -> None

Plot the spline trajectory along with its velocity and acceleration profiles.

Parameters:

Name Type Description Default
num_points int

Number of points to use for plotting. Default is 1000

1000

Returns:

Type Description
None

Displays the plot using matplotlib

Notes

This method creates a figure with three subplots showing: 1. Position trajectory with waypoints 2. Velocity profile 3. Acceleration profile

The original waypoints are marked with red circles on the position plot.

Example:

from interpolatepy import CubicSpline
import numpy as np

# Create spline through waypoints
t_points = [0, 1, 2, 3, 4]
q_points = [0, 1, 4, 2, 0]
spline = CubicSpline(t_points, q_points, v0=0.0, vn=0.0)

# Evaluate trajectory
t = 1.5
position = spline.evaluate(t)
velocity = spline.evaluate_velocity(t)
acceleration = spline.evaluate_acceleration(t)

# Vectorized evaluation
t_array = np.linspace(0, 4, 100)
trajectory = spline.evaluate(t_array)

CubicSmoothingSpline

interpolatepy.CubicSmoothingSpline

CubicSmoothingSpline(
    t_points: list[float],
    q_points: list[float],
    mu: float = 0.5,
    weights: list[float] | None = None,
    v0: float = 0.0,
    vn: float = 0.0,
    debug: bool = False,
)

Cubic smoothing spline trajectory planning with control over the smoothness versus waypoint accuracy trade-off.

This class implements cubic smoothing splines for trajectory generation as described in section 4.4.5 of the textbook. The algorithm minimizes a weighted sum of waypoint error and acceleration magnitude, allowing the user to control the trade-off between path smoothness and waypoint accuracy through the parameter μ.

Parameters:

Name Type Description Default
t_points list[float] or array_like

Time points [t₀, t₁, t₂, ..., tₙ] for the spline knots.

required
q_points list[float] or array_like

Position points [q₀, q₁, q₂, ..., qₙ] at each time point.

required
mu float

Trade-off parameter between accuracy (μ=1) and smoothness (μ=0). Must be in range (0, 1]. Default is 0.5.

0.5
weights list[float] or array_like

Individual point weights [w₀, w₁, ..., wₙ]. Higher values enforce closer approximation at corresponding points. Default is None (equal weights of 1.0 for all points).

None
v0 float

Initial velocity constraint at t₀. Default is 0.0.

0.0
vn float

Final velocity constraint at tₙ. Default is 0.0.

0.0
debug bool

Whether to print debug information. Default is False.

False

Attributes:

Name Type Description
t ndarray

Time points array.

q ndarray

Original position points array.

s ndarray

Approximated position points array.

mu float

Smoothing parameter value.

lambd float

Lambda parameter derived from μ: λ = (1-μ)/(6μ).

omega ndarray

Acceleration values at each time point.

coeffs ndarray

Polynomial coefficients for each segment.

Raises:

Type Description
ValueError

If time and position arrays have different lengths. If fewer than 2 points are provided. If time points are not strictly increasing. If parameter μ is outside the valid range (0, 1]. If weights array length doesn't match time and position arrays.

Notes

For μ=1, the spline performs exact interpolation. For μ approaching 0, the spline becomes increasingly smooth. Setting weight to infinity for a point forces exact interpolation at that point.

References

The implementation follows section 4.4.5 of the robotics textbook describing cubic smoothing splines for trajectory generation.

Parameters:

Name Type Description Default
t_points list[float] or array_like

Time points [t₀, t₁, t₂, ..., tₙ] for the spline knots.

required
q_points list[float] or array_like

Position points [q₀, q₁, q₂, ..., qₙ] at each time point.

required
mu float

Trade-off parameter between accuracy (μ=1) and smoothness (μ=0). Must be in range (0, 1]. Default is 0.5.

0.5
weights list[float] or array_like

Individual point weights [w₀, w₁, ..., wₙ]. Higher values enforce closer approximation at corresponding points. Default is None (equal weights of 1.0 for all points).

None
v0 float

Initial velocity constraint at t₀. Default is 0.0.

0.0
vn float

Final velocity constraint at tₙ. Default is 0.0.

0.0
debug bool

Whether to print debug information. Default is False.

False

Raises:

Type Description
ValueError

If time and position arrays have different lengths. If fewer than 2 points are provided. If time points are not strictly increasing. If parameter μ is outside the valid range (0, 1]. If weights array length doesn't match time and position arrays.

evaluate

evaluate(
    t: float | list[float] | ndarray,
) -> float | ndarray

Evaluate the spline at time t.

Parameters:

Name Type Description Default
t float or list[float] or ndarray

Time point or array of time points at which to evaluate the spline.

required

Returns:

Type Description
float or ndarray

Position(s) at the specified time(s). Returns a scalar if input is a scalar, otherwise returns an array matching the shape of input.

Notes

For t < t₀ or t > tₙ, the function extrapolates using the first or last segment respectively.

evaluate_velocity

evaluate_velocity(
    t: float | list[float] | ndarray,
) -> float | ndarray

Evaluate the velocity at time t.

Parameters:

Name Type Description Default
t float or list[float] or ndarray

Time point or array of time points at which to evaluate velocity.

required

Returns:

Type Description
float or ndarray

Velocity at the specified time(s). Returns a scalar if input is a scalar, otherwise returns an array matching the shape of input.

Notes

Computes the first derivative of the spline at the given time(s). For t < t₀ or t > tₙ, the function extrapolates using the first or last segment respectively.

evaluate_acceleration

evaluate_acceleration(
    t: float | list[float] | ndarray,
) -> float | ndarray

Evaluate the acceleration at time t.

Parameters:

Name Type Description Default
t float or list[float] or ndarray

Time point or array of time points at which to evaluate acceleration.

required

Returns:

Type Description
float or ndarray

Acceleration at the specified time(s). Returns a scalar if input is a scalar, otherwise returns an array matching the shape of input.

Notes

Computes the second derivative of the spline at the given time(s). For t < t₀ or t > tₙ, the function extrapolates using the first or last segment respectively.

plot

plot(num_points: int = 1000) -> None

Plot the spline trajectory with velocity and acceleration profiles.

Creates a three-panel figure showing position, velocity, and acceleration profiles over time.

Parameters:

Name Type Description Default
num_points int

Number of points for smooth plotting. Default is 1000.

1000

Returns:

Type Description
None

Displays the plot using matplotlib's show() function.

Notes

The plot includes: - Top panel: position trajectory with original waypoints and approximated points - Middle panel: velocity profile - Bottom panel: acceleration profile

Example:

from interpolatepy import CubicSmoothingSpline

# Noisy data points
t_points = [0, 0.5, 1.0, 1.5, 2.0]
q_noisy = [0.1, 1.05, -0.02, -0.98, 0.05]

# Create smoothing spline
spline = CubicSmoothingSpline(t_points, q_noisy, mu=0.1)
spline.plot()

CubicSplineWithAcceleration1

interpolatepy.CubicSplineWithAcceleration1

CubicSplineWithAcceleration1(
    t_points: list[float],
    q_points: list[float],
    v0: float = 0.0,
    vn: float = 0.0,
    a0: float = 0.0,
    an: float = 0.0,
    debug: bool = False,
)

Cubic spline trajectory planning with both velocity and acceleration constraints at endpoints.

Implements the method described in section 4.4.4 of the paper, which adds two extra points in the first and last segments to satisfy the acceleration constraints.

Parameters:

Name Type Description Default
t_points list of float or numpy.ndarray

Time points [t₀, t₂, t₃, ..., tₙ₋₂, tₙ]

required
q_points list of float or numpy.ndarray

Position points [q₀, q₂, q₃, ..., qₙ₋₂, qₙ]

required
v0 float

Initial velocity at t₀. Default is 0.0

0.0
vn float

Final velocity at tₙ. Default is 0.0

0.0
a0 float

Initial acceleration at t₀. Default is 0.0

0.0
an float

Final acceleration at tₙ. Default is 0.0

0.0
debug bool

Whether to print debug information. Default is False

False

Attributes:

Name Type Description
t_orig ndarray

Original time points

q_orig ndarray

Original position points

v0 float

Initial velocity

vn float

Final velocity

a0 float

Initial acceleration

an float

Final acceleration

debug bool

Debug flag

n_orig int

Number of original points

t ndarray

Time points including extra points

q ndarray

Position points including extra points

n int

Total number of points including extras

T ndarray

Time intervals between consecutive points

omega ndarray

Acceleration values at each point

coeffs ndarray

Polynomial coefficients for each segment

original_indices list

Indices of original points in expanded arrays

Notes

This implementation adds two extra points (at t₁ and tₙ₋₁) to the trajectory to satisfy both velocity and acceleration constraints at the endpoints. The extra points are placed at the midpoints of the first and last segments of the original trajectory.

The acceleration (omega) values are computed by solving a tridiagonal system that ensures C2 continuity throughout the trajectory.

Examples:

>>> import numpy as np
>>> # Define waypoints
>>> t_points = [0, 1, 2, 3]
>>> q_points = [0, 1, 0, 1]
>>> # Create spline with velocity and acceleration constraints
>>> spline = CubicSplineWithAcceleration1(t_points, q_points, v0=0.0, vn=0.0, a0=0.0, an=0.0)
>>> # Evaluate at specific time
>>> spline.evaluate(1.5)
>>> # Plot the trajectory
>>> spline.plot()

Parameters:

Name Type Description Default
t_points list of float or numpy.ndarray

Time points [t₀, t₂, t₃, ..., tₙ₋₂, tₙ]

required
q_points list of float or numpy.ndarray

Position points [q₀, q₂, q₃, ..., qₙ₋₂, qₙ]

required
v0 float

Initial velocity at t₀. Default is 0.0

0.0
vn float

Final velocity at tₙ. Default is 0.0

0.0
a0 float

Initial acceleration at t₀. Default is 0.0

0.0
an float

Final acceleration at tₙ. Default is 0.0

0.0
debug bool

Whether to print debug information. Default is 0.0

False

Raises:

Type Description
ValueError

If time and position arrays have different lengths If fewer than two points are provided If time points are not strictly increasing

original_indices instance-attribute

original_indices = _get_original_indices()

evaluate

evaluate(
    t: float | list[float] | ndarray,
) -> float | ndarray

Evaluate the spline at time t.

Parameters:

Name Type Description Default
t float or array_like

Time point or array of time points

required

Returns:

Type Description
float or ndarray

Position(s) at the specified time(s)

Examples:

>>> # Evaluate at a single time point
>>> spline.evaluate(1.5)
>>> # Evaluate at multiple time points
>>> spline.evaluate(np.linspace(0, 3, 100))

evaluate_velocity

evaluate_velocity(
    t: float | list[float] | ndarray,
) -> float | ndarray

Evaluate the velocity at time t.

Parameters:

Name Type Description Default
t float or array_like

Time point or array of time points

required

Returns:

Type Description
float or ndarray

Velocity at the specified time(s)

Examples:

>>> # Evaluate velocity at a single time point
>>> spline.evaluate_velocity(1.5)
>>> # Evaluate velocity at multiple time points
>>> spline.evaluate_velocity(np.linspace(0, 3, 100))

evaluate_acceleration

evaluate_acceleration(
    t: float | list[float] | ndarray,
) -> float | ndarray

Evaluate the acceleration at time t.

Parameters:

Name Type Description Default
t float or array_like

Time point or array of time points

required

Returns:

Type Description
float or ndarray

Acceleration at the specified time(s)

Examples:

>>> # Evaluate acceleration at a single time point
>>> spline.evaluate_acceleration(1.5)
>>> # Evaluate acceleration at multiple time points
>>> spline.evaluate_acceleration(np.linspace(0, 3, 100))

plot

plot(num_points: int = 1000) -> None

Plot the spline trajectory with velocity and acceleration profiles.

Parameters:

Name Type Description Default
num_points int

Number of points for smooth plotting. Default is 1000

1000

Returns:

Type Description
None

Displays the plot using matplotlib

Notes

This method creates a figure with three subplots showing: 1. Position trajectory with original and extra waypoints 2. Velocity profile with initial and final velocities marked 3. Acceleration profile with initial and final accelerations marked

Original waypoints are shown as red circles, while extra points are shown as green x-marks.

CubicSplineWithAcceleration2

interpolatepy.CubicSplineWithAcceleration2

CubicSplineWithAcceleration2(
    t_points: list[float] | ndarray,
    q_points: list[float] | ndarray,
    params: SplineParameters | None = None,
)

Bases: CubicSpline

Cubic spline trajectory planning with initial and final acceleration constraints.

This class extends CubicSpline to handle initial and final acceleration constraints by using 5th degree polynomials for the first and last segments, as mentioned in section 4.4.4 of the paper.

The spline consists of cubic polynomial segments for interior segments and optional quintic polynomial segments for the first and/or last segment when acceleration constraints are specified.

Parameters:

Name Type Description Default
t_points array_like

Array of time points (t0, t1, ..., tn).

required
q_points array_like

Array of position points (q0, q1, ..., qn).

required
params SplineParameters

Spline parameters including initial/final velocities and accelerations. If None, default parameters will be used.

None

Attributes:

Name Type Description
t_points ndarray

Array of time points.

q_points ndarray

Array of position points.

velocities ndarray

Array of velocities at each point.

t_intervals ndarray

Array of time intervals between consecutive points.

n int

Number of segments.

coefficients ndarray

Array of coefficients for each cubic segment.

a0 float or None

Initial acceleration constraint.

an float or None

Final acceleration constraint.

quintic_coeffs dict

Dictionary containing quintic coefficients for first and/or last segments.

Parameters:

Name Type Description Default
t_points array_like

Array of time points (t0, t1, ..., tn).

required
q_points array_like

Array of position points (q0, q1, ..., qn).

required
params SplineParameters

Spline parameters including initial/final velocities and accelerations. If None, default parameters will be used.

None

evaluate

evaluate(t: float | ndarray) -> float | ndarray

Evaluate the spline at time t.

Parameters:

Name Type Description Default
t float or ndarray

Time point or array of time points at which to evaluate the spline.

required

Returns:

Type Description
float or ndarray

Position(s) at the specified time(s). Returns a float if a single time point is provided, or an ndarray if an array of time points is provided.

Notes

For time values outside the spline range: - If t < t_points[0], returns the position at t_points[0] - If t > t_points[-1], returns the position at t_points[-1]

For the first and last segments, quintic polynomials are used if acceleration constraints were specified. For all other segments, cubic polynomials are used.

evaluate_velocity

evaluate_velocity(t: float | ndarray) -> float | ndarray

Evaluate the velocity at time t.

Parameters:

Name Type Description Default
t float or ndarray

Time point or array of time points at which to evaluate the velocity.

required

Returns:

Type Description
float or ndarray

Velocity at the specified time(s). Returns a float if a single time point is provided, or an ndarray if an array of time points is provided.

Notes

For time values outside the spline range: - If t < t_points[0], returns the velocity at t_points[0] - If t > t_points[-1], returns the velocity at t_points[-1]

For the first and last segments, derivatives of quintic polynomials are used if acceleration constraints were specified. For all other segments, derivatives of cubic polynomials are used.

evaluate_acceleration

evaluate_acceleration(
    t: float | ndarray,
) -> float | ndarray

Evaluate the acceleration at time t.

Parameters:

Name Type Description Default
t float or ndarray

Time point or array of time points at which to evaluate the acceleration.

required

Returns:

Type Description
float or ndarray

Acceleration at the specified time(s). Returns a float if a single time point is provided, or an ndarray if an array of time points is provided.

Notes

For time values outside the spline range: - If t < t_points[0], returns the acceleration at t_points[0] - If t > t_points[-1], returns the acceleration at t_points[-1]

For the first and last segments, second derivatives of quintic polynomials are used if acceleration constraints were specified. For all other segments, second derivatives of cubic polynomials are used.

B-Spline Family

BSpline

interpolatepy.BSpline

BSpline(
    degree: int,
    knots: list | ndarray,
    control_points: list | ndarray,
)

A class for representing and evaluating B-spline curves.

Parameters:

Name Type Description Default
degree int

The degree of the B-spline.

required
knots array_like

The knot vector.

required
control_points array_like

The control points defining the B-spline.

required

Attributes:

Name Type Description
degree int

The degree of the B-spline.

knots ndarray

The knot vector.

control_points ndarray

The control points defining the B-spline.

u_min float

Minimum valid parameter value.

u_max float

Maximum valid parameter value.

dimension int

The dimension of the control points (2D, 3D, etc.).

Parameters:

Name Type Description Default
degree int

The degree of the B-spline (must be positive).

required
knots array_like

The knot vector (must be non-decreasing).

required
control_points array_like

The control points defining the B-spline. Can be multidimensional (e.g., 2D or 3D points).

required

Raises:

Type Description
ValueError

If the inputs do not satisfy B-spline requirements.

__repr__

__repr__() -> str

Return a string representation of the B-spline.

Returns:

Type Description
str

String representation.

basis_function_derivatives

basis_function_derivatives(
    u: float, span_index: int, order: int
) -> ndarray

Calculate derivatives of basis functions up to the specified order.

Parameters:

Name Type Description Default
u float

The parameter value.

required
span_index int

The knot span index containing u.

required
order int

The maximum order of derivatives to calculate.

required

Returns:

Type Description
ndarray

2D array where ders[k][j] is the k-th derivative of the j-th basis function, where k is the derivative order and j is the basis function index.

basis_functions

basis_functions(u: float, span_index: int) -> ndarray

Calculate all non-zero basis functions at parameter value u.

Parameters:

Name Type Description Default
u float

The parameter value.

required
span_index int

The knot span index containing u.

required

Returns:

Type Description
ndarray

Array of basis function values (p+1 values).

create_periodic_knots staticmethod

create_periodic_knots(
    degree: int,
    num_control_points: int,
    domain_min: float = 0.0,
    domain_max: float = 1.0,
) -> ndarray

Create a periodic (uniform) knot vector for a B-spline.

Parameters:

Name Type Description Default
degree int

The degree of the B-spline.

required
num_control_points int

The number of control points.

required
domain_min float

Minimum value of the parameter domain. Default is 0.0.

0.0
domain_max float

Maximum value of the parameter domain. Default is 1.0.

1.0

Returns:

Type Description
ndarray

The periodic knot vector.

Raises:

Type Description
ValueError

If degree is negative or num_control_points is less than degree+1.

create_uniform_knots staticmethod

create_uniform_knots(
    degree: int,
    num_control_points: int,
    domain_min: float = 0.0,
    domain_max: float = 1.0,
) -> ndarray

Create a uniform knot vector for a B-spline with appropriate multiplicity at endpoints to ensure interpolation.

Parameters:

Name Type Description Default
degree int

The degree of the B-spline.

required
num_control_points int

The number of control points.

required
domain_min float

Minimum value of the parameter domain. Default is 0.0.

0.0
domain_max float

Maximum value of the parameter domain. Default is 1.0.

1.0

Returns:

Type Description
ndarray

The uniform knot vector with knots in the specified domain.

Raises:

Type Description
ValueError

If degree is negative or num_control_points is less than or equal to degree.

evaluate

evaluate(u: float) -> ndarray

Evaluate the B-spline curve at parameter value u.

Parameters:

Name Type Description Default
u float

The parameter value.

required

Returns:

Type Description
ndarray

The point on the B-spline curve at parameter u.

evaluate_derivative

evaluate_derivative(u: float, order: int = 1) -> ndarray

Evaluate the derivative of the B-spline curve at parameter value u.

Parameters:

Name Type Description Default
u float

The parameter value.

required
order int

The order of the derivative. Default is 1.

1

Returns:

Type Description
ndarray

The derivative of the B-spline curve at parameter u.

Raises:

Type Description
ValueError

If the order is greater than the degree of the B-spline.

find_knot_span

find_knot_span(u: float) -> int

Find the knot span index for a given parameter value u.

Parameters:

Name Type Description Default
u float

The parameter value.

required

Returns:

Type Description
int

The index of the knot span containing u.

Raises:

Type Description
ValueError

If u is outside the valid parameter range.

generate_curve_points

generate_curve_points(
    num_points: int = 100,
) -> tuple[ndarray, ndarray]

Generate points along the B-spline curve for visualization.

Parameters:

Name Type Description Default
num_points int

Number of points to generate. Default is 100.

100

Returns:

Name Type Description
u_values ndarray

Parameter values.

curve_points ndarray

Corresponding points on the curve.

plot_2d

plot_2d(
    num_points: int = 100,
    show_control_polygon: bool = True,
    show_knots: bool = False,
    ax: Axes | None = None,
) -> Axes

Plot a 2D B-spline curve with customizable styling.

Parameters:

Name Type Description Default
num_points int

Number of points to generate for the curve. Default is 100.

100
show_control_polygon bool

Whether to show the control polygon. Default is True.

True
show_knots bool

Whether to show the knot points on the curve. Default is False.

False
ax Axes

Matplotlib axis to use for plotting. If None, a new figure is created.

None

Returns:

Type Description
Axes

The matplotlib axis object.

Raises:

Type Description
ValueError

If the dimension of control points is not 2.

plot_3d

plot_3d(
    num_points: int = 100,
    show_control_polygon: bool = True,
    ax: Axes3D | None = None,
) -> Axes3D

Plot a 3D B-spline curve.

Parameters:

Name Type Description Default
num_points int

Number of points to generate for the curve. Default is 100.

100
show_control_polygon bool

Whether to show the control polygon. Default is True.

True
ax Axes

Matplotlib 3D axis to use for plotting. If None, a new figure is created.

None

Returns:

Type Description
Axes

The matplotlib 3D axis object.

Raises:

Type Description
ValueError

If the dimension of control points is not 3.

BSplineInterpolator

interpolatepy.BSplineInterpolator

BSplineInterpolator(
    degree: int,
    points: list | ndarray,
    times: list | ndarray | None = None,
    initial_velocity: list | ndarray | None = None,
    final_velocity: list | ndarray | None = None,
    initial_acceleration: list | ndarray | None = None,
    final_acceleration: list | ndarray | None = None,
    cyclic: bool = False,
)

Bases: BSpline

A B-spline that interpolates a set of points with specified degrees of continuity.

This class inherits from BSpline and computes the knot vector and control points required to interpolate given data points at specified times, while maintaining desired continuity constraints.

The implementation follows section 4.5 of the document, supporting: - Cubic splines (degree 3) with C² continuity - Quartic splines (degree 4) with C³ continuity (continuous jerk) - Quintic splines (degree 5) with C⁴ continuity (continuous snap)

Points can be of any dimension, including 2D and 3D.

Parameters:

Name Type Description Default
degree int

The degree of the B-spline (3, 4, or 5).

required
points list or ndarray

The points to be interpolated.

required
times list or ndarray or None

The time instants for each point. If None, uses uniform spacing.

None
initial_velocity list or ndarray or None

Initial velocity constraint.

None
final_velocity list or ndarray or None

Final velocity constraint.

None
initial_acceleration list or ndarray or None

Initial acceleration constraint.

None
final_acceleration list or ndarray or None

Final acceleration constraint.

None
cyclic bool

Whether to use cyclic (periodic) conditions.

False

Raises:

Type Description
ValueError

If the degree is not 3, 4, or 5.

ValueError

If there are not enough points for the specified degree.

plot_with_points

plot_with_points(
    num_points: int = 100,
    show_control_polygon: bool = True,
    ax: Axes | None = None,
) -> Axes

Plot the 2D B-spline curve along with the interpolation points.

Parameters:

Name Type Description Default
num_points int

Number of points to generate for the curve.

100
show_control_polygon bool

Whether to show the control polygon.

True
ax Axes or None

Optional matplotlib axis to use.

None

Returns:

Type Description
Axes

The matplotlib axis object.

Raises:

Type Description
ValueError

If points are not 2D.

plot_with_points_3d

plot_with_points_3d(
    num_points: int = 100,
    show_control_polygon: bool = True,
    ax: Axes | None = None,
) -> Axes

Plot the 3D B-spline curve along with the interpolation points.

Parameters:

Name Type Description Default
num_points int

Number of points to generate for the curve.

100
show_control_polygon bool

Whether to show the control polygon.

True
ax Axes or None

Optional matplotlib 3D axis to use.

None

Returns:

Type Description
Axes

The matplotlib 3D axis object.

Raises:

Type Description
ValueError

If points are not 3D.

Example:

from interpolatepy import BSplineInterpolator
import numpy as np

# 2D curve data
points = np.array([[0, 0], [1, 2], [3, 1], [4, 3], [5, 0]])
times = np.array([0, 1, 2, 3, 4])

# Create B-spline interpolator
bspline = BSplineInterpolator(
    degree=3, 
    points=points, 
    times=times,
    initial_velocity=np.array([1, 0]),
    final_velocity=np.array([0, -1])
)

# Evaluate curve
t = 2.5
position = bspline.evaluate(t)
velocity = bspline.evaluate_derivative(t, order=1)

ApproximationBSpline

interpolatepy.ApproximationBSpline

ApproximationBSpline(
    points: list | ndarray,
    num_control_points: int,
    *,
    degree: int = 3,
    weights: list | ndarray | None = None,
    method: str = "chord_length",
    debug: bool = False,
)

Bases: BSpline

A class for B-spline curve approximation of a set of points.

Inherits from BSpline class.

The approximation follows the theory described in Section 8.5 of the reference: - The end points are exactly interpolated - The internal points are approximated in the least squares sense - Degree 3 (cubic) is typically used to ensure C2 continuity

Attributes:

Name Type Description
original_points ndarray

The original points being approximated.

original_parameters ndarray

The parameter values corresponding to original points.

Parameters:

Name Type Description Default
points list or ndarray

The points to approximate.

required
num_control_points int

The number of control points to use.

required
degree int

The degree of the B-spline. Defaults to 3 for cubic.

3
weights list or ndarray or None

Weights for points in approximation. If None, uniform weighting is used.

None
method str

Method for parameter calculation. Options are 'equally_spaced', 'chord_length', or 'centripetal'.

"chord_length"
debug bool

Whether to print debug information.

False

Raises:

Type Description
ValueError

If inputs do not satisfy approximation requirements.

calculate_approximation_error

calculate_approximation_error(
    points: ndarray | None = None,
    u_bar: ndarray | None = None,
) -> float

Calculate the approximation error as the sum of squared distances.

Computes sum of squared distances between the points and the corresponding points on the B-spline.

Parameters:

Name Type Description Default
points ndarray or None

The points to compare with the B-spline. If None, the original points used for approximation are used.

None
u_bar ndarray or None

Parameter values for the points. If None, the original parameters are used for original points, or computed for new points.

None

Returns:

Type Description
float

The sum of squared distances.

refine

refine(
    max_error: float = 0.1, max_control_points: int = 100
) -> ApproximationBSpline

Refine the approximation by adding more control points.

Adds control points until the maximum error is below a threshold or the maximum number of control points is reached.

Parameters:

Name Type Description Default
max_error float

Maximum acceptable error.

0.1
max_control_points int

Maximum number of control points.

100

Returns:

Type Description
ApproximationBSpline

A refined approximation B-spline.

SmoothingCubicBSpline

interpolatepy.SmoothingCubicBSpline

SmoothingCubicBSpline(
    points: list | ndarray,
    params: BSplineParams | None = None,
)

Bases: BSpline

A class for creating smoothing cubic B-splines that approximate a set of points.

This class inherits from BSpline and implements the smoothing algorithm described in Section 8.7 of the document. It creates a cubic B-spline curve that balances between fitting the given points and maintaining smoothness.

Parameters:

Name Type Description Default
points array_like

The points to approximate.

required
params BSplineParams

Configuration parameters. If None, default parameters will be used.

None

calculate_approximation_error

calculate_approximation_error() -> ndarray

Calculate the approximation error for each point.

Returns:

Type Description
ndarray

Array with error values for each approximation point.

calculate_smoothness_measure

calculate_smoothness_measure(
    num_points: int = 100,
) -> float

Calculate the smoothness measure (integral of squared second derivative).

Parameters:

Name Type Description Default
num_points int

Number of points to use for numerical integration.

100

Returns:

Type Description
float

The smoothness measure.

calculate_total_error

calculate_total_error() -> float

Calculate the total weighted approximation error.

Returns:

Type Description
float

The total weighted error.

Motion Profiles

DoubleSTrajectory

interpolatepy.DoubleSTrajectory

DoubleSTrajectory(
    state_params: StateParams, bounds: TrajectoryBounds
)

Double S-Trajectory Planner Class

This class implements a trajectory planning algorithm that generates smooth motion profiles with bounded velocity, acceleration, and jerk (double S-trajectory).

Parameters:

state_params : StateParams Start and end states for trajectory planning bounds : TrajectoryBounds Velocity, acceleration, and jerk bounds for trajectory planning

create_trajectory staticmethod

create_trajectory(
    state_params: StateParams, bounds: TrajectoryBounds
) -> tuple[
    Callable[
        [float | ndarray], tuple[float | ndarray, ...]
    ],
    float,
]

Static factory method to create a trajectory function and return its duration. This method provides an interface similar to the original function-based API.

Parameters:

state_params : StateParams Start and end states for trajectory planning bounds : TrajectoryBounds Velocity, acceleration, and jerk bounds for trajectory planning

Returns:

trajectory_function : Callable A function that takes time t as input and returns position, velocity, acceleration, and jerk at that time T : float Total trajectory duration

evaluate

evaluate(t: float | ndarray) -> tuple[float | ndarray, ...]

Evaluate the double-S trajectory at time t.

Parameters:

t : float or ndarray Time(s) at which to evaluate the trajectory

Returns:

q : float or ndarray Position at time t qp : float or ndarray Velocity at time t qpp : float or ndarray Acceleration at time t qppp : float or ndarray Jerk at time t

get_duration

get_duration() -> float

Returns the total duration of the trajectory.

Returns:

T : float Total trajectory duration in seconds

get_phase_durations

get_phase_durations() -> dict[str, float]

Returns the durations of each phase in the trajectory.

Returns:

phases : dict Dictionary containing the durations of each phase

StateParams

interpolatepy.StateParams dataclass

StateParams(q_0: float, q_1: float, v_0: float, v_1: float)

Parameters representing position and velocity state.

Parameters:

Name Type Description Default
q_0 float

Start position.

required
q_1 float

End position.

required
v_0 float

Velocity at start of trajectory.

required
v_1 float

Velocity at end of trajectory.

required

TrajectoryBounds

interpolatepy.TrajectoryBounds dataclass

TrajectoryBounds(
    v_bound: float, a_bound: float, j_bound: float
)

Bounds for trajectory planning.

Parameters:

Name Type Description Default
v_bound float

Velocity bound (absolute value will be used for both min/max).

required
a_bound float

Acceleration bound (absolute value will be used for both min/max).

required
j_bound float

Jerk bound (absolute value will be used for both min/max).

required

__post_init__

__post_init__() -> None

Validate the bounds.

Example:

from interpolatepy import DoubleSTrajectory, StateParams, TrajectoryBounds

# Define trajectory parameters
state = StateParams(
    q_0=0.0,     # Initial position
    q_1=10.0,    # Final position
    v_0=0.0,     # Initial velocity
    v_1=0.0      # Final velocity
)

bounds = TrajectoryBounds(
    v_bound=5.0,   # Maximum velocity
    a_bound=10.0,  # Maximum acceleration
    j_bound=30.0   # Maximum jerk
)

# Create S-curve trajectory
trajectory = DoubleSTrajectory(state, bounds)

# Evaluate trajectory
t = trajectory.get_duration() / 2
result = trajectory.evaluate(t)
position = result[0]
velocity = result[1]
acceleration = result[2]
jerk = result[3]

print(f"Duration: {trajectory.get_duration():.2f}s")

TrapezoidalTrajectory

interpolatepy.TrapezoidalTrajectory

Generate trapezoidal velocity profiles for trajectory planning.

This class provides methods to create trapezoidal velocity profiles for various trajectory planning scenarios, including single segment trajectories and multi-point interpolation. The trapezoidal profile consists of three phases: acceleration, constant velocity (cruise), and deceleration phases.

The implementation follows the mathematical formulations described in Chapter 3 of trajectory planning literature, handling both time-constrained and velocity-constrained trajectory generation.

Methods:

Name Description
generate_trajectory

Generate a single-segment trapezoidal trajectory.

interpolate_waypoints

Generate a multi-segment trajectory through waypoints.

calculate_heuristic_velocities

Compute intermediate velocities for multi-point trajectories.

Examples:

>>> from interpolatepy import TrapezoidalTrajectory, TrajectoryParams
>>>
>>> # Simple point-to-point trajectory with velocity constraint
>>> params = TrajectoryParams(q0=0, q1=10, v0=0, v1=0, amax=2.0, vmax=5.0)
>>> trajectory_func, duration = TrapezoidalTrajectory.generate_trajectory(params)
>>>
>>> # Evaluate trajectory at various times
>>> for t in [0, duration/2, duration]:
...     pos, vel, acc = trajectory_func(t)
...     print(f"t={t:.2f}: pos={pos:.2f}, vel={vel:.2f}, acc={acc:.2f}")
>>>
>>> # Multi-point interpolation
>>> from interpolatepy import InterpolationParams
>>> waypoints = [0, 5, 3, 8]
>>> interp_params = InterpolationParams(points=waypoints, amax=2.0, vmax=4.0)
>>> traj_func, total_time = TrapezoidalTrajectory.interpolate_waypoints(interp_params)

calculate_heuristic_velocities staticmethod

calculate_heuristic_velocities(
    q_list: list[float],
    v0: float,
    vn: float,
    v_max: float | None = None,
    amax: float | None = None,
) -> list[float]

Calculate velocities based on height differences with multiple options for heuristic velocity calculation.

Parameters:

Name Type Description Default
q_list list[float]

List of height values [q0, q1, ..., qn]

required
v0 float

Initial velocity (assigned)

required
vn float

Final velocity (assigned)

required
v_max float | None

Maximum velocity value (positive magnitude)

None
amax float | None

Maximum acceleration (needed if v_max is not provided)

None

Returns:

Type Description
list[float]

Calculated velocities [v0, v1, ..., vn]

Raises:

Type Description
ValueError

If neither v_max nor amax is provided

generate_trajectory staticmethod

generate_trajectory(
    params: TrajectoryParams,
) -> tuple[
    Callable[[float], tuple[float, float, float]], float
]

Generate a trapezoidal trajectory with non-null initial and final velocities.

Handles both positive and negative displacements according to section 3.4.2. Uses absolute values for amax and vmax and includes numerical stability enhancements.

Parameters:

Name Type Description Default
params TrajectoryParams

Parameters for trajectory generation including initial and final positions, velocities, acceleration and velocity limits, and optional duration.

required

Returns:

Type Description
tuple[Callable[[float], tuple[float, float, float]], float]

A tuple containing: - Function that computes position, velocity, and acceleration at time t - Duration of trajectory

Raises:

Type Description
ValueError

If parameter combination is invalid or trajectory is not feasible

interpolate_waypoints classmethod

interpolate_waypoints(
    params: InterpolationParams,
) -> tuple[
    Callable[[float], tuple[float, float, float]], float
]

Generate a trajectory through a sequence of points using trapezoidal velocity profiles.

Supports both positive and negative displacements.

Parameters:

Name Type Description Default
params InterpolationParams

Parameters for interpolation including points, velocities, times, and motion constraints.

required

Returns:

Type Description
tuple[Callable[[float], tuple[float, float, float]], float]

A tuple containing: - Function that returns position, velocity, and acceleration at any time t - Total duration of the trajectory

Raises:

Type Description
ValueError

If less than two points are provided or if invalid velocity counts are provided

TrajectoryParams

interpolatepy.TrajectoryParams dataclass

TrajectoryParams(
    points: list[float],
    times: list[float],
    velocities: list[float] | None = None,
    accelerations: list[float] | None = None,
    jerks: list[float] | None = None,
    order: int = ORDER_3,
)

Parameters for multipoint polynomial trajectory generation.

Parameters:

Name Type Description Default
points list[float]

List of position waypoints to interpolate through.

required
times list[float]

List of time points corresponding to each waypoint.

required
velocities list[float]

Velocity constraints at each waypoint. If None, velocities are computed using heuristic rules.

None
accelerations list[float]

Acceleration constraints at each waypoint. Required for 5th and 7th order polynomials. If None, zero accelerations are assumed.

None
jerks list[float]

Jerk constraints at each waypoint. Required for 7th order polynomials. If None, zero jerks are assumed.

None
order int

Polynomial order (3, 5, or 7). Default is 3.

ORDER_3

Example:

from interpolatepy import TrapezoidalTrajectory
from interpolatepy.trapezoidal import TrajectoryParams

# Define trajectory parameters
params = TrajectoryParams(
    q0=0.0,       # Initial position
    q1=5.0,       # Final position
    v0=0.0,       # Initial velocity
    v1=0.0,       # Final velocity
    amax=2.0,     # Maximum acceleration
    vmax=1.5      # Maximum velocity
)

# Generate trajectory
traj_func, duration = TrapezoidalTrajectory.generate_trajectory(params)

# Evaluate at specific time
t = 1.0
pos, vel, acc = traj_func(t)
print(f"At t={t}: pos={pos:.2f}, vel={vel:.2f}, acc={acc:.2f}")

PolynomialTrajectory

interpolatepy.PolynomialTrajectory

Generate smooth polynomial trajectories with specified boundary conditions.

This class provides methods to create polynomial trajectories of different orders (3rd, 5th, and 7th) with specified boundary conditions such as position, velocity, acceleration, and jerk. The polynomials ensure smooth motion profiles with continuous derivatives up to the jerk level, making them ideal for robotics and control applications.

Methods:

Name Description
order_3_trajectory

Generate a 3rd order polynomial trajectory with position and velocity constraints.

order_5_trajectory

Generate a 5th order polynomial trajectory with position, velocity, and acceleration constraints.

order_7_trajectory

Generate a 7th order polynomial trajectory with position, velocity, acceleration, and jerk constraints.

heuristic_velocities

Compute intermediate velocities for a sequence of points using heuristic rules.

multipoint_trajectory

Generate a trajectory through a sequence of points with specified times.

Notes

The polynomial trajectories are defined as:

3rd Order: q(t) = a₀ + a₁τ + a₂τ² + a₃τ³ 5th Order: q(t) = a₀ + a₁τ + a₂τ² + a₃τ³ + a₄τ⁴ + a₅τ⁵ 7th Order: q(t) = a₀ + a₁τ + ... + a₇τ⁷

Where τ = t - t_start is the normalized time within each segment.

The coefficients are computed to satisfy the specified boundary conditions: - 3rd order requires position and velocity at both endpoints (4 constraints) - 5th order requires position, velocity, and acceleration (6 constraints) - 7th order requires position, velocity, acceleration, and jerk (8 constraints)

Examples:

>>> import numpy as np
>>> from interpolatepy import PolynomialTrajectory, BoundaryCondition, TimeInterval
>>>
>>> # Create a 5th order polynomial trajectory
>>> initial = BoundaryCondition(position=0, velocity=0, acceleration=0)
>>> final = BoundaryCondition(position=10, velocity=0, acceleration=0)
>>> time_interval = TimeInterval(start=0, end=2.0)
>>>
>>> trajectory_func = PolynomialTrajectory.order_5_trajectory(
...     initial, final, time_interval
... )
>>>
>>> # Evaluate trajectory at various times
>>> for t in np.linspace(0, 2, 5):
...     pos, vel, acc, jerk = trajectory_func(t)
...     print(f"t={t:.1f}: pos={pos:.2f}, vel={vel:.2f}, acc={acc:.2f}")
>>>
>>> # Multi-point trajectory example
>>> from interpolatepy import TrajectoryParams
>>> params = TrajectoryParams(
...     points=[0, 5, 3, 8],
...     times=[0, 1, 2, 3],
...     order=5
... )
>>> multi_traj = PolynomialTrajectory.multipoint_trajectory(params)
>>>
>>> # Evaluate at any time
>>> pos, vel, acc, jerk = multi_traj(1.5)

heuristic_velocities staticmethod

heuristic_velocities(
    points: list[float], times: list[float]
) -> list[float]

Compute intermediate velocities for a sequence of points using the heuristic rule.

The heuristic rule sets the velocity at each intermediate point to the average of the slopes of the adjacent segments, unless the slopes have different signs, in which case the velocity is set to zero. This prevents oscillatory behavior near direction changes.

Parameters:

Name Type Description Default
points list[float]

List of position points [q₀, q₁, ..., qₙ].

required
times list[float]

List of time points [t₀, t₁, ..., tₙ].

required

Returns:

Type Description
list[float]

List of velocities [v₀, v₁, ..., vₙ].

Notes

The heuristic rule is defined as:

For intermediate points i = 1, 2, ..., n-1: - If sign(sᵢ₋₁) ≠ sign(sᵢ): vᵢ = 0 - Otherwise: vᵢ = (sᵢ₋₁ + sᵢ) / 2

Where sᵢ = (qᵢ₊₁ - qᵢ) / (tᵢ₊₁ - tᵢ) is the slope of segment i.

The boundary velocities v₀ and vₙ are set to zero by default.

Examples:

>>> points = [0, 2, 1, 3]
>>> times = [0, 1, 2, 3]
>>> velocities = PolynomialTrajectory.heuristic_velocities(points, times)
>>> print(velocities)  # [0.0, 2.0, 0.0, 0.0]

multipoint_trajectory classmethod

multipoint_trajectory(
    params: TrajectoryParams,
) -> Callable[[float], tuple[float, float, float, float]]

Generate a trajectory through a sequence of points with specified times.

Parameters:

Name Type Description Default
params TrajectoryParams

Parameters for trajectory generation including points, times, and optional velocities, accelerations, jerks, and polynomial order.

required

Returns:

Type Description
Callable[[float], tuple[float, float, float, float]]

Function that computes trajectory at time t

Raises:

Type Description
ValueError

If number of points and times are not the same, or if order is not one of the valid polynomial orders.

order_3_trajectory staticmethod

order_3_trajectory(
    initial: BoundaryCondition,
    final: BoundaryCondition,
    time: TimeInterval,
) -> Callable[[float], tuple[float, float, float, float]]

Generate a 3rd order polynomial trajectory with specified boundary conditions.

Parameters:

Name Type Description Default
initial BoundaryCondition

Initial boundary conditions (position, velocity).

required
final BoundaryCondition

Final boundary conditions (position, velocity).

required
time TimeInterval

Time interval for the trajectory.

required

Returns:

Type Description
Callable[[float], tuple[float, float, float, float]]

Function that computes position, velocity, acceleration, and jerk at time t.

Notes

The 3rd order polynomial is defined as: q(τ) = a₀ + a₁τ + a₂τ² + a₃τ³

Where the coefficients are determined by the boundary conditions: - q(0) = q₀, q̇(0) = v₀ - q(T) = q₁, q̇(T) = v₁

The coefficient formulas (equation 2.2) are: - a₀ = q₀ - a₁ = v₀ - a₂ = (3h - (2v₀ + v₁)T) / T² - a₃ = (-2h + (v₀ + v₁)T) / T³

Where h = q₁ - q₀ and T = t_end - t_start.

Examples:

>>> # Simple point-to-point motion
>>> initial = BoundaryCondition(position=0, velocity=1)
>>> final = BoundaryCondition(position=5, velocity=0)
>>> time_interval = TimeInterval(start=0, end=2.0)
>>> traj = PolynomialTrajectory.order_3_trajectory(initial, final, time_interval)
>>>
>>> # Evaluate at midpoint
>>> pos, vel, acc, jerk = traj(1.0)

order_5_trajectory staticmethod

order_5_trajectory(
    initial: BoundaryCondition,
    final: BoundaryCondition,
    time: TimeInterval,
) -> Callable[[float], tuple[float, float, float, float]]

Generate a 5th order polynomial trajectory with specified boundary conditions.

Parameters:

Name Type Description Default
initial BoundaryCondition

Initial boundary conditions (position, velocity, acceleration).

required
final BoundaryCondition

Final boundary conditions (position, velocity, acceleration).

required
time TimeInterval

Time interval for the trajectory.

required

Returns:

Type Description
Callable[[float], tuple[float, float, float, float]]

Function that computes position, velocity, acceleration, and jerk at time t.

Notes

The 5th order polynomial provides smooth acceleration profiles and is defined as: q(τ) = a₀ + a₁τ + a₂τ² + a₃τ³ + a₄τ⁴ + a₅τ⁵

The six boundary conditions are: - q(0) = q₀, q̇(0) = v₀, q̈(0) = a₀ - q(T) = q₁, q̇(T) = v₁, q̈(T) = a₁

The coefficients (equation 2.5) ensure continuous position, velocity, and acceleration, making this ideal for applications requiring smooth acceleration profiles such as robotic manipulators.

Examples:

>>> # Trajectory with zero initial and final accelerations
>>> initial = BoundaryCondition(position=0, velocity=0, acceleration=0)
>>> final = BoundaryCondition(position=10, velocity=2, acceleration=0)
>>> time_interval = TimeInterval(start=0, end=3.0)
>>> traj = PolynomialTrajectory.order_5_trajectory(initial, final, time_interval)

order_7_trajectory staticmethod

order_7_trajectory(
    initial: BoundaryCondition,
    final: BoundaryCondition,
    time: TimeInterval,
) -> Callable[[float], tuple[float, float, float, float]]

Generate a 7th order polynomial trajectory with specified boundary conditions.

Parameters:

Name Type Description Default
initial BoundaryCondition

Initial boundary conditions (position, velocity, acceleration, jerk)

required
final BoundaryCondition

Final boundary conditions (position, velocity, acceleration, jerk)

required
time TimeInterval

Time interval for the trajectory

required

Returns:

Type Description
Callable[[float], tuple[float, float, float, float]]

Function that computes position, velocity, acceleration, and jerk at time t

BoundaryCondition

interpolatepy.BoundaryCondition dataclass

BoundaryCondition(
    position: float,
    velocity: float,
    acceleration: float = 0.0,
    jerk: float = 0.0,
)

Boundary conditions for polynomial trajectory generation.

Parameters:

Name Type Description Default
position float

Position constraint.

required
velocity float

Velocity constraint.

required
acceleration float

Acceleration constraint. Default is 0.0.

0.0
jerk float

Jerk constraint. Default is 0.0.

0.0
Notes

Higher-order polynomial trajectories require more boundary conditions: - 3rd order: position and velocity - 5th order: position, velocity, and acceleration - 7th order: position, velocity, acceleration, and jerk

TimeInterval

interpolatepy.TimeInterval dataclass

TimeInterval(start: float, end: float)

Time interval for trajectory generation.

Parameters:

Name Type Description Default
start float

Start time of the trajectory segment.

required
end float

End time of the trajectory segment.

required

Example:

from interpolatepy import PolynomialTrajectory, BoundaryCondition, TimeInterval

# Define boundary conditions
initial = BoundaryCondition(
    position=0.0,
    velocity=0.0,
    acceleration=0.0,
    jerk=0.0
)

final = BoundaryCondition(
    position=1.0,
    velocity=0.0,
    acceleration=0.0,
    jerk=0.0
)

interval = TimeInterval(start=0.0, end=2.0)

# Generate 7th-order polynomial
traj_func = PolynomialTrajectory.order_7_trajectory(initial, final, interval)

# Evaluate trajectory
t = 1.0
pos, vel, acc, jerk = traj_func(t)

ParabolicBlendTrajectory

interpolatepy.ParabolicBlendTrajectory

ParabolicBlendTrajectory(
    q: list | ndarray,
    t: list | ndarray,
    dt_blend: list | ndarray,
    dt: float = 0.01,
)

Class to generate trajectories composed of linear segments with parabolic blends at via points.

The trajectory duration is extended: total_duration = t[-1] - t[0] + (dt_blend[0] + dt_blend[-1]) / 2

Initial and final velocities are set to zero (q̇0,1 = q̇N,N+1 = 0).

Parameters:

Name Type Description Default
q list | ndarray

Positions of via points (length N).

required
t list | ndarray

Nominal times at which via points are reached (length N).

required
dt_blend list | ndarray

Blend durations at via points (length N).

required
dt float

Sampling interval for plotting trajectory. Default is 0.01.

0.01

generate

generate() -> tuple[
    Callable[[float], tuple[float, float, float]], float
]

Generate the parabolic blend trajectory function.

Returns:

Name Type Description
trajectory_function callable

Function that takes a time value and returns position, velocity, and acceleration.

total_duration float

The total duration of the trajectory.

plot

plot(
    times: ndarray | None = None,
    pos: ndarray | None = None,
    vel: ndarray | None = None,
    acc: ndarray | None = None,
) -> None

Plot the trajectory's position, velocity, and acceleration.

If trajectory data is not provided, it will be generated.

Parameters:

Name Type Description Default
times ndarray

Time samples; if None, generated from trajectory function.

None
pos ndarray

Position samples; if None, generated from trajectory function.

None
vel ndarray

Velocity samples; if None, generated from trajectory function.

None
acc ndarray

Acceleration samples; if None, generated from trajectory function.

None

Quaternion Interpolation

Quaternion

interpolatepy.Quaternion

Quaternion(
    s: float = 1.0,
    v1: float = 0.0,
    v2: float = 0.0,
    v3: float = 0.0,
)

Core quaternion class that implements: - Basic quaternion arithmetic and operations - Quaternion dynamics (time derivatives, integration) - Spherical linear interpolation (Slerp) - Spherical cubic interpolation (Squad) - Matrix conversions and utilities

A quaternion is represented as q = [s, v] where: - s is the scalar part (w component) - v is the vector part [v1, v2, v3] (x, y, z components)

Example usage: # Create quaternions q1 = Quaternion.identity() q2 = Quaternion.from_euler_angles(0.1, 0.2, 0.3)

# Basic operations
q3 = q1 * q2
q_normalized = q3.unit()

# Interpolation
q_interp = q1.slerp(q2, 0.5)

# Conversions
rotation_matrix = q2.R()
roll, pitch, yaw = q2.to_euler_angles()

Args: s: Scalar part (w component) v1: X component of vector part v2: Y component of vector part v3: Z component of vector part

norm

norm() -> float

Quaternion norm: ||q|| = sqrt(s² + v·v)

unit

unit() -> Quaternion

Normalize quaternion to unit length.

inverse

inverse() -> Quaternion

Alias for i() - quaternion inverse

conjugate

conjugate() -> Quaternion

Quaternion conjugate: q* = [s, -v]

slerp

slerp(other: Quaternion, t: float) -> Quaternion

Spherical Linear Interpolation (Slerp).

Log

Log() -> Quaternion

Quaternion logarithm for unit quaternions.

For unit q = [cos(θ), v*sin(θ)], log(q) = [0, v*θ]

exp

exp() -> Quaternion

Quaternion exponential.

For q = [0, θv], exp(q) = [cos(θ), v*sin(θ)]

to_axis_angle

to_axis_angle() -> tuple[ndarray, float]

Convert quaternion to axis-angle representation

from_angle_axis classmethod

from_angle_axis(angle: float, axis: ndarray) -> Quaternion

Create quaternion from rotation angle and axis.

Args: angle: Rotation angle in radians axis: 3D rotation axis vector

Returns: Quaternion representing the rotation

from_euler_angles classmethod

from_euler_angles(
    roll: float, pitch: float, yaw: float
) -> Quaternion

Create quaternion from Euler angles (roll, pitch, yaw) in radians

to_euler_angles

to_euler_angles() -> tuple[float, float, float]

Convert quaternion to Euler angles (roll, pitch, yaw) in radians

identity classmethod

identity() -> Quaternion

Create identity quaternion [1, 0, 0, 0]

Example:

from interpolatepy import Quaternion
import numpy as np

# Create quaternions
q1 = Quaternion.identity()
q2 = Quaternion.from_angle_axis(np.pi/2, np.array([0, 0, 1]))  # 90° about Z

# SLERP interpolation
t = 0.5
q_interp = q1.slerp(q2, t)

# Convert to axis-angle
axis, angle = q_interp.to_axis_angle()
print(f"Interpolated rotation: {np.degrees(angle):.1f}° about {axis}")

# Convert to Euler angles
roll, pitch, yaw = q_interp.to_euler_angles()
print(f"Euler angles: roll={np.degrees(roll):.1f}°, "
      f"pitch={np.degrees(pitch):.1f}°, yaw={np.degrees(yaw):.1f}°")

SquadC2

interpolatepy.SquadC2

SquadC2(
    time_points: list[float],
    quaternions: list[Quaternion],
    normalize_quaternions: bool = True,
    validate_continuity: bool = True,
)

C²-Continuous, Zero-Clamped Quaternion Interpolation using SQUAD with Quintic Polynomial Parameterization.

This class implements the SQUAD_C2 method as described in "Spherical Cubic Blends: C²-Continuous, Zero-Clamped, and Time-Optimized Interpolation of Quaternions" by Wittmann et al. (ICRA 2023).

Implementation follows paper specifications: 1. Creates extended quaternion sequence Q = [q₁, q₁ᵛⁱʳᵗ, q₂, ..., qₙ₋₁ᵛⁱʳᵗ, qₙ] where q₁ᵛⁱʳᵗ = q₁ and qₙ₋₁ᵛⁱʳᵗ = qₙ (Section III-B.1) 2. Computes intermediate quaternions using corrected formula (Equation 5): sᵢ = qᵢ ⊗ exp[(log(qᵢ⁻¹⊗qᵢ₊₁)/(-2(1+hᵢ/hᵢ₋₁))) + (log(qᵢ⁻¹⊗qᵢ₋₁)/(-2(1+hᵢ₋₁/hᵢ)))] 3. Uses SQUAD interpolation with proper time parameterization (Equations 2-4) 4. Applies quintic polynomial parameterization u(t) for C²-continuity and zero-clamped boundaries

Key Features: - Guarantees C²-continuous quaternion trajectories - Zero-clamped boundary conditions (zero angular velocity and acceleration at endpoints) - Proper handling of different segment durations hᵢ - Compatible with time-optimization frameworks

References: - Wittmann et al., "Spherical Cubic Blends: C²-Continuous, Zero-Clamped, and Time-Optimized Interpolation of Quaternions", ICRA 2023 - Original SQUAD: Shoemake, "Animating rotation with quaternion curves", SIGGRAPH 1985

The interpolator creates an extended quaternion sequence with virtual waypoints to enable zero-clamped boundary conditions and C²-continuous trajectories.

Args: time_points: List of time values (must be sorted and at least 2 points) quaternions: List of quaternions at each time point normalize_quaternions: Whether to normalize input quaternions to unit length validate_continuity: Whether to validate C² continuity (for debugging)

Raises: ValueError: If input validation fails

Note: The implementation follows the corrected SQUAD formulation from the paper, which properly handles non-uniform time spacing through the corrected intermediate quaternion formula (Equation 5).

__len__

__len__() -> int

Return number of original waypoints.

__repr__

__repr__() -> str

Detailed string representation.

__str__

__str__() -> str

String representation.

evaluate

evaluate(t: float) -> Quaternion

Evaluate quaternion at time t using proper SQUAD_C2 interpolation.

Args: t: Time value

Returns: Interpolated quaternion at time t

evaluate_acceleration

evaluate_acceleration(t: float) -> ndarray

Evaluate angular acceleration at time t.

Args: t: Time value

Returns: 3D angular acceleration vector in rad/s²

evaluate_velocity

evaluate_velocity(t: float) -> ndarray

Evaluate angular velocity at time t.

Args: t: Time value

Returns: 3D angular velocity vector in rad/s

get_extended_sequence_info

get_extended_sequence_info() -> dict

Get detailed information about the extended quaternion sequence for debugging.

Returns: Dictionary with extended sequence details

get_extended_waypoints

get_extended_waypoints() -> tuple[
    list[float], list[Quaternion]
]

Get all waypoint times and quaternions (including virtual waypoints).

get_time_range

get_time_range() -> tuple[float, float]

Get the time range of the trajectory (original waypoints only).

get_waypoints

get_waypoints() -> tuple[list[float], list[Quaternion]]

Get the original waypoint times and quaternions (without virtual waypoints).

Example:

from interpolatepy import SquadC2, Quaternion
import numpy as np

# Define rotation waypoints
times = [0, 1, 2, 3]
orientations = [
    Quaternion.identity(),
    Quaternion.from_angle_axis(np.pi/2, np.array([1, 0, 0])),
    Quaternion.from_angle_axis(np.pi, np.array([0, 1, 0])),
    Quaternion.from_angle_axis(np.pi/4, np.array([0, 0, 1]))
]

# Create C² continuous quaternion spline
squad = SquadC2(times, orientations)

# Evaluate smooth rotation trajectory
t = 1.5
orientation = squad.evaluate(t)
angular_velocity = squad.evaluate_velocity(t)
angular_acceleration = squad.evaluate_acceleration(t)

QuaternionSpline

interpolatepy.QuaternionSpline

QuaternionSpline(
    time_points: list[float],
    quaternions: list[Quaternion],
    interpolation_method: str = AUTO,
)

Quaternion spline interpolator for smooth trajectory planning.

Supports both SLERP and SQUAD interpolation methods with automatic method selection based on the number of control points.

Example usage: # Create quaternions q1 = Quaternion.identity() q2 = Quaternion.from_euler_angles(0.1, 0.2, 0.3) q3 = Quaternion.from_euler_angles(0.2, 0.4, 0.6) q4 = Quaternion.identity()

# Create spline with SLERP interpolation
spline_slerp = QuaternionSpline([0, 1, 2, 3], [q1, q2, q3, q4], Quaternion.SLERP)

# Create spline with SQUAD interpolation
spline_squad = QuaternionSpline([0, 1, 2, 3], [q1, q2, q3, q4], Quaternion.SQUAD)

# Interpolate at specific time
result, status = spline_slerp.interpolate_at_time(1.5)

# Change interpolation method
spline_slerp.set_interpolation_method(Quaternion.SQUAD)

# Force specific interpolation regardless of setting
slerp_result, _ = spline_squad.interpolate_slerp(1.5)
squad_result, _ = spline_slerp.interpolate_squad(1.5)

Args: time_points: List of time values (must be sorted) quaternions: List of quaternions at each time point interpolation_method: Interpolation method - "slerp", "squad", or "auto"

__len__

__len__() -> int

Return number of quaternion waypoints

__repr__

__repr__() -> str

Detailed string representation

__str__

__str__() -> str

String representation

get_interpolation_method

get_interpolation_method() -> str

Get the current interpolation method

get_quaternion_at_time

get_quaternion_at_time(t: float) -> Quaternion

Get quaternion at specific time, raising exception on error.

Returns: Interpolated quaternion Raises: ValueError if time is out of range or spline is empty

get_quaternions

get_quaternions() -> list[Quaternion]

Get all quaternions in the spline

get_time_points

get_time_points() -> list[float]

Get all time points in the spline

get_time_range

get_time_range() -> tuple[float, float]

Get the time range of the spline

interpolate_at_time

interpolate_at_time(t: float) -> tuple[Quaternion, int]

Quaternion interpolation at given time.

Returns: (interpolated_quaternion, status_code)

interpolate_slerp

interpolate_slerp(t: float) -> tuple[Quaternion, int]

Force SLERP interpolation at given time, regardless of current method setting.

Returns: (interpolated_quaternion, status_code)

interpolate_squad

interpolate_squad(t: float) -> tuple[Quaternion, int]

Force SQUAD interpolation at given time, regardless of current method setting.

Returns: (interpolated_quaternion, status_code)

interpolate_with_velocity

interpolate_with_velocity(
    t: float,
) -> tuple[Quaternion, ndarray, int]

Quaternion interpolation with angular velocity.

Returns: (interpolated_quaternion, angular_velocity, status_code)

is_empty

is_empty() -> bool

Check if this spline has no data

set_interpolation_method

set_interpolation_method(method: str) -> None

Set the interpolation method for this spline.

Args: method: "slerp", "squad", or "auto"

Path Planning

LinearPath

interpolatepy.LinearPath

LinearPath(pi: ndarray, pf: ndarray)

A linear path between two points in 3D space.

This class represents a straight-line trajectory from an initial point to a final point, providing methods to evaluate position, velocity, and acceleration along the path.

Parameters:

Name Type Description Default
pi array_like

Initial point coordinates [x, y, z].

required
pf array_like

Final point coordinates [x, y, z].

required

Attributes:

Name Type Description
pi ndarray

Initial point coordinates.

pf ndarray

Final point coordinates.

length float

Total length of the linear path.

tangent ndarray

Unit tangent vector (constant for linear path).

Examples:

>>> import numpy as np
>>> # Create a linear path from origin to point (1, 1, 1)
>>> pi = np.array([0, 0, 0])
>>> pf = np.array([1, 1, 1])
>>> path = LinearPath(pi, pf)
>>>
>>> # Evaluate position at half the path length
>>> midpoint = path.position(path.length / 2)
>>> print(midpoint)  # Should be [0.5, 0.5, 0.5]
>>>
>>> # Generate complete trajectory
>>> trajectory = path.all_traj(num_points=10)
>>> positions = trajectory['position']
>>> velocities = trajectory['velocity']

Parameters:

Name Type Description Default
pi array_like

Initial point coordinates [x, y, z].

required
pf array_like

Final point coordinates [x, y, z].

required

acceleration staticmethod

acceleration(_s: float | None = None) -> ndarray

Calculate second derivative with respect to arc length. For linear path, this is always zero.

Parameters:

Name Type Description Default
_s float

Arc length parameter (not used for linear path).

None

Returns:

Type Description
ndarray

Acceleration vector (always zero for linear path).

all_traj

all_traj(num_points: int = 100) -> dict[str, ndarray]

Generate a complete trajectory along the entire linear path.

Parameters:

Name Type Description Default
num_points int

Number of points to generate along the path. Default is 100.

100

Returns:

Type Description
dict[str, ndarray]

Dictionary containing arrays for position, velocity, and acceleration. Each array has shape (num_points, 3).

evaluate_at

evaluate_at(
    s_values: float | list[float] | ndarray,
) -> dict[str, ndarray]

Evaluate position, velocity, and acceleration at specific arc length values.

Parameters:

Name Type Description Default
s_values float or array_like

Arc length parameter(s).

required

Returns:

Type Description
dict[str, ndarray]

Dictionary containing arrays for position, velocity, and acceleration. Each array has shape (n, 3) where n is the number of s values.

position

position(s: float) -> ndarray

Calculate position at arc length s.

Parameters:

Name Type Description Default
s float or array_like

Arc length parameter(s).

required

Returns:

Type Description
ndarray

Position vector(s) at the specified arc length(s).

velocity

velocity(_s: float | None = None) -> ndarray

Calculate first derivative with respect to arc length. For linear path, this is constant and doesn't depend on s.

Parameters:

Name Type Description Default
_s float

Arc length parameter (not used for linear path).

None

Returns:

Type Description
ndarray

Velocity (tangent) vector.

Example:

from interpolatepy import LinearPath
import numpy as np

# Define line segment
pi = np.array([0, 0, 0])    # Start point
pf = np.array([5, 3, 2])    # End point

path = LinearPath(pi, pf)

# Evaluate along path (s = arc length parameter)
s = 2.0  # 2 units along path
position = path.position(s)
velocity = path.velocity(s)      # Unit tangent vector
acceleration = path.acceleration(s)  # Zero for straight line

# Evaluate multiple points
s_values = np.linspace(0, path.length, 50)
trajectory = path.evaluate_at(s_values)

CircularPath

interpolatepy.CircularPath

CircularPath(r: ndarray, d: ndarray, pi: ndarray)

A circular path in 3D space defined by an axis and a point on the circle.

This class represents a circular trajectory defined by an axis vector, a point on the axis, and a point on the circle. It provides methods to evaluate position, velocity, and acceleration along the circular arc.

Parameters:

Name Type Description Default
r array_like

Unit vector of circle axis.

required
d array_like

Position vector of a point on the circle axis.

required
pi array_like

Position vector of a point on the circle.

required

Attributes:

Name Type Description
r ndarray

Normalized axis vector of the circle.

d ndarray

Position vector of a point on the circle axis.

pi ndarray

Position vector of a point on the circle.

center ndarray

Center point of the circle.

radius float

Radius of the circle.

R ndarray

Rotation matrix from local to global coordinates.

Raises:

Type Description
ValueError

If the point pi lies on the circle axis.

Examples:

>>> import numpy as np
>>> # Create a circular path in the XY plane centered at origin
>>> r = np.array([0, 0, 1])     # Z-axis
>>> d = np.array([0, 0, 0])     # Origin on axis
>>> pi = np.array([1, 0, 0])    # Point on circle
>>> circle = CircularPath(r, d, pi)
>>>
>>> # Evaluate position at quarter circle
>>> quarter_arc = np.pi * circle.radius / 2
>>> pos = circle.position(quarter_arc)
>>>
>>> # Generate complete trajectory around the circle
>>> trajectory = circle.all_traj(num_points=100)
>>> positions = trajectory['position']

Parameters:

Name Type Description Default
r array_like

Unit vector of circle axis.

required
d array_like

Position vector of a point on the circle axis.

required
pi array_like

Position vector of a point on the circle.

required

acceleration

acceleration(s: float) -> ndarray

Calculate second derivative with respect to arc length.

Parameters:

Name Type Description Default
s float

Arc length parameter.

required

Returns:

Type Description
ndarray

Acceleration vector.

all_traj

all_traj(num_points: int = 100) -> dict[str, ndarray]

Generate a complete trajectory around the entire circular path.

Parameters:

Name Type Description Default
num_points int

Number of points to generate around the circle. Default is 100.

100

Returns:

Type Description
dict[str, ndarray]

Dictionary containing arrays for position, velocity, and acceleration. Each array has shape (num_points, 3).

evaluate_at

evaluate_at(
    s_values: float | list[float] | ndarray,
) -> dict[str, ndarray]

Evaluate position, velocity, and acceleration at specific arc length values.

Parameters:

Name Type Description Default
s_values float or array_like

Arc length parameter(s).

required

Returns:

Type Description
dict[str, ndarray]

Dictionary containing arrays for position, velocity, and acceleration. Each array has shape (n, 3) where n is the number of s values.

position

position(s: float | ndarray) -> ndarray

Calculate position at arc length s.

Parameters:

Name Type Description Default
s float or array_like

Arc length parameter(s).

required

Returns:

Type Description
ndarray

Position vector(s) at the specified arc length(s).

velocity

velocity(s: float) -> ndarray

Calculate first derivative with respect to arc length.

Parameters:

Name Type Description Default
s float

Arc length parameter.

required

Returns:

Type Description
ndarray

Velocity (tangent) vector.

Example:

from interpolatepy import CircularPath
import numpy as np

# Define circular arc
r = np.array([0, 0, 1])     # Axis direction (Z-axis)
d = np.array([0, 0, 0])     # Point on axis (origin)
pi = np.array([1, 0, 0])    # Point on circle

path = CircularPath(r, d, pi)

# Evaluate along arc
s = np.pi  # π units of arc length (180°)
position = path.position(s)
velocity = path.velocity(s)      # Tangent to circle
acceleration = path.acceleration(s)  # Centripetal acceleration

# Evaluate complete circle
s_values = np.linspace(0, 2*np.pi*path.radius, 100)
trajectory = path.evaluate_at(s_values)

Frenet Frame Computation

interpolatepy.compute_trajectory_frames

compute_trajectory_frames(
    position_func: Callable[
        [float], tuple[ndarray, ndarray, ndarray]
    ],
    u_values: ndarray,
    tool_orientation: float
    | tuple[float, float, float]
    | None = None,
) -> tuple[ndarray, ndarray]

Compute Frenet frames along a parametric curve and optionally apply tool orientation.

Parameters:

Name Type Description Default
position_func callable

A function that takes a parameter u and returns: - position p(u) - first derivative dp/du - second derivative d2p/du2

required
u_values ndarray

Parameter values at which to compute the frames.

required
tool_orientation float or tuple

If None: Returns the Frenet frames without modification. If float: Angle in radians to rotate around the binormal axis (legacy mode). If tuple: (roll, pitch, yaw) angles in radians representing RPY rotations.

None

Returns:

Name Type Description
points ndarray

Points on the curve with shape (len(u_values), 3).

frames ndarray

Frames at each point [et, en, eb] with shape (len(u_values), 3, 3), either Frenet frames or tool frames.

Example:

from interpolatepy import compute_trajectory_frames
import numpy as np

def helix_path(u):
    """Parametric helix with derivatives."""
    r, pitch = 2.0, 0.5

    position = np.array([
        r * np.cos(u),
        r * np.sin(u),
        pitch * u
    ])

    first_derivative = np.array([
        -r * np.sin(u),
        r * np.cos(u),
        pitch
    ])

    second_derivative = np.array([
        -r * np.cos(u),
        -r * np.sin(u),
        0
    ])

    return position, first_derivative, second_derivative

# Compute Frenet frames
u_values = np.linspace(0, 4*np.pi, 100)
points, frames = compute_trajectory_frames(
    helix_path, 
    u_values,
    tool_orientation=(0.1, 0.2, 0.0)  # Additional tool rotation
)

# frames[i] contains [tangent, normal, binormal] vectors at points[i]

Utilities

Linear Interpolation

interpolatepy.linear_traj

linear_traj(
    p0: float | list[float] | ndarray,
    p1: float | list[float] | ndarray,
    t0: float,
    t1: float,
    time_array: ndarray,
) -> tuple[ndarray, ndarray, ndarray]

Generate points along a linear trajectory using NumPy vectorization.

This function computes positions, velocities, and accelerations for points along a linear trajectory between starting position p0 and ending position p1. The trajectory is calculated for each time point in time_array.

Parameters:

Name Type Description Default
p0 float or list[float] or ndarray

Starting position. Can be a scalar for 1D motion or an array/list for multi-dimensional motion.

required
p1 float or list[float] or ndarray

Ending position. Must have the same dimensionality as p0.

required
t0 float

Start time of the trajectory.

required
t1 float

End time of the trajectory.

required
time_array ndarray

Array of time points at which to calculate the trajectory.

required

Returns:

Name Type Description
positions ndarray

Array of positions at each time point. For scalar inputs, shape is (len(time_array),). For vector inputs, shape is (len(time_array), dim) where dim is the dimension of p0/p1.

velocities ndarray

Constant velocity at each time point, with the same shape as positions.

accelerations ndarray

Zero acceleration at each time point, with the same shape as positions.

Examples:

Scalar positions (1D motion):

>>> import numpy as np
>>> times = np.linspace(0, 1, 5)
>>> pos, vel, acc = linear_traj(0, 1, 0, 1, times)
>>> print(pos)
[0.   0.25 0.5  0.75 1.  ]
>>> print(vel)
[1. 1. 1. 1. 1.]
>>> print(acc)
[0. 0. 0. 0. 0.]

Vector positions (2D motion):

>>> import numpy as np
>>> times = np.linspace(0, 2, 3)
>>> p0 = [0, 0]  # Start at origin
>>> p1 = [4, 6]  # End at point (4, 6)
>>> pos, vel, acc = linear_traj(p0, p1, 0, 2, times)
>>> print(pos)
[[0. 0.]
 [2. 3.]
 [4. 6.]]
>>> print(vel)
[[2. 3.]
 [2. 3.]
 [2. 3.]]
Notes
  • This function implements linear interpolation with constant velocity and zero acceleration.
  • For vector inputs (multi-dimensional motion), proper broadcasting is applied to ensure correct calculation across all dimensions.
  • The function handles both scalar and vector inputs automatically:
    • For scalar inputs: outputs have shape (len(time_array),)
    • For vector inputs: outputs have shape (len(time_array), dim)
  • Time points outside the range [t0, t1] will still produce valid positions by extrapolating the linear trajectory.
  • The velocity is always constant and equal to (p1 - p0) / (t1 - t0).
  • The acceleration is always zero.

Example:

from interpolatepy import linear_traj
import numpy as np

# Linear interpolation between points
p0 = [0, 0, 0]
p1 = [5, 3, 2]
t0, t1 = 0.0, 2.0

time_array = np.linspace(t0, t1, 50)
positions, velocities, accelerations = linear_traj(p0, p1, t0, t1, time_array)

# positions[i] = interpolated position at time_array[i]
# velocities[i] = constant velocity vector
# accelerations[i] = zero vector (constant velocity)

Tridiagonal Solver

interpolatepy.solve_tridiagonal

solve_tridiagonal(
    lower_diagonal: ndarray,
    main_diagonal: ndarray,
    upper_diagonal: ndarray,
    right_hand_side: ndarray,
) -> ndarray

Solve a tridiagonal system using the Thomas algorithm.

This function solves the equation Ax = b where A is a tridiagonal matrix. The system is solved efficiently using the Thomas algorithm (also known as the tridiagonal matrix algorithm).

Parameters:

Name Type Description Default
lower_diagonal ndarray

Lower diagonal elements (first element is not used). Must have the same length as main_diagonal.

required
main_diagonal ndarray

Main diagonal elements.

required
upper_diagonal ndarray

Upper diagonal elements (last element is not used). Must have the same length as main_diagonal.

required
right_hand_side ndarray

Right-hand side vector of the equation.

required

Returns:

Type Description
ndarray

Solution vector x.

Raises:

Type Description
ValueError

If a pivot is zero during forward elimination.

Examples:

>>> import numpy as np
>>> a = np.array([0, 1, 2, 3])  # Lower diagonal (a[0] is not used)
>>> b = np.array([2, 3, 4, 5])  # Main diagonal
>>> c = np.array([1, 2, 3, 0])  # Upper diagonal (c[-1] is not used)
>>> d = np.array([1, 2, 3, 4])  # Right hand side
>>> x = solve_tridiagonal(a, b, c, d)
>>> print(x)
Notes

The Thomas algorithm is a specialized form of Gaussian elimination for tridiagonal systems. It is much more efficient than general Gaussian elimination, with a time complexity of O(n) instead of O(n³).

The algorithm consists of two phases: 1. Forward elimination to transform the matrix into an upper triangular form 2. Back substitution to find the solution

For a system where the matrix A is: [b₀ c₀ 0 0 0] [a₁ b₁ c₁ 0 0] [0 a₂ b₂ c₂ 0] [0 0 a₃ b₃ c₃] [0 0 0 a₄ b₄]

References

.. [1] Thomas, L.H. (1949). "Elliptic Problems in Linear Differential Equations over a Network". Watson Sci. Comput. Lab Report.

Example:

from interpolatepy import solve_tridiagonal
import numpy as np

# Solve tridiagonal system Ax = b
# where A has diagonals a (lower), b (main), c (upper)

n = 5
a = np.array([0, 1, 1, 1, 1])      # Lower diagonal (first element unused)
b = np.array([2, 2, 2, 2, 2])      # Main diagonal
c = np.array([1, 1, 1, 1, 0])      # Upper diagonal (last element unused)
d = np.array([1, 2, 3, 4, 5])      # Right-hand side

# Solve system
x = solve_tridiagonal(a, b, c, d)
print(f"Solution: {x}")

Data Structures

Configuration Classes

The following dataclasses are used for algorithm configuration:

SplineConfig

interpolatepy.SplineConfig dataclass

SplineConfig(
    weights: list[float] | ndarray | None = None,
    v0: float = 0.0,
    vn: float = 0.0,
    max_iterations: int = 50,
    debug: bool = False,
)

Configuration parameters for smoothing spline calculation.

SplineParameters

interpolatepy.SplineParameters dataclass

SplineParameters(
    v0: float = 0.0,
    vn: float = 0.0,
    a0: float | None = None,
    an: float | None = None,
    debug: bool = False,
)

Container for spline initialization parameters.

Parameters:

Name Type Description Default
v0 float

Initial velocity constraint at the start of the spline.

0.0
vn float

Final velocity constraint at the end of the spline.

0.0
a0 float

Initial acceleration constraint at the start of the spline. If provided, the first segment will use a quintic polynomial.

None
an float

Final acceleration constraint at the end of the spline. If provided, the last segment will use a quintic polynomial.

None
debug bool

If True, prints detailed information about the spline calculation.

False

BSplineParams

interpolatepy.BSplineParams dataclass

BSplineParams(
    mu: float = 0.5,
    weights: list | ndarray | None = None,
    v0: list | ndarray | None = None,
    vn: list | ndarray | None = None,
    method: str = "chord_length",
    enforce_endpoints: bool = False,
    auto_derivatives: bool = False,
)

Parameters for initializing a SmoothingCubicBSpline.

Attributes:

Name Type Description
mu float, default=0.5

Smoothing parameter between 0 and 1, where higher values give more importance to fitting the data points exactly.

weights array_like or None, default=None

Weights for each data point.

v0 array_like or None, default=None

Tangent vector at the start point.

vn array_like or None, default=None

Tangent vector at the end point.

method str, default="chord_length"

Method for parameter calculation ('equally_spaced', 'chord_length', or 'centripetal').

enforce_endpoints bool, default=False

Whether to enforce interpolation at the endpoints.

auto_derivatives bool, default=False

Whether to automatically calculate derivatives at endpoints.

Performance Notes

Evaluation Complexity

Algorithm Setup Single Eval Vectorized Eval Memory
CubicSpline O(n) O(log n) O(k log n) O(n)
DoubleSTrajectory O(1) O(1) O(k) O(1)
BSplineInterpolator O(n²) O(p) O(kp) O(n)
SquadC2 O(n) O(1) O(k) O(n)
TrapezoidalTrajectory O(1) O(1) O(k) O(1)

Where: - n = number of waypoints - k = number of evaluation points
- p = B-spline degree

Memory Usage

  • Splines: Store coefficient arrays (4n floats for cubic splines)
  • Motion Profiles: Store only parameters (typically <10 floats)
  • Quaternions: Store waypoints and intermediate calculations (8n floats)

Vectorization

All algorithms support vectorized evaluation:

# Efficient vectorized evaluation
t_array = np.linspace(0, 10, 1000)
result = algorithm.evaluate(t_array)  # Single call

# Less efficient scalar evaluation
result = [algorithm.evaluate(t) for t in t_array]  # 1000 calls

Error Handling

Common Exceptions

ValueError

  • Invalid input dimensions
  • Non-monotonic time sequences
  • Evaluation outside trajectory domain

RuntimeError

  • Numerical instability in solver
  • Failed convergence in iterative algorithms

TypeError

  • Incorrect input types
  • Missing required parameters

Safe Evaluation Patterns

# Bounds checking
try:
    result = spline.evaluate(t)
except ValueError as e:
    # Handle out-of-bounds evaluation
    if t < spline.t_points[0]:
        result = spline.evaluate(spline.t_points[0])
    elif t > spline.t_points[-1]:
        result = spline.evaluate(spline.t_points[-1])
    else:
        raise e

# Input validation
def validate_waypoints(t_points, q_points):
    if len(t_points) != len(q_points):
        raise ValueError("Mismatched array lengths")
    if not all(t_points[i] < t_points[i+1] for i in range(len(t_points)-1)):
        raise ValueError("Time points must be strictly increasing")

Version Information

Current version: 2.0.0

Access version information:

import interpolatepy
print(interpolatepy.__version__)

For the complete changelog, see Changelog.