class HumanWithActivity_py(object): """ This is a quick implementation of a more realistic human body model and its activity and its position. Parameters ---------- loc: ndarray(2,) Location of the human in xy-plane. direction: double Azimuth angle. reflectivities: dict The default value is {'skin':0.66,'shirt':0.64,'furniture':0.04} for tx mode (uplink IR) {'skin':0.42,'shirt':0.61,'furniture':0.04} for rx mode (downlink VL) mode: {'tx','rx'} Describe whether transmitting (tx) or receiving (rx) activity: {'calling','reading','usbdongle'} 'calling' denotes the LED or the PD is near the right ear. Meanwhile, 'reading' denotes the device is in front of the human's chest. 'usbdongle' denotes the use of LiFi usb dongles attached to a laptop on a desk. Attributes ---------- head: Cube_py Modeling the head body: Cube_py Modeling the body leg: Cube_py Modeling the leg chair: Cube_py Modeling the chair table: RectPlane_py Modeling the table ctrPoint: ndarray(3,) The center point of the human model normalVect: ndarray(3,) The human's direction listPlanes: list List of RectPlane_py mode: {'tx','rx'} It is either tx mode or rx mode pd: BareDetector_py Modeling the PD if the mode is 'rx' led: PointSource_py Modeling the LED if the mode is 'tx' Notes ----- The dimensions are fixed. a. head (15cm x 15cm x 20cm) b. body (40cm x 15cm x 80cm) c. legs (30cm x 15cm x 80cm) d. chair (40cm x 40cm x 40cm) e. desk (220cm x 90cm) with the height of 60cm The geometries and locations of the LED and PD are also fixed. Examples -------- .. plot:: :format: doctest :include-source: True >>> import matplotlib.pyplot as plt >>> import numpy as np >>> >>> from owcsimpy.geoobjects.models.humanwithactivity_py import HumanWithActivity_py as Human >>> from owcsimpy.geoutils.draw import draw >>> # Calling-sitting-rx >>> human_sitting = Human(loc=[2,2],direction=np.deg2rad(45), >>> activity='calling',position='sitting',mode='rx') >>> >>> # Calling-standing-tx >>> human_standing = Human(loc=[2,2],direction=np.deg2rad(45), >>> activity='calling',position='standing',mode='tx') >>> >>> # Plot >>> fig,axs = draw(subplots=True,figsize=(6,4),nrows=1,ncols=2,xlim=[0,3],ylim=[0,3],zlim=[0,3]) >>> >>> draw(figure=fig,axes=axs[0],planes=human_sitting.listPlanes, >>> vectors=Vector(coord=human_sitting.normalVect,refPoint=human_sitting.ctrPoint,which='cartesian'), >>> enablevect='False', >>> alphas=[plane.reflectivity for plane in human_sitting.listPlanes]); >>> >>> draw(figure=fig,axes=axs[0], >>> circles=human_sitting.pd,scales=5e3, >>> vectors=human_sitting.led); >>> >>> draw(figure=fig,axes=axs[1],planes=human_standing.listPlanes, >>> vectors=Vector(coord=human_standing.normalVect,refPoint=human_standing.ctrPoint,which='cartesian'), >>> enablevect='False', >>> alphas=[plane.reflectivity for plane in human_standing.listPlanes]); >>> >>> draw(figure=fig,axes=axs[1], >>> circles=human_standing.pd,scales=5e3, >>> vectors=human_standing.led); >>> >>> plt.show() """ def __init__(self, loc, direction, reflectivities={ 'skin': 1, 'shirt': 1, 'furniture': 1 }, mode='rx', activity='calling', position='standing', m=1, area=1e-4, FoV=np.deg2rad(90)): # Assertion checks assert len(loc) == 2 and m > 0 and area > 0 and 0 <= FoV <= np.pi / 2 # assert sorted( # [string.lower() for string in list(reflectivities.keys())] # ) == sorted(['chair','face','hair','shirt','table']), "keys name are wrong" assert mode.lower() == 'tx' or mode.lower() == 'rx',\ ("'mode' is not recognized! Should be either 'tx' or 'rx'") assert activity.lower() == 'calling' or activity.lower() == 'reading' or activity.lower() == 'usbdongle',\ ("'activity' is not recognized! Should be either 'calling', 'reading' or 'usbdongle'") assert position.lower() == 'standing' or position.lower() == 'sitting',\ ("'mode' is not recognized! Should be either 'standing' or 'sitting'") assert not(activity.lower() == 'usbdongle' and position.lower()=='standing'),\ ("cannot choose the `usbdongle` aciticity and the `standing` position.") # offsetHeight = 0.4 if position.lower() == 'standing' else 0 if mode.lower() == 'tx': # IR-LED (uplink) reflectivities = {'skin': 0.66, 'shirt': 0.64, 'furniture': 0.04} elif mode.lower() == 'rx': # VL-LED (downlink) reflectivities = {'skin': 0.42, 'shirt': 0.61, 'furniture': 0.04} # Head part self.head = Cube(Vector(np.array([1, np.deg2rad(90), np.deg2rad(0)])), ctrPoint=np.array([0, 0, offsetHeight + 1.3]), dimensions=[0.2, 0.15, 0.15], reflectivities={ 'p0': reflectivities['skin'], 'p1': reflectivities['skin'], 'p2': reflectivities['skin'], 'p3': reflectivities['skin'], 'p4': reflectivities['skin'], 'p5': reflectivities['skin'] }) self.head = self.head.rotate(direction, np.array([0, 0, 1])) self.head = self.head.translate(np.array([*loc, self.head.ctrPoint[2]])) # Body part self.body = Cube(Vector(np.array([1, np.deg2rad(90), np.deg2rad(0)])), ctrPoint=np.array([0, 0, offsetHeight + 0.8]), dimensions=[0.8, 0.4, 0.15], reflectivities={ 'p0': reflectivities['shirt'], 'p1': reflectivities['shirt'], 'p2': reflectivities['shirt'], 'p3': reflectivities['shirt'], 'p4': reflectivities['shirt'], 'p5': reflectivities['shirt'] }) self.body = self.body.rotate(direction, np.array([0, 0, 1])) self.body = self.body.translate(np.array([*loc, self.body.ctrPoint[2]])) if position.lower() == 'sitting': self.chair = Cube(Vector( np.array([1, np.deg2rad(90), np.deg2rad(0)])), ctrPoint=np.array([0, 0, 0.2]), dimensions=[0.4, 0.4, 0.4], reflectivities={ 'p0': reflectivities['furniture'], 'p1': reflectivities['shirt'], 'p2': reflectivities['shirt'], 'p3': reflectivities['furniture'], 'p4': reflectivities['furniture'], 'p5': reflectivities['furniture'] }) self.chair = self.chair.rotate(direction, np.array([0, 0, 1])) self.chair = self.chair.translate( np.array([*loc, 0]) + self.chair.ctrPoint) Rd = getRodriguesMtx(direction, np.array([0, 0, 1])) shiftedVect = ( Rd @ np.array([0.2 - 0.075, 0, 0]).reshape(3, 1)).reshape(-1) self.chair = self.chair.translate(shiftedVect + self.chair.ctrPoint) self.table = Cube(Vector( np.array([1, np.deg2rad(90), np.deg2rad(0)])), ctrPoint=np.array([0, 0, 0.3]), dimensions=[0.6, 1.2, 0.9], reflectivities={ 'p0': reflectivities['furniture'], 'p1': reflectivities['furniture'], 'p2': reflectivities['furniture'], 'p3': reflectivities['furniture'], 'p4': reflectivities['furniture'], 'p5': reflectivities['furniture'] }) self.table = self.table.rotate(direction, np.array([0, 0, 1])) self.table = self.table.translate( np.array([*loc, 0]) + self.table.ctrPoint) Rd = getRodriguesMtx(direction, np.array([0, 0, 1])) shiftedVect = (Rd @ np.array([1, 0, 0]).reshape(3, 1)).reshape(-1) self.table = self.table.translate(shiftedVect + self.table.ctrPoint) # The table is modeled a simple plane self.table = self.table.listPlanes[2] self.leg = None elif position.lower() == 'standing': self.leg = Cube(Vector(np.array([1, np.deg2rad(90), np.deg2rad(0)])), ctrPoint=np.array([0, 0, 0.4]), dimensions=[0.8, 0.3, 0.15], reflectivities={ 'p0': reflectivities['shirt'], 'p1': reflectivities['shirt'], 'p2': reflectivities['shirt'], 'p3': reflectivities['shirt'], 'p4': reflectivities['shirt'], 'p5': reflectivities['shirt'] }) self.leg = self.leg.rotate(direction, np.array([0, 0, 1])) self.leg = self.leg.translate( np.array([*loc, self.leg.ctrPoint[2]])) self.chair, self.table = None, None self.ctrPoint = np.array([0, 0, 1.2]) + np.array([*loc, 0]) self.normalVect = self.head.normalVect self.listPlanes = self.getPartition(Ps=1) self.mode = None self.pd = None self.led = None if activity.lower() == 'calling': polar = np.deg2rad(45) azimuth = self.listPlanes[1]._RectPlane_py__normalVect.spherical[ 2] + np.pi loc = self.head.ctrPoint + 0.15 * self.head.listPlanes[4].normalVect elif activity.lower() == 'reading': polar = np.deg2rad(50) azimuth = self.listPlanes[1]._RectPlane_py__normalVect.spherical[ 2] + np.pi loc = (self.ctrPoint + 0.5 * self.listPlanes[1].normalVect + np.array([0, 0, -0.2 + offsetHeight])) elif activity.lower() == 'usbdongle': polar = np.deg2rad(0) azimuth = self.listPlanes[1]._RectPlane_py__normalVect.spherical[ 2] + np.pi loc = (self.ctrPoint + 1 * self.listPlanes[1].normalVect + np.array([0, 0, -0.6])) else: raise ValueError("'activity' is not recognized! \ Should be either 'calling' or 'reading'") if mode.lower() == 'rx': self.mode = mode.lower() # PD self.pd = BareDetector(polar, azimuth, loc, area=area, FoV=FoV) elif mode.lower() == 'tx': self.mode = mode.lower() # LED self.led = PointSource(polar, azimuth, loc, m=m) else: raise ValueError("'mode' is not recognized! \ Should be either 'tx' or 'rx'") def getPartition(self, Ps=1, delta=None): """ Partition all objects. Parameters ---------- Ps: list List of number of partition of each side. delta: list Define the partition based on partition lengths Returns ------- list: A list of partitioned planes. Each plane is an instant of RectPlane_py. """ planes = [] if delta == None: planes.append(self.head.getPartition(Ps=Ps)) planes.append(self.body.getPartition(Ps=Ps)) if self.leg: planes.append(self.leg.getPartition(Ps=Ps)) if self.chair: planes.append(self.chair.getPartition(Ps=Ps)) if self.table: planes.append(self.table.getPartition(Ps=Ps)) else: if delta > 0.15: delta = 0.15 planes.append(self.head.getPartition(delta=delta)) planes.append(self.body.getPartition(delta=delta)) if self.leg: planes.append(self.leg.getPartition(delta=delta)) if self.chair: planes.append(self.chair.getPartition(delta=delta)) if self.table: planes.append(self.table.getPartition(delta=delta)) planes = list(flatten(planes)) return planes
def __init__(self, roomDim, humanLoc, humanDirection, chairLoc=None, chairDirection=0, mode='rx', activity='calling', position='standing'): # Assertion checks assert len(roomDim) == 3 and np.alltrue(np.array(roomDim) > 0) assert mode.lower() == 'tx' or mode.lower() == 'rx',\ ("'mode' is not recognized! Should be either 'tx' or 'rx'") assert activity.lower() == 'calling' or activity.lower() == 'reading' or activity.lower() == 'usbdongle',\ ("'activity' is not recognized! Should be either 'calling', 'reading' or 'usbdongle'") assert position.lower() == 'standing' or position.lower() == 'sitting',\ ("'mode' is not recognized! Should be either 'standing' or 'sitting'") assert not(activity.lower() == 'usbdongle' and position.lower()=='standing'),\ ("cannot choose the `usbdongle` aciticity and the `standing` position.") # Human and other elements self.human = Human(loc=humanLoc, direction=humanDirection, mode=mode, activity=activity, position=position) # Room # Reflectivities # Except the floor, which is modeled as a pinewood, other # parts are modeled with plasters rho_keys = ['b', 't', 's', 'n', 'e', 'w'] if mode.lower() == 'tx': # IR-LED (uplink) rho_vals = [0.92, 0.83, 0.83, 0.83, 0.83, 0.83] elif mode.lower() == 'rx': # VL-LED (downlink) rho_vals = [0.54, 0.76, 0.76, 0.76, 0.76, 0.76] reflectivities = { rho_keys[i]: rho_vals[i] for i in range(len(rho_keys)) } self.room = Room(dimensions=roomDim, identity=1, reflectivities=reflectivities) # A chair and a table self.chair, self.table, self.tableAsCube = None, None, None if chairLoc: self.chair = Cube(Vector( np.array([1, np.deg2rad(90), np.deg2rad(0)])), ctrPoint=np.array([0, 0, 0.2]), dimensions=[0.4, 0.4, 0.4], reflectivities={ 'p0': 0.04, 'p1': 0.04, 'p2': 0.04, 'p3': 0.04, 'p4': 0.04, 'p5': 0.04 }) self.chair = self.chair.rotate(chairDirection, np.array([0, 0, 1])) self.chair = self.chair.translate( np.array([*chairLoc, 0]) + self.chair.ctrPoint) Rd = getRodriguesMtx(chairDirection, np.array([0, 0, 1])) shiftedVect = ( Rd @ np.array([0.2, 0, 0]).reshape(3, 1)).reshape(-1) self.chair = self.chair.translate(shiftedVect + self.chair.ctrPoint) # The table's location is defined based on self.table = Cube(Vector( np.array([1, np.deg2rad(90), np.deg2rad(0)])), ctrPoint=np.array([0, 0, 0.3]), dimensions=[0.6, 1.2, 0.9], reflectivities={ 'p0': 0.04, 'p1': 0.04, 'p2': 0.04, 'p3': 0.04, 'p4': 0.04, 'p5': 0.04 }) self.table = self.table.rotate(chairDirection, np.array([0, 0, 1])) self.table = self.table.translate( np.array([*chairLoc, 0]) + self.table.ctrPoint) Rd = getRodriguesMtx(chairDirection, np.array([0, 0, 1])) shiftedVect = (Rd @ np.array([1, 0, 0]).reshape(3, 1)).reshape(-1) self.table = self.table.translate(shiftedVect + self.table.ctrPoint) # The table is modeled a simple plane self.tableAsCube = self.table self.table = self.table.listPlanes[2] # LED or PD self.led, self.pd = None, None if mode.lower() == 'rx': self.led = PointSource( np.pi, 0, np.array([self.room.L / 2, self.room.W / 2, self.room.H]), m=-np.log(2) / np.log(np.cos(np.deg2rad(40.)))) elif mode.lower() == 'tx': self.pd = BareDetector( np.pi, 0, np.array([self.room.L / 2, self.room.W / 2, self.room.H]), area=1e-4, FoV=np.deg2rad(85)) self.updateListPlanesAndCheckValidity()
def __init__(self, loc, direction, reflectivities={ 'skin': 1, 'shirt': 1, 'furniture': 1 }, mode='rx', activity='calling', position='standing', m=1, area=1e-4, FoV=np.deg2rad(90)): # Assertion checks assert len(loc) == 2 and m > 0 and area > 0 and 0 <= FoV <= np.pi / 2 # assert sorted( # [string.lower() for string in list(reflectivities.keys())] # ) == sorted(['chair','face','hair','shirt','table']), "keys name are wrong" assert mode.lower() == 'tx' or mode.lower() == 'rx',\ ("'mode' is not recognized! Should be either 'tx' or 'rx'") assert activity.lower() == 'calling' or activity.lower() == 'reading' or activity.lower() == 'usbdongle',\ ("'activity' is not recognized! Should be either 'calling', 'reading' or 'usbdongle'") assert position.lower() == 'standing' or position.lower() == 'sitting',\ ("'mode' is not recognized! Should be either 'standing' or 'sitting'") assert not(activity.lower() == 'usbdongle' and position.lower()=='standing'),\ ("cannot choose the `usbdongle` aciticity and the `standing` position.") # offsetHeight = 0.4 if position.lower() == 'standing' else 0 if mode.lower() == 'tx': # IR-LED (uplink) reflectivities = {'skin': 0.66, 'shirt': 0.64, 'furniture': 0.04} elif mode.lower() == 'rx': # VL-LED (downlink) reflectivities = {'skin': 0.42, 'shirt': 0.61, 'furniture': 0.04} # Head part self.head = Cube(Vector(np.array([1, np.deg2rad(90), np.deg2rad(0)])), ctrPoint=np.array([0, 0, offsetHeight + 1.3]), dimensions=[0.2, 0.15, 0.15], reflectivities={ 'p0': reflectivities['skin'], 'p1': reflectivities['skin'], 'p2': reflectivities['skin'], 'p3': reflectivities['skin'], 'p4': reflectivities['skin'], 'p5': reflectivities['skin'] }) self.head = self.head.rotate(direction, np.array([0, 0, 1])) self.head = self.head.translate(np.array([*loc, self.head.ctrPoint[2]])) # Body part self.body = Cube(Vector(np.array([1, np.deg2rad(90), np.deg2rad(0)])), ctrPoint=np.array([0, 0, offsetHeight + 0.8]), dimensions=[0.8, 0.4, 0.15], reflectivities={ 'p0': reflectivities['shirt'], 'p1': reflectivities['shirt'], 'p2': reflectivities['shirt'], 'p3': reflectivities['shirt'], 'p4': reflectivities['shirt'], 'p5': reflectivities['shirt'] }) self.body = self.body.rotate(direction, np.array([0, 0, 1])) self.body = self.body.translate(np.array([*loc, self.body.ctrPoint[2]])) if position.lower() == 'sitting': self.chair = Cube(Vector( np.array([1, np.deg2rad(90), np.deg2rad(0)])), ctrPoint=np.array([0, 0, 0.2]), dimensions=[0.4, 0.4, 0.4], reflectivities={ 'p0': reflectivities['furniture'], 'p1': reflectivities['shirt'], 'p2': reflectivities['shirt'], 'p3': reflectivities['furniture'], 'p4': reflectivities['furniture'], 'p5': reflectivities['furniture'] }) self.chair = self.chair.rotate(direction, np.array([0, 0, 1])) self.chair = self.chair.translate( np.array([*loc, 0]) + self.chair.ctrPoint) Rd = getRodriguesMtx(direction, np.array([0, 0, 1])) shiftedVect = ( Rd @ np.array([0.2 - 0.075, 0, 0]).reshape(3, 1)).reshape(-1) self.chair = self.chair.translate(shiftedVect + self.chair.ctrPoint) self.table = Cube(Vector( np.array([1, np.deg2rad(90), np.deg2rad(0)])), ctrPoint=np.array([0, 0, 0.3]), dimensions=[0.6, 1.2, 0.9], reflectivities={ 'p0': reflectivities['furniture'], 'p1': reflectivities['furniture'], 'p2': reflectivities['furniture'], 'p3': reflectivities['furniture'], 'p4': reflectivities['furniture'], 'p5': reflectivities['furniture'] }) self.table = self.table.rotate(direction, np.array([0, 0, 1])) self.table = self.table.translate( np.array([*loc, 0]) + self.table.ctrPoint) Rd = getRodriguesMtx(direction, np.array([0, 0, 1])) shiftedVect = (Rd @ np.array([1, 0, 0]).reshape(3, 1)).reshape(-1) self.table = self.table.translate(shiftedVect + self.table.ctrPoint) # The table is modeled a simple plane self.table = self.table.listPlanes[2] self.leg = None elif position.lower() == 'standing': self.leg = Cube(Vector(np.array([1, np.deg2rad(90), np.deg2rad(0)])), ctrPoint=np.array([0, 0, 0.4]), dimensions=[0.8, 0.3, 0.15], reflectivities={ 'p0': reflectivities['shirt'], 'p1': reflectivities['shirt'], 'p2': reflectivities['shirt'], 'p3': reflectivities['shirt'], 'p4': reflectivities['shirt'], 'p5': reflectivities['shirt'] }) self.leg = self.leg.rotate(direction, np.array([0, 0, 1])) self.leg = self.leg.translate( np.array([*loc, self.leg.ctrPoint[2]])) self.chair, self.table = None, None self.ctrPoint = np.array([0, 0, 1.2]) + np.array([*loc, 0]) self.normalVect = self.head.normalVect self.listPlanes = self.getPartition(Ps=1) self.mode = None self.pd = None self.led = None if activity.lower() == 'calling': polar = np.deg2rad(45) azimuth = self.listPlanes[1]._RectPlane_py__normalVect.spherical[ 2] + np.pi loc = self.head.ctrPoint + 0.15 * self.head.listPlanes[4].normalVect elif activity.lower() == 'reading': polar = np.deg2rad(50) azimuth = self.listPlanes[1]._RectPlane_py__normalVect.spherical[ 2] + np.pi loc = (self.ctrPoint + 0.5 * self.listPlanes[1].normalVect + np.array([0, 0, -0.2 + offsetHeight])) elif activity.lower() == 'usbdongle': polar = np.deg2rad(0) azimuth = self.listPlanes[1]._RectPlane_py__normalVect.spherical[ 2] + np.pi loc = (self.ctrPoint + 1 * self.listPlanes[1].normalVect + np.array([0, 0, -0.6])) else: raise ValueError("'activity' is not recognized! \ Should be either 'calling' or 'reading'") if mode.lower() == 'rx': self.mode = mode.lower() # PD self.pd = BareDetector(polar, azimuth, loc, area=area, FoV=FoV) elif mode.lower() == 'tx': self.mode = mode.lower() # LED self.led = PointSource(polar, azimuth, loc, m=m) else: raise ValueError("'mode' is not recognized! \ Should be either 'tx' or 'rx'")
class SimpleOfficeEnv_py(object): """ A model of simple office environments. A simple office environment comprises only - a LED or a PD - a human model with different activities and positions - a furniture (a table and a chair) Parameters ---------- roomDim: list The dimensions of the room in [Length,Width,Height]. humanLoc The human's location. humanDirection The humand's direction. chairLoc The chair's location. Note that the location of the table is defined relative to the chair's location. chairDirection The chair's direction. mode: {'tx','rx'} Describe whether transmitting (tx) or receiving (rx) activity: {'calling','reading','usbdongle'} 'calling' denotes the LED or the PD is near the right ear. Meanwhile, 'reading' denotes the device is in front of the human's chest. 'usbdongle' denotes the use of LiFi usb dongles attached to a laptop on a desk. position: {'standing','sitting'} The human's positions. Attributes ---------- human: HumanWithActivity_py A human model with different positions and activities room: RoomCube_py A simple room model with a cube. chair: Cube_py A chair model with a cube. table: RectPlane_py A table model with a rectangular plane. tableAsCube: Cube_py A dummy variable to model the table as a cube. This is mostly used for the validation. led: PointSource_py A LED model. pd: BareDetector_py A PD model. listPlanes: list List of RectPlane_py isValid: bool To show that all elements are properly placed inside the room. It means that there is no element that is out of bounds and no element that intersects to one another. Examples -------- .. plot:: :format: doctest :include-source: True >>> import numpy as np >>> from owcsimpy.geoobjects.models.simpleofficeenv_py import SimpleOfficeEnv_py as OfficeEnv >>> >>> office = OfficeEnv(roomDim=[4,3,3], >>> humanLoc=[1,1.5],humanDirection=np.deg2rad(90), >>> activity='usbdongle',position='sitting') >>> >>> >>> office.draw(displayRoom=False) >>> print('is valid:', office.isValid) """ def __init__(self, roomDim, humanLoc, humanDirection, chairLoc=None, chairDirection=0, mode='rx', activity='calling', position='standing'): # Assertion checks assert len(roomDim) == 3 and np.alltrue(np.array(roomDim) > 0) assert mode.lower() == 'tx' or mode.lower() == 'rx',\ ("'mode' is not recognized! Should be either 'tx' or 'rx'") assert activity.lower() == 'calling' or activity.lower() == 'reading' or activity.lower() == 'usbdongle',\ ("'activity' is not recognized! Should be either 'calling', 'reading' or 'usbdongle'") assert position.lower() == 'standing' or position.lower() == 'sitting',\ ("'mode' is not recognized! Should be either 'standing' or 'sitting'") assert not(activity.lower() == 'usbdongle' and position.lower()=='standing'),\ ("cannot choose the `usbdongle` aciticity and the `standing` position.") # Human and other elements self.human = Human(loc=humanLoc, direction=humanDirection, mode=mode, activity=activity, position=position) # Room # Reflectivities # Except the floor, which is modeled as a pinewood, other # parts are modeled with plasters rho_keys = ['b', 't', 's', 'n', 'e', 'w'] if mode.lower() == 'tx': # IR-LED (uplink) rho_vals = [0.92, 0.83, 0.83, 0.83, 0.83, 0.83] elif mode.lower() == 'rx': # VL-LED (downlink) rho_vals = [0.54, 0.76, 0.76, 0.76, 0.76, 0.76] reflectivities = { rho_keys[i]: rho_vals[i] for i in range(len(rho_keys)) } self.room = Room(dimensions=roomDim, identity=1, reflectivities=reflectivities) # A chair and a table self.chair, self.table, self.tableAsCube = None, None, None if chairLoc: self.chair = Cube(Vector( np.array([1, np.deg2rad(90), np.deg2rad(0)])), ctrPoint=np.array([0, 0, 0.2]), dimensions=[0.4, 0.4, 0.4], reflectivities={ 'p0': 0.04, 'p1': 0.04, 'p2': 0.04, 'p3': 0.04, 'p4': 0.04, 'p5': 0.04 }) self.chair = self.chair.rotate(chairDirection, np.array([0, 0, 1])) self.chair = self.chair.translate( np.array([*chairLoc, 0]) + self.chair.ctrPoint) Rd = getRodriguesMtx(chairDirection, np.array([0, 0, 1])) shiftedVect = ( Rd @ np.array([0.2, 0, 0]).reshape(3, 1)).reshape(-1) self.chair = self.chair.translate(shiftedVect + self.chair.ctrPoint) # The table's location is defined based on self.table = Cube(Vector( np.array([1, np.deg2rad(90), np.deg2rad(0)])), ctrPoint=np.array([0, 0, 0.3]), dimensions=[0.6, 1.2, 0.9], reflectivities={ 'p0': 0.04, 'p1': 0.04, 'p2': 0.04, 'p3': 0.04, 'p4': 0.04, 'p5': 0.04 }) self.table = self.table.rotate(chairDirection, np.array([0, 0, 1])) self.table = self.table.translate( np.array([*chairLoc, 0]) + self.table.ctrPoint) Rd = getRodriguesMtx(chairDirection, np.array([0, 0, 1])) shiftedVect = (Rd @ np.array([1, 0, 0]).reshape(3, 1)).reshape(-1) self.table = self.table.translate(shiftedVect + self.table.ctrPoint) # The table is modeled a simple plane self.tableAsCube = self.table self.table = self.table.listPlanes[2] # LED or PD self.led, self.pd = None, None if mode.lower() == 'rx': self.led = PointSource( np.pi, 0, np.array([self.room.L / 2, self.room.W / 2, self.room.H]), m=-np.log(2) / np.log(np.cos(np.deg2rad(40.)))) elif mode.lower() == 'tx': self.pd = BareDetector( np.pi, 0, np.array([self.room.L / 2, self.room.W / 2, self.room.H]), area=1e-4, FoV=np.deg2rad(85)) self.updateListPlanesAndCheckValidity() def updateListPlanesAndCheckValidity(self): # Get all planes self.listPlanes = [] self.listPlanes.append(self.human.listPlanes) self.listPlanes.append(self.room.listPlanes) if self.chair and self.table: self.listPlanes.append(self.chair.getPartition(Ps=1)) self.listPlanes.append(self.table.getPartition(Ps=1)) self.listPlanes = list(flatten(self.listPlanes)) # Get blocking object self.blockingObj = [] if self.chair: self.blockingObj.append(self.chair) if self.table: self.blockingObj.append(self.table) if self.human: self.blockingObj.append(self.human) # Validate whether a vertice is NOT out of bounds roomVerts = np.append(self.room.listPlanes[0].verts, self.room.listPlanes[1].verts).reshape([-1, 3]) delaunay = Delaunay(roomVerts) verts = np.array( list(flatten([plane.verts.tolist() for plane in self.listPlanes]))).reshape([-1, 3]) if self.human.led: verts = np.append(verts, self.human.led.loc).reshape([-1, 3]) elif self.human.pd: verts = np.append(verts, self.human.pd.loc).reshape([-1, 3]) # # Check feasibility of human # verts = np.array(list(flatten([plane.verts.tolist() for plane in self.human.listPlanes]))).reshape([-1,3]) # # Check feasibility of chair # verts = np.array(list(flatten([plane.verts.tolist() for plane in self.chair.getPartition(Ps=1)]))).reshape([-1,3]) # # Check feasibility of table # verts = np.array(list(flatten([plane.verts.tolist() for plane in self.table.getPartition(Ps=1)]))).reshape([-1,3]) # # Check feasibility of LED # verts = self.human.led.loc # # Check feasibility of PD # verts = self.human.pd.loc self.isValid = np.alltrue(delaunay.find_simplex(verts) >= 0) # Check whether the human intersects with the furniture if self.chair and self.table: chairVerts = np.append(self.chair.listPlanes[0].verts, self.chair.listPlanes[1].verts).reshape( [-1, 3]) tableVerts = np.append( self.tableAsCube.listPlanes[0].verts, self.tableAsCube.listPlanes[1].verts).reshape([-1, 3]) verts = np.array( list( flatten([ plane.verts.tolist() for plane in self.human.listPlanes ]))).reshape([-1, 3]) if self.human.led: verts = np.append(verts, self.human.led.loc).reshape([-1, 3]) elif self.human.pd: verts = np.append(verts, self.human.pd.loc).reshape([-1, 3]) self.isValid = np.alltrue( Delaunay(chairVerts).find_simplex(verts) < 0) and np.alltrue( Delaunay(tableVerts).find_simplex(verts) < 0) def draw(self, displayRoom=False, displayReflectivity=False): """ Draw. Parameters ---------- displayRoom: bool displayReflectivity: bool """ if displayRoom: if displayReflectivity: alphas = [ 0.5 * plane.reflectivity for plane in self.listPlanes ] else: alphas = [1 for plane in self.listPlanes] fig, ax = draw(xlim=[0, self.room.L], ylim=[0, self.room.W], zlim=[0, self.room.H], planes=self.listPlanes, vectors=Vector(coord=self.human.normalVect, refPoint=self.human.ctrPoint, which='cartesian'), enablevect=False, alphas=alphas) else: listPlanes = [] listPlanes.append(self.human.listPlanes) if self.chair and self.table: listPlanes.append(self.chair.getPartition(Ps=1)) listPlanes.append(self.table.getPartition(Ps=1)) listPlanes = list(flatten(listPlanes)) if displayReflectivity: alphas = [0.5 * plane.reflectivity for plane in listPlanes] else: alphas = [1 for plane in listPlanes] fig, ax = draw(xlim=[0, self.room.L], ylim=[0, self.room.W], zlim=[0, self.room.H], planes=listPlanes, vectors=Vector(coord=self.human.normalVect, refPoint=self.human.ctrPoint, which='cartesian'), enablevect=False, colors='black', alphas=alphas) # fig, ax = draw(figure=fig,axes=ax, # circles=[self.human.pd,self.pd],scales=5e3, # vectors=[self.human.led,self.led]); fig, ax = draw(figure=fig, axes=ax, circles=[self.human.pd, self.pd], scales=5e3, vectors=[self.human.led]) fig, ax = draw(figure=fig, axes=ax, vectors=[self.led], colors='blue') return fig, ax
class HumanCubes_py(object): """ This is a quick implementation of a more realistic human body model. Parameters ---------- loc: ndarray(2,) Location of the human in xy-plane. direction: double Azimuth angle. reflectivities: dict The default value is {'hair':1,'face':1,'shirt':1} Notes ----- The dimensions are fixed, which is 1.8 m height and 0.4 m width. Examples -------- .. plot:: :format: doctest :include-source: True >>> import matplotlib.pyplot as plt >>> import numpy as np >>> >>> from owcsimpy.geoobjects.models.humancubes_py import HumanCubes_py as Human >>> from owcsimpy.geoutils.draw import draw >>> person = Human(np.array([1,1]),np.deg2rad(30),reflectivities={'hair':0.7,'face':0.5,'shirt':0.3}) >>> >>> draw(models3d=person,figsize=(6,6),azim=-100,elev=25,xlim=[0,3],ylim=[0,3],zlim=[0,3]); >>> >>> plt.show() """ def __init__(self, loc, direction, reflectivities={ 'hair': 1, 'face': 1, 'shirt': 1 }): assert len(loc) == 2 self.head = Cube(Vector(np.array([1, np.deg2rad(90), np.deg2rad(0)])), ctrPoint=np.array([0, 0, 1.7]), dimensions=[0.2, 0.15, 0.15], reflectivities={ 'p0': reflectivities['hair'], 'p1': reflectivities['face'], 'p2': reflectivities['hair'], 'p3': reflectivities['face'], 'p4': reflectivities['face'], 'p5': reflectivities['face'] }) self.head = self.head.rotate(direction, np.array([0, 0, 1])) self.head = self.head.translate(np.array([*loc, self.head.ctrPoint[2]])) self.body = Cube(Vector(np.array([1, np.deg2rad(90), np.deg2rad(0)])), ctrPoint=np.array([0, 0, 1.2]), dimensions=[0.8, 0.4, 0.15], reflectivities={ 'p0': reflectivities['shirt'], 'p1': reflectivities['shirt'], 'p2': reflectivities['shirt'], 'p3': reflectivities['shirt'], 'p4': reflectivities['shirt'], 'p5': reflectivities['shirt'] }) self.body = self.body.rotate(direction, np.array([0, 0, 1])) self.body = self.body.translate(np.array([*loc, self.body.ctrPoint[2]])) self.leg = Cube(Vector(np.array([1, np.deg2rad(90), np.deg2rad(0)])), ctrPoint=np.array([0, 0, 0.4]), dimensions=[0.8, 0.3, 0.15], reflectivities={ 'p0': reflectivities['shirt'], 'p1': reflectivities['shirt'], 'p2': reflectivities['shirt'], 'p3': reflectivities['shirt'], 'p4': reflectivities['shirt'], 'p5': reflectivities['shirt'] }) self.leg = self.leg.rotate(direction, np.array([0, 0, 1])) self.leg = self.leg.translate(np.array([*loc, self.leg.ctrPoint[2]])) self.ctrPoint = np.array([0, 0, 1.2]) + np.array([*loc, 0]) self.normalVect = self.head.normalVect # This is for draw method self.listPlanes = self.getPartition(Ps=1) def getPartition(self, Ps=1, delta=None): planes = [] if delta == None: planes.append(self.head.getPartition(Ps=Ps)) planes.append(self.body.getPartition(Ps=Ps)) planes.append(self.leg.getPartition(Ps=Ps)) else: if delta > 0.15: delta = 0.15 planes.append(self.head.getPartition(delta=delta)) planes.append(self.body.getPartition(delta=delta)) planes.append(self.leg.getPartition(delta=delta)) planes = list(flatten(planes)) return planes def draw(self): fig, ax = draw(cubes=[self.head, self.body, self.leg], xlim=[0, 3], ylim=[0, 3], zlim=[0, 3], lengths=0, enablevect='False') fig, ax = draw(figure=fig, axes=ax, vectors=Vector(coord=self.normalVect, refPoint=self.ctrPoint, which='cartesian'))
def __init__(self, loc, direction, reflectivities={ 'hair': 1, 'face': 1, 'shirt': 1 }): assert len(loc) == 2 self.head = Cube(Vector(np.array([1, np.deg2rad(90), np.deg2rad(0)])), ctrPoint=np.array([0, 0, 1.7]), dimensions=[0.2, 0.15, 0.15], reflectivities={ 'p0': reflectivities['hair'], 'p1': reflectivities['face'], 'p2': reflectivities['hair'], 'p3': reflectivities['face'], 'p4': reflectivities['face'], 'p5': reflectivities['face'] }) self.head = self.head.rotate(direction, np.array([0, 0, 1])) self.head = self.head.translate(np.array([*loc, self.head.ctrPoint[2]])) self.body = Cube(Vector(np.array([1, np.deg2rad(90), np.deg2rad(0)])), ctrPoint=np.array([0, 0, 1.2]), dimensions=[0.8, 0.4, 0.15], reflectivities={ 'p0': reflectivities['shirt'], 'p1': reflectivities['shirt'], 'p2': reflectivities['shirt'], 'p3': reflectivities['shirt'], 'p4': reflectivities['shirt'], 'p5': reflectivities['shirt'] }) self.body = self.body.rotate(direction, np.array([0, 0, 1])) self.body = self.body.translate(np.array([*loc, self.body.ctrPoint[2]])) self.leg = Cube(Vector(np.array([1, np.deg2rad(90), np.deg2rad(0)])), ctrPoint=np.array([0, 0, 0.4]), dimensions=[0.8, 0.3, 0.15], reflectivities={ 'p0': reflectivities['shirt'], 'p1': reflectivities['shirt'], 'p2': reflectivities['shirt'], 'p3': reflectivities['shirt'], 'p4': reflectivities['shirt'], 'p5': reflectivities['shirt'] }) self.leg = self.leg.rotate(direction, np.array([0, 0, 1])) self.leg = self.leg.translate(np.array([*loc, self.leg.ctrPoint[2]])) self.ctrPoint = np.array([0, 0, 1.2]) + np.array([*loc, 0]) self.normalVect = self.head.normalVect # This is for draw method self.listPlanes = self.getPartition(Ps=1)
def __init__(self, roomDim, humanLoc, humanDirection, chairLoc=None, chairDirection=0, mode='rx', activity='calling', position='standing'): # Assertion checks assert len(roomDim) == 3 and np.alltrue(np.array(roomDim) > 0) assert mode.lower() == 'tx' or mode.lower() == 'rx',\ ("'mode' is not recognized! Should be either 'tx' or 'rx'") assert activity.lower() == 'calling' or activity.lower() == 'reading' or activity.lower() == 'usbdongle',\ ("'activity' is not recognized! Should be either 'calling', 'reading' or 'usbdongle'") assert position.lower() == 'standing' or position.lower() == 'sitting',\ ("'mode' is not recognized! Should be either 'standing' or 'sitting'") assert not(activity.lower() == 'usbdongle' and position.lower()=='standing'),\ ("cannot choose the `usbdongle` aciticity and the `standing` position.") # Human and other elements self.human = Human(loc=humanLoc, direction=humanDirection, mode=mode, activity=activity, position=position) # Room # Reflectivities # Except the floor, which is modeled as a pinewood, other # parts are modeled with plasters rho_keys = ['b', 't', 's', 'n', 'e', 'w'] if mode.lower() == 'tx': # IR-LED (uplink) rho_vals = [0.92, 0.83, 0.83, 0.83, 0.83, 0.83] elif mode.lower() == 'rx': # VL-LED (downlink) rho_vals = [0.54, 0.76, 0.76, 0.76, 0.76, 0.76] reflectivities = { rho_keys[i]: rho_vals[i] for i in range(len(rho_keys)) } self.room = Room(dimensions=roomDim, identity=1, reflectivities=reflectivities) # A chair and a table self.chair, self.table, self.tableAsCube = None, None, None if chairLoc: self.chair = Cube(Vector( np.array([1, np.deg2rad(90), np.deg2rad(0)])), ctrPoint=np.array([0, 0, 0.2]), dimensions=[0.4, 0.4, 0.4], reflectivities={ 'p0': 0.04, 'p1': 0.04, 'p2': 0.04, 'p3': 0.04, 'p4': 0.04, 'p5': 0.04 }) self.chair = self.chair.rotate(chairDirection, np.array([0, 0, 1])) self.chair = self.chair.translate( np.array([*chairLoc, 0]) + self.chair.ctrPoint) Rd = getRodriguesMtx(chairDirection, np.array([0, 0, 1])) shiftedVect = ( Rd @ np.array([0.2, 0, 0]).reshape(3, 1)).reshape(-1) self.chair = self.chair.translate(shiftedVect + self.chair.ctrPoint) # The table's location is defined based on self.table = Cube(Vector( np.array([1, np.deg2rad(90), np.deg2rad(0)])), ctrPoint=np.array([0, 0, 0.3]), dimensions=[0.6, 1.2, 0.9], reflectivities={ 'p0': 0.04, 'p1': 0.04, 'p2': 0.04, 'p3': 0.04, 'p4': 0.04, 'p5': 0.04 }) self.table = self.table.rotate(chairDirection, np.array([0, 0, 1])) self.table = self.table.translate( np.array([*chairLoc, 0]) + self.table.ctrPoint) Rd = getRodriguesMtx(chairDirection, np.array([0, 0, 1])) shiftedVect = (Rd @ np.array([1, 0, 0]).reshape(3, 1)).reshape(-1) self.table = self.table.translate(shiftedVect + self.table.ctrPoint) # The table is modeled a simple plane self.tableAsCube = self.table self.table = self.table.listPlanes[2] # LED or PD self.led, self.pd = None, None if mode.lower() == 'rx': self.led = PointSource( np.pi, 0, np.array([self.room.L / 2, self.room.W / 2, self.room.H]), m=-np.log(2) / np.log(np.cos(np.deg2rad(40.)))) elif mode.lower() == 'tx': self.pd = BareDetector( np.pi, 0, np.array([self.room.L / 2, self.room.W / 2, self.room.H]), area=1e-4, FoV=np.deg2rad(85)) # Get all planes self.listPlanes = [] self.listPlanes.append(self.human.listPlanes) self.listPlanes.append(self.room.listPlanes) if self.chair and self.table: self.listPlanes.append(self.chair.getPartition(Ps=1)) self.listPlanes.append(self.table.getPartition(Ps=1)) self.listPlanes = list(flatten(self.listPlanes)) # Get blocking object self.blockingObj = [] if self.chair: self.blockingObj.append(self.chair) if self.table: self.blockingObj.append(self.table) if self.human: self.blockingObj.append(self.human) # Validate whether a vertice is NOT out of bounds roomVerts = np.append(self.room.listPlanes[0].verts, self.room.listPlanes[1].verts).reshape([-1, 3]) delaunay = Delaunay(roomVerts) verts = np.array( list(flatten([plane.verts.tolist() for plane in self.listPlanes]))).reshape([-1, 3]) if self.human.led: verts = np.append(verts, self.human.led.loc).reshape([-1, 3]) elif self.human.pd: verts = np.append(verts, self.human.pd.loc).reshape([-1, 3]) # # Check feasibility of human # verts = np.array(list(flatten([plane.verts.tolist() for plane in self.human.listPlanes]))).reshape([-1,3]) # # Check feasibility of chair # verts = np.array(list(flatten([plane.verts.tolist() for plane in self.chair.getPartition(Ps=1)]))).reshape([-1,3]) # # Check feasibility of table # verts = np.array(list(flatten([plane.verts.tolist() for plane in self.table.getPartition(Ps=1)]))).reshape([-1,3]) # # Check feasibility of LED # verts = self.human.led.loc # # Check feasibility of PD # verts = self.human.pd.loc self.isValid = np.alltrue(delaunay.find_simplex(verts) >= 0) # Check whether the human intersects with the furniture if self.chair and self.table: chairVerts = np.append(self.chair.listPlanes[0].verts, self.chair.listPlanes[1].verts).reshape( [-1, 3]) tableVerts = np.append( self.tableAsCube.listPlanes[0].verts, self.tableAsCube.listPlanes[1].verts).reshape([-1, 3]) verts = np.array( list( flatten([ plane.verts.tolist() for plane in self.human.listPlanes ]))).reshape([-1, 3]) if self.human.led: verts = np.append(verts, self.human.led.loc).reshape([-1, 3]) elif self.human.pd: verts = np.append(verts, self.human.pd.loc).reshape([-1, 3]) self.isValid = np.alltrue( Delaunay(chairVerts).find_simplex(verts) < 0) and np.alltrue( Delaunay(tableVerts).find_simplex(verts) < 0)
import matplotlib.pyplot as plt import numpy as np from owcsimpy.geoobjects.bases.vector_py import Vector_py as Vector from owcsimpy.geoobjects.bases.cube_py import Cube_py as Cube from owcsimpy.geoutils.draw import draw cube = Cube(Vector(np.array([1, np.deg2rad(90), np.deg2rad(90)])), ctrPoint=np.array([0.5, 0.5, 0.5]), dimensions=[2, 1, 1], RodriguesAngle=np.deg2rad(30)) planes = cube.getPartition(delta=0.5) fig, ax = draw(planes=planes, alphas=0.2, xlim=[-2, 2], ylim=[-2, 2], zlim=[-2, 2]) plt.show()