InterpolatePy 2.0.0__tar.gz → 2.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- interpolatepy-2.0.1/.github/FUNDING.yml +15 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/.github/workflows/docs.yml +1 -1
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/.github/workflows/pre-commit.yml +1 -1
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/.github/workflows/publish.yml +1 -1
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/.github/workflows/test.yml +2 -2
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/.pre-commit-config.yaml +2 -2
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/ALGORITHMS.md +4 -4
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/InterpolatePy.egg-info/PKG-INFO +53 -23
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/InterpolatePy.egg-info/SOURCES.txt +1 -0
- interpolatepy-2.0.1/InterpolatePy.egg-info/requires.txt +21 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/PKG-INFO +53 -23
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/README.md +41 -12
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/docs/algorithms.md +5 -4
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/docs/api-reference.md +14 -12
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/docs/examples.md +39 -17
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/docs/index.md +16 -1
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/docs/quickstart.md +53 -43
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/docs/troubleshooting.md +20 -10
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/docs/tutorials/motion-profiles.md +56 -11
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/docs/tutorials/spline-interpolation.md +31 -16
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/docs/user-guide.md +11 -4
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/interpolatepy/b_spline_approx.py +8 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/interpolatepy/b_spline_interpolate.py +8 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/interpolatepy/b_spline_smooth.py +8 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/interpolatepy/lin_poly_parabolic.py +10 -1
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/interpolatepy/linear.py +8 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/interpolatepy/polynomials.py +204 -45
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/interpolatepy/simple_paths.py +203 -57
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/interpolatepy/trapezoidal.py +103 -35
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/interpolatepy/tridiagonal_inv.py +8 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/interpolatepy/version.py +1 -1
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/pyproject.toml +14 -13
- interpolatepy-2.0.0/InterpolatePy.egg-info/requires.txt +0 -21
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/.editorconfig +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/.gitattributes +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/.gitignore +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/InterpolatePy.egg-info/dependency_links.txt +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/InterpolatePy.egg-info/top_level.txt +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/LICENSE +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/codecov.yml +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/docs/assets/extra.css +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/docs/assets/extra.js +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/docs/changelog.md +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/docs/contributing.md +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/docs/installation.md +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/examples/b_spline_approx_ex.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/examples/b_spline_cubic_ex.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/examples/b_spline_ex.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/examples/b_spline_interpolate_ex.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/examples/b_spline_smooth_ex.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/examples/c_s_smoot_search_ex.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/examples/c_s_smoothing_ex.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/examples/c_s_with_acc1_ex.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/examples/c_s_with_acc2_ex.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/examples/cubic_spline_ex.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/examples/double_s_ex.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/examples/frenet_frame_ex.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/examples/lin_poly_parabolic_ex.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/examples/linear_ex.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/examples/log_quat_ex.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/examples/log_quat_new_ex.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/examples/main.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/examples/polynomials_ex.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/examples/quat_visualization_ex.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/examples/simple_paths_ex.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/examples/squad_c2_ex.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/examples/trapezoidal_ex.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/interpolatepy/__init__.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/interpolatepy/b_spline.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/interpolatepy/b_spline_cubic.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/interpolatepy/c_s_smoot_search.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/interpolatepy/c_s_smoothing.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/interpolatepy/c_s_with_acc1.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/interpolatepy/c_s_with_acc2.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/interpolatepy/cubic_spline.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/interpolatepy/double_s.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/interpolatepy/frenet_frame.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/interpolatepy/log_quat.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/interpolatepy/quat_core.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/interpolatepy/quat_spline.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/interpolatepy/quat_visualization.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/interpolatepy/squad_c2.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/mkdocs.yml +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/requirements-dev.txt +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/requirements.txt +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/setup.cfg +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/tests/__init__.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/tests/inv_test.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/tests/test_b_spline.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/tests/test_b_spline_variants.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/tests/test_cubic_spline.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/tests/test_lin_poly_parabolic.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/tests/test_linear.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/tests/test_log_quat.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/tests/test_motion_profiles.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/tests/test_path_planning.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/tests/test_polynomials.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/tests/test_quat_interp.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/tests/test_quat_visualization.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/tests/test_smoothing.py +0 -0
- {interpolatepy-2.0.0 → interpolatepy-2.0.1}/tests/test_squad_c2.py +0 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# These are supported funding model platforms
|
|
2
|
+
|
|
3
|
+
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
|
4
|
+
patreon: # Replace with a single Patreon username
|
|
5
|
+
open_collective: # Replace with a single Open Collective username
|
|
6
|
+
ko_fi: giorgio23
|
|
7
|
+
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
|
8
|
+
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
|
9
|
+
liberapay: # Replace with a single Liberapay username
|
|
10
|
+
issuehunt: # Replace with a single IssueHunt username
|
|
11
|
+
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
|
12
|
+
polar: # Replace with a single Polar username
|
|
13
|
+
buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
|
|
14
|
+
thanks_dev: # Replace with a single thanks.dev username
|
|
15
|
+
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
|
@@ -12,7 +12,7 @@ jobs:
|
|
|
12
12
|
runs-on: ubuntu-latest
|
|
13
13
|
strategy:
|
|
14
14
|
matrix:
|
|
15
|
-
python-version: ['3.
|
|
15
|
+
python-version: ['3.11', '3.12', '3.13']
|
|
16
16
|
steps:
|
|
17
17
|
- uses: actions/checkout@v4
|
|
18
18
|
- name: Set up Python ${{ matrix.python-version }}
|
|
@@ -39,7 +39,7 @@ jobs:
|
|
|
39
39
|
runs-on: macos-latest
|
|
40
40
|
strategy:
|
|
41
41
|
matrix:
|
|
42
|
-
python-version: ['3.
|
|
42
|
+
python-version: ['3.11', '3.12', '3.13']
|
|
43
43
|
steps:
|
|
44
44
|
- uses: actions/checkout@v4
|
|
45
45
|
- name: Set up Python ${{ matrix.python-version }}
|
|
@@ -2,7 +2,7 @@ default_language_version:
|
|
|
2
2
|
python: python3
|
|
3
3
|
repos:
|
|
4
4
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
5
|
-
rev:
|
|
5
|
+
rev: v6.0.0
|
|
6
6
|
hooks:
|
|
7
7
|
- id: check-ast
|
|
8
8
|
- id: check-builtin-literals
|
|
@@ -12,7 +12,7 @@ repos:
|
|
|
12
12
|
- id: check-toml
|
|
13
13
|
|
|
14
14
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
15
|
-
rev: 'v0.12.
|
|
15
|
+
rev: 'v0.12.8'
|
|
16
16
|
hooks:
|
|
17
17
|
- id: ruff
|
|
18
18
|
types_or: [python, pyi, jupyter]
|
|
@@ -690,7 +690,7 @@ from interpolatepy import PolynomialTrajectory, BoundaryCondition, TimeInterval
|
|
|
690
690
|
# Define boundary conditions
|
|
691
691
|
initial = BoundaryCondition(position=0, velocity=0, acceleration=0)
|
|
692
692
|
final = BoundaryCondition(position=1, velocity=0, acceleration=0)
|
|
693
|
-
interval = TimeInterval(
|
|
693
|
+
interval = TimeInterval(start=0, end=2)
|
|
694
694
|
|
|
695
695
|
# Generate quintic trajectory
|
|
696
696
|
traj_func = PolynomialTrajectory.order_5_trajectory(initial, final, interval)
|
|
@@ -910,9 +910,9 @@ import numpy as np
|
|
|
910
910
|
times = [0, 1, 2, 3]
|
|
911
911
|
quats = [
|
|
912
912
|
Quaternion.identity(),
|
|
913
|
-
Quaternion.from_angle_axis(np.pi/2, [1, 0, 0]), # 90° about X
|
|
914
|
-
Quaternion.from_angle_axis(np.pi, [0, 1, 0]), # 180° about Y
|
|
915
|
-
Quaternion.from_angle_axis(np.pi/4, [0, 0, 1]) # 45° about Z
|
|
913
|
+
Quaternion.from_angle_axis(np.pi/2, np.array([1, 0, 0])), # 90° about X
|
|
914
|
+
Quaternion.from_angle_axis(np.pi, np.array([0, 1, 0])), # 180° about Y
|
|
915
|
+
Quaternion.from_angle_axis(np.pi/4, np.array([0, 0, 1])) # 45° about Z
|
|
916
916
|
]
|
|
917
917
|
|
|
918
918
|
# Create C² continuous interpolator
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: InterpolatePy
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.1
|
|
4
4
|
Summary: A comprehensive Python library for generating smooth trajectories and curves with precise control over position, velocity, acceleration, and jerk profiles
|
|
5
5
|
Author-email: Giorgio Medico <giorgio.medico11@gmail.com>
|
|
6
6
|
Maintainer-email: Giorgio Medico <giorgio.medico11@gmail.com>
|
|
@@ -20,6 +20,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.10
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.11
|
|
22
22
|
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
24
|
Classifier: Operating System :: POSIX :: Linux
|
|
24
25
|
Classifier: Operating System :: POSIX
|
|
25
26
|
Classifier: Operating System :: Unix
|
|
@@ -30,23 +31,23 @@ Classifier: Topic :: Scientific/Engineering :: Physics
|
|
|
30
31
|
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
31
32
|
Classifier: Topic :: Software Development :: Libraries
|
|
32
33
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
33
|
-
Requires-Python: >=3.
|
|
34
|
+
Requires-Python: >=3.11
|
|
34
35
|
Description-Content-Type: text/markdown
|
|
35
36
|
License-File: LICENSE
|
|
36
|
-
Requires-Dist: numpy>=2.
|
|
37
|
-
Requires-Dist: matplotlib>=3.10.
|
|
38
|
-
Requires-Dist: scipy>=1.
|
|
37
|
+
Requires-Dist: numpy>=2.3.0
|
|
38
|
+
Requires-Dist: matplotlib>=3.10.5
|
|
39
|
+
Requires-Dist: scipy>=1.16.0
|
|
39
40
|
Provides-Extra: test
|
|
40
|
-
Requires-Dist: pytest>=
|
|
41
|
+
Requires-Dist: pytest>=8.4.0; extra == "test"
|
|
41
42
|
Requires-Dist: pytest-cov>=4.1.0; extra == "test"
|
|
42
43
|
Requires-Dist: codecov>=2.1.13; extra == "test"
|
|
43
44
|
Requires-Dist: pytest-benchmark>=4.0.0; extra == "test"
|
|
44
|
-
Requires-Dist: pre-commit>=4.
|
|
45
|
+
Requires-Dist: pre-commit>=4.2.0; extra == "test"
|
|
45
46
|
Provides-Extra: dev
|
|
46
|
-
Requires-Dist: ruff>=0.
|
|
47
|
-
Requires-Dist: mypy>=1.
|
|
48
|
-
Requires-Dist: pre-commit>=4.
|
|
49
|
-
Requires-Dist: pyright>=1.1.
|
|
47
|
+
Requires-Dist: ruff>=0.12.8; extra == "dev"
|
|
48
|
+
Requires-Dist: mypy>=1.17.0; extra == "dev"
|
|
49
|
+
Requires-Dist: pre-commit>=4.2.0; extra == "dev"
|
|
50
|
+
Requires-Dist: pyright>=1.1.400; extra == "dev"
|
|
50
51
|
Requires-Dist: build>=1.0.3; extra == "dev"
|
|
51
52
|
Requires-Dist: twine>=4.0.2; extra == "dev"
|
|
52
53
|
Provides-Extra: all
|
|
@@ -116,7 +117,22 @@ bounds = TrajectoryBounds(v_bound=5.0, a_bound=10.0, j_bound=30.0)
|
|
|
116
117
|
trajectory = DoubleSTrajectory(state, bounds)
|
|
117
118
|
|
|
118
119
|
print(f"Duration: {trajectory.get_duration():.2f}s")
|
|
119
|
-
|
|
120
|
+
|
|
121
|
+
# Manual plotting (DoubleSTrajectory doesn't have built-in plot method)
|
|
122
|
+
t_eval = np.linspace(0, trajectory.get_duration(), 100)
|
|
123
|
+
results = [trajectory.evaluate(t) for t in t_eval]
|
|
124
|
+
positions = [r[0] for r in results]
|
|
125
|
+
velocities = [r[1] for r in results]
|
|
126
|
+
|
|
127
|
+
plt.figure(figsize=(10, 6))
|
|
128
|
+
plt.subplot(2, 1, 1)
|
|
129
|
+
plt.plot(t_eval, positions)
|
|
130
|
+
plt.ylabel('Position')
|
|
131
|
+
plt.title('S-Curve Trajectory')
|
|
132
|
+
plt.subplot(2, 1, 2)
|
|
133
|
+
plt.plot(t_eval, velocities)
|
|
134
|
+
plt.ylabel('Velocity')
|
|
135
|
+
plt.xlabel('Time')
|
|
120
136
|
|
|
121
137
|
plt.show()
|
|
122
138
|
```
|
|
@@ -183,13 +199,14 @@ orientations = [
|
|
|
183
199
|
times = [0.0, 2.0, 5.0]
|
|
184
200
|
|
|
185
201
|
# Smooth quaternion trajectory with C² continuity
|
|
186
|
-
quat_spline = QuaternionSpline(times, orientations,
|
|
202
|
+
quat_spline = QuaternionSpline(times, orientations, interpolation_method="squad")
|
|
187
203
|
|
|
188
204
|
# Evaluate at any time
|
|
189
|
-
orientation = quat_spline.
|
|
190
|
-
|
|
205
|
+
orientation, segment = quat_spline.interpolate_at_time(3.5)
|
|
206
|
+
# For angular velocity, use interpolate_with_velocity
|
|
207
|
+
orientation_with_vel, angular_velocity, segment = quat_spline.interpolate_with_velocity(3.5)
|
|
191
208
|
|
|
192
|
-
|
|
209
|
+
# QuaternionSpline doesn't have built-in plotting - manual visualization needed
|
|
193
210
|
plt.show()
|
|
194
211
|
```
|
|
195
212
|
</details>
|
|
@@ -200,14 +217,15 @@ plt.show()
|
|
|
200
217
|
```python
|
|
201
218
|
import numpy as np
|
|
202
219
|
import matplotlib.pyplot as plt
|
|
203
|
-
from interpolatepy import
|
|
220
|
+
from interpolatepy import CubicSmoothingSpline
|
|
204
221
|
|
|
205
222
|
# Fit smooth curve to noisy data
|
|
206
223
|
t = np.linspace(0, 10, 50)
|
|
207
224
|
q = np.sin(t) + 0.1 * np.random.randn(50)
|
|
208
225
|
|
|
209
|
-
|
|
210
|
-
|
|
226
|
+
# Use CubicSmoothingSpline with correct parameter name 'mu'
|
|
227
|
+
spline = CubicSmoothingSpline(t, q, mu=0.01)
|
|
228
|
+
spline.plot()
|
|
211
229
|
plt.show()
|
|
212
230
|
```
|
|
213
231
|
</details>
|
|
@@ -229,10 +247,22 @@ print(f"Duration: {trajectory.get_duration():.2f}s")
|
|
|
229
247
|
|
|
230
248
|
# Evaluate trajectory
|
|
231
249
|
t_eval = np.linspace(0, trajectory.get_duration(), 1000)
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
250
|
+
results = [trajectory.evaluate(t) for t in t_eval]
|
|
251
|
+
positions = [r[0] for r in results]
|
|
252
|
+
velocities = [r[1] for r in results]
|
|
253
|
+
|
|
254
|
+
# Manual plotting
|
|
255
|
+
plt.figure(figsize=(12, 8))
|
|
256
|
+
plt.subplot(2, 1, 1)
|
|
257
|
+
plt.plot(t_eval, positions)
|
|
258
|
+
plt.ylabel('Position')
|
|
259
|
+
plt.title('Industrial S-Curve Motion Profile')
|
|
260
|
+
plt.grid(True)
|
|
261
|
+
plt.subplot(2, 1, 2)
|
|
262
|
+
plt.plot(t_eval, velocities)
|
|
263
|
+
plt.ylabel('Velocity')
|
|
264
|
+
plt.xlabel('Time')
|
|
265
|
+
plt.grid(True)
|
|
236
266
|
plt.show()
|
|
237
267
|
```
|
|
238
268
|
</details>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
numpy>=2.3.0
|
|
2
|
+
matplotlib>=3.10.5
|
|
3
|
+
scipy>=1.16.0
|
|
4
|
+
|
|
5
|
+
[all]
|
|
6
|
+
interpolatepy[dev,test]
|
|
7
|
+
|
|
8
|
+
[dev]
|
|
9
|
+
ruff>=0.12.8
|
|
10
|
+
mypy>=1.17.0
|
|
11
|
+
pre-commit>=4.2.0
|
|
12
|
+
pyright>=1.1.400
|
|
13
|
+
build>=1.0.3
|
|
14
|
+
twine>=4.0.2
|
|
15
|
+
|
|
16
|
+
[test]
|
|
17
|
+
pytest>=8.4.0
|
|
18
|
+
pytest-cov>=4.1.0
|
|
19
|
+
codecov>=2.1.13
|
|
20
|
+
pytest-benchmark>=4.0.0
|
|
21
|
+
pre-commit>=4.2.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: InterpolatePy
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.1
|
|
4
4
|
Summary: A comprehensive Python library for generating smooth trajectories and curves with precise control over position, velocity, acceleration, and jerk profiles
|
|
5
5
|
Author-email: Giorgio Medico <giorgio.medico11@gmail.com>
|
|
6
6
|
Maintainer-email: Giorgio Medico <giorgio.medico11@gmail.com>
|
|
@@ -20,6 +20,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.10
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.11
|
|
22
22
|
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
24
|
Classifier: Operating System :: POSIX :: Linux
|
|
24
25
|
Classifier: Operating System :: POSIX
|
|
25
26
|
Classifier: Operating System :: Unix
|
|
@@ -30,23 +31,23 @@ Classifier: Topic :: Scientific/Engineering :: Physics
|
|
|
30
31
|
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
31
32
|
Classifier: Topic :: Software Development :: Libraries
|
|
32
33
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
33
|
-
Requires-Python: >=3.
|
|
34
|
+
Requires-Python: >=3.11
|
|
34
35
|
Description-Content-Type: text/markdown
|
|
35
36
|
License-File: LICENSE
|
|
36
|
-
Requires-Dist: numpy>=2.
|
|
37
|
-
Requires-Dist: matplotlib>=3.10.
|
|
38
|
-
Requires-Dist: scipy>=1.
|
|
37
|
+
Requires-Dist: numpy>=2.3.0
|
|
38
|
+
Requires-Dist: matplotlib>=3.10.5
|
|
39
|
+
Requires-Dist: scipy>=1.16.0
|
|
39
40
|
Provides-Extra: test
|
|
40
|
-
Requires-Dist: pytest>=
|
|
41
|
+
Requires-Dist: pytest>=8.4.0; extra == "test"
|
|
41
42
|
Requires-Dist: pytest-cov>=4.1.0; extra == "test"
|
|
42
43
|
Requires-Dist: codecov>=2.1.13; extra == "test"
|
|
43
44
|
Requires-Dist: pytest-benchmark>=4.0.0; extra == "test"
|
|
44
|
-
Requires-Dist: pre-commit>=4.
|
|
45
|
+
Requires-Dist: pre-commit>=4.2.0; extra == "test"
|
|
45
46
|
Provides-Extra: dev
|
|
46
|
-
Requires-Dist: ruff>=0.
|
|
47
|
-
Requires-Dist: mypy>=1.
|
|
48
|
-
Requires-Dist: pre-commit>=4.
|
|
49
|
-
Requires-Dist: pyright>=1.1.
|
|
47
|
+
Requires-Dist: ruff>=0.12.8; extra == "dev"
|
|
48
|
+
Requires-Dist: mypy>=1.17.0; extra == "dev"
|
|
49
|
+
Requires-Dist: pre-commit>=4.2.0; extra == "dev"
|
|
50
|
+
Requires-Dist: pyright>=1.1.400; extra == "dev"
|
|
50
51
|
Requires-Dist: build>=1.0.3; extra == "dev"
|
|
51
52
|
Requires-Dist: twine>=4.0.2; extra == "dev"
|
|
52
53
|
Provides-Extra: all
|
|
@@ -116,7 +117,22 @@ bounds = TrajectoryBounds(v_bound=5.0, a_bound=10.0, j_bound=30.0)
|
|
|
116
117
|
trajectory = DoubleSTrajectory(state, bounds)
|
|
117
118
|
|
|
118
119
|
print(f"Duration: {trajectory.get_duration():.2f}s")
|
|
119
|
-
|
|
120
|
+
|
|
121
|
+
# Manual plotting (DoubleSTrajectory doesn't have built-in plot method)
|
|
122
|
+
t_eval = np.linspace(0, trajectory.get_duration(), 100)
|
|
123
|
+
results = [trajectory.evaluate(t) for t in t_eval]
|
|
124
|
+
positions = [r[0] for r in results]
|
|
125
|
+
velocities = [r[1] for r in results]
|
|
126
|
+
|
|
127
|
+
plt.figure(figsize=(10, 6))
|
|
128
|
+
plt.subplot(2, 1, 1)
|
|
129
|
+
plt.plot(t_eval, positions)
|
|
130
|
+
plt.ylabel('Position')
|
|
131
|
+
plt.title('S-Curve Trajectory')
|
|
132
|
+
plt.subplot(2, 1, 2)
|
|
133
|
+
plt.plot(t_eval, velocities)
|
|
134
|
+
plt.ylabel('Velocity')
|
|
135
|
+
plt.xlabel('Time')
|
|
120
136
|
|
|
121
137
|
plt.show()
|
|
122
138
|
```
|
|
@@ -183,13 +199,14 @@ orientations = [
|
|
|
183
199
|
times = [0.0, 2.0, 5.0]
|
|
184
200
|
|
|
185
201
|
# Smooth quaternion trajectory with C² continuity
|
|
186
|
-
quat_spline = QuaternionSpline(times, orientations,
|
|
202
|
+
quat_spline = QuaternionSpline(times, orientations, interpolation_method="squad")
|
|
187
203
|
|
|
188
204
|
# Evaluate at any time
|
|
189
|
-
orientation = quat_spline.
|
|
190
|
-
|
|
205
|
+
orientation, segment = quat_spline.interpolate_at_time(3.5)
|
|
206
|
+
# For angular velocity, use interpolate_with_velocity
|
|
207
|
+
orientation_with_vel, angular_velocity, segment = quat_spline.interpolate_with_velocity(3.5)
|
|
191
208
|
|
|
192
|
-
|
|
209
|
+
# QuaternionSpline doesn't have built-in plotting - manual visualization needed
|
|
193
210
|
plt.show()
|
|
194
211
|
```
|
|
195
212
|
</details>
|
|
@@ -200,14 +217,15 @@ plt.show()
|
|
|
200
217
|
```python
|
|
201
218
|
import numpy as np
|
|
202
219
|
import matplotlib.pyplot as plt
|
|
203
|
-
from interpolatepy import
|
|
220
|
+
from interpolatepy import CubicSmoothingSpline
|
|
204
221
|
|
|
205
222
|
# Fit smooth curve to noisy data
|
|
206
223
|
t = np.linspace(0, 10, 50)
|
|
207
224
|
q = np.sin(t) + 0.1 * np.random.randn(50)
|
|
208
225
|
|
|
209
|
-
|
|
210
|
-
|
|
226
|
+
# Use CubicSmoothingSpline with correct parameter name 'mu'
|
|
227
|
+
spline = CubicSmoothingSpline(t, q, mu=0.01)
|
|
228
|
+
spline.plot()
|
|
211
229
|
plt.show()
|
|
212
230
|
```
|
|
213
231
|
</details>
|
|
@@ -229,10 +247,22 @@ print(f"Duration: {trajectory.get_duration():.2f}s")
|
|
|
229
247
|
|
|
230
248
|
# Evaluate trajectory
|
|
231
249
|
t_eval = np.linspace(0, trajectory.get_duration(), 1000)
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
250
|
+
results = [trajectory.evaluate(t) for t in t_eval]
|
|
251
|
+
positions = [r[0] for r in results]
|
|
252
|
+
velocities = [r[1] for r in results]
|
|
253
|
+
|
|
254
|
+
# Manual plotting
|
|
255
|
+
plt.figure(figsize=(12, 8))
|
|
256
|
+
plt.subplot(2, 1, 1)
|
|
257
|
+
plt.plot(t_eval, positions)
|
|
258
|
+
plt.ylabel('Position')
|
|
259
|
+
plt.title('Industrial S-Curve Motion Profile')
|
|
260
|
+
plt.grid(True)
|
|
261
|
+
plt.subplot(2, 1, 2)
|
|
262
|
+
plt.plot(t_eval, velocities)
|
|
263
|
+
plt.ylabel('Velocity')
|
|
264
|
+
plt.xlabel('Time')
|
|
265
|
+
plt.grid(True)
|
|
236
266
|
plt.show()
|
|
237
267
|
```
|
|
238
268
|
</details>
|
|
@@ -61,7 +61,22 @@ bounds = TrajectoryBounds(v_bound=5.0, a_bound=10.0, j_bound=30.0)
|
|
|
61
61
|
trajectory = DoubleSTrajectory(state, bounds)
|
|
62
62
|
|
|
63
63
|
print(f"Duration: {trajectory.get_duration():.2f}s")
|
|
64
|
-
|
|
64
|
+
|
|
65
|
+
# Manual plotting (DoubleSTrajectory doesn't have built-in plot method)
|
|
66
|
+
t_eval = np.linspace(0, trajectory.get_duration(), 100)
|
|
67
|
+
results = [trajectory.evaluate(t) for t in t_eval]
|
|
68
|
+
positions = [r[0] for r in results]
|
|
69
|
+
velocities = [r[1] for r in results]
|
|
70
|
+
|
|
71
|
+
plt.figure(figsize=(10, 6))
|
|
72
|
+
plt.subplot(2, 1, 1)
|
|
73
|
+
plt.plot(t_eval, positions)
|
|
74
|
+
plt.ylabel('Position')
|
|
75
|
+
plt.title('S-Curve Trajectory')
|
|
76
|
+
plt.subplot(2, 1, 2)
|
|
77
|
+
plt.plot(t_eval, velocities)
|
|
78
|
+
plt.ylabel('Velocity')
|
|
79
|
+
plt.xlabel('Time')
|
|
65
80
|
|
|
66
81
|
plt.show()
|
|
67
82
|
```
|
|
@@ -128,13 +143,14 @@ orientations = [
|
|
|
128
143
|
times = [0.0, 2.0, 5.0]
|
|
129
144
|
|
|
130
145
|
# Smooth quaternion trajectory with C² continuity
|
|
131
|
-
quat_spline = QuaternionSpline(times, orientations,
|
|
146
|
+
quat_spline = QuaternionSpline(times, orientations, interpolation_method="squad")
|
|
132
147
|
|
|
133
148
|
# Evaluate at any time
|
|
134
|
-
orientation = quat_spline.
|
|
135
|
-
|
|
149
|
+
orientation, segment = quat_spline.interpolate_at_time(3.5)
|
|
150
|
+
# For angular velocity, use interpolate_with_velocity
|
|
151
|
+
orientation_with_vel, angular_velocity, segment = quat_spline.interpolate_with_velocity(3.5)
|
|
136
152
|
|
|
137
|
-
|
|
153
|
+
# QuaternionSpline doesn't have built-in plotting - manual visualization needed
|
|
138
154
|
plt.show()
|
|
139
155
|
```
|
|
140
156
|
</details>
|
|
@@ -145,14 +161,15 @@ plt.show()
|
|
|
145
161
|
```python
|
|
146
162
|
import numpy as np
|
|
147
163
|
import matplotlib.pyplot as plt
|
|
148
|
-
from interpolatepy import
|
|
164
|
+
from interpolatepy import CubicSmoothingSpline
|
|
149
165
|
|
|
150
166
|
# Fit smooth curve to noisy data
|
|
151
167
|
t = np.linspace(0, 10, 50)
|
|
152
168
|
q = np.sin(t) + 0.1 * np.random.randn(50)
|
|
153
169
|
|
|
154
|
-
|
|
155
|
-
|
|
170
|
+
# Use CubicSmoothingSpline with correct parameter name 'mu'
|
|
171
|
+
spline = CubicSmoothingSpline(t, q, mu=0.01)
|
|
172
|
+
spline.plot()
|
|
156
173
|
plt.show()
|
|
157
174
|
```
|
|
158
175
|
</details>
|
|
@@ -174,10 +191,22 @@ print(f"Duration: {trajectory.get_duration():.2f}s")
|
|
|
174
191
|
|
|
175
192
|
# Evaluate trajectory
|
|
176
193
|
t_eval = np.linspace(0, trajectory.get_duration(), 1000)
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
194
|
+
results = [trajectory.evaluate(t) for t in t_eval]
|
|
195
|
+
positions = [r[0] for r in results]
|
|
196
|
+
velocities = [r[1] for r in results]
|
|
197
|
+
|
|
198
|
+
# Manual plotting
|
|
199
|
+
plt.figure(figsize=(12, 8))
|
|
200
|
+
plt.subplot(2, 1, 1)
|
|
201
|
+
plt.plot(t_eval, positions)
|
|
202
|
+
plt.ylabel('Position')
|
|
203
|
+
plt.title('Industrial S-Curve Motion Profile')
|
|
204
|
+
plt.grid(True)
|
|
205
|
+
plt.subplot(2, 1, 2)
|
|
206
|
+
plt.plot(t_eval, velocities)
|
|
207
|
+
plt.ylabel('Velocity')
|
|
208
|
+
plt.xlabel('Time')
|
|
209
|
+
plt.grid(True)
|
|
181
210
|
plt.show()
|
|
182
211
|
```
|
|
183
212
|
</details>
|
|
@@ -349,10 +349,11 @@ The algorithm solves for total time considering all constraints and boundary con
|
|
|
349
349
|
|
|
350
350
|
# Evaluate at midpoint
|
|
351
351
|
t_mid = trajectory.get_duration() / 2
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
352
|
+
result = trajectory.evaluate(t_mid)
|
|
353
|
+
pos = result[0]
|
|
354
|
+
vel = result[1]
|
|
355
|
+
acc = result[2]
|
|
356
|
+
jerk = result[3]
|
|
356
357
|
```
|
|
357
358
|
|
|
358
359
|
### Trapezoidal Trajectory
|
|
@@ -135,7 +135,7 @@ bspline = BSplineInterpolator(
|
|
|
135
135
|
# Evaluate curve
|
|
136
136
|
t = 2.5
|
|
137
137
|
position = bspline.evaluate(t)
|
|
138
|
-
velocity = bspline.
|
|
138
|
+
velocity = bspline.evaluate_derivative(t, order=1)
|
|
139
139
|
```
|
|
140
140
|
|
|
141
141
|
#### ApproximationBSpline {#approximation-b-spline}
|
|
@@ -193,10 +193,11 @@ trajectory = DoubleSTrajectory(state, bounds)
|
|
|
193
193
|
|
|
194
194
|
# Evaluate trajectory
|
|
195
195
|
t = trajectory.get_duration() / 2
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
196
|
+
result = trajectory.evaluate(t)
|
|
197
|
+
position = result[0]
|
|
198
|
+
velocity = result[1]
|
|
199
|
+
acceleration = result[2]
|
|
200
|
+
jerk = result[3]
|
|
200
201
|
|
|
201
202
|
print(f"Duration: {trajectory.get_duration():.2f}s")
|
|
202
203
|
```
|
|
@@ -215,7 +216,8 @@ print(f"Duration: {trajectory.get_duration():.2f}s")
|
|
|
215
216
|
|
|
216
217
|
**Example:**
|
|
217
218
|
```python
|
|
218
|
-
from interpolatepy import TrapezoidalTrajectory
|
|
219
|
+
from interpolatepy import TrapezoidalTrajectory
|
|
220
|
+
from interpolatepy.trapezoidal import TrajectoryParams
|
|
219
221
|
|
|
220
222
|
# Define trajectory parameters
|
|
221
223
|
params = TrajectoryParams(
|
|
@@ -273,7 +275,7 @@ final = BoundaryCondition(
|
|
|
273
275
|
jerk=0.0
|
|
274
276
|
)
|
|
275
277
|
|
|
276
|
-
interval = TimeInterval(
|
|
278
|
+
interval = TimeInterval(start=0.0, end=2.0)
|
|
277
279
|
|
|
278
280
|
# Generate 7th-order polynomial
|
|
279
281
|
traj_func = PolynomialTrajectory.order_7_trajectory(initial, final, interval)
|
|
@@ -319,7 +321,7 @@ import numpy as np
|
|
|
319
321
|
|
|
320
322
|
# Create quaternions
|
|
321
323
|
q1 = Quaternion.identity()
|
|
322
|
-
q2 = Quaternion.from_angle_axis(np.pi/2, [0, 0, 1]) # 90° about Z
|
|
324
|
+
q2 = Quaternion.from_angle_axis(np.pi/2, np.array([0, 0, 1])) # 90° about Z
|
|
323
325
|
|
|
324
326
|
# SLERP interpolation
|
|
325
327
|
t = 0.5
|
|
@@ -350,9 +352,9 @@ import numpy as np
|
|
|
350
352
|
times = [0, 1, 2, 3]
|
|
351
353
|
orientations = [
|
|
352
354
|
Quaternion.identity(),
|
|
353
|
-
Quaternion.from_angle_axis(np.pi/2, [1, 0, 0]),
|
|
354
|
-
Quaternion.from_angle_axis(np.pi, [0, 1, 0]),
|
|
355
|
-
Quaternion.from_angle_axis(np.pi/4, [0, 0, 1])
|
|
355
|
+
Quaternion.from_angle_axis(np.pi/2, np.array([1, 0, 0])),
|
|
356
|
+
Quaternion.from_angle_axis(np.pi, np.array([0, 1, 0])),
|
|
357
|
+
Quaternion.from_angle_axis(np.pi/4, np.array([0, 0, 1]))
|
|
356
358
|
]
|
|
357
359
|
|
|
358
360
|
# Create C² continuous quaternion spline
|
|
@@ -401,7 +403,7 @@ velocity = path.velocity(s) # Unit tangent vector
|
|
|
401
403
|
acceleration = path.acceleration(s) # Zero for straight line
|
|
402
404
|
|
|
403
405
|
# Evaluate multiple points
|
|
404
|
-
s_values = np.linspace(0, path.
|
|
406
|
+
s_values = np.linspace(0, path.length, 50)
|
|
405
407
|
trajectory = path.evaluate_at(s_values)
|
|
406
408
|
```
|
|
407
409
|
|