TrajectorySegment
Full Docs
PyDynSys.core.euclidean.trajectory.TrajectorySegment
Represents a numerically computed segment of a trajectory on a monotone increasing evaluation space.
A segment corresponds to a single continuous solution from scipy.solve_ivp, representing the trajectory over a contiguous time interval with a single interpolant.
Fields
t (NDArray[np.float64]): Monotone increasing array of evaluation times, shape (len(t),) y (NDArray[np.float64]): Array of trajectory evaluations x(t), shape (n, len(t)) domain (Tuple[float, float]): Time domain [t[0], t[-1]] where segment is defined interpolant (Optional[Callable]): Continuous interpolant x(t) on domain, or None method (str): ODE solver method used ('RK45', 'LSODA', etc.) meta (Dict[str, Any]): Metadata about numerical solution (success, message, etc.)
Usage
Segments are created via from_scipy_solution() factory, not direct instantiation. Users primarily interact with EuclideanTrajectory, which aggregates segments.
Source code in src/PyDynSys/core/euclidean/trajectory.py
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | |
from_scipy_solution(sol: SciPyIvpSolution, method: str) -> TrajectorySegment
classmethod
Factory: Create segment from scipy solve_ivp solution.
Handles backward integration (monotone decreasing t) by reversing arrays to enforce monotone increasing time convention for all segments.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sol
|
SciPyIvpSolution
|
Wrapped scipy OdeResult from solve_ivp |
required |
method
|
str
|
ODE solver method used (e.g. 'RK45', 'LSODA') |
required |
Returns:
| Name | Type | Description |
|---|---|---|
EuclideanTrajectorySegment |
TrajectorySegment
|
Segment with monotone increasing time |
Example
from scipy.integrate import solve_ivp result = solve_ivp(fun, t_span, y0, t_eval, method, dense_output) wrapped = SciPyIvpSolution(raw_solution=result) # not necessary, but provides type safety segment = EuclideanTrajectorySegment.from_scipy_solution(wrapped, 'RK45') # default method is RK45
Source code in src/PyDynSys/core/euclidean/trajectory.py
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | |
in_domain(t: float) -> bool
Check if time t is within segment domain.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
t
|
float
|
Time point to check |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if t ∈ [domain[0], domain[1]], False otherwise |
Source code in src/PyDynSys/core/euclidean/trajectory.py
89 90 91 92 93 94 95 96 97 98 99 | |
interpolant_at_time(t: float) -> NDArray[np.float64]
Evaluate interpolant at time t.
Uses scipy's dense output interpolant to compute x(t) continuously within the segment domain. Raises errors if t is outside domain or if no interpolant is available (dense_output=False in original solve_ivp call).
For speed, we employ agressive programming here and assume
- t is in domain
- interpolant is available
If either of these fails, an esoteric error may be incurred. This is a worthwhile tradeoff as this function may be called thousands of times (e.g. when plotting a trajectory).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
t
|
float
|
Time point for evaluation |
required |
Returns:
| Type | Description |
|---|---|
NDArray[float64]
|
NDArray[np.float64]: State vector x(t) at time t, shape (n,) |
Example
x_t = segment.interpolate(0.5) # Evaluate at t=0.5
Source code in src/PyDynSys/core/euclidean/trajectory.py
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | |