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.