[Python] My DJI drone simulator can't switch into 'GUIDED' mode

Discussão em 'Python' iniciado por Stack, Junho 28, 2025.

  1. Stack

    Stack Membro Participativo

    I am running a simulator for my DJI drone so I can learn to use the drone before flying it in person. However, whenever I initialize the code the drone fails to enter GUIDED mode. This is my code:

    import collections
    import collections.abc
    collections.MutableMapping = collections.abc.MutableMapping #this is a technical issue. might actually affect a future issue
    #there was some sort of update that switched around the files, and this switches it back

    from dronekit import connect, VehicleMode, LocationGlobalRelative
    import dronekit_sitl

    import time
    import math
    import threading
    from pymavlink import mavutil
    from pynput import keyboard
    import dronekit_sitl

    sitl = dronekit_sitl.start_default(lat=0, lon=0)
    connection_string = sitl.connection_string()


    class Location:
    def __init__(self, lat, lon, alt):
    self.lat = lat
    self.lon = lon
    self.alt = alt
    def __repr__(self):
    return "Location(%s, %s, %s)" % (self.lat, self.lon, self.alt)


    class DroneController:
    def __init__(self, connection_string=""):
    print(f"Attempting to connect to {connection_string}")
    self.vehicle = connect(connection_string, wait_ready=True, timeout=60)
    print("Successfully connected to the vehicle")

    def get_location(self):
    return Location(self.vehicle.location.global_relative_frame.lat,
    self.vehicle.location.global_relative_frame.lon,
    self.vehicle.location.global_relative_frame.alt)

    def arm_and_takeoff(self, target_altitude):
    print("Basic pre-arm checks")
    while not self.vehicle.is_armable:
    print(" Waiting for vehicle to initialise...")
    time.sleep(1)

    if not self.set_guided_mode():
    print("not guieded mode")
    return False

    print("Arming motors")
    self.vehicle.armed = True

    arming_timeout = 60
    start_time = time.time()
    while not self.vehicle.armed:
    if time.time() - start_time > arming_timeout:
    print("Failed to arm within timeout period")
    return False
    print(" Waiting for arming...")
    time.sleep(1)

    print("Taking off!")
    self.vehicle.simple_takeoff(target_altitude)

    takeoff_timeout = 30
    start_time = time.time()

    while True:
    current_altitude = self.vehicle.location.global_relative_frame.alt
    print(f" Altitude: {current_altitude}")
    if current_altitude >= target_altitude * 0.95:
    print("Reached target altitude")
    return True
    elif time.time() - start_time > takeoff_timeout:
    print("Takeoff failed, timeout reached")
    return False
    time.sleep(1)

    def pre_arm_check(self):
    print("waiting for vehicle to initialise")
    while not self.vehicle.is_armable:
    print("waiting for vehicle to initialise...")
    time.sleep(1)
    print("vehicle is ready to arm")

    def set_guided_mode(self):
    print("Attempting to set GUIDED mode")

    # Try to set mode using standard method
    self.vehicle.mode = VehicleMode("GUIDED")
    self.vehicle.flush()

    start_time = time.time()
    timeout = 10
    while self.vehicle.mode.name != 'GUIDED':
    if time.time() - start_time > timeout:
    print("Failed to set GUIDED mode within timeout period")
    print(f"Mode: {self.vehicle.mode.name}")
    return False
    time.sleep(1)
    print("GUIDED mode set successfully")
    return True



    def fly_to_point(self, location: Location):
    print("Flying to point")
    point_end = LocationGlobalRelative(location.lat, location.lon, location.alt)
    self.vehicle.simple_goto(point_end)

    # Wait until the drone reaches the correct spot
    while True:
    distance = self.distance_to(location)
    print(f"Distance to target: {distance:.2f} meters")
    if distance <= 1:
    print("Reached target point")
    break
    time.sleep(1)

    def land(self):
    print("Landing...")
    self.vehicle.mode = VehicleMode("RTL") #might be "LAND"

    def close(self):
    self.vehicle.close()

    def get_distance(self, location1: Location, location2: Location):
    #use the haversine formula to calculate the distance between two points on a 3d sphere
    earth_radius = 6371000 #meters
    lat1 = math.radians(location1.lat)
    lon1 = math.radians(location1.lon)
    lat2 = math.radians(location2.lat)
    lon2 = math.radians(location2.lon)

    dlat = lat2 - lat1 # differences in latitude and longitude
    dlon = lon2 - lon1

    #haversine formula to calculate the distance between two points on a sphere
    a = (math.sin(dlat/2) * math.sin(dlat/2) + math.cos(lat1) * math.cos(lat2) * math.sin(dlon/2) * math.sin(dlon/2))
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))

    distance = earth_radius * c

    alt_diff = abs(location2.alt - location1.alt)
    total_distance = math.sqrt(distance**2 + alt_diff**2)

    return total_distance

    def distance_to(self, location: Location):
    current_location = self.get_location()
    return self.get_distance(current_location, location)

    def print_position(self):
    location = self.vehicle.location.global_relative_frame
    print(f"Position: Lat: {location.lat}, Lon: {location.lon}, Alt: {location.alt}")

    def position_printer(self, stop):
    while not stop():
    self.print_position()
    time.sleep(1) #print the position every second

    def keyboard_control(self):
    print("starting keyboard control. use arrow keys to move the drone, press 'q' to quit")
    with keyboard.Listener(on_press=self.on_press, on_release=self.on_release) as listener:
    listener.join()

    def set_velocity(self, x, y, z, yaw):
    msg = self.vehicle.message_factory.set_position_target_local_ned_encode(
    0, # time_boot_ms (not used)
    0, 0, # target system, target component
    mavutil.mavlink.MAV_FRAME_LOCAL_NED, # frame
    0b0000111111000111, # type_mask (only speeds enabled)
    0, 0, 0, # x, y, z positions (not used)
    x, y, z, # x, y, z velocity in m/s
    0, 0, 0, # x, y, z acceleration (not supported yet, ignored in GCS_Mavlink)
    0, math.radians(yaw)) # yaw, yaw_rate (not supported yet, ignored in GCS_Mavlink)
    self.vehicle.send_mavlink(msg)
    self.vehicle.flush()

    def move_forward(self):
    self.set_velocity(5, 0, 0, 0)
    print("moving forward")

    def move_backward(self):
    self.set_velocity(-5, 0, 0, 0)
    print("moving backward")

    def move_left(self):
    self.set_velocity(0, 5, 0, 0)
    print("moving left")

    def move_right(self):
    self.set_velocity(0, -5, 0, 0)
    print("moving right")

    def move_up(self):
    self.set_velocity(0, 0, -5, 0)
    print("moving up")

    def move_down(self):
    self.set_velocity(0, 0, 5, 0)
    print("moving down")

    def stop(self):
    self.set_velocity(0, 0, 0, 0)
    print("stopping")

    def on_press(self, key):
    try:
    if key == keyboard.Key.up:
    self.move_forward()
    elif key == keyboard.Key.down:
    self.move_backward()
    elif key == keyboard.Key.left:
    self.move_left()
    elif key == keyboard.Key.right:
    self.move_right()
    elif hasattr(key, 'char'):
    if key.char == 'w':
    self.move_up()
    elif key.char == 's':
    self.move_down()
    elif key.char == 'q':
    print("Quitting keyboard control")
    return False
    except AttributeError:
    print('special key {0} pressed'.format(key))

    def on_release(self, key):
    self.set_velocity(0, 0, 0, 0)
    print("stopping")
    if key == keyboard.Key.esc:
    # Stop listener
    return False

    if __name__ == "__main__":


    print("Connecting to vehicle on: %s" % connection_string)
    drone = DroneController(connection_string)

    stop_threads = False
    printer_thread = threading.Thread(target=drone.position_printer, args=(lambda: stop_threads,))

    try:
    print("Performing pre-arm check")
    drone.pre_arm_check()
    print("Pre-arm check completed. Attempting takeoff")
    print(f"Is Armable: {drone.vehicle.is_armable}")
    print(f"System Status: {drone.vehicle.system_status.state}")
    print(f"Mode: {drone.vehicle.mode.name}")

    takeoff_success = drone.arm_and_takeoff(10)
    if takeoff_success:
    print("Takeoff successful")
    time.sleep(2)

    print("Starting keyboard control")
    printer_thread.start()
    drone.keyboard_control()
    else:
    print("Takeoff failed. Checking vehicle state:")
    print(f"Is Armed: {drone.vehicle.armed}")
    print(f"System Status: {drone.vehicle.system_status.state}")
    print(f"Mode: {drone.vehicle.mode.name}")
    print("Aborting mission")

    except Exception as e:
    print(f"An error occurred: {str(e)}")

    finally:
    print("Landing and closing connection")
    stop_threads = True
    printer_thread.join()
    drone.land()
    drone.close()
    sitl.stop()


    and this is the error I keep getting:

    Starting copter simulator (SITL)
    SITL already Downloaded and Extracted.
    Ready to boot.
    Connecting to vehicle on: tcp:127.0.0.1:5760
    Attempting to connect to tcp:127.0.0.1:5760
    CRITICAL:autopilot:APM:Copter V3.3 (d6053245)
    CRITICAL:autopilot:Frame: QUAD
    CRITICAL:autopilot:Calibrating barometer
    CRITICAL:autopilot:Initialising APM...
    CRITICAL:autopilot:barometer calibration complete
    CRITICAL:autopilot:GROUND START
    Successfully connected to the vehicle
    Performing pre-arm check
    waiting for vehicle to initialise
    waiting for vehicle to initialise...
    waiting for vehicle to initialise...
    waiting for vehicle to initialise...
    waiting for vehicle to initialise...
    waiting for vehicle to initialise...
    vehicle is ready to arm
    Pre-arm check completed. Attempting takeoff
    Is Armable: True
    System Status: STANDBY
    Mode: STABILIZE
    Basic pre-arm checks
    Attempting to set GUIDED mode
    Failed to set GUIDED mode within timeout period
    Mode: STABILIZE
    not guieded mode
    Takeoff failed. Checking vehicle state:
    Is Armed: False
    System Status: STANDBY
    Mode: STABILIZE
    Aborting mission
    Landing and closing connection
    Traceback (most recent call last):
    File "/Users/koviressler/Desktop/AeroCleanTech/Drone_Control/drone_controller.py", line 274, in <module>
    printer_thread.join()
    File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/threading.py", line 1107, in join
    raise RuntimeError("cannot join thread before it is started")
    RuntimeError: cannot join thread before it is started


    Don't worry about the thread error. I am simply using threading to print out the drone's position every second and the error only occurs because I only start the thread if the drone takes of correctly, which it isn't.

    I tried debugging by adding tons of print statements, but it always led back to the GUIDED mode issue. It used to work, but one day I must have added something that broke it and it hasn't worked since. It could be a compatability issue.

    Continue reading...

Compartilhe esta Página