ray without reflections
This commit is contained in:
parent
0ae6bdd382
commit
b28b79df83
188
libs/spacemap.py
188
libs/spacemap.py
|
|
@ -19,7 +19,7 @@ class SpaceBlock():
|
|||
self.has_transmitter = False
|
||||
self.loss_penetration = 0.0
|
||||
self.loss_reflection = -100.0
|
||||
self.related_rays = []
|
||||
self.prev_ray = None
|
||||
|
||||
def __mul__(self, val):
|
||||
return SpaceBlock(self.x * val, self.y * val, self.z * val)
|
||||
|
|
@ -49,6 +49,12 @@ class SpaceBlock():
|
|||
def __eq__(self, blk):
|
||||
return self.distance(blk) < FLOAT_TOLERANCE
|
||||
|
||||
def __contains__(self, lst):
|
||||
for each in lst:
|
||||
if self == each:
|
||||
return True
|
||||
return False
|
||||
|
||||
def includes(self, x, y, z=None, block_size=0.1):
|
||||
flag = x >= self.x and x < (self.x + block_size)
|
||||
flag = flag and y >= self.y and y < (self.y + block_size)
|
||||
|
|
@ -110,7 +116,7 @@ class SpaceRay():
|
|||
'''
|
||||
def __init__(self, point1, point2):
|
||||
self.start = point1
|
||||
if not isinstance(point2, SpaceBlock):
|
||||
if isinstance(point2, float):
|
||||
self.end = point1 + SpaceBlock(np.cos(point2), np.sin(point2)) * MAX_RANGE
|
||||
else:
|
||||
self.end = point2
|
||||
|
|
@ -122,16 +128,19 @@ class SpaceRay():
|
|||
self.angle_theta_cos = None
|
||||
self.angle_theta_tan = self.slope = None
|
||||
# power and propagation
|
||||
self.begininng_pwr = 0.0
|
||||
self.begininng_phase = 0.0
|
||||
self.this_starting_pwr = 0.0
|
||||
self.this_starting_phase = 0.0
|
||||
self.this_ending_pwr = 0.0
|
||||
self.this_ending_phase = 0.0
|
||||
self.this_pass_through_loss = None
|
||||
self.this_pass_through_blks = None
|
||||
self.this_gamma = None
|
||||
self.loss_total = None
|
||||
self.init_pwr = None
|
||||
self.init_phase = None
|
||||
self.starting_loss = None
|
||||
self.starting_distance = None
|
||||
self.ending_pwr = None
|
||||
self.ending_phase = None
|
||||
self.ending_loss = None
|
||||
self.ending_distance = None
|
||||
self.passthrough_loss = None
|
||||
self.passthrough_blks = None
|
||||
self.reflection_blks = None
|
||||
self.gamma = 2.0
|
||||
# distance traveled prior to this distance
|
||||
self.distance_traveled = None
|
||||
self.reflection_count = 0
|
||||
# id
|
||||
|
|
@ -139,6 +148,23 @@ class SpaceRay():
|
|||
self.prev_ray = None
|
||||
self.next_rays = []
|
||||
|
||||
def __eq__(self, spaceray):
|
||||
return (self.start - self.end) == (spaceray.start - spaceray.end)
|
||||
|
||||
def __contains__(self, lst):
|
||||
for each in lst:
|
||||
if self == each:
|
||||
return True
|
||||
return False
|
||||
|
||||
def __str__(self):
|
||||
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)
|
||||
)
|
||||
|
||||
def getAngle(self, degree=False):
|
||||
if self.angle_theta is None:
|
||||
self.angle_theta = np.arctan2(
|
||||
|
|
@ -174,65 +200,81 @@ class SpaceRay():
|
|||
self.distance = self.start.distance(self.end)
|
||||
return self.distance
|
||||
|
||||
def setTravelDistance(self, prior_distance):
|
||||
self.distance_traveled = prior_distance + self.getDistance()
|
||||
def setStartingDistance(self, val):
|
||||
self.starting_distance = val
|
||||
|
||||
def getTraveledDistance(self):
|
||||
if self.starting_distance is None:
|
||||
print("need to run `setStartingLoss` first")
|
||||
return
|
||||
if self.ending_distance is None:
|
||||
self.ending_distance = self.starting_distance + self.getDistance()
|
||||
return self.ending_distance
|
||||
|
||||
def derivePassAndReflectBlocks(self, space_map):
|
||||
self.this_pass_through_blks = []
|
||||
self.this_reflection_blks = []
|
||||
step_blk = SpaceBlock(self.getAngleThetaCos(), self.getAngleThetaSin()) * factor
|
||||
for i in range(1, int(self.getDistance() / factor)):
|
||||
self.passthrough_blks = []
|
||||
self.reflection_blks = []
|
||||
step_blk = SpaceBlock(self.getAngleThetaCos(), self.getAngleThetaSin()) * space_map.bs
|
||||
early_stop_flag = False
|
||||
for i in range(1, int(self.getDistance() / space_map.bs)):
|
||||
next_blk = self.start + step_blk * i
|
||||
# assume 2D
|
||||
x_idx, y_idx = [int(x) for x in (next_blk / factor).round()]
|
||||
if x_idx < bounds[0] and x_idx > -1 and y_idx < bounds[1] and y_idx > -1:
|
||||
if space_map.map[x_idx, y_idx].loss_penetration < 0:
|
||||
self.this_pass_through_blks.append(space_map.map[x_idx, y_idx])
|
||||
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:
|
||||
self.passthrough_blks.append(space_map.map[x_idx, y_idx])
|
||||
if space_map.map[x_idx, y_idx].loss_reflection > -100:
|
||||
self.this_reflection_blks.append(space_map.map[x_idx, y_idx])
|
||||
# space_map.map[x_idx, y_idx].related_rays.append(self)
|
||||
self.reflection_blks.append(space_map.map[x_idx, y_idx])
|
||||
continue
|
||||
if early_stop_flag:
|
||||
break
|
||||
|
||||
def getPassThroughLoss(self):
|
||||
if self.this_pass_through_blks is None:
|
||||
print("need to run `derivePassAndReflectBlocks` first")
|
||||
return
|
||||
self.this_pass_through_loss = np.sum([
|
||||
each.loss_penetration
|
||||
for each in self.this_pass_through_blks
|
||||
])
|
||||
if self.passthrough_loss is None:
|
||||
if self.passthrough_blks is None:
|
||||
print("need to run `derivePassAndReflectBlocks` first")
|
||||
return
|
||||
self.passthrough_loss = np.sum([
|
||||
each.loss_penetration
|
||||
for each in self.passthrough_blks
|
||||
])
|
||||
return self.passthrough_loss
|
||||
|
||||
def setTotalLoss(self, prior_loss):
|
||||
def getEndingLoss(self):
|
||||
'''
|
||||
excluding the end penetration/reflection loss
|
||||
'''
|
||||
if self.this_pass_through_loss is None:
|
||||
print("need to run `getPassThroughLoss` first")
|
||||
if self.starting_loss is None:
|
||||
print("need to run `setStartingLoss` first")
|
||||
return
|
||||
self.loss_total = prior_loss + self.this_pass_through_loss
|
||||
|
||||
def setInitPower(self, power, gamma=2.0):
|
||||
self.begininng_pwr = power
|
||||
self.this_gamma = gamma
|
||||
|
||||
def computeResultingPwr(self):
|
||||
if self.loss_total is None:
|
||||
print("need to run `setTotalLoss` first")
|
||||
if self.passthrough_loss is None and self.getPassThroughLoss() is None:
|
||||
return
|
||||
if self.begininng_pwr is None:
|
||||
self.ending_loss = self.starting_loss + self.passthrough_loss
|
||||
return self.ending_loss
|
||||
|
||||
def setStartingLoss(self, val):
|
||||
self.starting_loss = val
|
||||
|
||||
def setInitPower(self, amplitude, phase=0.0):
|
||||
self.init_pwr = amplitude
|
||||
self.init_phase = phase
|
||||
|
||||
def getEndingPower(self):
|
||||
if self.ending_loss is None:
|
||||
if self.getEndingLoss() is None:
|
||||
return
|
||||
if self.init_pwr is None:
|
||||
print("need to run `setInitPower` first")
|
||||
return
|
||||
if self.distance_traveled is None:
|
||||
print("need to run `setTravelDistance` first")
|
||||
return
|
||||
self.this_ending_pwr = log_gamma_dist(
|
||||
np.array([self.distance_traveled]),
|
||||
self.begininng_pwr,
|
||||
self.this_gamma,
|
||||
loss = self.loss_total,
|
||||
gaussian_noise = False,
|
||||
is_squared = False
|
||||
self.ending_pwr = log_gamma_dist(
|
||||
np.array([self.ending_distance]),
|
||||
self.init_pwr,
|
||||
self.gamma,
|
||||
loss = self.ending_loss,
|
||||
gaussian_noise = False
|
||||
)[0]
|
||||
return self.this_ending_pwr
|
||||
return self.ending_pwr
|
||||
|
||||
|
||||
class SpaceMap():
|
||||
|
|
@ -301,13 +343,45 @@ 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
|
||||
# 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.setPower(tx_power, self.env_gamma)
|
||||
ray.ray_id = "ray_{0:.3f}".format(direction)
|
||||
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 = []
|
||||
while len(rays) > 0:
|
||||
ray = rays.pop(0)
|
||||
# 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)
|
||||
continue
|
||||
return rx_loc_rays
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -16,19 +16,10 @@ from libs.plotting import plotSpace
|
|||
|
||||
def test():
|
||||
spacemap = SpaceMap(width=6.4, length=6.4, block_size=0.1)
|
||||
print(spacemap.getLosses())
|
||||
print(spacemap.getLoss(np.array([1, 2, 3]), 1))
|
||||
ray = SpaceRay(SpaceBlock(0.0, 0.0), SpaceBlock(2, 6.38))
|
||||
ray.derivePassAndReflectBlocks(spacemap)
|
||||
ray.getPassThroughLoss()
|
||||
ray.setTotalLoss(0.0)
|
||||
ray.setInitPower(0, gamma=2.0)
|
||||
ray.setTravelDistance(0.0)
|
||||
pwr = ray.computeResultingPwr()
|
||||
print("pwr = {}".format(pwr))
|
||||
print(ray.this_pass_through_blks[0].related_rays)
|
||||
print(ray.this_pass_through_blks[0])
|
||||
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)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
Loading…
Reference in New Issue