Manual control - python

hi I try to use the manual control example from GitHub

this code doesn’t work
this is something that the developer knows?

Ok, and what doesn’t work?

I am running px4-sitl on jmavsim and receives this error:

Waiting for drone to connect...
-- Connected to drone!
-- Global position state is good enough for flying.
-- Arming
-- Taking off
-- Starting manual control
Traceback (most recent call last):
  File "/usr/lib/python3.10/idlelib/run.py", line 578, in runcode
    exec(code, self.locals)
  File "/home/amitkatav/MAVSDK/examples/manual_control.py", line 99, in <module>
    asyncio.run(manual_controls())
  File "/usr/lib/python3.10/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/usr/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete
    return future.result()
  File "/home/amitkatav/MAVSDK/examples/manual_control.py", line 73, in manual_controls
    await drone.manual_control.start_position_control()
  File "/home/amitkatav/.local/lib/python3.10/site-packages/mavsdk/manual_control.py", line 228, in start_position_control
    raise ManualControlError(result, "start_position_control()")
mavsdk.manual_control.ManualControlError: COMMAND_DENIED: 'Command Denied'; origin: start_position_control(); params: ()

Ok, so the error is “command denied”. You need to find out why. I suggest to subscribe to statustext messages in MAVSDK to see if there is some output. Alternatively, if you run the mavsdk_server separately, you can also see that output.

i receive just the same error

StatusText: [type: CRITICAL, text: Switching to Position is currently not available	]

and in the terminal:

WARN  [commander] Switching to Position is currently not available

QGC:

16:16:17.502] Info: Armed by external command
[16:16:17.503] Info: Using default takeoff altitude: 15.00 m
[16:16:17.504] Critical: Manual control lost
[16:16:17.504] Critical: Failsafe activated due to manual control loss, triggering RTL in 5 seconds
[16:16:19.524] Info: Takeoff detected
[16:16:21.956] Critical: Switching to mode 'Position control' is currently not possible
No manual control input
[16:16:21.972] Info: Pilot took over using sticks
[16:16:21.972] Info: Manual control regained after 4.8 s
[16:16:21.972] Info: Using default takeoff altitude: 15.00 m
[16:16:22.644] Critical: Manual control lost
[16:16:22.655] Critical: Failsafe activated due to manual control loss, triggering RTL in 1 seconds
[16:16:23.355] Critical: Failsafe activated due to manual control loss, triggering RTL
[16:16:23.355] Info: RTL: start return at 492 m (4 m above destination)
[16:16:23.516] Info: RTL: land at destination
[16:16:35.064] Info: Landing detected
[16:16:37.072] Info: Disarmed by landing

This is the reason. You need to have manual control working to switch to position control.

So, there is a problem with the example code. In the first step, I just want the example to work in mavsdk-python using px4 sitl running with jmavsim.

I managed to make it work by running an asynchronous loop to maintain the control inputs.

import asyncio
from mavsdk import System

roll = ""
pitch = ""
throttle = ""
yaw = ""

async def main():
    """Main function to connect to the drone and input manual controls"""
    global roll, pitch, yaw, throttle
    # Connect to the Simulation
    drone = System()
    await drone.connect(system_address="udp://:14540")

    # This waits till a mavlink based drone is connected
    print("Waiting for drone to connect...")
    async for state in drone.core.connection_state():
        if state.is_connected:
            print(f"-- Connected to drone!")
            break

    # Checking if Global Position Estimate is ok
    async for health in drone.telemetry.health():
        if health.is_global_position_ok and health.is_home_position_ok:
            print("-- Global position state is good enough for flying.")
            break

    # Arming the drone
    print("-- Arming")
    await drone.action.arm()

    # Take off
    print("-- Taking off")
    await drone.action.takeoff()
    await asyncio.sleep(10)

    print("-- Set manual control")
    roll = 0.0
    pitch = 0.0
    throttle = 0.5
    yaw = 0.0
    # set the manual control input after arming
    manual = asyncio.create_task(manual_controls(drone))
    print("-- wait")
    await asyncio.sleep(1)

    # start manual control
    print("-- Starting manual control")
    await drone.manual_control.start_position_control()
    print("-- wait")
    await asyncio.sleep(1)
    print("-- Change manual control")
    roll = 0.1
    pitch = 0.1
    throttle = 0.4
    yaw = 0.0
    await asyncio.sleep(5)

    await drone.action.land()
    print("-- end")

async def manual_controls(drone):
    global roll, pitch, yaw, throttle
    while True:
        await drone.manual_control.set_manual_control_input(pitch, roll, throttle, yaw)


if __name__ == "__main__":
    # Run the asyncio loop
    asyncio.run(main())

1 Like