POI with Anafi AI

Hello,
I am using Olympe with ROS1 Noetic with the anafi AI.
I want to use POI features of Olympe to achieve a POI while flying.
Until now I have tried to use the PointNFly feature of Olympe with no success but I managed to achieve a POI using StartPilotedPOIV2 in the Piloting feature.

Until now, with the mode in StartPilotedPOIV2 set to “locked_gimbal”, the drone achieves the POI, I can make it move to a certain point (not facing the POI) but when arrived at the waypoint, it faces the poi again.

I would like the drone to lock on the POI even while moving, have you any idea how to do it and if it is possible ?

Thank you !

Hello Jatou,

I have understood your issue, and here is how it goes.

Olympe is an API that eases the communication between the drone and a third part (the user). It has several features, but at its simplest, it passes on orders and events to and from the drone. The ‘PointNFly’ feature as you called it, is simply a command to send to the drone, that will answer events to Olympe

Below is an example of how to properly use the PointNFly command.
In case an expectation does not succeed even if it should, think of adjusting the timeout :wink:

# Start with Olympe imports
import olympe

# Import Fly and Point protobuf messages. Those are objects-like that will store the data
# of the location to point to, and how, and some other characteristics

# If a Point directive is executed, the drone will constantly point at the target as it
# moves, until the Point directive is deactivated or a Fly directive is executed.
# If a Fly directive is executed, the drone will move to that location
from olympe.messages.pointnfly import Fly, Point

# Execute is a command to send to the drone, that indicates whether a Point or a Fly
# directive should be executed
# Deactivate will abort any current directive
from olympe.messages.pointnfly.Command import Execute, Deactivate

# State is an event received from the drone, that indicates whether the piloting state is
# 'unavailable', 'idle' or 'active' ; and if so, whether the current directive is 'Point'
# or 'Fly'
# Execution informs on the execution status, whether it is 'successed', 'failed' or 'interrupted'
from olympe.messages.pointnfly.Event import State, Execution

# TakeOff commands
from olympe.messages.ardrone3.Piloting import TakeOff, Landing
from olympe.messages.ardrone3.PilotingState import FlyingStateChanged, AttitudeChanged



# Let's define a waypoint
# ToDo: adjust to your own case
latitude_value=_
longitude_value=_

# Let's define a 'Point' directive
point = Point(
    gimbal_control_mode="locked", # can be 'locked', 'locked_once' or 'free'
    latitude=latitude_value,
    longitude=longitude_value,
    altitude=10.0,
)

# Let's define a 'Fly' directive
fly = Fly(
    latitude=latitude_value,
    longitude=longitude_value,
    altitude=10.0,
    max_horizontal_speed=12.5,
    max_vertical_speed=3.5,
    max_yaw_rotation_speed=360.0,
)

