Skip to content

Commit b420b8f

Browse files
author
Giorgio Medico
committed
doc
1 parent adf8e0f commit b420b8f

16 files changed

Lines changed: 1419 additions & 227 deletions

ALGORITHMS.md

Lines changed: 72 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,29 @@ for t ∈ [tₖ, tₖ₊₁]. The spline satisfies:
7777
- **Interpolation**: qₖ(tᵢ) = qᵢ for all waypoints
7878
- **Boundary conditions**: Configurable velocity/acceleration at endpoints
7979

80-
The algorithm solves a tridiagonal linear system for accelerations ωᵢ = q̈(tᵢ):
81-
82-
```
83-
Aω = c
84-
```
85-
86-
where A is tridiagonal with entries based on time intervals Tᵢ = tᵢ₊₁ - tᵢ.
80+
**Mathematical Derivation**:
81+
82+
1. **Hermite Form**: Express each segment using accelerations ωᵢ = q̈(tᵢ):
83+
```
84+
qₖ(t) = Aₖ + Bₖ(t-tₖ) + (Cₖ/6)(t-tₖ)³ + (Dₖ/6)(t-tₖ)²
85+
```
86+
where Cₖ = ωₖ, Dₖ = ωₖ₊₁ - ωₖ
87+
88+
2. **Continuity Constraints**: At interior points tᵢ, enforce:
89+
- Position: qᵢ₋₁(tᵢ) = qᵢ₊₁(tᵢ) = qᵢ
90+
- Velocity: q̇ᵢ₋₁(tᵢ) = q̇ᵢ₊₁(tᵢ)
91+
92+
3. **Tridiagonal System**: These constraints yield the linear system Aω = c where:
93+
```
94+
Aᵢᵢ = (Tᵢ₋₁ + Tᵢ)/3, Aᵢ,ᵢ₋₁ = Tᵢ₋₁/6, Aᵢ,ᵢ₊₁ = Tᵢ/6
95+
cᵢ = (qᵢ₊₁ - qᵢ)/Tᵢ - (qᵢ - qᵢ₋₁)/Tᵢ₋₁
96+
```
97+
with Tᵢ = tᵢ₊₁ - tᵢ being the time intervals.
98+
99+
4. **Boundary Conditions**:
100+
- **Natural**: ω₀ = ωₙ = 0 (zero curvature at endpoints)
101+
- **Clamped**: Specified derivatives v₀, vₙ modify first/last equations
102+
- **Not-a-knot**: Force C³ continuity at second/penultimate points
87103

88104
#### API Reference
89105

@@ -224,27 +240,31 @@ This provides an objective way to balance smoothness and fidelity without manual
224240

225241
```python
226242
def smoothing_spline_with_tolerance(
227-
t_points: list[float], q_points: list[float],
228-
tolerance: float, max_iterations: int = 50,
229-
mu_min: float = 1e-10, mu_max: float = 1e6
230-
) -> CubicSmoothingSpline
243+
t_points: np.ndarray,
244+
q_points: np.ndarray,
245+
tolerance: float,
246+
config: SplineConfig,
247+
) -> tuple[CubicSmoothingSpline, float, float, int]
231248
```
232249

233250
**Parameters**:
251+
- `t_points`: Time points as numpy array
252+
- `q_points`: Position points as numpy array
234253
- `tolerance`: Maximum allowed deviation from waypoints
235-
- `max_iterations`: Maximum binary search iterations
236-
- `mu_min`, `mu_max`: Search bounds for smoothing parameter
254+
- `config`: SplineConfig with search parameters
237255

238256
#### Example
239257

240258
```python
241-
from interpolatepy import smoothing_spline_with_tolerance
259+
from interpolatepy import smoothing_spline_with_tolerance, SplineConfig
260+
import numpy as np
242261

243262
# Automatically find optimal smoothing
244-
spline = smoothing_spline_with_tolerance(
245-
t_points, q_noisy, tolerance=0.01
263+
config = SplineConfig(max_iterations=50)
264+
spline, mu, error, iterations = smoothing_spline_with_tolerance(
265+
np.array(t_points), np.array(q_noisy), tolerance=0.01, config=config
246266
)
247-
print(f"Optimal μ = {spline.mu}")
267+
print(f"Optimal μ = {mu:.6f}, error = {error:.6f}")
248268
```
249269

250270
### CubicSplineWithAcceleration1
@@ -403,7 +423,7 @@ Motion profiles are classical trajectory planning methods optimized for robotics
403423

404424
#### Theory
405425

