Adanced Olympe expectation usage#
Before continuing with this Olympe example, you might want to read the Olympe eDSL section (if you haven’t read it already).
Sometimes it can be useful to send a command to the drone only if it is in a specific state. For example, if the drone is already hovering when you start an Olympe script, you might want to skip the usual taking off command. This can be useful if a previous execution of your script left your drone in a hovering state.
1import olympe 2import os 3from olympe.messages.ardrone3.Piloting import TakeOff 4from olympe.messages.ardrone3.PilotingState import FlyingStateChanged 5from olympe.enums.ardrone3.PilotingState import FlyingStateChanged_State 6from olympe.messages.ardrone3.GPSSettingsState import GPSFixStateChanged 7 8DRONE_IP = os.environ.get("DRONE_IP", "10.202.0.1") 9 10 11def test_takeoff_if_necessary_1(): 12 with olympe.Drone(DRONE_IP) as drone: 13 drone.connect() 14 print("Takeoff if necessary...") 15 if (drone.get_state(FlyingStateChanged)["state"] is not 16 FlyingStateChanged_State.hovering): 17 drone(GPSFixStateChanged(fixed=1, _timeout=10, _policy="check_wait")).wait() 18 drone( 19 TakeOff(_no_expect=True) 20 & FlyingStateChanged(state="takingoff", _policy="wait", _timeout=5) 21 ).wait() 22 drone.disconnect() 23 24 25if __name__ == "__main__": 26 test_takeoff_if_necessary_1()
olympe.Drone.get_state() is used to check the current flying state of the drone. If
the drone is not in hovering, we check and eventually wait for a GPS fix. Note that “check_wait” is
the default value for the _policy parameter. The possible values for the _policy parameter are:
“check”, to check the current state of the drone (i.e. match the last event message of this kind received from the drone).
“wait”, to wait for a new event message from the drone (even if the last event message of this kind that has been received would have matched).
“check_wait” (the default), to “check” the current state of the drone and if necessary “wait” for a matching event message.
In the above example we are using a compound expectation expression to send a taking off command when the drone has a GPS fix and when it is not already in the hovering state.
The default expectations for the
TakeOff command are:
FlyingStateChanged(state='motor_ramping', _policy='wait') &
TakeOff() command documentation). When the
controller receives the “takingoff” flying state a few milliseconds after the
command has been sent, the drone has just climbed a few centimeters. Here, we don’t really care for
this “takingoff” flying state and this is why we are disabling the default expectations of the
TakeOff(_no_expect=True) sends the takeoff command and does not
wait for the default expectations for this command. Instead of the default expectations, we are
directly expecting the “hovering” flying state. We are using the ‘&’ (“AND”) operator instead of
‘>>’ (“THEN”) to wait for this event while Olympe sends the
TakeOff command concurrently.
If the “>>” (“THEN”) operator were to be used instead, we might (theoretically) miss the
FlyingStateChanged event drone response while Olympe sends the ‘TakeOff’ message.
As demonstrated below, this problem can also be solved without using any control flow statements:
1import olympe 2import os 3from olympe.messages.ardrone3.Piloting import TakeOff 4from olympe.messages.ardrone3.PilotingState import FlyingStateChanged 5from olympe.messages.ardrone3.GPSSettingsState import GPSFixStateChanged 6 7DRONE_IP = os.environ.get("DRONE_IP", "10.202.0.1") 8 9 10def test_takeoff_if_necessary_2(): 11 with olympe.Drone(DRONE_IP) as drone: 12 drone.connect() 13 print("Takeoff if necessary...") 14 drone( 15 FlyingStateChanged(state="hovering", _policy="check") 16 | ( 17 GPSFixStateChanged(fixed=1, _timeout=10) 18 >> ( 19 TakeOff(_no_expect=True) 20 & FlyingStateChanged(state="takingoff", _policy="wait", _timeout=5) 21 ) 22 ) 23 ).wait() 24 drone.disconnect() 25 26 27if __name__ == "__main__": 28 test_takeoff_if_necessary_2()
Here, the ‘|’ (“OR”) operator is used to “check” if the current flying state is “hovering”. If not, we wait for a GPS fix if necessary with the implicit “check_wait” policy. Then (“>>”) we send the taking off command and override the default expectations to wait for the “hovering” flying state as before.