Files
RDC_Simulation/docs/drone_guide.md
2025-12-31 23:50:26 +00:00

4.4 KiB

DroneController Guide (GPS-Denied)

Implement your landing algorithm in drone_controller.py.

Quick Start

  1. Edit drone_controller.py
  2. Find calculate_landing_maneuver()
  3. Implement your algorithm
  4. Test: python controllers.py --pattern stationary

GPS-Denied Challenge

No GPS available. You must use:

Sensor Data
IMU Orientation, angular velocity
Altimeter Altitude, vertical velocity
Velocity Estimated from optical flow
Camera 320x240 downward image (base64 JPEG)
Landing Pad Relative position (may be null!)

Function to Implement

def calculate_landing_maneuver(self, telemetry, rover_telemetry):
    # Your code here
    return (thrust, pitch, roll, yaw)

Sensor Data

IMU

imu = telemetry['imu']
roll = imu['orientation']['roll']
pitch = imu['orientation']['pitch']
yaw = imu['orientation']['yaw']
angular_vel = imu['angular_velocity']  # {x, y, z}

Altimeter

altimeter = telemetry['altimeter']
altitude = altimeter['altitude']
vertical_vel = altimeter['vertical_velocity']

Velocity

velocity = telemetry['velocity']  # {x, y, z} in m/s

Camera

The drone has a downward-facing camera providing 320x240 JPEG images.

import base64
from PIL import Image
import io

camera = telemetry['camera']
image_b64 = camera.get('image')

if image_b64:
    image_bytes = base64.b64decode(image_b64)
    image = Image.open(io.BytesIO(image_bytes))
    # Process image for custom vision algorithms

Landing Pad (Vision)

Important: May be None if pad not visible!

landing_pad = telemetry['landing_pad']

if landing_pad is not None:
    relative_x = landing_pad['relative_x']   # body frame
    relative_y = landing_pad['relative_y']   # body frame
    distance = landing_pad['distance']       # vertical
    confidence = landing_pad['confidence']   # 0-1

Control Output

Value Range Effect
thrust ±1.0 Up/down
pitch ±0.5 Forward/back
roll ±0.5 Left/right
yaw ±0.5 Rotation

Example Algorithm

def calculate_landing_maneuver(self, telemetry, rover_telemetry):
    altimeter = telemetry.get('altimeter', {})
    altitude = altimeter.get('altitude', 5.0)
    vertical_vel = altimeter.get('vertical_velocity', 0.0)
    
    velocity = telemetry.get('velocity', {})
    vel_x = velocity.get('x', 0.0)
    vel_y = velocity.get('y', 0.0)
    
    landing_pad = telemetry.get('landing_pad')
    
    # Altitude control
    thrust = 0.5 * (0 - altitude) - 0.3 * vertical_vel
    
    # Horizontal control
    if landing_pad is not None:
        pitch = 0.3 * landing_pad['relative_x'] - 0.2 * vel_x
        roll = 0.3 * landing_pad['relative_y'] - 0.2 * vel_y
    else:
        pitch = -0.2 * vel_x
        roll = -0.2 * vel_y
    
    return (thrust, pitch, roll, 0.0)

Using the Camera

You can implement custom vision processing on the camera image:

import cv2
import numpy as np
import base64

def process_camera(telemetry):
    camera = telemetry.get('camera', {})
    image_b64 = camera.get('image')
    
    if not image_b64:
        return None
    
    # Decode JPEG
    image_bytes = base64.b64decode(image_b64)
    nparr = np.frombuffer(image_bytes, np.uint8)
    image = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
    
    # Example: detect green landing pad
    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    green_mask = cv2.inRange(hsv, (35, 50, 50), (85, 255, 255))
    
    # Find contours
    contours, _ = cv2.findContours(green_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    
    if contours:
        largest = max(contours, key=cv2.contourArea)
        M = cv2.moments(largest)
        if M['m00'] > 0:
            cx = int(M['m10'] / M['m00'])
            cy = int(M['m01'] / M['m00'])
            # cx, cy is center of detected pad in image coordinates
            return (cx, cy)
    
    return None

Strategies

When Pad Not Visible

  • Maintain altitude and stabilize
  • Search by ascending or spiraling
  • Dead reckoning from last known position

State Machine

  1. Search → find pad
  2. Approach → move above pad
  3. Align → center over pad
  4. Descend → controlled descent
  5. Land → touch down

Testing

# Easy
python controllers.py --pattern stationary

# Medium
python controllers.py --pattern circular --speed 0.2

# Hard
python controllers.py --pattern random --speed 0.3