Skip to content

Drone Agent Proposal #59

@jmalegankar

Description

@jmalegankar

Overview

This proposal introduces new drone-type agents to the existing agent system. Drones will be able to move freely through X/Y/Z coordinates rather than being constrained to node-to-node movement or a 2D plane. This 3D movement capability allows drones to navigate around obstacles like buildings and bridges. They will have limited flight time, requiring periodic landing, and can be terminated by land agents when landed ( rules set by the user)

Key Features

  1. 3D Coordinate-Based Movement: Drones can move to any X/Y/Z position rather than just graph nodes
  2. Flight Time Limitations: Drones must land after a configurable number of turns
  3. Aerial Sensing: New sensor type for detecting nodes and agents from the air with height-based adjustments
  4. Landing Mechanics: Drones land at the nearest node and can be terminated while landed
  5. Obstacle Avoidance: Drones can navigate around buildings, bridges, and other 3D structures

Implementation

DroneAgent Class

The DroneAgent class extends the existing Agent class, adding capabilities for 3D movement with height considerations:

class DroneAgent(Agent):
    def __init__(self, ctx: IContext, name, start_node_id, max_flight_time=30, **kwargs):
        super().__init__(ctx, name, start_node_id, **kwargs)
        
        # Drone-specific attributes
        self._max_flight_time = max_flight_time
        self._current_flight_time = 0
        self._position = (0.0, 0.0, 0.0)  # x, y, z coordinates
        self._orientation = (0.0, 0.0, 0.0, 0.0)  # orientation vector
        
        # Set initial position from start node
        start_node = self._graph.graph.get_node(start_node_id)
        self._position = (start_node.x, start_node.y, 0.0)  # Start at ground level
    
    @property
    def position(self):
        return self._position
    
    @position.setter
    def position(self, new_position):
        if self._ctx.record.record():
            self._ctx.record.write(
                opCode=OpCodes.DRONE_MOVE,
                data={
                    "agent_name": self.name,
                    "old_position": self._position,
                    "new_position": new_position,
                }
            )
        self._position = new_position
    
    @property
    def orientation(self):
        return self._orientation
    
    @orientation.setter
    def orientation(self, new_orientation):
        if self._ctx.record.record():
            self._ctx.record.write(
                opCode=OpCodes.DRONE_ORIENTATION,
                data={
                    "agent_name": self.name,
                    "old_orientation": self._orientation,
                    "new_orientation": new_orientation,
                }
            )
        self._orientation = new_orientation
    
    @property
    def altitude(self):
        return self._position[2]
    
    @property
    def is_flying(self):
        return self.altitude > 0
    
    @property
    def is_landed(self):
        return self.altitude <= 0
    
    def _find_nearest_landing_spot(self):
        # Find the nearest suitable landing spot considering terrain and obstacles
        pass
    
    def move_to_xyz(self, x, y, z):
        # Implementation for moving to specific 3D coordinates
        # Should include collision detection with buildings/bridges
        pass
    
    def adjust_altitude(self, delta_z):
        # Change altitude by a relative amount
        pass
    
    def get_state(self) -> dict:
        # Override to include drone-specific state with 3D position and orientation
        pass
    
    def set_state(self) -> None:
        # Override to handle drone-specific actions in 3D space
        pass
    
    def detect_obstacles(self, target_position):
        # Check if there are obstacles (buildings, bridges) between current position
        # and target position
        pass

AerialSensor Class

The AerialSensor class provides specialized 3D sensing capabilities for drone agents:

class AerialSensor(ISensor):
    def __init__(self, ctx, sensor_id, sensor_type, sensor_range=50.0, fov=2*math.pi, 
                 vertical_fov=math.pi/2, occlusion_detection=True):
        self._sensor_id = sensor_id
        self.ctx = ctx
        self._type = sensor_type
        self.range = sensor_range
        self.fov = fov  # Horizontal field of view
        self.vertical_fov = vertical_fov  # Vertical field of view
        self.occlusion_detection = occlusion_detection  # Whether to check for obstructions
        self._data = {
            'nodes': {},      # Visible nodes
            'agents': {},     # Visible agents
            'obstacles': {},  # Detected obstacles like buildings/bridges
            'terrain': {}     # Ground features
        }
        self._owner = None
    
    @property
    def sensor_id(self) -> str:
        return self._sensor_id
    
    @property
    def type(self) -> SensorType:
        return self._type
    
    @property
    def data(self):
        return self._data
    
    def set_owner(self, owner: str) -> None:
        self._owner = owner
    
    def sense(self, node_id: int) -> None:
        # Implement 3D aerial sensing logic with height considerations
        # Should handle occlusion by obstacles like buildings
        pass
    
    def check_line_of_sight(self, from_position, to_position):
        # Check if there's a clear line of sight between two 3D positions
        # Returns True if no obstacles block the view
        pass
    
    def adjust_range_by_altitude(self, base_range, altitude):
        # Adjust sensing range based on altitude
        # Higher altitude = greater range but potentially less detail
        pass
    
    def update(self, data: Dict[str, Any]) -> None:
        pass

Required Extensions

New OpCodes

extend_enum(OpCodes, "DRONE_MOVE", len(OpCodes))
extend_enum(OpCodes, "DRONE_ORIENTATION", len(OpCodes))
extend_enum(OpCodes, "DRONE_ALTITUDE_CHANGE", len(OpCodes))
extend_enum(OpCodes, "DRONE_OBSTACLE_DETECT", len(OpCodes))

New SensorTypes

extend_enum(SensorType, "AERIAL", len(SensorType))
extend_enum(SensorType, "AERIAL_RANGE", len(SensorType))
extend_enum(SensorType, "AERIAL_3D", len(SensorType))
extend_enum(SensorType, "OBSTACLE_DETECTOR", len(SensorType))

Integration Points

  1. AgentEngine: Extend create_agent to support drone type agents
  2. SensorEngine: Add support for creating 3D aerial sensors
  3. OpCodes: Add drone-specific operation codes for 3D movement and orientation
  4. SensorType: Add aerial and obstacle sensing types
  5. Environment: Add support for 3D obstacles and terrain modeling
  6. Physics Engine: Simple collision detection and realistic movement constraints

Environment Modeling Requirements

For the 3D drone movement to work effectively, the environment needs some additional modeling:

  1. Building/Structure Representation: Define height, width, and position of obstacles
  2. Terrain Height Map: For appropriate ground-level references
  3. No-Fly Zones: Areas where drones cannot enter
  4. Line-of-Sight Calculations: To determine visibility through/around structures

Metadata

Metadata

Labels

CoreDevelopment related to core functionality

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions