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
# 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()