# Architecture Overview ## Modes ### 1. Standalone (1 Terminal) ```bash python standalone_simulation.py --pattern circular ``` ``` ┌────────────────────────────────────────┐ │ standalone_simulation.py │ │ PyBullet + Controllers + Camera │ └────────────────────────────────────────┘ ``` ### 2. Gazebo + ROS 2 (2 Terminals) ``` Terminal 1 Terminal 2 ┌───────────────────┐ ┌───────────────────┐ │ Gazebo + Bridge │◄──────►│ run_gazebo.py │ └───────────────────┘ ROS └───────────────────┘ ``` ### 3. ArduPilot (2 Terminals) ``` Terminal 1 Terminal 2 ┌───────────────────┐ ┌────────────────────────────┐ │ Gazebo + │◄──────►│ run_ardupilot_controller.sh│ │ ArduPilot Plugin │ JSON │ ┌──────────────────┐ │ └───────────────────┘ │ │ ArduPilot SITL │ │ │ └─────────┬────────┘ │ │ │ MAVLink │ │ ┌─────────▼────────┐ │ │ │ run_ardupilot.py │ │ │ └──────────────────┘ │ └────────────────────────────┘ ``` ## Data Flow ### Standalone ``` Controller → PyBullet → Telemetry → Controller ``` ### Gazebo ``` Controller → /cmd_vel → Gazebo → /odometry → Controller ``` ### ArduPilot ``` Gazebo ◄─── JSON ───► SITL ◄─── MAVLink ───► Controller ``` ## Key Files | File | Purpose | |------|---------| | `drone_controller.py` | **Your landing algorithm (used in ALL modes)** | | `run_ardupilot.py` | MAVLink interface for ArduPilot | | `run_gazebo.py` | ROS 2 interface for Gazebo | | `standalone_simulation.py` | PyBullet simulation engine | | `config.py` | Shared configuration | ## GPS-Denied Sensors The controller receives this standardized telemetry structure in all modes: ```python telemetry = { "altimeter": { "altitude": float, # Meters "vertical_velocity": float # m/s (positive = up) }, "velocity": { # Body or Local frame "x": float, "y": float, "z": float }, "imu": { "orientation": { "roll": float, "pitch": float, "yaw": float } }, "landing_pad": { # If visible (None otherwise) "relative_x": float, "relative_y": float, "distance": float } } ```