From 0907bda23611e14678487b8a257858bf76bc3483 Mon Sep 17 00:00:00 2001 From: HappyZ Date: Thu, 23 May 2019 12:33:22 -0500 Subject: [PATCH] bug fix --- libs/models.py | 3 +- libs/spacemap.py | 189 ++++++++++++++++++++-------------- syngen_floorplan_multipath.py | 6 +- tests/spacemap.py | 25 +++-- 4 files changed, 129 insertions(+), 94 deletions(-) diff --git a/libs/models.py b/libs/models.py index c6ad811..c94fd6b 100644 --- a/libs/models.py +++ b/libs/models.py @@ -59,5 +59,6 @@ def log_gamma_floorplan( print("err: only support a single loc") return noise = normal(GAUSSIAN_NOISE_MEAN, GAUSSIAN_NOISE_STD) if gaussian_noise else 0.0 - rss, paths = floorplan.traceRay(pwr, tx_loc, rx_loc) + floorplan.traceRays(pwr, tx_loc) + rss, paths = floorplan.traceRay(rx_loc) return max(rss + noise, NOISE_FLOOR), paths diff --git a/libs/spacemap.py b/libs/spacemap.py index bcf6e42..7cdcd1c 100644 --- a/libs/spacemap.py +++ b/libs/spacemap.py @@ -303,6 +303,45 @@ class SpaceRay(): return self.ending_pwr +def getPathFromRay(ray, stop_blk, spacemap): + path = SpaceRay(ray.start, stop_blk) + # prevent 0 distance + if path.getDistance() < FLOAT_TOLERANCE: + return None + # inherit ray properties + path.derivePassAndReflectBlocks(spacemap) + # 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'): + if path.getEndingPower() <= NOISE_FLOOR: + return None + 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 + + class SpaceMap(): ''' TODO: extend to 3D @@ -341,6 +380,8 @@ class SpaceMap(): self.map[i, j].right = self.map[i+1, j] if i < self.map.shape[0]-1 else None # propagation + self.endpaths = [] + self.tx_loc = None self.env_gamma = 2.0 self.ray_trace_deg_step = 1.0 # according to VTC paper @@ -384,42 +425,56 @@ class SpaceMap(): def setEnvGamma(self, val: float): self.env_gamma = val - def traceRay(self, tx_power: float, tx_loc: SpaceBlock, rx_loc: SpaceBlock): - 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 traceRays(self, tx_power: float, tx_loc: SpaceBlock): + ''' + ''' + if self.tx_loc is not None and tx_loc == self.tx_loc: + return + self.endpaths = [] + self.tx_loc = tx_loc + rays = [] + for direction in np.arange(0, 359.99, self.ray_trace_deg_step): + ray = SpaceRay(tx_loc, direction / 180.0 * np.pi) + ray.setInitPower(tx_power, self.env_gamma) + ray.setStartingLoss(0.0) + ray.setStartingDistance(0.0) + rays.append(ray) + # fake_init_ray.next_rays.append(ray) + # BFS + 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 only have a LoS here + # safe to save this last ray (instead of path) + self.endpaths.append(ray) + continue + ref_blk = ray.reflection_blks[0] + path = getPathFromRay(ray, ref_blk, self) + # zero length + if path is None: + continue + # too weak + if path.getEndingPower() < NOISE_FLOOR: + self.endpaths.append(path) + continue + # penetrated ray + ray_p = getRayFromPath(path, ray.getAngle(), t='penetrate') + if ray_p is not None: + rays.append(ray_p) + # reflected ray + if ref_blk.getOrientation() is None: + # if no orientation info provided, cannot calculate reflected ray + continue + ray_r = getRayFromPath(path, 2.0 * ref_blk.getOrientation() - path.getAngle() , t='reflect') + if ray_r is not None: + rays.append(ray_r) + print("size of all found rays: {}".format(len(self.endpaths))) + def traceRay(self, rx_loc: SpaceBlock): + ''' + ''' def aggreatePower(paths): if not paths: return NOISE_FLOOR @@ -460,53 +515,29 @@ class SpaceMap(): for each in sorted(to_be_removed, reverse=True): del paths[each] - # # 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): - ray = SpaceRay(tx_loc, direction / 180.0 * np.pi) - ray.setInitPower(tx_power, self.env_gamma) - ray.setStartingLoss(0.0) - ray.setStartingDistance(0.0) - rays.append(ray) - # fake_init_ray.next_rays.append(ray) - # BFS + + if not self.endpaths: + return NOISE_FLOOR, [] 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: - # 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 + for path in self.endpaths: + current_p = path + target_p_found = None + while current_p is not None: + target_p = getPathFromRay(current_p, rx_loc, self) + if target_p is None: + break if ( - abs(path.getAngle() - ray.getAngle()) < - self.ray_trace_deg_tol * path.getTraveledDistance() and - path not in rx_loc_paths + abs(target_p.getAngle() - current_p.getAngle()) < + self.ray_trace_deg_tol * target_p.getTraveledDistance() and + target_p not in rx_loc_paths ): - rx_loc_paths.append(path) - continue - ref_blk = ray.reflection_blks[0] - path = getPathFromRay(ray, ref_blk) - # too weak - if path is None or path.getEndingPower() < NOISE_FLOOR: - continue - # penetrated ray - ray_p = getRayFromPath(path, ray.getAngle(), t='penetrate') - if ray_p is not None: - rays.append(ray_p) - # reflected ray - if ref_blk.getOrientation() is None: - # if no orientation info provided, cannot calculate reflected ray - continue - ray_r = getRayFromPath(path, 2.0 * ref_blk.getOrientation() - path.getAngle() , t='reflect') - if ray_r is not None: - rays.append(ray_r) + if target_p.getEndingPower() < NOISE_FLOOR: + break + target_p_found = target_p + current_p = current_p.prev_ray + if target_p_found is not None: + rx_loc_paths.append(target_p_found) + # clean up for too nearby paths removeRedundantPaths(rx_loc_paths) return aggreatePower(rx_loc_paths), rx_loc_paths diff --git a/syngen_floorplan_multipath.py b/syngen_floorplan_multipath.py index bea99e4..3a5496d 100644 --- a/syngen_floorplan_multipath.py +++ b/syngen_floorplan_multipath.py @@ -84,12 +84,13 @@ def generateData(floormap, tx_locs, args): for power in powers: rss_vec = [] starttime = int(time.time()) + tx_loc = SpaceBlock(0, 0) + floormap.traceRays(power, tx_loc) for j in range(0, rx_locs.shape[0], args.procnum): procs = [] results = Manager().dict() for kk in range(args.procnum): rx_loc = SpaceBlock(rx_locs[j, 0], rx_locs[j, 1]) - tx_loc = SpaceBlock(rx_locs[i, 0], rx_locs[i, 1]) proc = Process( target=log_gamma_floorplan_multi, args=(floormap, rx_loc, tx_loc, power, args.withnoise, results, kk) @@ -101,7 +102,6 @@ def generateData(floormap, tx_locs, args): rss_vec.extend([results[kk] for kk in range(args.procnum)]) # rx_loc = SpaceBlock(rx_locs[j, 0], rx_locs[j, 1]) - # tx_loc = SpaceBlock(rx_locs[i, 0], rx_locs[i, 1]) # rss, multipaths = log_gamma_floorplan( # floormap, # rx_loc, @@ -119,7 +119,7 @@ def generateData(floormap, tx_locs, args): duration = (int(time.time()) - starttime) print("duration: {}s ({:.2f}%) - len {}".format(duration, j/rx_locs.shape[0]*100.0, len(rss_vec))) - print("results: {}".format(rss_vec)) + # print("results: {}".format(rss_vec)) rss_map = convert_vector_to_mat(rx_locs, np.array(rss_vec), (64, 64)) with open("{}_{}.pickle".format(fp_base, int(power)), 'wb') as f: diff --git a/tests/spacemap.py b/tests/spacemap.py index 4443ef1..863d383 100644 --- a/tests/spacemap.py +++ b/tests/spacemap.py @@ -33,8 +33,8 @@ def test(): spacemap = SpaceMap(width=6.4, length=6.4, block_size=0.1) # add walls - wall_penetration = -20.0 - wall_reflection = -3.0 + wall_penetration = -30.0 + wall_reflection = -10.0 glass_penetration = -3.0 glass_reflection = -3.0 # walls @@ -52,15 +52,18 @@ def test(): spacemap.setOrientations(orientations) plotSpace(spacemap, cminmax=(-50, 0.0)) - return - rx_loc = SpaceBlock(6.25, 3.2) - rx_loc_rss, rx_loc_paths = spacemap.traceRay(0.0, SpaceBlock(0.0, 0.0), rx_loc) - multipaths = [] - for path in rx_loc_paths: - print("found path: {}".format(path)) - multipaths.extend(list(path)) - print("rss = {:.6f}dB".format(rx_loc_rss)) - plotSpace(spacemap, space_rays=multipaths, cminmax=(-50, 0.0)) + + rx_locs = [SpaceBlock(3.2, 3.2), SpaceBlock(5.2, 4.3)] + spacemap.traceRays(0.0, SpaceBlock(0.0, 0.0)) + for rx_loc in rx_locs: + rx_loc_rss, rx_loc_paths = spacemap.traceRay(rx_loc) + multipaths = [] + for path in rx_loc_paths: + print("found path: {}".format(path)) + multipaths.extend(list(path)) + print("rss = {:.6f}dB".format(rx_loc_rss)) + plotSpace(spacemap, space_rays=multipaths, cminmax=(-50, 0.0)) + if __name__ == "__main__":