Rangefinder altitude lost when switching from Loiter to Guided mode with Optical Flow

I’m using an indoor drone setup with:

  • Optical flow sensor for horizontal position

  • Downward-facing rangefinder for altitude hold

  • No GPS (GPS-denied environment)

  • SpeedyBee F4V5 flight controller

What works:

  • In Loiter mode, the drone maintains altitude perfectly using the rangefinder.

  • Log analysis shows CTUN.DSAlt (desired rangefinder altitude) properly tracks CTUN.SAlt, and the drone responds as expected.

The problem:
When I switch from Loiter to Guided mode (for velocity commands via MAVLink SET_POSITION_TARGET_LOCAL_NED), the rangefinder altitude is no longer used for the altitude target.

  • CTUN.DSAlt data stops appearing in logs

  • CTUN.DAlt remains constant at the barometer altitude at the moment of mode switch

  • The drone’s altitude becomes barometer-dependent, which drifts significantly indoors due to prop wash and temperature changes

I’ve verified:

  • EK3_SRC1_POSZ is set to 1 (Barometer)

  • EK3_RNG_USE_HGT is -1

  • SURFTRAK_MODE is enabled

  • Rangefinder works perfectly in Loiter mode

Question:
Is there a way to make Guided mode respect the rangefinder altitude target (like Loiter does via Surface Tracking), or is this an intentional design limitation? I need precise altitude hold while sending velocity commands in Guided mode.

I’m using ArduPilot Copter 4.8

What I’ve tried:

  • Verified rangefinder works in Loiter/AltHold

  • Confirmed CTUN.DSAlt logging stops immediately upon Guided mode entry

  • Checked that Surface Tracking is correctly configured

Why this matters:

Barometer drift indoors makes altitude unreliable. The rangefinder provides accurate ground distance, which is critical for my application.

Update: I’ve also attached a log snippet showing CTUN.DSAlt dropping to zero/stopping after mode change.

The log file: https://drive.google.com/file/d/1GkvsRbodb6JihvcDygZ8UYeC25fADHLL/view?usp=sharing

If your floor is flat you could use rangefinder as your altitude source.

Unfortunately MAVLink doesn’t have local terrain frame. You could try commanding in global terrain frame though I am not sure if that will work.

Thank you for the suggestion
I’m currently using SET_POSITION_TARGET_LOCAL_NED with velocity-only type mask (3527) for real-time control. The terrain frame option (MAV_FRAME_GLOBAL_TERRAIN_ALT) seems to be designed for position waypoints (SET_POSITION_TARGET_GLOBAL_INT), not velocity commands. I don’t have GPS in this setup. Since my future application will use a camera and image processing (which operates in a local, relative frame), position commands with global coordinates aren’t practical for my use case. I need to keep using velocity commands in a local frame.

Almost certainly this is not the cause of the problem but don’t use copter 4.8 as of now as it is in development and can have broken stuff or bugs somewhere. You should use copter 4.7.0 as of now

Thanks.
The reason I’m on a newer version is that my board wasn’t officially supported in earlier stable releases, but that’s no longer the case. I’ll take your advice and stick with the stable 4.7.0 release for now, since it supports my hardware properly.