def aircraft_x_array_from_span() -> np.ndarray: """Takes the AIRCRAFT_ASPECTS and the camera data to calculate the ranges of the aircraft using apparent span. Time is in video B time. """ array_length = 0 for frame in AIRCRAFT_ASPECTS: if frame <= AIRCRAFT_ASPECTS_SPAN_FRAME_LIMIT: array_length += 1 array = np.empty((array_length, 4), dtype=np.float64) idx = 0 for frame in sorted(AIRCRAFT_ASPECTS.keys()): if frame <= AIRCRAFT_ASPECTS_SPAN_FRAME_LIMIT: # Compute mid point of span mid_span = map_funcs.mid_point( AIRCRAFT_ASPECTS[frame].left_tip, AIRCRAFT_ASPECTS[frame].right_tip, ) brg_deg = bearing_x_degrees(mid_span.x) # Pixels of apparent span span_px: float = map_funcs.distance_between_points( AIRCRAFT_ASPECTS[frame].left_tip, AIRCRAFT_ASPECTS[frame].right_tip, ) array[idx, 0] = frame_to_time(frame) apparent_span = aircraft.ANTONOV_AN_24_SPAN * math.cos( math.radians(brg_deg - google_earth.RUNWAY_HEADING_DEG)) for i, px_error in enumerate((0, -AIRCRAFT_ASPECTS_ERROR_PIXELS, AIRCRAFT_ASPECTS_ERROR_PIXELS)): rng = range_to_target(span_px + px_error, apparent_span) # print('TRACE:', span_px, brg_deg, apparent_span, rng) x, bearing = x_bearing_from_range(rng) array[idx, i + 1] = x idx += 1 return array
def aircraft_x_array_from_bearings() -> np.ndarray: """Takes the AIRCRAFT_ASPECTS and the camera data to create a numpy array of the aircraft position from the bearings of the aircraft. Time is in video B time. """ array = np.empty((len(AIRCRAFT_ASPECTS), 4), dtype=np.float64) for f, frame in enumerate(sorted(AIRCRAFT_ASPECTS)): # Compute mid point of span mid_span = map_funcs.mid_point( AIRCRAFT_ASPECTS[frame].left_tip, AIRCRAFT_ASPECTS[frame].right_tip, ) array[f, 0] = frame_to_time(frame) for b, brg_deg in enumerate(( bearing_x_degrees(mid_span.x), bearing_x_degrees(mid_span.x - AIRCRAFT_ASPECTS_ERROR_PIXELS, +PX_PER_DEGREE_ERROR) - CAMERA_BEARING_ERROR, bearing_x_degrees(mid_span.x + AIRCRAFT_ASPECTS_ERROR_PIXELS, -PX_PER_DEGREE_ERROR) + CAMERA_BEARING_ERROR, )): # Compute x, y relative to runway theta_deg = brg_deg - google_earth.RUNWAY_HEADING_DEG x = CAMERA_POSITION_XY.x - CAMERA_POSITION_XY.y * math.tan( math.radians(90 - theta_deg)) array[f, b + 1] = x return array
def print_aircraft_x_from_bearings(): """Takes the AIRCRAFT_ASPECTS and the camera data to print bearings of the aircraft.""" print('print_aircraft_bearings_and_x():') t_prev = None x_prev = None print(f'{"Frame":>6s} {"t":>6s} {"brg":>6s}' f' {"x":>6s} {"dt":>6s} {"dx":>6s} {"dx/dt":>6s}') for frame in sorted(AIRCRAFT_ASPECTS): # Compute mid point of span mid_span = map_funcs.mid_point( AIRCRAFT_ASPECTS[frame].left_tip, AIRCRAFT_ASPECTS[frame].right_tip, ) brg_deg = bearing_x_degrees(mid_span.x) # Compute x, y relative to runway theta_deg = brg_deg - google_earth.RUNWAY_HEADING_DEG x = CAMERA_POSITION_XY.x - CAMERA_POSITION_XY.y * math.tan( math.radians(90 - theta_deg)) t = frame_to_time(frame) if t_prev is not None: dt = t - t_prev dx = x - x_prev dx_dt = dx / dt else: dt = 0.0 dx = 0.0 dx_dt = 0.0 print(f'{frame:6d} {t:6.2f} {brg_deg:6.2f}' f' {x:6.1f} {dt:6.2f} {dx:6.2f} {dx_dt:6.2f}') t_prev = t x_prev = x
def print_aspects() -> None: """This does not seem to be a useful/reliable/accurate calculation compared to others.""" print('Aspects:') for k in sorted(AIRCRAFT_ASPECTS.keys()): mid_span = map_funcs.mid_point( AIRCRAFT_ASPECTS[k].left_tip, AIRCRAFT_ASPECTS[k].right_tip, ) mid_length = map_funcs.mid_point( AIRCRAFT_ASPECTS[k].nose, AIRCRAFT_ASPECTS[k].tail, ) mid_point = map_funcs.mid_point(mid_span, mid_length) aspect = AIRCRAFT_ASPECTS[k].aspect(aircraft.ANTONOV_AN_24_SPAN, aircraft.ANTONOV_AN_24_LENGTH) print( f'{k:3d} aspect={aspect :5.3f} x: {mid_point.x:6.2f} y: {mid_point.y:6.2f}' ) print('Aspects from tail height:') for k in sorted(AIRCRAFT_ASPECTS.keys()): span_px = map_funcs.distance( AIRCRAFT_ASPECTS[k].left_tip, AIRCRAFT_ASPECTS[k].right_tip, 1, ) / aircraft.ANTONOV_AN_24_SPAN m_per_pixel = aircraft.ANTONOV_AN_24_HEIGHT / map_funcs.distance( AIRCRAFT_ASPECTS[k].fin_tip, AIRCRAFT_ASPECTS[k].fin_gnd, 1, ) apparent_span_m = m_per_pixel * span_px aspect = 90 - math.degrees( math.asin(apparent_span_m / aircraft.ANTONOV_AN_24_SPAN)) print( f'{k:3d} span={span_px :5.3f} (px) m/px: {m_per_pixel :6.3f} aspect: {aspect :6.2f}' )
def print_aircraft_bearings_and_ranges(): """Takes the AIRCRAFT_ASPECTS and the camera data to print bearing and ranges of the aircraft.""" print('print_aircraft_bearings_and_ranges():') t_prev = None x_prev = None print(f'{"Frame":>8} {"t":>6} {"Brg":>6} {"Tail deg":>8}' f' {"Range":>6} {"x":>6} {"y":>6} {"dt":>6} {"dx":>6} {"dx/dt":>6}') for frame in sorted(AIRCRAFT_ASPECTS): # Compute mid point of span mid_span = map_funcs.mid_point( AIRCRAFT_ASPECTS[frame].left_tip, AIRCRAFT_ASPECTS[frame].right_tip, ) brg_deg = bearing_x_degrees(mid_span.x) # Compute height of tail tail_height_px = map_funcs.distance(AIRCRAFT_ASPECTS[frame].fin_gnd, AIRCRAFT_ASPECTS[frame].fin_tip, 1.0) tail_height_deg = tail_height_px / PX_PER_DEGREE rng = range_to_target(tail_height_px, aircraft.ANTONOV_AN_24_HEIGHT) # Compute x, y relative to runway x, y = xy_from_range_bearing(rng, brg_deg) t = frame_to_time(frame) if t_prev is not None: dt = t - t_prev dx = x - x_prev dx_dt = dx / dt else: dt = 0.0 dx = 0.0 dx_dt = 0.0 print( f'{frame:8d} {t:6.2f} {brg_deg:6.2f} {tail_height_deg:8.2f}' f' {rng:6.1f} {x:6.2f} {y:6.2f} {dt:6.2f} {dx:6.2f} {dx_dt:6.2f}') t_prev = t x_prev = x