In [14]:
from math import pi
import math
from shablona.config import AMP_heading
from shablona.config import M3_swath
from shablona.config import M3_avgeraging_time
from shablona.targets import TargetSpace
import datetime
In [15]:
def target_velocity(target):
"""
Calculates "delta_v" for classification given a target.
Delta_v is the norm of the difference between the current velocity
and the target velocity. This function returns the maximum delta_v
calculated for the target. Target velocity is calculated at intervals
of M3_averaging_time
i.e. if M3_averaging_time is 1 second, and a target was detected every
ping at 10 Hz for 5 seconds, the velocity would be calculated 5 times.
The most recent ADCP data at the time of target detection is used to
calculate delta_v.
"""
# extract target data
nims_indices = target.get_entry('nims')['aggregate_indices']
adcp = target.get_entry('adcp')
# sort nims data by timestamp
sort(nims_indices,
key = lambda x: target_space.get_engry_by_index('nims', x)['timestamp'])
# extract all targets from nims data
targets = []
for index in nims_indices:
target_instance = target.target_space.get_entry_by_index('nims', index)
targets.append(target_instance)
points_to_avg = []
index = 0
# determine points between which to calculate velocity (must have at least
# M3_averaging_time between the timestamps)
while index < len(targets):
start_time = targets[index]['timestamp']
for i, target in targets:
# add to points_to_avg if the difference in time between
# target sightings is greater than the M3_averaging_time
diff = delta_t_in_seconds(targets[i]['timestamp'], start_time)
if diff >= M3_averaging_time:
points_to_avg.append(targets[i])
index = i
break
if not points_to_avg:
# if the target was less than the M3_averaging_time, use first
# and last points
points_to_avg += nims_indices[0]
points_to_avg += nims_indices[-1]
# convert ADCP to cartesian coordinates
velocity_adcp = [adcp['speed'] * math.cos(adcp['heading']),
adcp['speed'] * math.sin(adcp['heading'])]
delta_v = []
for i, point in enumerate(points_to_avg):
# calculate delta_v between two consecutive points
point1 = point
try:
point2 = points_to_avg[i+1]
except:
break
# velocity of target between point 1 and point 2
velocity_target = velocity_between_two_points(point1, point2)
# difference between target and adcp velocity
velocity_dif = [velocity_target[0]-velocity_adcp[0],
velocity_target[1]-velocity_adcp[1]]
# "delta_v" is magnitude of velocity difference
delta_v += (velocity_diff[0]**2 + velocity_diff[1]**2)**0.5
return(max(delta_v))
def velocity_between_two_points(point1, point2):
"""
Determines magnitude and direction of target trajectory (from point 1 to point 2)
Inputs:
point 1, point 2 = points where target was detected, in list format [range, bearing in degrees]
AMP_heading = heading of AMP, in radians from due north
M3_swath = list containing minimum and maximum angle ( in degrees) for M3 target
detection. Default is 0 --> 120 degrees
Outputs:
vel = [velocity magnitude, velocity direction]
"""
# TO DO: divide by time! points are targets. ****
point1_cartesian = transform_NIMS_to_vector(point1)
point2_cartesian = transform_NIMS_to_vector(point2)
dt = delta_t_in_seconds(point1, point2)
# subtract 2-1 to get velocity
vel = [(point2_cartesian[0] - point1_cartesian[0])/dt,
(point2_cartesian[1] - point1_cartesian[1])/dt]
return(vel)
def transform_NIMS_to_vector(point):
"""
Transform NIMS detection (in format [range, bearing in degrees]) to earth coordinates (East-North)
Returns X-Y coordinates of point after transformation.
"""
# convert target heading to radians, and shift such that zero degrees is center of swath
point_heading = (point['last_pos_angle'] - (M3_swath[1] - M3_swath[0])/2) * pi/180
# convert bearing to angle from due N by subtracting AMP angle
point_heading = point_heading - AMP_heading
# get vector components for point 1 and 2
point_cartesian = [point['last_pos_range'] * math.cos(point_heading),
point['last_pos_range'] * math.sin(point_heading)]
return(point_cartesian)
def delta_t_in_seconds(self, datetime1, datetime2):
"""
calculate delta t in seconds between two datetime objects
(returns absolute value, so order of dates is insignifigant)
"""
delta_t = datetime1 - datetime2
days_s = delta_t.days*(86400)
microseconds_s = delta_t.microseconds/1000000
delta_t_s = days_s + delta_t.seconds + microseconds_s
return abs(delta_t_s)
In [ ]: