diff --git a/libs/plotting.py b/libs/plotting.py index 766539a..79bda1a 100644 --- a/libs/plotting.py +++ b/libs/plotting.py @@ -9,7 +9,10 @@ from libs.consts import COLORMAP_MAX from libs.spacemap import SpaceMap -def plotSpace(space_map: SpaceMap): +def plotSpace( + space_map: SpaceMap, + cminmax: tuple = (COLORMAP_MIN, COLORMAP_MAX) +): ''' ''' tx_locs = space_map.getTransmitterLocs() @@ -24,8 +27,8 @@ def plotSpace(space_map: SpaceMap): cmap='hot', origin='lower', interpolation='nearest', - vmin=COLORMAP_MIN, - vmax=COLORMAP_MAX + vmin=cminmax[0], + vmax=cminmax[1] ) plt.colorbar() @@ -36,8 +39,8 @@ def plotSpace(space_map: SpaceMap): cmap='hot', origin='lower', interpolation='nearest', - vmin=COLORMAP_MIN, - vmax=COLORMAP_MAX + vmin=cminmax[0], + vmax=cminmax[1] ) plt.colorbar() @@ -52,7 +55,8 @@ def plotRSS( ori_rss: np.ndarray, est_rss: np.ndarray = None, est_tx_loc: np.ndarray = None, - true_tx_loc: np.ndarray = None + true_tx_loc: np.ndarray = None, + cminmax: tuple = (COLORMAP_MIN, COLORMAP_MAX) ): ''' ''' @@ -64,8 +68,8 @@ def plotRSS( cmap='hot', origin='lower', interpolation='nearest', - vmin=COLORMAP_MIN, - vmax=COLORMAP_MAX + vmin=cminmax[0], + vmax=cminmax[1] ) plt.colorbar() @@ -77,8 +81,8 @@ def plotRSS( cmap='hot', origin='lower', interpolation='nearest', - vmin=COLORMAP_MIN, - vmax=COLORMAP_MAX + vmin=cminmax[0], + vmax=cminmax[1] ) plt.colorbar() if est_tx_loc is not None: diff --git a/libs/spacemap.py b/libs/spacemap.py index 198266d..d44a657 100644 --- a/libs/spacemap.py +++ b/libs/spacemap.py @@ -4,6 +4,7 @@ import numpy as np from libs.consts import MAX_RANGE +from libs.consts import NOISE_FLOOR from libs.consts import FLOAT_TOLERANCE from libs.models import log_gamma_dist @@ -19,7 +20,6 @@ class SpaceBlock(): self.has_transmitter = False self.loss_penetration = 0.0 self.loss_reflection = -100.0 - self.prev_ray = None def __mul__(self, val): return SpaceBlock(self.x * val, self.y * val, self.z * val) @@ -146,7 +146,6 @@ class SpaceRay(): # id self.ray_id = '' self.prev_ray = None - self.next_rays = [] def __eq__(self, spaceray): return (self.start - self.end) == (spaceray.start - spaceray.end) @@ -161,8 +160,8 @@ class SpaceRay(): return ( "SpaceRay(start = {0}, end = {1}): ".format(self.start, self.end) + "pwr_init = {0:.2f}, pwr_end = {1:.2f}, ".format(self.init_pwr, self.ending_pwr) + - "loss_start = {0:.2f}, loss_end = {1:.2f}, ".format(self.starting_loss, self.ending_loss) + - "prev_ray = {}".format(self.prev_ray) + "loss_start = {0:.2f}, loss_end = {1:.2f}\n".format(self.starting_loss, self.ending_loss) + + " <- prev_ray = {}".format(self.prev_ray) ) def getAngle(self, degree=False): @@ -222,7 +221,7 @@ class SpaceRay(): x_idx, y_idx = [int(x) for x in (next_blk / space_map.bs).round()] if x_idx < space_map.map.shape[0] and x_idx > -1 and y_idx < space_map.map.shape[1] and y_idx > -1: early_stop_flag = True - if space_map.map[x_idx, y_idx].loss_penetration < 100: + if space_map.map[x_idx, y_idx].loss_penetration < 0.1: self.passthrough_blks.append(space_map.map[x_idx, y_idx]) if space_map.map[x_idx, y_idx].loss_reflection > -100: self.reflection_blks.append(space_map.map[x_idx, y_idx]) @@ -343,8 +342,51 @@ class SpaceMap(): self.env_gamma = val def traceRay(self, tx_power: float, tx_loc: SpaceBlock, rx_loc: SpaceBlock): - # round - rx_loc = ((rx_loc / self.bs).round() + 0.5) * self.bs + def getPathFromRay(ray, stop_blk): + path = SpaceRay(ray.start, stop_blk) + # prevent 0 distance + if path.getDistance() < FLOAT_TOLERANCE: + return None + # inherit ray properties + path.derivePassAndReflectBlocks(self) + # path.passthrough_blks = ray.passthrough_blks[:ray.passthrough_blks.index(stop_blk)] + path.setInitPower(ray.init_pwr, ray.gamma) + path.setStartingDistance(ray.starting_distance) + path.setStartingLoss(ray.starting_loss) + path.prev_ray = ray.prev_ray + # + path.getTraveledDistance() + path.getPassThroughLoss() + path.getEndingLoss() + # + path.getEndingPower() + return path + + def getRayFromPath(path, direction, t='penetrate'): + ray = SpaceRay(path.end, direction) + ray.setInitPower(path.init_pwr, path.gamma) + ray.setStartingDistance(path.getTraveledDistance()) + if t == 'penetrate': + ray.setStartingLoss(path.getEndingLoss() + path.end.getLoss()[0]) + elif t == 'reflect': + ray.setStartingLoss(path.getEndingLoss() + path.end.getLoss()[1]) + else: + ray.setStartingLoss(path.getEndingLoss()) + if ray.starting_loss < NOISE_FLOOR: + return None + ray.prev_ray = path + return ray + + def aggreatePower(paths): + if not paths: + return NOISE_FLOOR + sig_pwr = 0.0 + for path in paths: + sig_pwr += np.power(10, path.getEndingPower() / 10.0) + return 10.0 * np.log10(sig_pwr) + + # # round + # rx_loc = ((rx_loc / self.bs).round() + 0.5) * self.bs # fake_init_ray = SpaceRay(None, None) rays = [] for direction in np.arange(0, 359.99, self.ray_trace_deg_step): @@ -352,36 +394,38 @@ class SpaceMap(): ray.setInitPower(tx_power, self.env_gamma) ray.setStartingLoss(0.0) ray.setStartingDistance(0.0) - ray.derivePassAndReflectBlocks(self) rays.append(ray) # fake_init_ray.next_rays.append(ray) # BFS - rx_loc_rays = [] + rx_loc_paths = [] while len(rays) > 0: ray = rays.pop(0) + ray.derivePassAndReflectBlocks(self) # if no reflections exist, then only passing through, simple if not ray.reflection_blks: # if passing through the receiver block, we have a LoS here - if rx_loc in ray.passthrough_blks: - path = SpaceRay(ray.start, rx_loc) - # prevent 0 distance - if path.getDistance() < FLOAT_TOLERANCE: - continue - # inherit ray properties - path.passthrough_blks = ray.passthrough_blks[:ray.passthrough_blks.index(rx_loc)] - path.setInitPower(ray.init_pwr, ray.gamma) - path.setStartingDistance(ray.starting_distance) - path.setStartingLoss(ray.starting_loss) - path.prev_ray = ray.prev_ray - # - path.getTraveledDistance() - path.getPassThroughLoss() - path.getEndingLoss() - # - path.getEndingPower() - if path not in rx_loc_rays: - rx_loc_rays.append(path) + # if rx_loc in ray.passthrough_blks: + # use a different way to check if it passes through, as the angles may not be precise + path = getPathFromRay(ray, rx_loc) + if path is None or path.getEndingPower() < NOISE_FLOOR: + continue + if ( + abs(path.getAngle() - ray.getAngle()) < + self.ray_trace_deg_tol * path.getTraveledDistance() and + path not in rx_loc_paths + ): + rx_loc_paths.append(path) continue - return rx_loc_rays + ref_blk = ray.reflection_blks[0] + path = getPathFromRay(ray, ref_blk) + if path is None or path.getEndingPower() < NOISE_FLOOR: + continue + ray_p = getRayFromPath(path, ray.getAngle(), t='penetrate') + if ray_p is not None: + rays.append(ray_p) + # ray_r = getRayFromPath(path, path.getAngle() + 0.5 * np.pi, t='reflect') + # ray_r = getRayFromPath(path, path.getAngle() - 0.5 * np.pi, t='reflect') + + return aggreatePower(rx_loc_paths), rx_loc_paths diff --git a/tests/spacemap.py b/tests/spacemap.py index 4634f0b..a25dac5 100644 --- a/tests/spacemap.py +++ b/tests/spacemap.py @@ -16,10 +16,15 @@ from libs.plotting import plotSpace def test(): spacemap = SpaceMap(width=6.4, length=6.4, block_size=0.1) - plotSpace(spacemap) - rx_locs_rays = spacemap.traceRay(0.0, SpaceBlock(0.0, 0.0), SpaceBlock(6.25, 3.2)) - for ray in rx_locs_rays: - print(ray) + for i in range(10, 40): + spacemap.setLoss(i, 10, penetration=-5.0, reflection=-80.0) + spacemap.setLoss(i, 20, penetration=-5.0, reflection=-80.0) + plotSpace(spacemap, cminmax=(-50, 0.0)) + rx_loc = SpaceBlock(6.25, 3.2) + rx_loc_rss, rx_loc_paths = spacemap.traceRay(0.0, SpaceBlock(0.0, 0.0), rx_loc) + for path in rx_loc_paths: + print(path) + print(rx_loc_rss) if __name__ == "__main__":