ANAFI AI Precise Landing

Hello,
In my application I have my own Airsdk mission. In this mission I’m trying to implement Precise Home Landing. In order to take a photo at 0.8 meters I have a state called take_off_to_photo and in that I do following:

• import and initialize PreciseHomeManager with following code :

self.precise_home_mng = self.mission.get_manager(
PreciseHomeManager, create_if_needed=True)

• start and initialize precise home manager with following :
	self.precise_home_mng.start_process()
	self.precise_home_mng.enable_precise_home(True)
• Take photo at 0.8 meters with following :

self.precise_home_mng.check_reset_sensor_timer = 30
self.precise_home_mng.get_precise_home_local_position = True
self.precise_home_mng.set_ref_image = True
ref_image = self.precise_home_mng.check_set_ref_image_condition
self.log.info("PRECISE PHOTO IMAGE CONDITION : " + str(ref_image))
self.log.info("PRECISE HOME STATUS " + str(self.precise_home_mng))

From the logs I read that image is a valid ref image from the following:
prhome_Strategy(pimp-hovering-a-188/prhome-queue:sr-476): EVT:VISION; feature=‘precise_home’; status='ref_image_valid"
pimp_hovering(pimp-hovering-a-188/prhome-queue: sr-476): packages/pimp-hovering/src/pimp-hovering.c:300 precise home is ready for compute pausing the pipeline
I vipcsrc (pimp-hovering-a-188/prhome-src:src-478): gstvipcsrc.c:1461:gst_vipc_src_flush:vipc stopped (gzserver-9710/vertical_camera-46272): vcam.sock:3.prhome-src:src-478/vcam_raw stop
vipcs

After the mission during descent I use following to make sure that drone is approaching and tracking landing pad and making corrections:
self.log.info(“entering Precise Home Descent State”)
self.gdnc_dsc_svc = self.mc.attach_client_service_pair(
self.mc.gdnc_channel, gdnc_descent_msgs, forward_events=True)
self.log.info("LANDING PAD FOUND " + str(self.precise_home_mng.is_target_found()))

self.set_guidance_mode(
“com.parrot.missions.default.descent_to_position”,
gdnc_descent_msgs.Config(
type=gdnc_descent_msgs.TYPE_DEFAULT_PRECISE,
target_type=gdnc_descent_msgs.TARGET_TYPE_ALTITUDE_ATO,
altitude=1.0,),)
self.mc.dctl.cmd.sender.set_estimation_mode(cbry_est.LANDING)

• My questions :
    ◦ What is the right way to accomplish precise landing?
    ◦ What am I missing?
    ◦ What do following available functions do exactly. 
                    ▪ check_reset_sensor_timer(self, _)
                    ▪ check_set_ref_image_condition(self)
                    ▪ enable_precise_home(self, enable)
                    ▪ get_drone_geo_position(self)
                    ▪ get_drone_local_position(self)
                    ▪ get_precise_home_local_position(self)
                    ▪ is_move_already_interrupted(self)
                    ▪ is_target_found(self)
                    ▪ on_gps_ok(self)
                    ▪ on_pcmd_horiz(self)
                    ▪ on_set_mode(self, mode)
                    ▪ on_state(self, state)
                    ▪ reset_sensor(self)
                    ▪ set_heading_is_locked(self)
                    ▪ set_move_in_progress(self, ok)
                    ▪ set_ref_image_timer(self, _)
                    ▪ should_reset_sensor_score(self)
                    ▪ should_search_phome(self)
                    ▪ start_process(self)
                    ▪ stop_process(self)
                    ▪ check_reset_sensor_timer
                    ▪ set_ref_image_timer

Thanks in advance.

Hello @Vulture151,

For me, the simplest way to accomplish precise landing is in this code:

self.phome_manager = self.mission.get_manager(PreciseHomeManager, True)

#To enable descent precise home
self.landing_type = gdnc_descent_msgs.TYPE_DEFAULT

if (
    self.phome_manager is not None
    and not self.phome_manager.is_move_already_interrupted()
):
   # Start precise home manager and find target
    self.phome_manager.start_process()
    if self.phome_manager.is_target_found():
        self.landing_type = gdnc_descent_msgs.TYPE_DEFAULT_PRECISE
        self.phome_manager.set_move_in_progress(True)

# Descent precise home if its manager is valid and a target is successfully found.
# If not, descent normal to ground
self.set_guidance_mode(
    UID + ".descent_to_ground",
    gdnc_descent_msgs.Config(
        type=self.landing_type,
        target_type=gdnc_descent_msgs.TARGET_TYPE_GROUND,
    ),
)

