def __init__(self, platform_id): # check that the platform_id refers to a known satellite if not Satellite.get_by_id(platform_id): raise ValueError( "platform_id does not exist: {}".format(platform_id)) self.platform_id = platform_id self.segment_times = {} # segment_id : list of times self.segment_positions = {} # segment_id : list of positions self.segment_velocities = {} # segment_id : list of velocities self.segments = Satellite.get_by_id( platform_id).orbit_segments # Store orbit segments
def interpolate(self, timestamp, kind="linear"): """Estimate the position and velocity of the satellite at a given time. Args: timestamp: The time for which to get the estimated position and velocity, in Unix epoch seconds. kind: The type of interpolation to do. This defaults to "linear." Alternatives include "quadratic", "cubic", etc. See scipy.interpolate. Return: A tuple (pos, vel). Each of pos, vel is a 3-tuple representing the vector components of the position and velocity, respectively. Raise: ValueError if interpolation could not be performed for the given timestamp. """ # find the correct segment from stored data segment = next( (segment for segment in self.segments if segment.start_time <= timestamp and segment.end_time >= timestamp), None) if not segment: # segment was not in stored data, ask DB segment = OrbitSegment.get_by_platform_and_time( self.platform_id, timestamp) if not segment: raise InterpolationError("No segment found: {}, {}".format( self.platform_id, timestamp)) else: # update stored segments self.segments = Satellite.get_by_id( self.platform_id).orbit_segments # get orbit records for the segment segment_id = segment.segment_id if segment_id not in self.segment_times: records = OrbitRecord.get_by_segment(segment_id) # don't bother to proceed if there are too few records for an interpolation if not records or len(records) < 2: raise InterpolationError( "No orbit records found: {}, {}".format( self.platform_id, segment_id)) # extract and cache time, position, velocity self.segment_times[segment_id] = np.array( [rec.time for rec in records]) self.segment_positions[segment_id] = np.array( [np.array(rec.position) for rec in records]) self.segment_velocities[segment_id] = np.array( [np.array(rec.velocity) for rec in records]) # interpolate the position and velocity position = Interpolator.vector_interp( self.segment_times[segment_id], self.segment_positions[segment_id], [timestamp], kind=kind)[0] velocity = Interpolator.vector_interp( self.segment_times[segment_id], self.segment_velocities[segment_id], [timestamp], kind=kind)[0] return tuple(position), tuple(velocity)