Emergency Landing as interrupt

I have been trying to run tasks asynchronously (similarly to what is being done in the asyncaction.py example). I would like to add the possibility to send an Emergency() command at any time, especially while the flyingAction is being executed:

flyingAction = drone(
    TakeOff()
    >> FlyingStateChanged(state="hovering", _timeout=5)
    >> moveBy(10, 0, 0, 0)
    >> FlyingStateChanged(state="hovering", _timeout=5)
    >> Landing()
)

[...]

# Wait for the end of the flying action
if not flyingAction.wait().success():
    raise RuntimeError("Cannot complete the flying action")

I am using Pynput to acquire keyboard input and to trigger the Emergency() command as follows:

from pynput.keyboard import Listener, KeyCode
def on_press(key):
    if key == KeyCode.from_char('e'):
        print('EMERGENCY cutoff triggered')
        drone(Emergency())
listener = Listener(on_press=self.on_press)
listener.start()

To my understanding, the flyingAction itself is non-blocking, but the if statement that follows is: therefore, the Emergency command is sent only after the *flyingAction.wait().success()* has been satisfied, no matter when it is triggered. Is there a simple way to still wait for the task completion but being able to dynamically send commands to the drone (similarly to what happens in the FreeFlight apps)?
1 Like

Hello,

After reworking the asyncaction.py example, I’ve managed to send an Emergency() message during the flyingAction. Everything worked as expected.

# -*- coding: UTF-8 -*-

import olympe
from olympe.messages.ardrone3.Piloting import TakeOff, moveBy, Landing, Emergency
from olympe.messages.ardrone3.PilotingState import FlyingStateChanged
from pynput.keyboard import Listener, KeyCode


def on_press(key):
    if key == KeyCode.from_char('e'):
        print('EMERGENCY cutoff triggered')
        drone(Emergency())


listener = Listener(on_press=on_press)
listener.start()


with olympe.Drone("10.202.0.1") as drone:
    drone.connection()

    # Start a flying action asynchronously
    flyingAction = drone(
        TakeOff()
        >> FlyingStateChanged(state="hovering", _timeout=5)
        >> moveBy(10, 0, 0, 0)
        >> FlyingStateChanged(state="hovering", _timeout=5)
        >> Landing()
    )

    # press 'e' here will send the Emergency message

    # Wait for the end of the flying action
    if not flyingAction.wait().success():
        raise RuntimeError("Cannot complete the flying action")

    # Leaving the with statement scope: implicit drone.disconnection()

Without a complete script, it’s difficult to tell what went wrong for you.

Yes

which statement is blocking? I don’t follow you here. The Emergency() message is sent asynchronously the moment you press ‘e’. There is nothing preventing it from being sent before flyingAction.wait().success().

I hope that the full example above answers your question.