Spaces:
Configuration error
Configuration error
#!/usr/bin/env python3 | |
""" | |
Drone SITL (Software In The Loop) Simulator | |
Starts a virtual drone for testing DeepDrone commands. | |
""" | |
import subprocess | |
import sys | |
import time | |
import socket | |
import threading | |
from pathlib import Path | |
def check_mavproxy_installed(): | |
"""Check if MAVProxy is installed.""" | |
try: | |
result = subprocess.run(['mavproxy.py', '--help'], | |
capture_output=True, text=True, timeout=5) | |
return result.returncode == 0 | |
except (subprocess.TimeoutExpired, FileNotFoundError): | |
return False | |
def check_ardupilot_installed(): | |
"""Check if ArduPilot SITL is available.""" | |
try: | |
result = subprocess.run(['sim_vehicle.py', '--help'], | |
capture_output=True, text=True, timeout=5) | |
return result.returncode == 0 | |
except (subprocess.TimeoutExpired, FileNotFoundError): | |
return False | |
def find_available_port(start_port=14550): | |
"""Find an available UDP port starting from start_port.""" | |
for port in range(start_port, start_port + 100): | |
try: | |
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s: | |
s.bind(('127.0.0.1', port)) | |
return port | |
except OSError: | |
continue | |
return None | |
def start_simple_sitl(port=14550): | |
"""Start a simple SITL simulation using ArduPilot.""" | |
print(f"π Starting ArduPilot SITL on port {port}...") | |
try: | |
# Try to start ArduPilot SITL | |
cmd = [ | |
'sim_vehicle.py', | |
'-v', 'ArduCopter', | |
'--out', f'udp:127.0.0.1:{port}', | |
'--map', | |
'--console' | |
] | |
process = subprocess.Popen( | |
cmd, | |
stdout=subprocess.PIPE, | |
stderr=subprocess.PIPE, | |
text=True | |
) | |
return process, port | |
except FileNotFoundError: | |
print("β ArduPilot SITL not found. Please install ArduPilot.") | |
return None, None | |
def start_mavproxy_sitl(port=14550): | |
"""Start SITL using MAVProxy.""" | |
print(f"π Starting MAVProxy SITL on port {port}...") | |
try: | |
cmd = [ | |
'mavproxy.py', | |
'--master', 'tcp:127.0.0.1:5760', | |
'--out', f'udp:127.0.0.1:{port}', | |
'--aircraft', 'test' | |
] | |
process = subprocess.Popen( | |
cmd, | |
stdout=subprocess.PIPE, | |
stderr=subprocess.PIPE, | |
text=True | |
) | |
return process, port | |
except FileNotFoundError: | |
print("β MAVProxy not found.") | |
return None, None | |
def create_basic_simulator(port=14550): | |
"""Create a very basic drone simulator for testing.""" | |
print(f"π Starting basic drone simulator on port {port}...") | |
print("β οΈ This is a minimal simulator for testing purposes only.") | |
# Create a simple UDP server that responds to basic MAVLink messages | |
import socket | |
import struct | |
def simulator_thread(): | |
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) | |
sock.bind(('127.0.0.1', port)) | |
sock.settimeout(1.0) | |
print(f"β Basic simulator listening on 127.0.0.1:{port}") | |
while True: | |
try: | |
data, addr = sock.recvfrom(1024) | |
# Echo back a simple response | |
sock.sendto(data, addr) | |
except socket.timeout: | |
continue | |
except KeyboardInterrupt: | |
break | |
sock.close() | |
thread = threading.Thread(target=simulator_thread, daemon=True) | |
thread.start() | |
return thread, port | |
def print_connection_info(port): | |
"""Print connection information.""" | |
connection_string = f"udp:127.0.0.1:{port}" | |
print("\n" + "="*60) | |
print("π DRONE SIMULATOR STARTED") | |
print("="*60) | |
print(f"π‘ Connection String: {connection_string}") | |
print(f"π IP Address: 127.0.0.1") | |
print(f"π Port: {port}") | |
print("="*60) | |
print("\nπ‘ To connect DeepDrone:") | |
print(f" 1. Run: python main.py") | |
print(f" 2. Choose your AI provider") | |
print(f" 3. In chat, say: 'Connect to {connection_string}'") | |
print("\nπ― Example commands once connected:") | |
print(" β’ 'Take off to 30 meters'") | |
print(" β’ 'Fly in a square pattern'") | |
print(" β’ 'Show battery status'") | |
print(" β’ 'Return home and land'") | |
print("\nβ οΈ Press Ctrl+C to stop the simulator") | |
print("="*60) | |
def main(): | |
"""Main function to start the drone simulator.""" | |
print("π DeepDrone Simulator Starting...") | |
print("Checking for available drone simulation software...\n") | |
# Find available port | |
port = find_available_port() | |
if not port: | |
print("β No available ports found. Please check your network configuration.") | |
return | |
simulator_process = None | |
simulator_thread = None | |
try: | |
# Try ArduPilot SITL first | |
if check_ardupilot_installed(): | |
print("β ArduPilot SITL found. Starting professional simulation...") | |
simulator_process, port = start_simple_sitl(port) | |
if simulator_process: | |
print_connection_info(port) | |
simulator_process.wait() | |
elif check_mavproxy_installed(): | |
print("β MAVProxy found. Starting MAVProxy simulation...") | |
simulator_process, port = start_mavproxy_sitl(port) | |
if simulator_process: | |
print_connection_info(port) | |
simulator_process.wait() | |
else: | |
print("β οΈ No professional drone simulation software found.") | |
print("Installing ArduPilot SITL is recommended for full simulation.") | |
print("Falling back to basic simulator for testing...") | |
simulator_thread, port = create_basic_simulator(port) | |
print_connection_info(port) | |
# Keep the basic simulator running | |
try: | |
while True: | |
time.sleep(1) | |
except KeyboardInterrupt: | |
pass | |
except KeyboardInterrupt: | |
print("\nπ Stopping drone simulator...") | |
finally: | |
if simulator_process: | |
simulator_process.terminate() | |
try: | |
simulator_process.wait(timeout=5) | |
except subprocess.TimeoutExpired: | |
simulator_process.kill() | |
print("β Drone simulator stopped.") | |
def install_instructions(): | |
"""Print installation instructions for drone simulation software.""" | |
print("\nπ To install professional drone simulation:") | |
print("\nπ§ ArduPilot SITL (Recommended):") | |
print(" git clone https://github.com/ArduPilot/ardupilot.git") | |
print(" cd ardupilot") | |
print(" git submodule update --init --recursive") | |
print(" ./Tools/environment_install/install-prereqs-ubuntu.sh -y") | |
print(" . ~/.profile") | |
print(" ./waf configure --board sitl") | |
print(" ./waf copter") | |
print(" echo 'export PATH=$PATH:$HOME/ardupilot/Tools/autotest' >> ~/.bashrc") | |
print(" source ~/.bashrc") | |
print("\nπ§ MAVProxy (Alternative):") | |
print(" pip install MAVProxy") | |
print("\nπ‘ For now, you can use the basic simulator for testing.") | |
if __name__ == "__main__": | |
if len(sys.argv) > 1 and sys.argv[1] == "--install-help": | |
install_instructions() | |
else: | |
main() |