Using Olympe asynchronously#

In the basic examples above we’ve always performed actions synchronously because we were always immediately waiting for an action to complete with the .wait() method.

In this example, we will send some flying commands to the drone asynchronously. While the drone executes those commands, we will start a video recording and change the gimbal velocity target along the pitch axis. After sending those camera-related commands, we will call the .wait() method on the “flying action” and then stop the recording.

Create the following python script somewhere in your home directory:

 1import os
 2import olympe
 3from olympe.messages.ardrone3.Piloting import TakeOff, moveBy, Landing
 4from olympe.messages.ardrone3.PilotingState import FlyingStateChanged
 5from import start_recording, stop_recording
 6from olympe.messages import gimbal
 8DRONE_IP = os.environ.get("DRONE_IP", "")
11def test_asyncaction():
12    with olympe.Drone(DRONE_IP) as drone:
13        drone.connect()
15        # Start a flying action asynchronously
16        flyingAction = drone(
17            TakeOff()
18            >> FlyingStateChanged(state="hovering", _timeout=5)
19            >> moveBy(10, 0, 0, 0)
20            >> FlyingStateChanged(state="hovering", _timeout=5)
21            >> Landing()
22        )
24        # Start video recording while the drone is flying
25        if not drone(start_recording(cam_id=0)).wait().success():
26            assert False, "Cannot start video recording"
28        # Send a gimbal pitch velocity target while the drone is flying
29        cameraAction = drone(gimbal.set_target(
30            gimbal_id=0,
31            control_mode="velocity",
32            yaw_frame_of_reference="none",
33            yaw=0.0,
34            pitch_frame_of_reference="none",
35            pitch=0.1,
36            roll_frame_of_reference="none",
37            roll=0.0,
38        )).wait()
40        if not cameraAction.success():
41            assert False, "Cannot set gimbal velocity target"
43        # Wait for the end of the flying action
44        if not flyingAction.wait().success():
45            assert False, "Cannot complete the flying action"
47        # Stop video recording while the drone is flying
48        if not drone(stop_recording(cam_id=0)).wait().success():
49            assert False, "Cannot stop video recording"
51        # Leaving the with statement scope: implicit drone.disconnect() but that
52        # is still a good idea to perform the drone disconnection explicitly
53        drone.disconnect()
56if __name__ == "__main__":
57    test_asyncaction()

Reset the simulation (sphinx-cli action -m world fwman world_reset_all in a terminal) and execute this script, from the same shell/terminal you have source’d the shell script:

In this example, the olympe.Drone.__call__() functor process commands and events asynchronously so that multiple commands can be sent to the drone and processed concurrently. The events associated to asynchronous actions are interleaved in an undefined order. The following sequence diagram illustrates a possible sequence of event for this script.

blockdiag Olympe Drone flyingAction pending start record pending start record successful flyingAction pending cameraAction successful flyingAction pending waiting for FlyingStateChanged(state='hovering') flyingAction pending flyingAction pending flyingAction pending flyingAction pending waiting for FlyingStateChanged(state='hovering') flyingAction pending flyingAction pending flyingAction pending flyingAction successful stop record pending stop record successful connect connected TakeOff() VideoV2(record='start') VideoStateChangedV2(state='started') FlyingStateChanged(state='motor_ramping') set_target(control_mode='velocity', ...) FlyingStateChanged(state='takingoff') FlyingStateChanged(state='hovering') moveBy() FlyingStateChanged(state='flying') moveByEnd() FlyingStateChanged(state='hovering') Landing() FlyingStateChanged(state='landing') FlyingStateChanged(state='landed') VideoV2(record='stop') VideoStateChangedV2(state='stopped') disconnect disconnected

Asynchronous command examples#