def use_pointnfly(drone_ip = "10.202.0.1"):
    # SET UP THE CONNECTion to your drone
    drone = olympe.Drone(drone_ip)
    drone.connect()

    # Make sure that the drone won't apply any directive in its 'landed' state
    expectation_pointnfly_not_flying = drone(
        State(unavailable=dict(reasons=["UNAVAILABILITY_REASON_DRONE_NOT_FLYING"]))
    ).wait(_timeout=10)
    if not expectation_pointnfly_not_flying.success():
        print("PointNFly is not possible when the drone is not flying")
        return
    print("PointNFly correct state 'unavailable' when the drone is in 'landed' state")

    # Check that a 'Point' or 'Fly' directive won't be executed
    expectation_point_not_flying = drone(State(active=dict(point=point))).wait(_timeout=5)
    if expectation_point_not_flying.success():
        print("PointNFly 'Point' directive should not be active in 'landed' state!")

    expectation_fly_not_flying = drone(State(active=dict(fly=fly))).wait(_timeout=5)
    if expectation_fly_not_flying.success():
        print("PointNFly 'Fly' directive should not be active in 'landed' state!")

    # Takeoff
    expectation_takeoff = drone(TakeOff() >> FlyingStateChanged(state="hovering")).wait(_timeout=10)
    if not expectation_takeoff.success():
        print("The drone has failed taking off")
        return
    print("TakeOff succeeded! The drone is flying in 'hovering' state!")

    # Make sure that the drone can apply a directive in its 'hovering' (ie flying) state
    expectation_pointnfly_flying = drone(State(idle=dict())).wait(_timeout=10)
    if not expectation_pointnfly_flying.success():
        print("PointNFly is not possible even if the drone is flying")
        return
    print("PointNFly correct state 'idle' when the drone is in 'hovering' state!")

    # Send a 'Point' directive
    expectation_point = drone(
        Execute(point=point)
        >> State(active=dict(point=point))
        >> FlyingStateChanged(state="flying")
    ).wait(_timeout=10)
    if not expectation_point.success():
        print("The drone has failed executing the 'Point' directive")
        return
    print("PointNFly 'Point' directive is executing! The drone is pointing to it")

    # Wait for the drone to reach its targeted orientation
    # ToDo: adjust the yaw value to your calculations
    expectation_orientation = drone(AttitudeChanged(yaw=_, _float_tol=(1e-7, 0.1))).wait(_timeout=30)
    if not expectation_orientation.success():
        print("The drone has failed reaching its targeted orientation")
        return
    print("The drone points to the right direction!")

    # Check that the PointNFly 'Point' directive is still active
    expectation_point = drone(
        State(active=dict(point=point), _policy="check")
    ).wait(_timeout=30)
    if not expectation_point.success():
        print("The drone has failed keeping the 'Point' directive active")
        return
    print("PointNFly 'Point' directive is still active!")

    # Deactivate properly PointNFly 'Point' directive
    expectation_point_deactivate = drone(
        Deactivate()
        >> FlyingStateChanged(state="hovering")
        >> State(idle=dict())
        >> Execution(status="interrupted")
    ).wait(_timeout=30)
    if not expectation_point_deactivate.success():
        print("The drone has failed to deactivate the 'Point' directive")
        return
    print("PointNFly 'Point' directive is interrupted! The drone is still in hovering state!")

    # Send a 'Fly' directive
    expectation_fly = drone(
        Execute(fly=fly) >> State(active=dict(fly=fly))
    ).wait(_timeout=10)
    if not expectation_fly.success():
        print("The drone has failed executing the 'Fly' directive")
        return
    print("PointNFly 'Fly' directive is executing! The drone is flying to its direction")

    # Wait the end of the 'Fly' directive
    expectation_fly_success = drone(
        Execution(status="success")
        >> FlyingStateChanged(state="hovering")
        >> State(idle=dict())
    ).wait(_timeout=10)
    if not expectation_fly_success.success():
        print("The drone has failed reaching its targeted direction")
        return
    print("PointNFly 'Fly' directive has succeeded! The drone has stopped flying and reached its targeted location and is in hovering state!")

    # Land
    drone(Landing()).wait()
    drone(FlyingStateChanged(state="landed")).wait()

    drone.disconnect()

if __name__ == "__main__":
    use_pointnfly()

Hello,
Thanks for that ! Very useful !
As I am using StartPilotedPOIV2() from the piloting feature, what about it ? Are we able to perform a POI while sending moveto orders ? Meaning : is it possible to lock on a POI while moving ?

Nope, because that is what PointNFly is for :slight_smile: it is the specific command to use for your purpose

Okay so a moveto command will not cancel the POI ? I will try to make PointNFly work, i did not managed to until now.

Let me know if you have issues with the example I’ve provided you!

Hello again, I tried your code with sphinx and even in hovering or flying state, I get :

“PointNFly is not possible even if the drone is flying”

As a result of :
expectation_pointnfly_flying = drone(State(idle=dict())).wait(_timeout=10)
if not expectation_pointnfly_flying.success():
print(“PointNFly is not possible even if the drone is flying”)
Do you have an idea why ?
Thank you for your answer !

Hello,
I would really love your input on this, I am really stuck :confused: