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()
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
    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()
Ejemplo n.º 4
0
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()
Ejemplo n.º 5
0
    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
Ejemplo n.º 6
0
 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()
Ejemplo n.º 7
0
 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
Ejemplo n.º 8
0
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)
Ejemplo n.º 9
0
 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
     ]
Ejemplo n.º 10
0
 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))
     ]
Ejemplo n.º 11
0
    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)
Ejemplo n.º 12
0

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
Ejemplo n.º 13
0
    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)
Ejemplo n.º 14
0
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--` |  |
                 / . \\
                / / \\ \\
               / /   \\ \\
        """)
Ejemplo n.º 16
0
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
Ejemplo n.º 17
0
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