Trajectory is a dynamically sized trajectory container that stores time-series state data with runtime-determined dimensions. Unlike static trajectory types, Trajectory allows you to specify the state vector dimension at creation time, making it ideal for applications where the dimension varies or is not known at compile time.
Use Trajectory when:
State dimension is determined at runtime
You need flexibility to work with different dimensions in the same codebase
State vectors are non-standard (not 3D or 6D)
Flexibility is prioritized over maximum performance
importbraheasbhimportnumpyasnpbh.initialize_eop()# Create trajectory with multiple statestraj=bh.Trajectory(6)epoch0=bh.Epoch.from_datetime(2024,1,1,0,0,0.0,0.0,bh.TimeSystem.UTC)foriinrange(5):epoch=epoch0+i*60.0state=np.array([bh.R_EARTH+500e3+i*1000,0.0,0.0,0.0,7600.0,0.0])traj.add(epoch,state)# Get nearest state to a specific epochquery_epoch=epoch0+120.0# 2 minutes after startnearest_epoch,nearest_state=traj.nearest_state(query_epoch)print(f"Nearest state at t+120s altitude: {(nearest_state[0]-bh.R_EARTH)/1e3:.2f} km")# Get nearest state between stored epochsquery_epoch=epoch0+125.0# Between stored epochsnearest_epoch,nearest_state=traj.nearest_state(query_epoch)print(f"Nearest state at t+125s altitude: {(nearest_state[0]-bh.R_EARTH)/1e3:.2f} km")# Output:# Nearest state at t+120s altitude: 502.00 km# Nearest state at t+125s altitude: 502.00 km
usebraheasbh;usebh::time::Epoch;usebh::trajectories::DTrajectory;usebh::traits::Trajectory;usebh::constants::R_EARTH;usenalgebraasna;fnmain(){bh::initialize_eop().unwrap();// Create trajectory with multiple statesletmuttraj=DTrajectory::new(6);letepoch0=Epoch::from_datetime(2024,1,1,0,0,0.0,0.0,bh::time::TimeSystem::UTC);foriin0..5{letepoch=epoch0+(iasf64)*60.0;letstate=na::DVector::from_vec(vec![R_EARTH+500e3+(iasf64)*1000.0,0.0,0.0,0.0,7600.0,0.0]);traj.add(epoch,state);}// Get nearest state to a specific epochletquery_epoch1=epoch0+120.0;// 2 minutes after startlet(_,nearest_state)=traj.nearest_state(&query_epoch1).unwrap();println!("Nearest state at t+120s altitude: {:.2} km",(nearest_state[0]-R_EARTH)/1e3);// Get nearest state between stored epochsletquery_epoch2=epoch0+125.0;// Between stored epochslet(_,nearest_state)=traj.nearest_state(&query_epoch2).unwrap();println!("Nearest state at t+125s altitude: {:.2} km",(nearest_state[0]-R_EARTH)/1e3);}// Output:// Nearest state at t+120s altitude: 502.00 km// Nearest state at t+125s altitude: 502.00 km
importbraheasbhimportnumpyasnpbh.initialize_eop()# Create trajectory with sparse datatraj=bh.Trajectory(6)epoch0=bh.Epoch.from_datetime(2024,1,1,0,0,0.0,0.0,bh.TimeSystem.UTC)# Add states every 60 secondsforiinrange(3):epoch=epoch0+i*60.0# Simplified motion: position changes linearly with timestate=np.array([bh.R_EARTH+500e3+i*10000,0.0,0.0,0.0,7600.0,0.0])traj.add(epoch,state)# Interpolate state at intermediate timequery_epoch=epoch0+30.0# Halfway between first two statesinterpolated_state=traj.interpolate(query_epoch)print(f"Interpolated altitude: {(interpolated_state[0]-bh.R_EARTH)/1e3:.2f} km")# Expected: approximately 505 km (halfway between 500 and 510 km)# Output:# Interpolated altitude: 505.00 km
usebraheasbh;usebh::time::Epoch;usebh::trajectories::DTrajectory;usebh::traits::{Trajectory,InterpolatableTrajectory};usebh::constants::R_EARTH;usenalgebraasna;fnmain(){bh::initialize_eop().unwrap();// Create trajectory with sparse dataletmuttraj=DTrajectory::new(6);letepoch0=Epoch::from_datetime(2024,1,1,0,0,0.0,0.0,bh::time::TimeSystem::UTC);// Add states every 60 secondsforiin0..3{letepoch=epoch0+(iasf64)*60.0;letstate=na::DVector::from_vec(vec![R_EARTH+500e3+(iasf64)*10000.0,0.0,0.0,0.0,7600.0,0.0]);traj.add(epoch,state);}// Interpolate state at intermediate timeletquery_epoch=epoch0+30.0;// Halfway between first two statesletinterpolated_state=traj.interpolate(&query_epoch).unwrap();println!("Interpolated altitude: {:.2} km",(interpolated_state[0]-R_EARTH)/1e3);// Expected: approximately 505 km (halfway between 500 and 510 km)}// Output:// Interpolated altitude: 505.00 km
importbraheasbhimportnumpyasnpbh.initialize_eop()# Create trajectory with max size limittraj=bh.Trajectory(6).with_eviction_policy_max_size(3)epoch0=bh.Epoch.from_datetime(2024,1,1,0,0,0.0,0.0,bh.TimeSystem.UTC)# Add 5 statesforiinrange(5):epoch=epoch0+i*60.0state=np.array([bh.R_EARTH+500e3+i*1000,0.0,0.0,0.0,7600.0,0.0])traj.add(epoch,state)# Only the 3 most recent states are keptprint(f"Trajectory length: {len(traj)}")print(f"Start epoch: {traj.start_epoch()}")print(f"Start altitude: {(traj.state_at_idx(0)[0]-bh.R_EARTH)/1e3:.2f} km")# Output: ~502 km (states 0 and 1 were evicted)# Output# Trajectory length: 3# Start epoch: 2024-01-01 00:02:00.000 UTC# Start altitude: 502.00 km
usebraheasbh;usebh::time::Epoch;usebh::trajectories::DTrajectory;usebh::traits::Trajectory;usebh::constants::R_EARTH;usenalgebraasna;fnmain(){bh::initialize_eop().unwrap();// Create trajectory with max size limitletmuttraj=DTrajectory::new(6).with_eviction_policy_max_size(3);letepoch0=Epoch::from_datetime(2024,1,1,0,0,0.0,0.0,bh::time::TimeSystem::UTC);// Add 5 statesforiin0..5{letepoch=epoch0+(iasf64)*60.0;letstate=na::DVector::from_vec(vec![R_EARTH+500e3+(iasf64)*1000.0,0.0,0.0,0.0,7600.0,0.0]);traj.add(epoch,state);}// Only the 3 most recent states are keptprintln!("Trajectory length: {}",traj.len());println!("Start epoch: {}",traj.start_epoch().unwrap());println!("Start altitude: {:.2} km",(traj.state_at_idx(0).unwrap()[0]-R_EARTH)/1e3);// Output: ~502 km (states 0 and 1 were evicted)}// Output// Trajectory length: 3// Start epoch: 2024-01-01 00:02:00.000 UTC// Start altitude: 502.00 km
importbraheasbhimportnumpyasnpbh.initialize_eop()# Keep only states within last 2 minutes (120 seconds)traj=bh.Trajectory(6).with_eviction_policy_max_age(120.0)epoch0=bh.Epoch.from_datetime(2024,1,1,0,0,0.0,0.0,bh.TimeSystem.UTC)# Add states spanning 4 minutesforiinrange(5):epoch=epoch0+i*60.0state=np.array([bh.R_EARTH+500e3,0.0,0.0,0.0,7600.0,0.0])traj.add(epoch,state)# Only states within 120 seconds of the most recent are keptprint(f"Trajectory length: {len(traj)}")print(f"Timespan: {traj.timespan():.1f} seconds")# Output:# Trajectory length: 3# Timespan: 120.0 seconds
usebraheasbh;usebh::time::Epoch;usebh::trajectories::DTrajectory;usebh::traits::Trajectory;usebh::constants::R_EARTH;usenalgebraasna;fnmain(){bh::initialize_eop().unwrap();// Keep only states within last 2 minutes (120 seconds)letmuttraj=DTrajectory::new(6).with_eviction_policy_max_age(120.0);letepoch0=Epoch::from_datetime(2024,1,1,0,0,0.0,0.0,bh::time::TimeSystem::UTC);// Add states spanning 4 minutesforiin0..5{letepoch=epoch0+(iasf64)*60.0;letstate=na::DVector::from_vec(vec![R_EARTH+500e3,0.0,0.0,0.0,7600.0,0.0]);traj.add(epoch,state);}// Only states within 120 seconds of the most recent are keptprintln!("Trajectory length: {}",traj.len());println!("Timespan: {:.1} seconds",traj.timespan().unwrap());}// Output:// Trajectory length: 3// Timespan: 120.0 seconds
importbraheasbhimportnumpyasnpbh.initialize_eop()# Create trajectorytraj=bh.Trajectory(6)epoch0=bh.Epoch.from_datetime(2024,1,1,0,0,0.0,0.0,bh.TimeSystem.UTC)foriinrange(3):epoch=epoch0+i*60.0state=np.array([bh.R_EARTH+500e3,0.0,0.0,0.0,7600.0+i*10,0.0])traj.add(epoch,state)# Convert to matrix (rows are states, columns are dimensions)matrix=traj.to_matrix()print(f"Matrix type: {type(matrix)}")print(f"Matrix shape: {matrix.shape}")print(f"First state velocity: {matrix[0,4]:.1f} m/s")# Output:# Matrix type: <class 'numpy.ndarray'># Matrix shape: (3, 6)# First state velocity: 7600.0 m/s
usebraheasbh;usebh::time::Epoch;usebh::trajectories::DTrajectory;usebh::traits::Trajectory;usebh::constants::R_EARTH;usenalgebraasna;fnmain(){bh::initialize_eop().unwrap();// Create trajectoryletmuttraj=DTrajectory::new(6);letepoch0=Epoch::from_datetime(2024,1,1,0,0,0.0,0.0,bh::time::TimeSystem::UTC);foriin0..3{letepoch=epoch0+(iasf64)*60.0;letstate=na::DVector::from_vec(vec![R_EARTH+500e3,0.0,0.0,0.0,7600.0+(iasf64)*10.0,0.0]);traj.add(epoch,state);}// Convert to matrix (rows are states, columns are dimensions)letmatrix=traj.to_matrix().unwrap();println!("Matrix shape: ({}, {})",matrix.nrows(),matrix.ncols());println!("First state velocity: {:.1} m/s",matrix[(0,4)]);}// Output:// Matrix shape: (3, 6)// First state velocity: 7600.0 m/s