Depth Hold Mode Does Not Hold at 1 Meter How to Set Target Depth Autonomously?

Yes, as you said, I am working with pymavlink in depth hold mode by sending the target depth using the SET_POSITION_TARGET_GLOBAL_INT message and controlling yaw with the SET_ATTITUDE_TARGET message. I am also focusing on and trying to implement these parts.

Below is an example code I took from the MAVLink documentation on the ArduSub site:

import time
import math
from pymavlink import mavutil
from pymavlink.quaternion import QuaternionBase

def set_target_depth(depth):
    master.mav.set_position_target_global_int_send(
        int(1e3 * (time.time() - boot_time)),
        master.target_system, master.target_component,
        coordinate_frame=mavutil.mavlink.MAV_FRAME_GLOBAL_INT,
        type_mask=(
            mavutil.mavlink.POSITION_TARGET_TYPEMASK_X_IGNORE |
            mavutil.mavlink.POSITION_TARGET_TYPEMASK_Y_IGNORE |
            # DON'T ignore Z
            mavutil.mavlink.POSITION_TARGET_TYPEMASK_VX_IGNORE |
            mavutil.mavlink.POSITION_TARGET_TYPEMASK_VY_IGNORE |
            mavutil.mavlink.POSITION_TARGET_TYPEMASK_VZ_IGNORE |
            mavutil.mavlink.POSITION_TARGET_TYPEMASK_AX_IGNORE |
            mavutil.mavlink.POSITION_TARGET_TYPEMASK_AY_IGNORE |
            mavutil.mavlink.POSITION_TARGET_TYPEMASK_AZ_IGNORE |
            mavutil.mavlink.POSITION_TARGET_TYPEMASK_YAW_IGNORE |
            mavutil.mavlink.POSITION_TARGET_TYPEMASK_YAW_RATE_IGNORE
        ),
        lat_int=0, lon_int=0, alt=depth,
        vx=0, vy=0, vz=0,
        afx=0, afy=0, afz=0, yaw=0, yaw_rate=0
    )

def set_target_attitude(roll, pitch, yaw):
    master.mav.set_attitude_target_send(
        int(1e3 * (time.time() - boot_time)),
        master.target_system, master.target_component,
        mavutil.mavlink.ATTITUDE_TARGET_TYPEMASK_THROTTLE_IGNORE,
        QuaternionBase([math.radians(angle) for angle in (roll, pitch, yaw)]),
        0, 0, 0, 0
    )

master = mavutil.mavlink_connection('udpin:0.0.0.0:14550')
boot_time = time.time()
master.wait_heartbeat()

master.arducopter_arm()
master.motors_armed_wait()

DEPTH_HOLD = 'ALT_HOLD'
DEPTH_HOLD_MODE = master.mode_mapping()[DEPTH_HOLD]
while not master.wait_heartbeat().custom_mode == DEPTH_HOLD_MODE:
    master.set_mode(DEPTH_HOLD)

set_target_depth(-0.5)

roll_angle = pitch_angle = 0
for yaw_angle in range(0, 500, 10):
    set_target_attitude(roll_angle, pitch_angle, yaw_angle)
    time.sleep(1)

for yaw_angle in range(500, 0, -30):
    set_target_attitude(roll_angle, pitch_angle, yaw_angle)
    time.sleep(1)

master.arducopter_disarm()
master.motors_disarmed_wait()

My question is: Is it enough to just give the target depth as a negative value in meters here? Do I need any extra setting or conversion, or can I simply keep the target depth stable by sending this value?

Also, I don’t fully understand how to use the Depth Hold mode effectively and stably, especially for maintaining a constant depth like 1 meter. Where do I set the PID or gain parameters? Are these configured inside the Pixhawk or should I handle them in my code? If you have any experience or advice, I would really appreciate it.

Thanks again for your help!