# You should call self.phome_manager.stop_process() in exit() of your state 
# in order to make precise home manager ready for the next takeoff

You don’t need to re-affect check_reset_sensor_timer, get_precise_home_local_position, set_ref_image, etc. because they are all set as default in constructor.

About available functions of precise home manager:

  1. check_reset_sensor_timer: check if precise home target was already found each 30 seconds. If yes, reset score. If no, do nothing
  2. check_set_ref_image_condition: check if the precise home target image was correctly taken each 30 seconds. If already took, do nothing. If not, verify if current drone altitude is bigger than 0.8m, if we meet this condition, take the photo of home and save its geo/local position
  3. enable_precise_home: enable/disable precise home
  4. get_drone_geo_position: get current drone’s geo position based on telemetry data
  5. get_drone_local_position: get current drone’s local position based on telemetry data
  6. is_move_already_interrupted: return a boolean which is true if the precise move was already interrupted. 2 possibilities to make this value to true: the drone is reaching precise home position; user is piloting during takeoff
  7. is_target_found: true if the drone’s sensor successfully found its precise home target
  8. on_xxx: a callback when event named xxx is triggered
  9. reset_sensor: reset to default value for all precise home manager’s attribute
  10. set_xxx: update value for precise home’s status/attribute xxx
  11. should_xxx: trigger xxx if the conditions are met
  12. start_process: compute precise home, get value of sensor to know if the target is found and update necessary attributes
  13. stop_process: stop computing precise home and reset precise home’s status in order to be ready for next precise home takeoff
  14. xxx_timer: timer triggers function 1,2 after 30 seconds

Best regards,
Trang

Thank you so much.

Hi Trangpham,
what should I understand from following logs?
01-01 01:03:25.586 N prhome_Strategy(pimp-hovering-a-188/prhome-queue:sr-496): EVT:VISION;feature=‘precise_home’;status=‘searching’
01-01 01:03:26.051 I rtsp_server (stream-server-187) : received RTSP request GET_PARAMETER: cseq=78 session=cd2577c7321137e1
01-01 01:03:26.051 I rtsp_server (stream-server-187) : send RTSP response to GET_PARAMETER: status=200(OK) cseq=78 session=cd2577c7321137e1
01-01 01:03:28.000 E vstrm (stream-server-187) : invalid DLSR vs. time diff for RTD
01-01 01:03:28.067 E vstrm (stream-server-187) : RTD is now valid (1 invalid RTD(s))
01-01 01:03:28.633 I rtsp_server (stream-server-187) : received RTSP request GET_PARAMETER: cseq=79 session=cd2577c7321137e1
01-01 01:03:28.633 I rtsp_server (stream-server-187) : send RTSP response to GET_PARAMETER: status=200(OK) cseq=79 session=cd2577c7321137e1
01-01 01:03:28.719 N toad_tm_robust_est(pimp-hovering-a-188/prhome-queue:sr-496): EVT:VISION;feature=‘precise_home’;status=‘estim_initialized’
01-01 01:03:28.719 W toad_tm_est (pimp-hovering-a-188/prhome-queue:sr-496): Patch cannot be bigger than train image, estimate aborted
01-01 01:03:28.736 W toad_tm_est (pimp-hovering-a-188/prhome-queue:sr-496): Patch cannot be bigger than train image, estimate aborted
01-01 01:03:28.736 W toad_tm_est (pimp-hovering-a-188/prhome-queue:sr-496): Patch cannot be bigger than train image, estimate aborted
01-01 01:03:28.752 W toad_tm_est (pimp-hovering-a-188/prhome-queue:sr-496): Patch cannot be bigger than train image, estimate aborted
01-01 01:03:28.752 W toad_tm_est (pimp-hovering-a-188/prhome-queue:sr-496): Patch cannot be bigger than train image, estimate aborted
01-01 01:03:28.769 W toad_tm_est (pimp-hovering-a-188/prhome-queue:sr-496): Patch cannot be bigger than train image, estimate aborted
01-01 01:03:28.769 W toad_tm_est (pimp-hovering-a-188/prhome-queue:sr-496): Patch cannot be bigger than train image, estimate aborted
01-01 01:03:28.786 I toad_tm_robust_est(pimp-hovering-a-188/prhome-queue:sr-496): offset found after local search: 0
01-01 01:03:28.786 N toad_tm_robust_est(pimp-hovering-a-188/prhome-queue:sr-496): EVT:VISION;feature=‘precise_home’;status=‘estim_local_search_KO’
01-01 01:03:28.786 W toad_tm_est (pimp-hovering-a-188/prhome-queue:sr-496): Patch cannot be bigger than train image, estimate aborted
01-01 01:03:28.786 W toad_tm_est (pimp-hovering-a-188/prhome-queue:sr-496): Patch cannot be bigger than train image, estimate aborted
01-01 01:03:28.802 W toad_tm_est (pimp-hovering-a-188/prhome-queue:sr-496): Patch cannot be bigger than train image, estimate aborted
01-01 01:03:28.802 W toad_tm_est (pimp-hovering-a-188/prhome-queue:sr-496): Patch cannot be bigger than train image, estimate aborted
01-01 01:03:28.819 W toad_tm_est (pimp-hovering-a-188/prhome-queue:sr-496): Patch cannot be bigger than train image, estimate aborted
01-01 01:03:28.836 W toad_tm_est (pimp-hovering-a-188/prhome-queue:sr-496): Patch cannot be bigger than train image, estimate aborted
01-01 01:03:28.852 W toad_tm_est (pimp-hovering-a-188/prhome-queue:sr-496): Patch cannot be bigger than train image, estimate aborted
01-01 01:03:28.869 W toad_tm_est (pimp-hovering-a-188/prhome-queue:sr-496): Patch cannot be bigger than train image, estimate aborted
01-01 01:03:28.886 I toad_tm_robust_est(pimp-hovering-a-188/prhome-queue:sr-496): offset found after global search: 0
01-01 01:03:28.886 W toad_tm_est (pimp-hovering-a-188/prhome-queue:sr-496): Patch cannot be bigger than train image, estimate aborted
01-01 01:03:28.902 W toad_tm_est (pimp-hovering-a-188/prhome-queue:sr-496): Patch cannot be bigger than train image, estimate aborted
01-01 01:03:28.919 W toad_tm_est (pimp-hovering-a-188/prhome-queue:sr-496): Patch cannot be bigger than train image, estimate aborted
01-01 01:03:28.936 W toad_tm_est (pimp-hovering-a-188/prhome-queue:sr-496): Patch cannot be bigger than train image, estimate aborted
01-01 01:03:28.952 N toad_tm_robust_est(pimp-hovering-a-188/prhome-queue:sr-496): EVT:VISION;feature=‘precise_home’;status=‘estim_best_effort_failed’
01-01 01:03:28.952 I toad_tm_robust_est(pimp-hovering-a-188/prhome-queue:sr-496): final offset: 0
01-01 01:03:28.952 W toad_tm_est (pimp-hovering-a-188/prhome-queue:sr-496): Patch cannot be bigger than train image, estimate aborted
01-01 01:03:28.969 W toad_tm_est (pimp-hovering-a-188/prhome-queue:sr-496): Patch cannot be bigger than train image, estimate aborted

