Trying to figure out gimbal capabilities, current attitude

…to no avail. It is IMHO not really well documented and I’m constantly failing.

gimbal_capabilities = self.drone(gimbal.gimbal_capabilities(gimbal_id = 0, model=model.main, axes=olympe.enums.gimbal.axis.pitch))

Could you please proved a sample?

Hi,

The gimbal.gimbal_capabilities message tells you for each camera which axis are controllable through the SDK.

For ANAFI, there is only one gimbal for the front camera for which only the pitch axis is controllable (the roll axis is stabilized and there is no yaw axis).

To get the current attitude of the gimbal use the gimbal.attitude event message (current value for each axis in the absolute and relative frames of reference).

I tried that and got this:

        gimbal_attitude = self.drone(gimbal.attitude(gimbal_id = 0, yaw_frame_of_reference=1, pitch_frame_of_reference=1, roll_frame_of_reference=1))
        print(gimbal_attitude)

gives (in red):

 gimbal.attitude(
        gimbal_id=0,
        yaw_frame_of_reference=1,
        pitch_frame_of_reference=1,
        roll_frame_of_reference=1,
        policy=ExpectPolicy.check_wait,
    )

Similar with other values for the reference frame. Tested on a real drone. Does somehow not give me the expected attitude.

Adding a wait() hangs the request.

Any additional pointer on this available?

Hi,

In your code snippet you create an expectation object waiting for the gimbal.attitude( (gimbal_id=0, yaw_frame_of_reference='RELATIVE', pitch_frame_of_reference='RELATIVE', roll_frame_of_reference='RELATIVE' ) event message but the drone only send gimbal.attitude messages with the *_frame_of_reference parameters set to ‘NONE’ (0). This explains why your expectation object does not match any event and eventually times out.

Anyway, these *_frame_of_reference parameters should be ignored because every message contains the *_relative and *_absolute values for each gimbal axis (yaw, pitch and roll).

I think you should probably be using the drone.get_state method as explained in the tutorial here instead.

Here is a code sample showing how to get the gimbal.attitude parameters in three different way including the drone.get_state method :

from olympe.messages import gimbal
from logging import getLogger
import olympe
import time
import os

olympe.log.update_config({
    "loggers": {
        "olympe": {"level": "WARNING"},
    }
})

# Drone IP
DRONE_IP = os.environ.get("DRONE_IP", "10.202.0.1")


class GimbalAttituteEventListener(olympe.EventListener):
    @olympe.listen_event(gimbal.attitude())
    def onGimbaAttitude(self, event, scheduler):
        print(f"pitch={event.args['pitch_relative']}")


drone = olympe.Drone(DRONE_IP)
assert drone.connect()

# This example demonstrate three different way to access the an event message parameters values
# (We're using the gimbal.attitude event here, but it could be any other event message).

# 1. Using the an expectation.received_events() method :
gimbal_attitude_exp = drone(gimbal.attitude()).wait(1.0)
# Here, we match every event regardless of their *_frame_of_reference parameters (always NONE for
# historical reasons).
# The gimbal.attitude event is sent by the drone at 5Hz, so the following assert should not fail
assert gimbal_attitude_exp

print(gimbal_attitude_exp.received_events())

# 2. Using the drone.get_state() method
# gimbal.attitude states are stored in a dictionary by gimbal_id (0):
gimbal_id = 0
print(drone.get_state(gimbal.attitude)[gimbal_id]["pitch_relative"])

# 3. Using an event listener:
with GimbalAttituteEventListener(drone) as listener:
    time.sleep(10)

drone.disconnect()

Thanks for the elaborated answer. Sure it will help. Will let you know.

Confirming both methods to work fine. Thanks again

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.