def start(self, verbose=True, use_internal_gps=False): """ Start execution of the main loop This is the central point of the antenna tracking system. It put all together the data and trigger calculations. Then a nice output is given to STDOUT. """ # Display some funky ascii self.greeting() # Setup antenna tracking system self.antenna = Antenna(use_internal_gps) if self.antenna.ready: while True: # Apply a pwm according to the calculations self.antenna.update_target_orientation() # time.sleep(0.2) NOOOO if verbose: self.antenna.print_current_data() else: logging.error( 'Initialization aborted due to unmet startup conditions for one or more module.' ) self.stop()
def __init__(self, source_fn: str, radar_fn: str, dipole=False): # To pass values to parent classes Source.__init__(self, source_fn, dipole) Antenna.__init__(self, radar_fn) # Source to antenna distances self.distance, self.path_vec = self.multi_dist() print("\x1b[1;31mDistance:\n\x1b[0m", self.distance, "\n\x1b[1;31mVector:\n\x1b[0m", self.path_vec)
def __init__(self): self.display = (1000, 800) # window'un boyutlari self.mouseX = 0 # mouse hareketinin x koordinati self.mouseY = 0 # mouse hareketinin y koordinati self.flag = False self.flag2 = False self.currentValue = 0 self.antenna = Antenna() self.plane = Plane() self.ground = Ground(100, 100) # ground'un boyutlari self.sidebar = SideBar()
class Interface(): def __init__(self): self.system = Antenna() ant_list = self.system.get_list() self.target = Target() target_list = self.target.get_list() title = "INP Generator for Orbit ACUs" subtitle = "Choose your Antenna" # A menu to select our antenna selection = SelectionMenu.get_selection(ant_list, title=title, subtitle=subtitle) if selection == len(ant_list): sys.exit() sys_name = ant_list[selection] subtitle = "Using " + sys_name + ", Choose the target" # A menu to select our target selection = SelectionMenu.get_selection(target_list, title=title, subtitle=subtitle) if selection == len(target_list): sys.exit() target_name = target_list[selection] self.system.ready(sys_name) self.target.ready(target_name) self.target.ready_antenna(self.system.lat, self.system.lon, self.system.alt) self.target.generate_report() if self.target.rise_time is None: output = "\n\n " + target_name + " doesn't rise in the next 12 hours...\n\n" print(output) sys.exit() else: output = "\n\n " + target_name + " will be up at " + self.target.rise_time + "\n" print(output) output = " The report ends or " + target_name + " fades at " + self.target.fade_time + "\n\n" print(output) filename = "/home/scheduler/Desktop/" + sys_name + "_" + target_name + ".orb" output = " Saving INP file to " + filename + "\n\n" print(output) with open(filename, 'w') as f: for line in self.target.report: f.write(line) sys.exit()
def findValidAntennas(self, antennaLayer, geotransform, xmin, xmax, ymin, ymax): start_point = QgsPoint(xmin, ymax) end_point = QgsPoint(xmax, ymin) startcella = self.findcell(start_point, geotransform) sluttcella = self.findcell(end_point, geotransform) antennas = Antenna.fromFeatures(antennaLayer.getFeatures()) validAntennas = [] self.timeit("Antenna area start: " + str(startcella[0]) + ", " + str(startcella[1])) self.timeit("Antenna area end: " + str(sluttcella[0]) + ", " + str(sluttcella[1])) for ant in antennas: ant.qgisPoint = self.findcell(ant.point, geotransform) self.timeit("Compared to: " + str(ant.qgisPoint[0]) + ", " + str(ant.qgisPoint[1])) if ant.qgisPoint[0] > startcella[0] and ant.qgisPoint[ 0] < sluttcella[0] and ant.qgisPoint[1] > startcella[ 1] and ant.qgisPoint[1] < sluttcella[1]: validAntennas.append(ant) return validAntennas
def __init__(self): self.wind_speed = 5.0 # default wind speed self.coherent_pow_flg = True # add coherent power self.coh_integrate_time = 0.001 # coherent integrateed time self.num_angles = 360 # integrated angle resolution self.interface_flg = 1 # curvature surface self.ddm_cov_factor = 5 # cov mode factor for ddm # # atmosphere loss for signal propagation 0.5 dB self.atmospheric_loss = pow(10.0, (0.5 / 10.0)) # # members self.geometry = Geometry() self.nadir_RF = Antenna() self.zenith_RF = Antenna() self.signal = Signal() self.power_waveform = Waveform(True, 1000) self.interface = Interface()
def add_antenna(self, loss, orientation, device=None, channel=None, force_device=None): av_devs = self.available_devices if force_device is None else force_device # If the device is not provided we must find the best one for this link if not device: src_device = ubnt.get_fastest_link_hardware( loss, available_devices=av_devs)[1] else: src_device = ubnt.get_fastest_link_hardware( loss, device[0], available_devices=av_devs)[1] if not channel: channel = self._pick_channel() else: self.check_channel(channel) if not src_device: raise LinkUnfeasibilty if len(self.antennas) >= self.max_ant: raise AntennasExahustion ant = Antenna(src_device, orientation, channel) self.antennas.append(ant) return ant
def macrocells(grid, radius, n_bs, macrocells_center): center = numpy.array([grid.size[0]/2, grid.size[1]/2]) #Center Antenna macrocells_center.append((grid.size[0]/2, grid.size[1]/2)) bs = Antenna(0, Antenna.BS_ID, center, None, grid) grid.add_antenna(bs)
def __read_file__(self, filename, tx_power=None, freq=None): data = pd.read_csv(filename).to_records() radio = self.__calc_radio__(tx_power, freq) return [ Antenna(d[0], d[1], d[2], len(data), radio, tx_power=tx_power, freq=freq) for d in data ]
def refreshNetworkInterfaces(self): """ Uses `lshw -c network` to get interface names of all USB based Wifi cards. :return: A List[String] of interface names. """ results = subprocess.check_output(["lshw", "-c", "network"]) raw_interface_output = results.split('*-network') interface_dict = { iface.split("\n")[0]: { line.split(":")[0].strip(): line.split(':')[1].strip() for line in iface.split('\n')[1:] if (len(line.split(":")) > 1) } for iface in raw_interface_output } interface_list = [a.interface for a in self.known_interfaces] + [ v['logical name'] for k, v in interface_dict.iteritems() if ('bus info' in v.keys()) if v['bus info'].startswith("usb") ] self.known_interfaces = [ Antenna(iface) for iface in list(set(interface_list)) ]
def __init__(self, bounds=((0, 0), (1, 0), (1, 1), (0, 1)), antennas=10, csv_file=None, seed=0, verbose=False): """System that contains the antennas and the analyzer Args: bounds (tuple): Tuple with coordinates of the spacial system bounds. It starts from top-left and continues clockwise. antennas (int, optional): Number of randomly generated antennas. Defaults to 10. csv_file ([type], optional): Path of CSV to load custom antennas, if it is different to None, the previous argument is ignored. Defaults to None. verbose (bool, optional): Verbose mode. Defaults to False. seed (int, optional): Seed of random generator. Defaults to 0. """ rd.seed(seed) tx_power = 50 freq = 9e8 if csv_file == None: radio = self.__calc_radio__(tx_power, freq) self.__antennas = [ Antenna(i, rd.rand(), rd.rand(), antennas, radio, tx_power=tx_power, freq=freq) for i in range(antennas) ] else: self.__antennas = self.__read_file__(csv_file, tx_power=tx_power, freq=freq) self.__analyzer = SpectrumAnalyzer(bounds, verbose=True)
def simple_antenna_rad_pattern(th, phi): if th == 0 and phi == 0: return 1 if math.fabs(th) < 1 * math.pi / 180 and math.fabs( phi) < 1 * math.pi / 180: width_hor = 10 * math.pi / 180 width_ver = 10 * math.pi / 180 return math.sin(math.sqrt((th * 1.39156 * 2 / width_hor) * (th * 1.39156 * 2 / width_hor) + (phi * 1.39156 * 2 / width_ver) * (phi * 1.39156 * 2/width_ver))) /\ math.sqrt((th * 1.39156 * 2 / width_hor) * (th * 1.39156 * 2 / width_hor) + (phi * 1.39156 * 2 / width_ver) * (phi * 1.39156 * 2 / width_ver)) return 0 antenna = Antenna(simple_antenna_rad_pattern, 1000, math.pi / 30, math.pi / 30, DnMode["by_func"]) #signal = Rect(5000000, 200000, 5e-6) signal = PacketRect(10000000, 100000, 5e-6, 50) settings = { "antenna": antenna, "signal": signal, "sigma": 0.05, "max_range": 150000, "F": 0.0001 } max_r = int(settings["max_range"] / settings["signal"].resol) - 1 max_p = int(2 * math.pi / settings["antenna"].dph) - 1
def __init__(self, mode, received_bid, received_waypoints, start_pos, goal_pos, environment, goal_dist, rrt_iters): """ Initializer for Agent class; represents a robot capable of planning and moving in an environment. Args: mode: a string: "normal" or "cooperative" indicates whether to use DMA-RRT or Cooperative DMA-RRT (respectively). received_bid: a method representing the callback for bid messages passed over the network. received_waypoints: a method representing the callback for the waypoints and winner_id messages passed over the network. start_pos: a 2-tuple representing the starting x-y position. goal_pos: a 2-tuple representing the goal x-y position. environment: an Environment object representing the map in which the agent must plan. goal_dist: a float representing the length of a single branch in the RRT tree for the agent's planner. rrt_iters: the number of iterations to run for RRT at each spin_once. """ self.antenna = Antenna() # Assign interaction callbacks for messages Agent.received_bid = received_bid Agent.received_waypoints = received_waypoints self.curr_time = 0.0 # Simulation time. Updated externally self.mode = mode self.token_holder = False # Keeps track of other agents' current bids for PPI # (potential path improvement) at any given time: self.bids = {} # Keeps track of other agents' plans so that we can # add the other agents as obstacles when replanning: self.other_agent_plans = {} # Initial state and environment self.start = start_pos self.goal = goal_pos self.pos = self.start self.environment = environment self.rrt = RRTstar(self.start, self.goal, self.environment, goal_dist, max_iter=rrt_iters) self.goal_dist = goal_dist # curr_plan is the currently executing plan; best_plan is a lower-cost path # than curr_plan, if one exists. The cost difference is the bid! self.curr_plan = Path() self.best_plan = Path() # Register as listener for different kinds of messages self.antenna.on_message("peers", self.received_id) self.antenna.on_message("bids", self.received_bid) self.antenna.on_message("waypoints", self.received_waypoints)
class Agent: def __init__(self, mode, received_bid, received_waypoints, start_pos, goal_pos, environment, goal_dist, rrt_iters): """ Initializer for Agent class; represents a robot capable of planning and moving in an environment. Args: mode: a string: "normal" or "cooperative" indicates whether to use DMA-RRT or Cooperative DMA-RRT (respectively). received_bid: a method representing the callback for bid messages passed over the network. received_waypoints: a method representing the callback for the waypoints and winner_id messages passed over the network. start_pos: a 2-tuple representing the starting x-y position. goal_pos: a 2-tuple representing the goal x-y position. environment: an Environment object representing the map in which the agent must plan. goal_dist: a float representing the length of a single branch in the RRT tree for the agent's planner. rrt_iters: the number of iterations to run for RRT at each spin_once. """ self.antenna = Antenna() # Assign interaction callbacks for messages Agent.received_bid = received_bid Agent.received_waypoints = received_waypoints self.curr_time = 0.0 # Simulation time. Updated externally self.mode = mode self.token_holder = False # Keeps track of other agents' current bids for PPI # (potential path improvement) at any given time: self.bids = {} # Keeps track of other agents' plans so that we can # add the other agents as obstacles when replanning: self.other_agent_plans = {} # Initial state and environment self.start = start_pos self.goal = goal_pos self.pos = self.start self.environment = environment self.rrt = RRTstar(self.start, self.goal, self.environment, goal_dist, max_iter=rrt_iters) self.goal_dist = goal_dist # curr_plan is the currently executing plan; best_plan is a lower-cost path # than curr_plan, if one exists. The cost difference is the bid! self.curr_plan = Path() self.best_plan = Path() # Register as listener for different kinds of messages self.antenna.on_message("peers", self.received_id) self.antenna.on_message("bids", self.received_bid) self.antenna.on_message("waypoints", self.received_waypoints) """ The following methods represent the interaction component of DMA-RRT as described in algorithms 5 and 8. """ ########################################################################## def broadcast_id(self): msg = {"topic":TOPIC_PEERS} self.antenna.broadcast(TOPIC_PEERS, msg) def received_id(self, sender_id, msg): if sender_id != self.antenna.uuid: self.bids[sender_id] = 0.0 self.other_agent_plans[sender_id] = Path() def broadcast_bid(self, bid): msg = {"topic":TOPIC_BIDS, "bid":bid} self.antenna.broadcast(TOPIC_BIDS, msg) def broadcast_waypoints(self, winner_id): msg = {"topic":TOPIC_WAYPOINTS, "plan":self.curr_plan, "winner_id":winner_id} self.antenna.broadcast(TOPIC_WAYPOINTS, msg) def received_bid(self, sender_id, msg): """ Callback for messages over the network. """ raise NotImplementedError def received_waypoints(self, sender_id, msg): """ Callback for messages over the network. """ raise NotImplementedError ########################################################################## def at_goal(self): """ Checks if the agent's current location is the goal location. """ dist = np.sqrt((self.pos[0]-self.goal[0])**2 + \ (self.pos[1]-self.goal[1])**2) if dist <= 0.3: return True return False def update_time(self, curr_time): """ Update the internal time counter. """ self.curr_time = curr_time def spin(self, rate): """ Runs the agent's individual component on a timer until it is sufficiently close to the goal. Args: rate: float representing the rate for the spin, in Hz. """ # go until agent has reached its goal state while not self.at_goal(): self.spin_once() time.sleep(1.0 / rate) def spin_once(self): """ Runs the agent's individual DMA-RRT component once. The interaction component is handled using Agent callbacks. """ # Move agent if we have reached the next node if self.curr_plan.nodes: if self.curr_time in self.curr_plan.ts_dict.keys(): self.pos = (self.curr_plan.ts_dict[self.curr_time].x, self.curr_plan.ts_dict[self.curr_time].y) # curr_time may have moved on past the plans timestamps elif self.curr_time > self.curr_plan.nodes[-1].stamp: self.pos = (self.curr_plan.nodes[-1].x, self.curr_plan.nodes[-1].y)
class AntennaTrackingController: """ This class will controll all antenna calculation loop. It has the responsability to ensure we can fetch all neccessary data in order to make the system working properly """ # MAVLink packet id for GPS. See: # https://pixhawk.ethz.ch/mavlink/#GLOBAL_POSITION_INT MAVLINK_GPS_ID = 33 def __init__(self): """ Constructor """ def start(self, verbose=True, use_internal_gps=False): """ Start execution of the main loop This is the central point of the antenna tracking system. It put all together the data and trigger calculations. Then a nice output is given to STDOUT. """ # Display some funky ascii self.greeting() # Setup antenna tracking system self.antenna = Antenna(use_internal_gps) if self.antenna.ready: while True: # Apply a pwm according to the calculations self.antenna.update_target_orientation() # time.sleep(0.2) NOOOO if verbose: self.antenna.print_current_data() else: logging.error( 'Initialization aborted due to unmet startup conditions for one or more module.' ) self.stop() def stop(self): """ Gracefully stop antenna tracking controller """ logging.info('Closing antenna tracking system') # Close threads self.antenna.close() def greeting(self): """ Welcome message """ print(""" ___ _ _ _ _ / _ \ | | | | | | (_) / /_\ \_ __ | |_ ___ _ __ _ __ __ _ | |_ _ __ __ _ ___| | ___ _ __ __ _ | _ | '_ \| __/ _ \ '_ \| '_ \ / _` | | __| '__/ _` |/ __| |/ / | '_ \ / _` | | | | | | | | || __/ | | | | | | (_| | | |_| | | (_| | (__| <| | | | | (_| | \_| |_/_| |_|\__\___|_| |_|_| |_|\__,_| \__|_| \__,_|\___|_|\_\_|_| |_|\__, | __/ | _.--l--._ |___/ .` | `. .` `. | .` `. .` ` | .` `. POWERED BY DRONOLAB / __ .|.` __ \ Source code: github.com/dronolab/antenna_tracking | ''--._ V _.--'' | License: MIT | _ (") _ | | __..--' ^ '--..__ | _ \\ .`|`. /-.) `. .` | `. .` `. .` | `. .` `._ | _.`| `--l--` | | / . \\ / / \\ \\ / / \\ \\ """)
class Simulator(object): def __init__(self): self.wind_speed = 5.0 # default wind speed self.coherent_pow_flg = True # add coherent power self.coh_integrate_time = 0.001 # coherent integrateed time self.num_angles = 360 # integrated angle resolution self.interface_flg = 1 # curvature surface self.ddm_cov_factor = 5 # cov mode factor for ddm # # atmosphere loss for signal propagation 0.5 dB self.atmospheric_loss = pow(10.0, (0.5 / 10.0)) # # members self.geometry = Geometry() self.nadir_RF = Antenna() self.zenith_RF = Antenna() self.signal = Signal() self.power_waveform = Waveform(True, 1000) self.interface = Interface() def plot_delay_waveform(self, flg=False): """ plot delay simulated waveform """ if flg: waveform = self.integrate_waveform title = "Integrated waveform" else: waveform = self.waveform title = "Delay waveform" noise_level = waveform[0] plt.figure() plt.plot(self.wave_range / 1000.0, 10.0 * np.log10(waveform / noise_level), '*-') plt.grid() plt.title(title) plt.xlabel("Range from specular [km]") plt.ylabel("SNR [dB]") plt.ylim(0, 5) plt.xlim(-1.0, 5.0) plt.tight_layout() plt.show() def plot_power_ddm(self): """ plot scattered power DDM """ plt.figure(figsize=(4, 3)) noise_level = self.ddm.min() extent = [ self.wave_range[0] / 1000.0, self.wave_range[-1] / 1000.0, -self.dopp_bin * self.center_dopp / 1000.0, self.dopp_bin * self.center_dopp / 1000.0 ] plt.imshow(self.ddm, extent=extent, vmin=noise_level, vmax=max(self.ddm[self.center_dopp, :]), cmap='jet', aspect='auto') plt.title("Scattered power DDM") plt.xlabel("Range from specular [km]") plt.ylabel("Doppler [kHz]") plt.colorbar() plt.tight_layout() plt.show() def plot_scattered_area(self, flg=True): """ plot scattered area """ if flg: sca_area = self.eff_area title = "Effective scatter area" else: sca_area = self.phy_area title = "Physical scatter area" plt.figure(figsize=(4, 3)) noise_level = sca_area.min() max_pow = max(sca_area[self.center_dopp, :]) extent = [ self.wave_range[0] / 1000.0, self.wave_range[-1] / 1000.0, -self.dopp_bin * self.center_dopp / 1000.0, self.dopp_bin * self.center_dopp / 1000.0 ] plt.imshow(sca_area, extent=extent, vmin=noise_level, vmax=max_pow, cmap='jet', aspect='auto') plt.title(title) plt.xlabel("Range from specular [km]") plt.ylabel("Doppler [kHz]") plt.colorbar() plt.tight_layout() plt.show() ########################################################################### def compute_direct_power(self, transmit_pow): """ compute direct signal power """ # # receiver body frame bf_e, bf_h, bf_k = self.zenith_RF.get_antenna_bf() # # receiver body frame to specular self.geometry.BF2spfs(bf_e, bf_h, bf_k) scat_vec, rang = self.geometry.compute_r2t_vector() angles = self.geometry.compute_antenna_gain_pos(scat_vec) directivity = pow(10.0, (self.nadir_RF.get_receiver_gain(angles)) / 10.0) tmp = const.C_LIGHT / (self.signal.freq * 4.0 * const.PI * rang) self.direct_pow = pow(tmp, 2) self.direct_pow *= transmit_pow * directivity / self.atmospheric_loss def correlate_direct_signal(self): sin_arg = 2 * self.zenith_RF.filter_bb_bw / self.sampling_rate sin_arg *= np.arange(0, self.range_samples_len) sin_arg[sin_arg == 0.0] = 1.0 sin_arg = np.sinc(sin_arg) self.nd_nr_cov = abs(sin_arg) self.sd_nr_cov = np.convolve(sin_arg, self.signal.lambda_fun, mode="same") self.sd_nr_cov = np.abs(self.sd_nr_cov) max_value = self.sd_nr_cov.max() if max_value > 0.0: self.sd_nr_cov = self.sd_nr_cov / max_value for i in range(self.dopps): power = self.power[:, i] pass ########################################################################### def compute_coherent_power(self, scat_vec): """ compute coherent power at scat_vec diretion, commonly coherent relection accur at specular point """ # # compute receiver antenna gain at scat_vec diretion # # receiver body frame bf_e, bf_h, bf_k = self.nadir_RF.get_antenna_bf() # # receiver body frame to specular self.geometry.BF2spfs(bf_e, bf_h, bf_k) angles = self.geometry.compute_antenna_gain_pos(scat_vec) directivity = pow(10.0, (self.nadir_RF.get_receiver_gain(angles)) / 10.0) # # specular point sinc function self.cosi = cos(self.geometry.tx_inc) self.tani = tan(self.geometry.tx_inc) self.sinc_dopps = np.zeros(self.dopps) sinc_arg = self.dopp_bin * self.coh_integrate_time if sinc_arg == 0.0: self.sinc_dopps[self.center_dopp] = 1.0 else: self.sinc_dopps[self.center_dopp] = pow(np.sinc(sinc_arg), 2) # # compute fresnel coefficients self.interface.compute_fresnel(self.geometry.tx_inc) # # get corherent power tmp = 4.0 * const.PI * self.interface.sigma_z * self.cosi coherent_pow = self.signal.trans_pow * self.interface.fresnel coherent_pow *= exp(-1.0 * pow(tmp / self.signal.wavelen, 2)) tmp = const.C_LIGHT * self.coh_integrate_time tmp /= (4.0 * const.PI * self.signal.freq) tmp /= (norm(self.geometry.tx_spf) + norm(self.geometry.rx_spf)) coherent_pow *= directivity * self.sinc_dopps[self.center_dopp] coherent_pow *= pow(tmp, 2) / self.atmospheric_loss self.coherent_pow = coherent_pow def set_pow_waveform(self, init_range, sampling_rate): """ set power waveform for delays computation """ self.power_waveform.sampling_rate = sampling_rate self.power_waveform.set_init_range(init_range) def set_nadir_antenna(self, gain, temp, figure, filter_bb_bw, antenna_flg=True): """ set antenna attitude information for receiver antenna gain computation """ self.nadir_RF.set_receiver(gain, temp, figure, filter_bb_bw, antenna_flg) def set_radar_signal(self, sampling_rate, filter_bb_bw, exponent): """ initailze the bistatic radar signal """ self.signal.set_radar_signal(sampling_rate, filter_bb_bw) # # compute corelation function of WAF self.signal.compute_lambda() self.isotropic_factor = (self.signal.wavelen**2) / (4.0 * const.PI)**3 self.dt = const.C_LIGHT / sampling_rate # just for computation later # # compute the transmit power ele = const.PI / 2 - self.geometry.tx_inc self.signal.compute_transmit_power(self.signal, ele) def set_interface(self, wind_speed): self.interface.ws = wind_speed self.interface.set_polarization(self.polar_mode) def configure_radar_geometry(self, tx, tv, rx, rv, undulation_flg=True): """ set bistatic radar configuration, need the ecef postion and velocity of transimiter and receiver, compute specular point postion. function can also account for the undualtion of geoid """ self.geometry.tx_pos = np.asarray(tx) self.geometry.tx_vel = np.asarray(tv) self.geometry.rx_pos = np.asarray(rx) self.geometry.rx_vel = np.asarray(rv) # # compute the specular point self.geometry.compute_sp_pos(undulation_flg) def earth_curvature_appro(self, tau, x): """ modified surface glisten zone coordinations for earth curvature """ rad = norm(x[:2]) az = atan2(x[1], x[0]) x[2] = sqrt(const.RE_WGS84**2 - rad**2) - const.RE_WGS84 rr = norm(self.geometry.rx_spf - x) rt = norm(self.geometry.tx_spf - x) delay = rr + rt - self.geometry.rrt - self.sp_delay rad *= sqrt(tau / delay) x[0] = rad * cos(az) x[1] = rad * sin(az) x[2] = sqrt(const.RE_WGS84**2 - rad**2) - const.RE_WGS84 def compute_sinc(self, dopp): """ compute doppler sinc function """ sinc_arg = (np.arange(self.dopps) - self.center_dopp) * self.dopp_bin sinc_arg = (dopp - sinc_arg) * self.coh_integrate_time ind = sinc_arg != 0.0 self.sinc_dopps[ind] = pow(np.sinc(sinc_arg[ind]), 2) self.sinc_dopps[~ind] = 1.0 def delay_integration(self, tau, a, c, delta): """ integration points over the surface ellipse for each range sample """ x = np.zeros(3) pow_tau = np.zeros(self.dopps) phy_area = np.zeros(self.dopps) eff_area = np.zeros(self.dopps) left_side = -1.0 * (self.center_dopp + 0.5) * self.dopp_bin for i in range(self.num_angles): # # surface point calculation theta = i * delta x[0] = a * self.cosi * cos(theta) x[1] = a * sin(theta) + c # # surface point earth curvature modified if self.interface_flg == 1: self.earth_curvature_appro(tau, x) # # surface point scatter vector and scatter area inc_vec, sca_vec, jacob, coeff = self.geometry.compute_scattering_vector( x) # # surface point relative doppler shift to the specular point dopp = self.geometry.doppler_shift(inc_vec, sca_vec, self.signal.freq) - self.sp_dopp # if self.dopps % 2 == 0: # dopp -= self.dopp_bin # # sinc function self.compute_sinc(dopp) # # reflected coeffcient simga0 = self.interface.compute_scattered_coeff( inc_vec, sca_vec, self.geometry.tx_az) # # receicer antenna gain at the surface point direction angles = self.geometry.compute_antenna_gain_pos(inc_vec) rev_gain_db = self.nadir_RF.get_receiver_gain(angles) directivity = pow(10.0, rev_gain_db / 10.0) # # a factor for correlation calculation factor = directivity * self.isotropic_factor * simga0 * jacob * coeff if i == 0: # # restore the first surface point fx = np.copy(x[:2]) px = np.copy(x[:2]) # the former point relative to current one fst_dopp = pre_dopp = dopp fst_jac = pre_jac = jacob fst_ft = factor * self.sinc_dopps pre_ft = fst_ft.copy() fst_area = jacob * self.sinc_dopps pre_area = fst_area.copy() continue diff_ang = abs(atan2(x[1], x[0]) - atan2(px[1], px[0])) new_theta = min(diff_ang, 2.0 * const.PI - diff_ang) px = np.copy(x[:2]) tmp = factor * self.sinc_dopps area = jacob * self.sinc_dopps pow_tau += new_theta * (tmp + pre_ft) / 2.0 # accumulate the power ind = int(((dopp + pre_dopp) / 2.0 - left_side) // self.dopp_bin) if (ind >= 0) and (ind < self.dopps): phy_area[ind] += (jacob + pre_jac) / 2.0 * new_theta eff_area += new_theta * (area + pre_area) / 2.0 pre_dopp = dopp pre_jac = jacob pre_ft = tmp.copy() pre_area = area.copy() if i == self.num_angles - 1: # # intergration to finish the whole ellipse, connect # # the last point to the first point diff_ang = abs(atan2(fx[1], fx[0]) - atan2(x[1], x[0])) new_theta = min(diff_ang, 2.0 * const.PI - diff_ang) pow_tau += new_theta * (fst_ft + tmp) / 2.0 # accumulate the power ind = int( ((dopp + fst_dopp) / 2.0 - left_side) // self.dopp_bin) if (ind >= 0) and (ind < self.dopps): phy_area[ind] += (jacob + fst_jac) / 2.0 * new_theta eff_area += new_theta * (fst_area + area) / 2.0 return pow_tau, phy_area, eff_area def compute_noise_floor(self): """ compute noise floor """ eta_factor = 1.0 self.noise_floor = eta_factor * pow(10.0, self.nadir_RF.noise_power / 10.0) self.noise_floor /= self.nadir_RF.filter_bb_bw * self.coh_integrate_time def compute_power_waveform(self, ind): """ get lambda function """ lam_len = self.signal.lambda_size half_lam = lam_len // 2 waveform_conv = np.convolve(self.power[:, ind], self.signal.lambda_fun, mode="same") area_conv = np.convolve(self.dis_eff_area[:, ind], self.signal.lambda_fun, mode="same") # # compute delay power waveform tmp = waveform_conv[half_lam:half_lam + self.delays] tmp *= self.signal.trans_pow * self.dt / self.atmospheric_loss tmp += self.noise_floor if lam_len > self.delays: lam_len = self.delays tmp[:lam_len] += self.coherent_pow * self.signal.lambda_fun[:lam_len] return abs(tmp), area_conv[half_lam:half_lam + self.delays] def compute_ddm(self): """ compute ddm of scattered surface """ half_lam = self.signal.lambda_size // 2 self.ddm = np.zeros((self.dopps, self.delays)) self.eff_area = np.zeros((self.dopps, self.delays)) self.phy_area = self.dis_phy_area[half_lam:half_lam + self.delays, range(self.dopps)].T # # zero doppler shift delay waveform for i in range(self.dopps): sca_pow, eff_area = self.compute_power_waveform(i) self.ddm[i, :] = sca_pow self.eff_area[i, :] = eff_area # # integrated waveform self.integrate_waveform = self.ddm.sum(axis=0) if not hasattr(self, "wave_range"): self.power_waveform.set_waveform(self.ddm[self.center_dopp, :]) self.power_waveform.compute_waveform_delays() self.wave_range = self.power_waveform.get_range_waveform() self.wave_range -= self.geometry.geometric_delay def compute_center_waveform(self): """ compute delay power waveform """ self.compute_noise_floor() self.waveform, _ = self.compute_power_waveform(self.center_dopp) # # compute spatical delays of delay waveform in meters self.power_waveform.set_waveform(self.waveform) self.power_waveform.compute_waveform_delays() self.wave_range = self.power_waveform.get_range_waveform() self.wave_range -= self.geometry.geometric_delay def compute_power_distribution(self): """ Computation power distribution over reflecting surface origin located at sample = gnss_signal.lambda_size """ # # signal correlation starting postion lam_len = self.signal.lambda_size end = self.range_samples_len - lam_len self.power = np.zeros((self.range_samples_len, self.dopps)) self.dis_phy_area = np.zeros((self.range_samples_len, self.dopps)) self.dis_eff_area = np.zeros((self.range_samples_len, self.dopps)) for i in range(lam_len, end): # # compute relative delay tau = (i - lam_len) * self.dt tau = 1.0e-6 if i == lam_len else tau # # compute absolute delay tau_abs = tau + self.sp_delay a = tau_abs / self.cosi**2 * sqrt(1.0 - self.sp_delay / tau_abs) c = self.tani / self.cosi * tau delta = 2.0 * const.PI / self.num_angles sca_pow, phy_area, eff_area = self.delay_integration( tau, a, c, delta) self.power[i, :] = sca_pow self.dis_phy_area[i, :] = phy_area self.dis_eff_area[i, :] = eff_area def compute_sp_info(self): """ compute the delay/dopper on the specular point, also calculate the coherent power on the specular point for the coherent reflection """ # # compute scattering vector inc_vec = -1.0 * self.geometry.tx_spf / norm(self.geometry.tx_spf) scat_vec = self.geometry.rx_spf / norm(self.geometry.rx_spf) # # delay and dopper at specular point self.sp_dopp = self.geometry.doppler_shift(inc_vec, scat_vec, self.signal.freq) self.sp_delay = self.geometry.geometric_delay # # coherent power if self.coherent_pow_flg: self.compute_coherent_power(scat_vec) def set_model(self, rx_pos, rx_vel, tx_pos, tx_vel, cov_mode=False): """ set model for simulator initalization""" self.ddm_cov_mode = cov_mode # # equal 244ns( 1/(1/1023000/4)), it is ddm delay sampling rate, self.sampling_rate = 4091750.0 # 4092000 self.range_len_exponent = 8 self.delays = 17 # DDM delay chips self.dopps = 11 # DDM doppler bins self.dopp_bin = 500.0 # doppler resolution unit in Hz self.filter_bb_bw = 5000000.0 # receiver baseband bandwidth in Hz self.polar_mode = "RL" # poliariztion of reflected signal # # variable initialize if self.ddm_cov_mode: self.dopps = (self.dopps - 1) * 2 * self.ddm_cov_factor self.center_dopp = self.dopps // 2 self.range_samples_len = 2**self.range_len_exponent # # set bistatic radar geometry self.configure_radar_geometry(tx_pos, tx_vel, rx_pos, rx_vel, True) # # set interface self.set_interface(self.wind_speed) # # set radar signal self.set_radar_signal(self.sampling_rate, self.filter_bb_bw, self.range_len_exponent) # # set intrument information self.gain = 0.0 self.antenna_temperature = 200 self.noise_figure = 3.0 self.set_nadir_antenna(self.gain, self.antenna_temperature, self.noise_figure, self.filter_bb_bw, False) # # set power waveform information init_range = self.geometry.geometric_delay init_range -= (self.signal.lambda_size // 2 + 1) * self.dt self.set_pow_waveform(init_range, self.sampling_rate) def simulate(self, rx_pos, rx_vel, tx_pos, tx_vel): self.set_model(rx_pos, rx_vel, tx_pos, tx_vel) self.compute_sp_info() self.compute_power_distribution() self.compute_center_waveform() self.compute_ddm() # self.output_subddm() return self.waveform, self.integrate_waveform, self.wave_range
class Application: def __init__(self): self.display = (1000, 800) # window'un boyutlari self.mouseX = 0 # mouse hareketinin x koordinati self.mouseY = 0 # mouse hareketinin y koordinati self.flag = False self.flag2 = False self.currentValue = 0 self.antenna = Antenna() self.plane = Plane() self.ground = Ground(100, 100) # ground'un boyutlari self.sidebar = SideBar() def resetCamera(self): glMatrixMode( GL_PROJECTION ) # characteristics of camera such as clip planes, field of view, projection method glLoadIdentity() # replace the current matrix with the identity matrix width, height = self.display # display'in degerleri width ve height'a atandi gluPerspective(90.0, width / float(height), 1, 200.0) # set up a perspective projection matrix glTranslatef(0.0, 0.0, -5) # multiply the current matrix by a translation matrix glEnable(GL_DEPTH_TEST) # enable server-side GL capabilities glMatrixMode( GL_MODELVIEW ) # model matrix defines the frame’s position of the primitives you are going to draw # ModelView is the matrix that represents your camera(position, pointing and up vector.) # The reason for two separate matrices, instead of one, is that lighting is applied after the modelview view matrix # (i.e. on eye coordinates) and before the projection matrix. Otherwise, the matrices could be combined. def start(self): glutInit(sys.argv) # used to initialize the GLUT library pygame.init() # initialize all imported pygame modules self.screen = pygame.display.set_mode( self.display, OPENGL | DOUBLEBUF | OPENGLBLIT) # initialize a window or screen for display glLightfv(GL_LIGHT0, GL_POSITION, (-40, 200, 100, 0.0)) # set light source parameters glLightfv(GL_LIGHT0, GL_AMBIENT, (0.2, 0.2, 0.2, 1.0)) # set light source parameters glLightfv(GL_LIGHT0, GL_DIFFUSE, (0.5, 0.5, 0.5, 1.0)) # set light source parameters glEnable(GL_LIGHT0) # enable server-side GL capabilities glEnable(GL_LIGHTING) # enable server-side GL capabilities glEnable(GL_COLOR_MATERIAL) # enable server-side GL capabilities glEnable(GL_DEPTH_TEST) # enable server-side GL capabilities glShadeModel(GL_SMOOTH) # most obj files expect to be smooth-shaded self.resetCamera() self.antenna.prepare() # antenna objesi olusturuldu self.plane.prepare() # plane objesi olusturuldu self.loop() def check(self): glMatrixMode(GL_PROJECTION) # kamera ayarlarını sıfırla for event in pygame.event.get( ): # pygame.event.get = (get events from the queue) if event.type == pygame.QUIT: self.plane.stop() # plane objesi icin thread sona erer pygame.quit() # uninitialize all pygame modules quit() if event.type == pygame.MOUSEBUTTONDOWN: # eger mouse'a basili ise if event.button == 4: # forward glScaled(1.05, 1.05, 1.05) # zoom-in elif event.button == 5: # backward glScaled(0.95, 0.95, 0.95) # zoom-out if pygame.key.get_pressed()[K_LCTRL] and pygame.mouse.get_pressed( )[0]: # object rotation (CTRL ve mouse'un sol butonuna basilmis ise) if self.flag == True: # ilk basistaki hareketi engellemek icin self.mouseX, self.mouseY = pygame.mouse.get_rel( ) # get the amount of mouse movement glRotatef(self.mouseX / 5, 0.0, 0.0, 1.0) glRotatef(self.mouseY / 5, cos(radians(self.currentValue)), abs(sin(radians(self.currentValue))), 0.0) self.currentValue += self.mouseX / 5 elif self.flag == False: pygame.mouse.get_rel() # get the amount of mouse movement self.flag = True else: self.flag = False if pygame.key.get_pressed()[K_LCTRL] and pygame.mouse.get_pressed( )[2]: # camera rotation (CTRL ve mouse'un sag kligine basilmis ise) if self.flag2 == True: # ilk basistaki hareketi engellemek icin self.mouseX, self.mouseY = pygame.mouse.get_rel( ) # get the amount of mouse movement glTranslatef(-self.mouseX / 25, self.mouseY / 25, 0.0) elif self.flag2 == False: pygame.mouse.get_rel() # get the amount of mouse movement self.flag2 = True else: self.flag2 = False if event.type == pygame.KEYDOWN and event.key == pygame.K_r: # eger klavyeye basilmissa ve basilan harf r ise self.currentValue = 0 self.resetCamera() glMatrixMode( GL_MODELVIEW ) # model çizmek için matrisi sıfırla. Applies subsequent matrix operations to the modelview matrix stack. def loop(self): self.plane.start() # plane objesi icin thread baslatilir self.sidebar.setFunc(self.antenna, self.plane) while True: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # clear buffers to preset values self.antenna.rotateToPoint(self.plane.coord[0], self.plane.coord[1], self.plane.coord[2]) self.check() # mouse ve klavye kontrolleri icin self.ground.draw() # ground objesini cizdir self.antenna.draw() # antenna objesini cizdir self.plane.draw() # plane objesini cizdir self.sidebar.draw() #sidebar objesini cizdir pygame.display.flip( ) # update the full display surface to the screen pygame.time.wait(10) # pause the program for an amount of time