Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions spatialmath/base/quaternions.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@
import spatialmath.base as smb
from spatialmath.base.argcheck import getunit
from spatialmath.base.types import *
import scipy.interpolate as interpolate
from typing import Optional
from typing import TYPE_CHECKING, Optional
from functools import lru_cache
import warnings

if TYPE_CHECKING:
import scipy.interpolate as interpolate

_eps = np.finfo(np.float64).eps


Expand Down Expand Up @@ -897,7 +899,7 @@ def _compute_cdf_sin_squared(theta: float):
@lru_cache(maxsize=1)
def _generate_inv_cdf_sin_squared_interp(
num_interpolation_points: int = 256,
) -> interpolate.interp1d:
) -> "interpolate.interp1d":
"""
Computes an interpolation function for the inverse CDF of the distribution of angular magnitude.

Expand All @@ -910,6 +912,8 @@ def _generate_inv_cdf_sin_squared_interp(
This function returns interpolation function for the inverse of the integral of the
pdf of angular magnitudes (2/pi * sin^2(theta/2)), which is not analytically defined.
"""
import scipy.interpolate as interpolate # deferred, it is slow to import

cdf_sin_squared_interp_angles = np.linspace(0, np.pi, num_interpolation_points)
cdf_sin_squared_interp_values = _compute_cdf_sin_squared(
cdf_sin_squared_interp_angles
Expand Down
7 changes: 5 additions & 2 deletions spatialmath/spline.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
from typing import TYPE_CHECKING, List, Optional, Tuple

import numpy as np
from scipy.interpolate import BSpline, CubicSpline
from scipy.spatial.transform import Rotation, RotationSpline

from spatialmath import SE3, SO3, Twist3
from spatialmath.base.transforms3d import tranimate
Expand Down Expand Up @@ -122,6 +120,9 @@ def __init__(
self.timepoints = self.timepoints - self.timepoints[0]
self.timepoints = self.timepoints / self.timepoints[-1]

from scipy.interpolate import CubicSpline # deferred, scipy is slow to import
from scipy.spatial.transform import Rotation, RotationSpline

self.spline_xyz = CubicSpline(
self.timepoints,
np.array([pose.t for pose in self.control_poses]),
Expand Down Expand Up @@ -292,6 +293,8 @@ def __init__(
) # ensures the curve ends on the last control pose
self.knots = knots

from scipy.interpolate import BSpline # deferred, scipy is slow to import

self.splines = [
BSpline(knots, self.control_pose_matrix[:, i], degree)
for i in range(0, 6) # twists are length 6
Expand Down
16 changes: 16 additions & 0 deletions tests/test_import.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import subprocess
import sys
import unittest


class TestImport(unittest.TestCase):
def test_import_does_not_load_scipy(self):
# scipy is slow to import and only a few functions need it, so it is
# imported by those functions and not when spatialmath is imported
code = "import sys, spatialmath; sys.exit(any(m.split('.')[0] == 'scipy' for m in sys.modules))"
result = subprocess.run([sys.executable, "-c", code])
self.assertEqual(result.returncode, 0, "import spatialmath loaded scipy")


if __name__ == "__main__": # pragma nocover
unittest.main()