Pixhawk flying/landed state

I have build a new drone (running 3.4.6) a couple of days ago and so far it flies pretty well. One aspect that I would just like to understand better is the way the disarming logic works after the copter has landed.

The way that I understand the take-off procedure is that once I arm my drone the motors will spin up to a speed related to the MOT_SPIN_ARM value. Then I increase the throttle and the copter takes to the sky afterwhich the copter will have a “flying” status and will then use MOT_SPIN_MIN as the lower limit for the motors to spin.

The part I don’t get is how the copter determines when it has landed to then disarm the motors. From my flight logs I can see that once I touched down and lowered my throttle to minimum the motors drop to a speed which works out to be MOT_SPIN_MIN for a few seconds then drops to MOT_SPIN_ARM speed for a few seconds and only then disarms and stops the motors after probably 5 to 10 seconds. This leaves me with some questions:

Is this normal? To me it looks like the copter does not immediately realise that it has landed and takes some time to change to “landed” status.

How does the copter know that it is now flying (maybe when throttle pass MOT_SPIN_MIN…) and later know that it has landed. Is there parameters one can use to fine tune this?

Is there a status flag one can look at in the log to see if the copter is in flying, landed or any other state?

From what I understand the parameter DISARM_DELAY, is the time window in which the throttle should remain zero for the motors to disarm (when on the ground). Is this both valid for arming before flight and after taking throttle to zero when landing?

If anyone has any input about any of these points it would be very interesting to hear and help me build a better understanding of this aspect.
Thanks!

DISARM_DELAY applies to both before takeoff and after landing. So if you were to set it for something foolish like 1 second, it would probably disarm before you even have a chance to push the throttle stick up.

What you are seeing is normal behavior. The oversimplified version of landing detection is this: If the throttle output is at minimum (MOT_SPIN_MIN) and the vertical speed is less than +/- 20cm/s for longer than X seconds (I forget the number), it assumes it has landed. At which point the throttle drops down to MOT_SPIN_ARMED and stays there until the DISARM_DELAY expires or you command a disarm with the stick down and left.

Someone correct me if I’m wrong but this is how I understand it.

Thanks for your input Matt, I think I will drop my DISARM_DELAY a bit then, maybe closer to 5 seconds.
So I also had a look at the code (https://github.com/ArduPilot/ardupilot/blob/master/ArduCopter/land_detector.cpp) and this is how I understand it now.

When it comes to landing there is basically two flags land_complete_maybe and land_complete. When a landing condition is detected the land_complete_maybe flag is set and once a sure landing condition is detected the land_complete flag is set. These can be seen in the log files under EV.id, a value of 17 = land_complete_maybe and a value of 18 = land_complete.

To have either of these flags set the following checks are done:

  • motor_at_lower_limit. Check if the throttle is close to the lower limit.
  • accel_stationary. Check that the airframe is not accelerating.
  • descent_rate_low. Check that vertical speed is within 1m/s of zero.
  • rangefinder_check. If installed, check if below 2 meters.

Then there is a land_detector_count value which is increased every time all of the above conditions are true and reset when not. When this counter goes over a certain limit (looks to be the equivalent of about 200ms) the land_complete_maybe flag is set and once it crosses a second threshold (1 second) it sets the land_complete flag.

So it would then seem, like you said, that the landing behavior I am seeing is pretty normal.