def get_los_path(self, dvec): """ Computes LOS path loss and angles Parameters ---------- dvec : (n,3) array Vector from cell to UAV Returns ------- los_pl: (n,) array LOS path losses computed from Friis' Law los_ang: (n,AngleFormat.nangle) = (n,4) array LOS angles los_dly: (n,) array Delay of the paths computed from the speed of light """ # Compute free space path loss from Friis' law dist = np.maximum(np.sqrt(np.sum(dvec**2,axis=1)), 1) lam = 3e8/self.fc los_pl = 20*np.log10(dist*4*np.pi/lam) # Compute the LOS angles r, los_aod_phi, los_aod_theta = cart_to_sph(dvec) r, los_aoa_phi, los_aoa_theta = cart_to_sph(-dvec) # Stack the angles los_ang = np.stack((los_aoa_phi, los_aoa_theta,\ los_aod_phi, los_aod_theta), axis=-1) # Compute the delay los_dly = dist/PhyConst.light_speed return los_pl, los_ang, los_dly
def transform_ang(self, dvec, nlos_ang, nlos_pl): """ Performs the transformation on the angle data Parameters ---------- dvec : (nlink,ndim) array Vectors from cell to UAV for each link nlos_ang : (nlink,npaths_max,nangle) array Angles of each path in each link. The angles are in degrees nlos_pl : (nlink,npaths_max) array Path losses of each path in each link. A value of pl_max indicates no path Returns ------- Xang : (nlink,nangle*npaths_max) Tranformed angle coordinates """ # Compute the LOS angles r, los_aod_phi, los_aod_theta = cart_to_sph(dvec) r, los_aoa_phi, los_aoa_theta = cart_to_sph(-dvec) # Get the NLOS angles nlos_aod_phi = nlos_ang[:,:,AngleFormat.aod_phi_ind] nlos_aod_theta = nlos_ang[:,:,AngleFormat.aod_theta_ind] nlos_aoa_phi = nlos_ang[:,:,AngleFormat.aoa_phi_ind] nlos_aoa_theta = nlos_ang[:,:,AngleFormat.aoa_theta_ind] # Rotate the NLOS angles by the LOS angles to compute # the relative angle aod_phi_rel, aod_theta_rel = spherical_add_sub(\ nlos_aod_phi, nlos_aod_theta,\ los_aod_phi[:,None], los_aod_theta[:,None]) aoa_phi_rel, aoa_theta_rel = spherical_add_sub(\ nlos_aoa_phi, nlos_aoa_theta,\ los_aoa_phi[:,None], los_aoa_theta[:,None]) # Set the relative angle on non-existent paths to zero I = (nlos_pl < self.pl_max-0.01) aod_phi_rel = aod_phi_rel*I aod_theta_rel = aod_theta_rel*I aoa_phi_rel = aoa_phi_rel*I aoa_theta_rel = aoa_theta_rel*I # Stack the relative angles and scale by 180 Xang = np.hstack(\ (aoa_phi_rel/180, aoa_theta_rel/180,\ aod_phi_rel/180, aod_theta_rel/180)) return Xang
def inv_transform_ang(self, dvec, Xang): """ Performs the transformation on the angle data Parameters ---------- dvec : (nlink,ndim) array Vectors from cell to UAV for each link Xang : (nlink,nangle*npaths_max) Tranformed angle coordinates Returns ------- nlos_ang : (nlink,npaths_max,nangle) array Angles of each path in each link. The angles are in degrees """ # Compute the LOS angles r, los_aod_phi, los_aod_theta = cart_to_sph(dvec) r, los_aoa_phi, los_aoa_theta = cart_to_sph(-dvec) # Get the transformed angles npm = self.npaths_max aoa_phi_rel = Xang[:,:npm]*180 aoa_theta_rel = Xang[:,npm:2*npm]*180 aod_phi_rel = Xang[:,2*npm:3*npm]*180 aod_theta_rel = Xang[:,3*npm:]*180 # Rotate the relative angles by the LOS angles to compute # the original NLOS angles nlos_aoa_phi, nlos_aoa_theta = spherical_add_sub(\ aoa_phi_rel, aoa_theta_rel,\ los_aoa_phi[:,None], los_aoa_theta[:,None], sub=False) nlos_aod_phi, nlos_aod_theta = spherical_add_sub(\ aod_phi_rel, aod_theta_rel,\ los_aod_phi[:,None], los_aod_theta[:,None], sub=False) # Stack the relative angles nlink = nlos_aod_phi.shape[0] nlos_ang = np.zeros((nlink,self.npaths_max,AngleFormat.nangle)) nlos_ang[:,:,AngleFormat.aoa_phi_ind] = nlos_aoa_phi nlos_ang[:,:,AngleFormat.aoa_theta_ind] = nlos_aoa_theta nlos_ang[:,:,AngleFormat.aod_phi_ind] = nlos_aod_phi nlos_ang[:,:,AngleFormat.aod_theta_ind] = nlos_aod_theta return nlos_ang