Change a drone setting - Understand the “expectation” mechanism

Objective:

Change the current value of the “maximum tilt” drone’s setting.

A little explanation first

This setting indirectly controls the maximum drone acceleration and speed. The more the drone can tilt, the more speed the drone gains.

The maximum tilt value must be within a minimum and maximum range. A drone with a max tilt value of 0° is not particularly useful while a maximum tilt over 180° might only be useful for a racer.

Note

For Anafi the maximum tilt setting must be within 1° and 40°.

You might be wondering:

  • What is happening when you send an invalid setting value (ex: 180°)?

  • How does the drone respond to that?

  • How do we catch this kind of error with Olympe?

Let’s see how this is done in the following example. First, reset the simulation: sphinx-cli action -m world fwman world_reset_all in a terminal.

Copy paste the following Python maxtilt_set.py script somewhere in your directory:

Body

This time, the script connects to the drone and sends two MaxTilt commands. The first one with a 10° tilt value, the second with a 0° tilt value.

Note that this time, we are assigning the object returned by the olympe.Expectation.wait() method into the maxTilt_expectation variable. For now, all you have to know is that you can call .success() -> bool on an “expectation” object to know if your command has succeeded or not. The olympe.Expectation.success() function returns True in case of success and False otherwise.

You can also call .timedout() -> bool on an “action” object to know if your command message timed out. This olympe.Expectation.timedout() method is not particularly useful in this example because we always call olympe.Expectation.wait() on the action object, so the action is either successful or has timed out already.

Execution

To execute this script, run the following command from the shell you’ve just sourced:

(olympe-python3) $ python ./maxtilt_set.py

If all goes well, you should see the following output in your terminal:

MaxTilt(10) set succeeded
MaxTilt(0) set timedout

Obviously, the 10° maximum tilt value is correct, so the first command succeeded while the second command failed to set an incorrect 0° maximum tilt value.

How does Olympe deal with expectation timeout and drone refusal when setting wrong

It is important to understand how Olympe knows if a particular command succeeded or not. When Olympe sends a command message, it usually implicitly expects an event message in return.

Note

Command messages and event messages are somewhat similar. They are both associated with an internal unique ID and eventually with some arguments (ex: the maximum tilt value) and they both travel from one source to a destination.

When Olympe sends the MaxTilt(10) command message, it implicitly expects a MaxTiltChanged(10) event message in return. If the event is received in time, everything is fine: maxTilt_expectation.success() is True and maxTilt_expectation.timedout() is False. Otherwise, the maxTilt_expectation times out (maxTilt_expectation.success() is False and maxTilt_expectation.timedout() is True).

When Olympe sends the MaxTilt(0) command message, it receives a MaxTiltChanged(1) event message because 0° is an invalid setting value. The drone informs the controller that it has set the minimum setting value instead (1°). Olympe does not assume that this response means “No, I won’t do what you are asking”. Instead, it still waits for a MaxTiltChanged(0) event that will never come and the command message times out: (maxTilt_expectation.success() is False and maxTilt_expectation.timedout() is True).

This behavior is identical for every command message: when Olympe sends a command message to a drone, it either results in a success or a timeout.

Important

The ARSDK protocol defined in arsdk-xml does not provide a way to report errors uniformly. This is why Olympe cannot detect errors like this one and just time out instead. Olympe associates to each command a default timeout that can be overridden with the _timeout message parameter. For example:

maxTilt_expectation = drone(MaxTilt(10, _timeout=1)).wait()