These logs are from sphinx. I have a landing pad picture on the terrain for testing precise landing. What does “Patch cannot be bigger than train image, estimate aborted”

Hi @Vulture151,

I think the problem is your landing pad picture does not known by our image treatment system or its scale does not fit. So drone cannot estimate precise home position. It is better to try with a real landing pad to see if this problem is always like that or not.

Best regards,

Thank you so much,
Best regards.

hi @trangpham,
I am able to import oa_manager with the following:

from fsup.features.oa_manager import ObstacleAvoidanceManager
** def init(self, args, kwargs):
** super().init(args, kwargs)
** self.oa_manager = self.supervisor.obstacle_avoidance_manager

But I was not able to activate it. I looked into the functions and attributes of oa_manager in the documentation somehow couldnt make it. Whats is the easiest way to do obstacle avaoidance?

Hello @Vulture151,

For supervisor’s manager, it is activated automatically when the supervisor is successfully created. To retrieve the latest alert of ObstacleAvoidanceManager, you can do:

# A default function for each fsup state
def step(self, msg):
    if is_msg(msg, self.mc.autopilot.evt.msg_class, "obstacle_avoidance_alerts"):
        # Get obstacle avoidance alerts : alert from guidance and from sensor (0 or 1)
        print(msg.alerts)
        # Do your stuff here
    if is_msg(msg, self.mc.autopilot.evt.msg_class, "obstacle_avoidance_status"):
        # Get obstacle avoidance status: availability, mode, state, owner
        print(msg.mode)
        print(msg.state)
        print(msg.availability)
        print(msg.owner)
        # Do your stuff here

Hope this helps.
Best regards,
Trang

1 Like

This topic was automatically closed after 30 days. New replies are no longer allowed.