Landing - descend to height 2m then disarm

Most of the times when I send MAVLink message to change mode to land to MAVProxy, it changes the mode to LAND but the copter descends until height of 2 meters then disarm. However, when the drone takeoff again directly after landing, it starts from height 0 not 2 meters. In some cases, when the copter lands completely, it lands to height of -1 meters!

What is the cause of this problem and how can I land accurately to height 0?

Are you saying it disarms 2m above ground (then falls) or that the indicated altitude is 2m when landed. ?
Altitude is not the thing that determines when a landing is complete.
In any case, logs would help

The altitude uses barometric pressure. It can vary when close to the ground. The propeller down wash gets into the copter body and messes with the pressure reading. Also, as atmospheric pressure changes in your area (weather), the barometric pressure at ground level changes. So if you land and it says something other than zero, like 2 or -3 or whatever, that is nothing to be concerned with. It is perfectly normal behavior of a barometric altimeter in these small vehicles.

The altitude will always change to zero when you arm for takeoff because it resets the altitude to zero on the ground when you arm. Also perfectly normal.

If you’re trying to say the copter is disarming while 2 meters up in the air and causing a crash, that is entirely different and not correct behavior. That should be essentially impossible. Please elaborate.

Thanks for your replies.
First of all, I’m just simulating the mission on MAVProxy, so no real-flight.
The copter doesn’t crash. It lands normally. I think the problem is in the indicated altitude (which is the same altitude that I get from GLOBAL_POSITION_INT message. I use the current altitude to check if the landing process is complete or not. What other way to check if it’s complete? Maybe being disarmed?
When the indicated altitude is in minus (e.g., -1), I can’t arm the copter again and I have to re-run (mavproxy).

Oh, this is in simulation. I’m unfamiliar with that.

None the less, barometric altitude is not even part of the landing detection code because of how susceptible it is variance. Landing detection uses accelerators and throttle. When it detects no vertical movement with the throttles at minimum for a given amount of time, it assumes it has landed.

Thanks for your quick reply.
OK, now I understand. I would be grateful if someone explained how can I check if landing is done or not in coding (MAVLink).

I would assume the simulator doesn’t simulate pressure variance/errors in the altimeter, though I did get slightly lower than 0 when I landed, probably due to it not hitting its mark perfectly. I did this and it worked out in my testing:

assert(vehicle.location.global_relative_frame.alt == pytest.approx(0.0, rel=0.1, abs=0.1))