def __init__(self): super(Array, self).__init__() # Define hydrophones self.hydrophones = Phys_Obj() # Define Pinger_Contours self.pinger_contours = [] # Define unknown variables self.last_known_pinger_location = None self.last_known_pinger_direction = None
class Array(Phys_Obj): # Always mind the coordinate axes! # # z y # ^ 7 # | / # | / # |/ # - - - - - - > x # # ...z represents the vertical axis (gravity acts in # this direction. y represents the forward direction of # the array. As shown, the frame (a.k.a. coordinate axes) # are fixed to the array such the if the array rotates, then # the frame will rotate the same amount. def __init__(self): super(Array, self).__init__() # Define hydrophones self.hydrophones = Phys_Obj() # Define Pinger_Contours self.pinger_contours = [] # Define unknown variables self.last_known_pinger_location = None self.last_known_pinger_direction = None def define(self, locations): """Specify the hydrophone configuration by passing an Nx3 numpy array, where each row is an XYZ coordinate representing a coordinate location of a hydrophone with respect to the array origin. """ self.hydrophones.set_XYZ(XYZ=locations) # Generate immediate parameters self.n_elements = locations.shape[0] # Make a list of all relative hydrophone locations self.element_pos = locations # Enumerate all pair combinations self.pairs = [ ID for ID in itertools.combinations(range(self.n_elements), 2) ] # compute pair properties self.d = [] self.COM = [] self.d_vect = [] self.norm_uvect = [] self.pair_y_rot = [] for (ID0, ID1) in self.pairs: # General basic paremeters l0 = self.element_pos[ID0] l1 = self.element_pos[ID1] # compute vectorized distance between pairs d_vect = l1 - l0 self.d_vect.append(d_vect) # absolute distance between each pair self.d.append(np.linalg.norm(l0 - l1)) # determine center of mass for each pair self.COM.append(l0 + (l1 - l0) / 2) # Get nNormal for each pair (assuming each pair rests on # the z = 0 plane). norm_vect = np.array([[-d_vect[1], d_vect[0], 0]]) norm_uvect = norm_vect / np.linalg.norm(norm_vect) self.norm_uvect.append(norm_uvect) # Get y_based rotation abs_y_rot = np.arccos(np.dot(norm_vect[0], K_HAT[0]) / np.linalg.norm(norm_vect)) # [0] is ugly syntax to yield a 1D vector if (norm_uvect[DIM1, 0] < 0): y_rot = -abs_y_rot else: y_rot = abs_y_rot self.pair_y_rot.append(y_rot) def compute_D1minusD2(self, Dx): self.ddoa = [] for (ID_a, ID_b) in self.pairs: ddoa = Dx[ID_a] - Dx[ID_b] (self.ddoa).append(ddoa) def compute_ab_coefficients(self): n_pairs = len(self.pairs) i = 0 self.ab = [] for i in range(n_pairs): ab = dd_to_hyperboloid_coe(self.ddoa[i], self.d[i]) (self.ab).append(ab) def bulk_compute_ab_from_distances(self, Dx): self.compute_D1minusD2(Dx) self.compute_ab_coefficients() def get_direction(self, doa): """ Takes a list of distances of arrival (doa) values corresponding to each hydrophone element and uses such information to generate a pinger location """ self.bulk_compute_ab_from_distances(doa) # ^^ Updates self.ddoa and self.ab self.last_known_pinger_direction = 0 def re_build(self, locations): self.__init__(locations) def refresh_data(self): pass def print_drawing(self): pass