Bases: Extension
This extension simulates a camera hardware that can detect other nodes within its area of detection. The camera
has a reach, field of view, and direction of facing. The camera is capable of taking pictures, returning the list
of detected nodes within its area of detection.
The area of detection is a cone whose point is at the node's position and base faces the direction the camera is
pointing to, determined by the facing_inclination and facing_rotation attributes of the configuration. The cone's
angle at the point is determined by the field_of_view attribute of the configuration. The cone's length, or the
distance between its point and base, is determined by the cone_reach attribute of the configuration.
Source code in gradysim/simulator/extension/camera.py
| class CameraHardware(Extension):
"""
This extension simulates a camera hardware that can detect other nodes within its area of detection. The camera
has a reach, field of view, and direction of facing. The camera is capable of taking pictures, returning the list
of detected nodes within its area of detection.
The area of detection is a cone whose point is at the node's position and base faces the direction the camera is
pointing to, determined by the facing_inclination and facing_rotation attributes of the configuration. The cone's
angle at the point is determined by the field_of_view attribute of the configuration. The cone's length, or the
distance between its point and base, is determined by the cone_reach attribute of the configuration.
"""
def __init__(self, protocol: IProtocol, configuration: CameraConfiguration):
super().__init__(protocol)
if self._provider is not None:
self._mobility: Optional[MobilityHandler] = self._provider.handlers.get('mobility')
self._configuration = configuration
self._camera_vector = self._camera_direction_unit_vector()
self._camera_theta = math.radians(self._configuration.camera_theta)
def _camera_direction_unit_vector(self) -> Tuple[float, float, float]:
"""
Returns the unit vector that represents the direction the camera is facing to
Returns:
A tuple representing the unit vector
"""
facing_inclination = math.radians(self._configuration.facing_elevation)
facing_rotation = math.radians(self._configuration.facing_rotation)
x = math.sin(facing_inclination) * math.cos(facing_rotation)
y = math.sin(facing_inclination) * math.sin(facing_rotation)
z = math.cos(facing_inclination)
return x, y, z
def take_picture(self) -> List[DetectedNode]:
"""
This simulated camera hardware is able to detect other nodes within its are of detection. This method returns
the list of nodes currently inside the area of detection of the camera.
Returns:
A list of detected nodes
"""
if self._mobility is None:
return []
node_position = self._provider.node.position
other_nodes = [node for node in self._mobility.nodes.values() if node.id != self._provider.node.id]
detected_nodes = []
for node in other_nodes:
other_node_position = node.position
relative_vector = (
other_node_position[0] - node_position[0],
other_node_position[1] - node_position[1],
other_node_position[2] - node_position[2]
)
# Check if the node is within the camera's reach
distance = math.sqrt(relative_vector[0] ** 2 + relative_vector[1] ** 2 + relative_vector[2] ** 2)
if distance > self._configuration.camera_reach:
continue
if distance > 0:
# Check if the angle between vectors is less than theta
normalized_relative_vector = (
relative_vector[0] / distance,
relative_vector[1] / distance,
relative_vector[2] / distance
)
dot_product = (
self._camera_vector[0] * normalized_relative_vector[0] +
self._camera_vector[1] * normalized_relative_vector[1] +
self._camera_vector[2] * normalized_relative_vector[2]
)
angle = math.acos(dot_product) - 1e-6 # Tolerance
if angle > self._camera_theta:
continue
detected_nodes.append({
'position': other_node_position,
'type': 'node'
})
return detected_nodes
def change_facing(self, facing_elevation: float, facing_rotation: float):
"""
Changes the direction the camera is facing to
Args:
facing_elevation: The inclination of where the camera is pointing to in degrees, with 0 being at the ground
facing_rotation: The rotation of the camera in degrees, with zero being along the x-axis in the positive direction
"""
self._configuration.facing_elevation = facing_elevation
self._configuration.facing_rotation = facing_rotation
self._camera_vector = self._camera_direction_unit_vector()
|
change_facing(facing_elevation, facing_rotation)
Changes the direction the camera is facing to
Args:
facing_elevation: The inclination of where the camera is pointing to in degrees, with 0 being at the ground
facing_rotation: The rotation of the camera in degrees, with zero being along the x-axis in the positive direction
Source code in gradysim/simulator/extension/camera.py
| def change_facing(self, facing_elevation: float, facing_rotation: float):
"""
Changes the direction the camera is facing to
Args:
facing_elevation: The inclination of where the camera is pointing to in degrees, with 0 being at the ground
facing_rotation: The rotation of the camera in degrees, with zero being along the x-axis in the positive direction
"""
self._configuration.facing_elevation = facing_elevation
self._configuration.facing_rotation = facing_rotation
self._camera_vector = self._camera_direction_unit_vector()
|
take_picture()
This simulated camera hardware is able to detect other nodes within its are of detection. This method returns
the list of nodes currently inside the area of detection of the camera.
Returns:
A list of detected nodes
Source code in gradysim/simulator/extension/camera.py
| def take_picture(self) -> List[DetectedNode]:
"""
This simulated camera hardware is able to detect other nodes within its are of detection. This method returns
the list of nodes currently inside the area of detection of the camera.
Returns:
A list of detected nodes
"""
if self._mobility is None:
return []
node_position = self._provider.node.position
other_nodes = [node for node in self._mobility.nodes.values() if node.id != self._provider.node.id]
detected_nodes = []
for node in other_nodes:
other_node_position = node.position
relative_vector = (
other_node_position[0] - node_position[0],
other_node_position[1] - node_position[1],
other_node_position[2] - node_position[2]
)
# Check if the node is within the camera's reach
distance = math.sqrt(relative_vector[0] ** 2 + relative_vector[1] ** 2 + relative_vector[2] ** 2)
if distance > self._configuration.camera_reach:
continue
if distance > 0:
# Check if the angle between vectors is less than theta
normalized_relative_vector = (
relative_vector[0] / distance,
relative_vector[1] / distance,
relative_vector[2] / distance
)
dot_product = (
self._camera_vector[0] * normalized_relative_vector[0] +
self._camera_vector[1] * normalized_relative_vector[1] +
self._camera_vector[2] * normalized_relative_vector[2]
)
angle = math.acos(dot_product) - 1e-6 # Tolerance
if angle > self._camera_theta:
continue
detected_nodes.append({
'position': other_node_position,
'type': 'node'
})
return detected_nodes
|