Source code for vlcsim.scene.access_point

"""AccessPoint base class for VLC access points."""

import numpy as np
from enum import Enum
from typing import Optional, Any


[docs] class AccessPoint: """Base class for all communication access points in VLC simulation. AccessPoint provides the foundational structure for both VLC (VLed) and RF communication access points. It manages spatial positioning, operational state, and time-division multiplexing (TDM) parameters. The class implements a state machine where access points can be either IDLE or BUSY, and supports TDM frame slicing for resource allocation. Attributes: stateap (Enum): Enumeration defining AP states (IDLE, BUSY) Properties: x (float): X-coordinate position in meters y (float): Y-coordinate position in meters z (float): Z-coordinate position in meters (typically height) position (ndarray): 3D position vector [x, y, z] state (stateap): Current operational state ID (int): Unique identifier for the access point B (float): Bandwidth in Hz sliceTime (float): Duration of each time slice in seconds slicesInFrame (int): Number of slices per TDM frame Example: AccessPoint is typically not instantiated directly, but through subclasses :: # Create VLed access point vled = VLed(x=5.0, y=5.0, z=3.0, nLedsX=2, nLedsY=2, ledPower=20, theta=60) vled.sliceTime = 0.1 # 100ms slices vled.slicesInFrame = 10 # 10 slices per frame # Create RF access point rf = RF(x=5.0, y=5.0, z=1.0) rf.B = 5e6 # 5 MHz bandwidth Note: - Position coordinates use a standard 3D Cartesian coordinate system - Z-coordinate typically represents height (e.g., ceiling height for LEDs) - Bandwidth B is used in capacity calculations - TDM parameters control resource allocation granularity """ stateap = Enum("state", "IDLE BUSY")
[docs] def __init__( self, x: float, y: float, z: float, ) -> None: """Initialize an AccessPoint at a given 3D position. Creates a new access point with specified coordinates and default configuration. The access point is initialized in IDLE state with default TDM parameters. Args: x: X-coordinate position in meters y: Y-coordinate position in meters z: Z-coordinate position in meters (typically height from ground) Example: Typically called from subclass constructors:: class MyAccessPoint(AccessPoint): def __init__(self, x, y, z): super().__init__(x, y, z) # Add subclass-specific initialization Note: - Default bandwidth is set to 1 MHz - Default slice time is 0.1 seconds (100ms) - Default frame has 10 slices - Initial state is IDLE """ self._x: float = x self._y: float = y self._z: float = z self._state = AccessPoint.stateap.IDLE self._sliceTime: float = 0.1 self._slicesInFrame: int = 10 self._ID: Optional[int] = None self._position: np.ndarray[Any, np.dtype[np.float64]] = np.array([x, y, z]) self._B: float = 1e6
@property def B(self) -> float: """Get the bandwidth of this access point. Returns: float: Bandwidth in Hz (default: 1 MHz) """ return self._B @B.setter def B(self, value: float) -> None: """Set the bandwidth of this access point. Args: value: Bandwidth in Hz """ self._B = value @property def ID(self) -> Optional[int]: """Get the unique identifier of this access point. Returns: int or None: Access point ID, None if not yet assigned """ return self._ID @ID.setter def ID(self, value: int) -> None: """Set the unique identifier of this access point. Args: value: ID number to assign """ self._ID = value @property def x(self) -> float: """Get the X-coordinate of this access point. Returns: float: X-coordinate in meters """ return self._x @x.setter def x(self, value: float) -> None: """Set the X-coordinate of this access point. Updates both the individual coordinate and the position vector. Args: value: X-coordinate in meters """ self._x = value self._position = np.array([self._x, self.y, self.z]) @property def y(self) -> float: """Get the Y-coordinate of this access point. Returns: float: Y-coordinate in meters """ return self._y @y.setter def y(self, value: float) -> None: """Set the Y-coordinate of this access point. Updates both the individual coordinate and the position vector. Args: value: Y-coordinate in meters """ self._y = value self._position = np.array([self.x, self._y, self.z]) @property def z(self) -> float: """Get the Z-coordinate of this access point. Returns: float: Z-coordinate in meters (typically height) """ return self._z @z.setter def z(self, value: float) -> None: """Set the Z-coordinate of this access point. Updates both the individual coordinate and the position vector. Args: value: Z-coordinate in meters """ self._z = value self._position = np.array([self.x, self.y, self._z]) @property def position(self) -> np.ndarray[Any, np.dtype[np.float64]]: """Get the 3D position vector of this access point. Returns: ndarray: Position vector [x, y, z] in meters """ return self._position @property def state(self) -> stateap: """Get the current operational state of this access point. Returns: stateap: Current state, either IDLE or BUSY """ return self._state
[docs] def setIDLE(self) -> None: """Set this access point to IDLE state. Transitions the access point to IDLE, indicating it is ready to accept new connections. """ self._state = AccessPoint.stateap.IDLE
[docs] def setBUSY(self) -> None: """Set this access point to BUSY state. Transitions the access point to BUSY, indicating it is actively serving connections. """ self._state = AccessPoint.stateap.BUSY
@property def sliceTime(self) -> float: """Get the time duration of each TDM slice. The slice time determines how long each connection can use the access point in a single time slice. Returns: float: Slice time duration in seconds (default: 0.1s) """ return self._sliceTime @sliceTime.setter def sliceTime(self, value: float) -> None: """Set the time duration of each TDM slice. Args: value: Slice time duration in seconds """ self._sliceTime = value @property def slicesInFrame(self) -> int: """Get the number of time slices in each TDM frame. This determines the frame structure for time-division multiplexing. Total frame duration equals sliceTime * slicesInFrame. Returns: int: Number of slices per frame (default: 10) """ return self._slicesInFrame @slicesInFrame.setter def slicesInFrame(self, value: int) -> None: """Set the number of time slices in each TDM frame. Args: value: Number of slices per frame """ self._slicesInFrame = value