Trajectory¶
- class sargeom.Trajectory(timestamps, positions, orientations=None)[source]¶
Bases:
object
A Trajectory object represents a sequence of positions and orientations over time.
It is defined by the following characteristics:
Timestamps are expressed in seconds. They may correspond to UTC, GPS Seconds of Week (SOW), Time of Day (TOD), or a custom time reference.
Positions are provided in either the WGS84 geographic coordinate system (EPSG:4979) or the WGS84 geocentric coordinate system (EPSG:4978).
Orientations are defined in the local North-East-Down (NED) Cartesian frame, relative to the associated position coordinates.
- Parameters:
- timestampsarray_like
1D array of timestamps corresponding to each trajectory sample.
- positions
sargeom.coordinates.CartesianECEF
orsargeom.coordinates.Cartographic
Array of positions in either ECEF (x, y, z) or geographic (latitude, longitude, altitude) format.
- orientations
scipy.spatial.transform.Rotation
, optional Sequence of orientations as Rotation objects. Defined in the NED frame. Default is None.
- Raises:
TypeError
If positions are not of type CartesianECEF or Cartographic.
If orientations are provided but not of type scipy.spatial.transform.Rotation.
Examples
Create a Trajectory instance using ECEF (Cartesian) coordinates:
>>> timestamps = np.array([0, 1, 2]) >>> positions = CartesianECEF( ... x=[4614831.06382533, 4583825.9258778, 4610933.91105407], ... y=[312803.18870294, 388064.96749322, 440116.57314554], ... z=[4377307.25608437, 4403747.15229078, 4370795.76589696] ... ) >>> traj = Trajectory(timestamps, positions)
Create a Trajectory instance using geographic (Cartographic) coordinates:
>>> positions = Cartographic( ... longitude=[3.8777, 4.8391, 5.4524], ... latitude=[43.6135, 43.9422, 43.5309], ... height=[300.0, 400.0, 500.0] ... ) >>> traj = Trajectory(timestamps, positions)
Create a Trajectory instance with orientations:
>>> from scipy.spatial.transform import Rotation >>> orientations = Rotation.from_euler("ZYX", [[0, 0, 0], [90, 0, 0], [180, 0, 0]], degrees=True) >>> traj = Trajectory(timestamps, positions, orientations)
Attributes Summary
Arc lengths between consecutive trajectory positions.
Orientations of the trajectory samples, in the NED frame.
Positions of the trajectory samples, in ECEF coordinates.
Sampling rate of the trajectory.
Timestamps of the trajectory samples, in seconds.
Velocities between consecutive trajectory samples.
Methods Summary
from_numpy
(data)Create a Trajectory instance from a numpy structured array.
Whether the trajectory has orientation data.
interp
(new_timestamps)Interpolate the trajectory to new timestamps.
plot
(**kwargs)read_csv
(filename)Read a TRAJ CSV file and create a Trajectory instance.
read_pamela_pos
(filename)Read a PAMELA .pos file and create a Trajectory instance.
read_pamela_traj
(filename)Read a PAMELA .traj file and create a Trajectory instance.
read_pivot
(filename)resample
(sampling_rate)Resample the trajectory at a specified sampling rate.
save_csv
(filename)Save the Trajectory instance to a TRAJ CSV file.
save_kml
(filename, **kwargs)save_npy
(filename)Save the Trajectory instance to a numpy .npy file.
save_pamela_pos
(filename)Save the Trajectory instance to a PAMELA .pos file.
save_pivot
(filename)sort
([inplace, reverse])Sort the trajectory by timestamps.
to_numpy
()Convert the Trajectory instance to a numpy structured array.
Convert the Trajectory instance to a pandas DataFrame.
Compute the total arc length of the trajectory.
Attributes Documentation
- arc_lengths¶
Arc lengths between consecutive trajectory positions.
- Returns:
numpy.ndarray
1D array of distances in meters.
Examples
>>> traj = Trajectory( ... timestamps=[0, 1, 2], ... positions=Cartographic( ... longitude=[3.8777, 4.8391, 5.4524], ... latitude=[43.6135, 43.9422, 43.5309], ... height=[300.0, 400.0, 500.0] ... ) ... ) >>> traj.arc_lengths array([85584.58995186, 67305.32205239])
- orientations¶
Orientations of the trajectory samples, in the NED frame.
- Returns:
scipy.spatial.transform.Rotation
Sequence of orientations as a Rotation object.
- Raises:
ValueError
If the trajectory has no orientations.
Notes
The orientations are defined in the local North-East-Down (NED) Cartesian frame, relative to the associated position coordinates. The orientations can be converted to quaternions, Euler angles, or other representations using the methods provided by the Rotation class.
Examples
>>> from scipy.spatial.transform import Rotation >>> attitude = Rotation.from_euler("ZYX", [[0, 0, 0], [90, 0, 0], [180, 0, 0]], degrees=True) >>> traj = Trajectory( ... timestamps=[0, 1, 2], ... positions=Cartographic( ... longitude=[3.8777, 4.8391, 5.4524], ... latitude=[43.6135, 43.9422, 43.5309], ... height=[300.0, 400.0, 500.0] ... ), ... orientations=attitude ... ) >>> traj.orientations.as_quat() array([[0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 1.00000000e+00], [0.00000000e+00, 0.00000000e+00, 7.07106781e-01, 7.07106781e-01], [0.00000000e+00, 0.00000000e+00, 1.00000000e+00, 6.12323400e-17]])
- positions¶
Positions of the trajectory samples, in ECEF coordinates.
- Returns:
sargeom.coordinates.CartesianECEF
3D positions expressed in the WGS84 geocentric frame (EPSG:4978).
Examples
>>> traj = Trajectory( ... timestamps=[0, 1, 2], ... positions=Cartographic( ... longitude=[3.8777, 4.8391, 5.4524], ... latitude=[43.6135, 43.9422, 43.5309], ... height=[300.0, 400.0, 500.0] ... ) ... ) >>> traj.positions XYZ CartesianECEF points [[4614831.06382533 312803.18870294 4377307.25608437] [4583825.9258778 388064.96749322 4403747.15229078] [4610933.91105407 440116.57314554 4370795.76589696]]
- sampling_rate¶
Sampling rate of the trajectory.
- Returns:
float
Sampling frequency in Hz.
- Raises:
ValueError
If there are fewer than two timestamps.
Examples
>>> traj = Trajectory( ... timestamps=[0, 1, 2], ... positions=Cartographic( ... longitude=[3.8777, 4.8391, 5.4524], ... latitude=[43.6135, 43.9422, 43.5309], ... height=[300.0, 400.0, 500.0] ... ) ... ) >>> traj.sampling_rate np.float64(1.0)
- timestamps¶
Timestamps of the trajectory samples, in seconds.
- Returns:
numpy.ndarray
1D array of timestamps (e.g., UTC, GPS SOW, TOD).
Examples
>>> traj = Trajectory( ... timestamps=[0, 1, 2], ... positions=Cartographic( ... longitude=[3.8777, 4.8391, 5.4524], ... latitude=[43.6135, 43.9422, 43.5309], ... height=[300.0, 400.0, 500.0] ... ) ... ) >>> traj.timestamps array([0, 1, 2])
- velocities¶
Velocities between consecutive trajectory samples.
- Returns:
numpy.ndarray
1D array of velocity magnitudes, in meters per second.
- Raises:
ValueError
If there are fewer than two timestamps.
Examples
>>> traj = Trajectory( ... timestamps=[0, 1, 2], ... positions=Cartographic( ... longitude=[3.8777, 4.8391, 5.4524], ... latitude=[43.6135, 43.9422, 43.5309], ... height=[300.0, 400.0, 500.0] ... ) ... ) >>> traj.velocities array([85584.58995186, 67305.32205239])
Methods Documentation
- static from_numpy(data)[source]¶
Create a Trajectory instance from a numpy structured array.
- Parameters:
- data
numpy.ndarray
Input data as a numpy structured array using the
TRAJ_DTYPE
type.
- data
- Returns:
Trajectory
A new Trajectory instance.
- Raises:
TypeError
If the input data is not a numpy array.
ValueError
If the input data does not have the correct dtype.
Examples
>>> data = np.array([ ... (0., 3.8777, 43.6135, 300., 0., 0., 0.), ... (1., 4.8391, 43.9422, 400., 0., 0., 0.), ... (2., 5.4524, 43.5309, 500., 0., 0., 0.) ... ], dtype=TRAJ_DTYPE) >>> traj = Trajectory.from_numpy(data)
- has_orientation()[source]¶
Whether the trajectory has orientation data.
- Returns:
bool
True if orientations are defined, False otherwise.
Examples
>>> traj = Trajectory( ... timestamps=[0, 1, 2], ... positions=Cartographic( ... longitude=[3.8777, 4.8391, 5.4524], ... latitude=[43.6135, 43.9422, 43.5309], ... height=[300.0, 400.0, 500.0] ... ) ... ) >>> traj.has_orientation() False
- interp(new_timestamps)[source]¶
Interpolate the trajectory to new timestamps.
- Parameters:
- new_timestampsarray_like
Array of new timestamps to interpolate the trajectory to.
- Returns:
Trajectory
A new Trajectory instance with interpolated data.
- Raises:
ValueError
If the new timestamps are not within the range of existing timestamps.
Examples
>>> traj = Trajectory( ... timestamps=[0, 1, 2], ... positions=Cartographic( ... longitude=[3.8777, 4.8391, 5.4524], ... latitude=[43.6135, 43.9422, 43.5309], ... height=[300.0, 400.0, 500.0] ... ) ... ) >>> interp_traj = traj.interp([0.5, 1.5])
- read_csv(filename)[source]¶
Read a TRAJ CSV file and create a Trajectory instance.
- Parameters:
- filename
str
orpathlib.Path
The filename or path to the .traj.csv file.
- filename
- Returns:
Trajectory
A new Trajectory instance.
- Raises:
FileNotFoundError
If the file does not exist.
ValueError
If the file does not have a .traj.csv extension.
- read_pamela_pos(filename)[source]¶
Read a PAMELA .pos file and create a Trajectory instance.
- Parameters:
- filename
str
orpathlib.Path
The filename or path to the .pos file.
- filename
- Returns:
Trajectory
A new Trajectory instance.
- Raises:
FileNotFoundError
If the file does not exist.
ValueError
If the file does not have a .pos extension.
- read_pamela_traj(filename)[source]¶
Read a PAMELA .traj file and create a Trajectory instance.
- Parameters:
- filename
str
orpathlib.Path
The filename or path to the .traj file.
- filename
- Returns:
Trajectory
A new Trajectory instance.
- Raises:
FileNotFoundError
If the file does not exist.
ValueError
If the file does not have a .traj extension.
ValueError
If the old PAMELA file format is detected.
- resample(sampling_rate)[source]¶
Resample the trajectory at a specified sampling rate.
- Parameters:
- sampling_rate
float
The desired sampling rate in Hz.
- sampling_rate
- Returns:
Trajectory
A new Trajectory instance with resampled data.
- Raises:
TypeError
If the sampling rate is not a number.
ValueError
If the sampling rate is not positive.
Examples
>>> traj = Trajectory( ... timestamps=[0, 1, 2], ... positions=Cartographic( ... longitude=[3.8777, 4.8391, 5.4524], ... latitude=[43.6135, 43.9422, 43.5309], ... height=[300.0, 400.0, 500.0] ... ) ... ) >>> resampled_traj = traj.resample(2.0)
- save_csv(filename)[source]¶
Save the Trajectory instance to a TRAJ CSV file.
- Parameters:
- filename
str
orpathlib.Path
The filename or path to save the .traj.csv file.
- filename
Examples
>>> traj = Trajectory( ... timestamps=[0, 1, 2], ... positions=Cartographic( ... longitude=[3.8777, 4.8391, 5.4524], ... latitude=[43.6135, 43.9422, 43.5309], ... height=[300.0, 400.0, 500.0] ... ) ... ) >>> traj.save_csv("output.traj.csv")
- save_npy(filename)[source]¶
Save the Trajectory instance to a numpy .npy file.
- Parameters:
- filename
str
orpathlib.Path
The filename or path to save the .npy file.
- filename
Examples
>>> traj = Trajectory( ... timestamps=[0, 1, 2], ... positions=Cartographic( ... longitude=[3.8777, 4.8391, 5.4524], ... latitude=[43.6135, 43.9422, 43.5309], ... height=[300.0, 400.0, 500.0] ... ) ... ) >>> traj.save_npy("output.npy")
- save_pamela_pos(filename)[source]¶
Save the Trajectory instance to a PAMELA .pos file.
- Parameters:
- filename
str
orpathlib.Path
The filename or path to save the .pos file.
- filename
Examples
>>> traj = Trajectory( ... timestamps=[0, 1, 2], ... positions=Cartographic( ... longitude=[3.8777, 4.8391, 5.4524], ... latitude=[43.6135, 43.9422, 43.5309], ... height=[300.0, 400.0, 500.0] ... ) ... ) >>> traj.save_pamela_pos("output.pos")
- sort(inplace=True, reverse=False)[source]¶
Sort the trajectory by timestamps.
- Parameters:
- Returns:
Trajectory
or NoneThe sorted Trajectory instance if inplace is False, otherwise None.
Examples
Sort the trajectory in place:
>>> traj = Trajectory( ... timestamps=[2, 0, 1], ... positions=Cartographic( ... longitude=[3.8777, 4.8391, 5.4524], ... latitude=[43.6135, 43.9422, 43.5309], ... height=[300.0, 400.0, 500.0] ... ) ... ) >>> traj.sort() Trajectory samples (t, x, y, z, h, e, b) [(0., 4.8391, 43.9422, 400., 0., 0., 0.) (1., 5.4524, 43.5309, 500., 0., 0., 0.) (2., 3.8777, 43.6135, 300., 0., 0., 0.)]
Sort the trajectory and return a new instance:
>>> sorted_traj = traj.sort(inplace=False)
- to_numpy()[source]¶
Convert the Trajectory instance to a numpy structured array.
- Returns:
numpy.ndarray
The trajectory data as a numpy structured array using the
TRAJ_DTYPE
type.
Examples
>>> traj = Trajectory( ... timestamps=[0, 1, 2], ... positions=Cartographic( ... longitude=[3.8777, 4.8391, 5.4524], ... latitude=[43.6135, 43.9422, 43.5309], ... height=[300.0, 400.0, 500.0] ... ) ... ) >>> data = traj.to_numpy()
- to_pandas()[source]¶
Convert the Trajectory instance to a pandas DataFrame.
- Returns:
pandas.DataFrame
The trajectory data as a pandas DataFrame.
- Raises:
ModuleNotFoundError
If pandas is not installed.
Examples
>>> traj = Trajectory( ... timestamps=[0, 1, 2], ... positions=Cartographic( ... longitude=[3.8777, 4.8391, 5.4524], ... latitude=[43.6135, 43.9422, 43.5309], ... height=[300.0, 400.0, 500.0] ... ) ... ) >>> df = traj.to_pandas()
- total_arc_length()[source]¶
Compute the total arc length of the trajectory.
- Returns:
float
Sum of distances between consecutive positions, in meters.
Examples
>>> traj = Trajectory( ... timestamps=[0, 1, 2], ... positions=Cartographic( ... longitude=[3.8777, 4.8391, 5.4524], ... latitude=[43.6135, 43.9422, 43.5309], ... height=[300.0, 400.0, 500.0] ... ) ... ) >>> traj.total_arc_length() np.float64(152889.9120042545)