406-
Implements double-S (jerk-bounded) trajectories that limit the rate of acceleration change. The velocity profile follows an S-curve shape with 7 distinct phases:
426+
Implements double-S (jerk-bounded) trajectories that limit the rate of acceleration change. The velocity profile follows an S-curve shape with up to 7 distinct phases:
407427

408428
1. **Jerk-up phase**: q⃛ = +jₘₐₓ (acceleration increases)
409429
2. **Constant acceleration**: q⃛ = 0, q̈ = aₘₐₓ
@@ -413,6 +433,27 @@ Implements double-S (jerk-bounded) trajectories that limit the rate of accelerat
413433
6. **Constant acceleration**: q⃛ = 0, q̈ = -aₘₐₓ
414434
7. **Jerk-up phase**: q⃛ = +jₘₐₓ (deceleration decreases to 0)
415435

436+
**Mathematical Model**:
437+
438+
The trajectory is computed by solving the time-optimal control problem:
439+
```
440+
minimize T
441+
subject to: |q̇(t)| ≤ vₘₐₓ, |q̈(t)| ≤ aₘₐₓ, |q⃛(t)| ≤ jₘₐₓ
442+
q(0) = q₀, q(T) = q₁, q̇(0) = v₀, q̇(T) = v₁
443+
```
444+
445+
**Phase Duration Calculation**:
446+
1. **Acceleration phases**: T₁ = min(aₘₐₓ/jₘₐₓ, √((v₁-v₀)/(2jₘₐₓ)))
447+
2. **Constant acceleration**: T₂ determined by velocity limit constraints
448+
3. **Velocity phase**: T₄ calculated from displacement requirements
449+
450+
**Kinematic Equations**: For each phase i with jerk jᵢ, acceleration a₀ᵢ, velocity v₀ᵢ:
451+
```
452+
q̈ᵢ(t) = a₀ᵢ + jᵢt
453+
q̇ᵢ(t) = v₀ᵢ + a₀ᵢt + ½jᵢt²
454+
qᵢ(t) = q₀ᵢ + v₀ᵢt + ½a₀ᵢt² + ⅙jᵢt³
455+
```
456+
416457
**Constraints**:
417458
- **Jerk limit**: |q⃛(t)| ≤ jₘₐₓ
418459
- **Acceleration limit**: |q̈(t)| ≤ aₘₐₓ
@@ -424,18 +465,16 @@ Implements double-S (jerk-bounded) trajectories that limit the rate of accelerat
424465
```python
425466
@dataclass
426467
class StateParams:
427-
q0: float = 0.0 # Initial position
428-
q1: float = 1.0 # Final position
429-
v0: float = 0.0 # Initial velocity
430-
v1: float = 0.0 # Final velocity
431-
a0: float = 0.0 # Initial acceleration
432-
a1: float = 0.0 # Final acceleration
468+
q_0: float = 0.0 # Initial position
469+
q_1: float = 1.0 # Final position
470+
v_0: float = 0.0 # Initial velocity
471+
v_1: float = 0.0 # Final velocity
433472

434473
@dataclass
435474
class TrajectoryBounds:
436-
v_max: float = 1.0 # Maximum velocity
437-
a_max: float = 1.0 # Maximum acceleration
438-
j_max: float = 1.0 # Maximum jerk
475+
v_bound: float = 1.0 # Velocity bound
476+
a_bound: float = 1.0 # Acceleration bound
477+
j_bound: float = 1.0 # Jerk bound
439478

440479
class DoubleSTrajectory:
441480
def __init__(self, state_params: StateParams, bounds: TrajectoryBounds)
@@ -458,8 +497,8 @@ def plot(self) -> None
458497
from interpolatepy import DoubleSTrajectory, StateParams, TrajectoryBounds
459498

460499
# Define trajectory parameters
461-
state = StateParams(q0=0, q1=10, v0=0, v1=0)
462-
bounds = TrajectoryBounds(v_max=2.0, a_max=1.0, j_max=0.5)
500+
state = StateParams(q_0=0, q_1=10, v_0=0, v_1=0)
501+
bounds = TrajectoryBounds(v_bound=2.0, a_bound=1.0, j_bound=0.5)
463502

464503
# Create trajectory
465504
traj = DoubleSTrajectory(state, bounds)
@@ -746,6 +785,8 @@ class Quaternion:
746785
**File**: `log_quat.py`
747786
**Class**: `LogQuaternionInterpolation`
748787

788+
> **Note**: This class is available in the `log_quat.py` module but not exported in the main `__init__.py`. Import directly: `from interpolatepy.log_quat import LogQuaternionInterpolation`
789+
749790
#### Theory
750791

751792
Implements the Logarithmic Quaternion Interpolation (LQI) method from Parker et al. (2023). The algorithm:
@@ -786,6 +827,8 @@ class LogQuaternionInterpolation:
786827
**File**: `log_quat.py`
787828
**Class**: `ModifiedLogQuaternionInterpolation`
788829

830+
> **Note**: This class is available in the `log_quat.py` module but not exported in the main `__init__.py`. Import directly: `from interpolatepy.log_quat import ModifiedLogQuaternionInterpolation`
831+
789832
#### Theory
790833

791834
Enhanced version of LQI that decouples angle and axis interpolation:

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ state = StateParams(q_0=0.0, q_1=10.0, v_0=0.0, v_1=0.0)
6060
bounds = TrajectoryBounds(v_bound=5.0, a_bound=10.0, j_bound=30.0)
6161
trajectory = DoubleSTrajectory(state, bounds)
6262

63-
print(f"Duration: {trajectory.total_time:.2f}s")
63+
print(f"Duration: {trajectory.get_duration():.2f}s")
6464
trajectory.plot()
6565

6666
plt.show()
@@ -170,10 +170,10 @@ state = StateParams(q_0=0.0, q_1=50.0, v_0=0.0, v_1=0.0)
170170
bounds = TrajectoryBounds(v_bound=10.0, a_bound=5.0, j_bound=2.0)
171171

172172
trajectory = DoubleSTrajectory(state, bounds)
173-
print(f"Duration: {trajectory.total_time:.2f}s")
173+
print(f"Duration: {trajectory.get_duration():.2f}s")
174174

175175
# Evaluate trajectory
176-
t_eval = np.linspace(0, trajectory.total_time, 1000)
176+
t_eval = np.linspace(0, trajectory.get_duration(), 1000)
177177
positions = [trajectory.evaluate(t) for t in t_eval]
178178
velocities = [trajectory.evaluate_velocity(t) for t in t_eval]
179179

@@ -281,6 +281,7 @@ This library implements algorithms from:
281281
**Quaternion Interpolation:**
282282
- Parker et al. (2023). "Logarithm-Based Methods for Interpolating Quaternion Time Series"
283283
- Wittmann et al. (2023). "Spherical Cubic Blends: C²-Continuous Quaternion Interpolation"
284+
- Dam, E. B., Koch, M., & Lillholm, M. (1998). "Quaternions, Interpolation and Animation"
284285

285286
</details>
286287

docs/algorithms.md

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -345,10 +345,10 @@ The algorithm solves for total time considering all constraints and boundary con
345345
# Generate trajectory
346346
trajectory = DoubleSTrajectory(state, bounds)
347347

348-
print(f"Duration: {trajectory.total_time:.2f}s")
348+
print(f"Duration: {trajectory.get_duration():.2f}s")
349349

350350
# Evaluate at midpoint
351-
t_mid = trajectory.total_time / 2
351+
t_mid = trajectory.get_duration() / 2
352352
pos = trajectory.evaluate(t_mid)
353353
vel = trajectory.evaluate_velocity(t_mid)
354354
acc = trajectory.evaluate_acceleration(t_mid)
@@ -808,18 +808,11 @@ This library implements algorithms from the following research:
808808
### Quaternion Interpolation
809809
- Parker, J. K., et al. (2023). "Logarithm-Based Methods for Interpolating Quaternion Time Series." *IEEE Transactions on Robotics*.
810810
- Wittmann, D., et al. (2023). "Spherical Cubic Blends: C²-Continuous Quaternion Interpolation." *IEEE International Conference on Robotics and Automation (ICRA)*.
811-
812-
### Spline Theory
813-
- de Boor, C. (2001). *A Practical Guide to Splines*. Springer.
814-
- Schumaker, L. L. (2007). *Spline Functions: Basic Theory*. Cambridge University Press.
815-
816-
### Numerical Methods
817-
- Press, W. H., et al. (2007). *Numerical Recipes: The Art of Scientific Computing*. Cambridge University Press.
818-
- Golub, G. H., & Van Loan, C. F. (2013). *Matrix Computations*. Johns Hopkins University Press.
811+
- Dam, E. B., Koch, M., & Lillholm, M. (1998). "Quaternions, Interpolation and Animation." Technical Report DIKU-TR-98/5, Department of Computer Science, University of Copenhagen.
819812

820813
---
821814

822815
For practical examples and usage patterns, see:
823816
- **[API Reference](api-reference.md)**: Complete function documentation
824817
- **[Examples](examples.md)**: Real-world applications
825-
- **[Tutorials](tutorials/spline-interpolation.md)**: Step-by-step guides
818+
- **[Tutorials](tutorials/spline-interpolation.md)**: Step-by-step guides

0 commit comments

Comments
 (0)