ArduCopter 4.4.1 ignoring set_position_target_local_ned mavlink messages

I’m running a Python 3.10 system on a Jetson Orin Nano, using dronekit installed from this GH repo and Ardupilot 4.4.1 on a Pixhawk 6C. The drone itself has good GPS lock, optical flow, and rangefinder for altitude information. The following code constructs a mavlink message for set_position_target_local_ned using dronekit, which I then send simply using self.vehicle.send_mavlink(self.setpoint_msg) once per second. But for some reason, the UAV ignores all the setpoint messages, regardless of what kind of bit mask I use.

I can take off and land autonomously, but for all messages that I send, the drone just hovers in place doing nothing.

Any help will be very appreciated! Thanks in advance.

def update_velocity_setpoint(self, frdy: np.ndarray) -> None:
        """Sets a new velocity setpoint.

        Args:
            frdy (np.ndarray): frdy
        """
        setpoint = self.enu2ned(frdy)

        # check the flight ceiling, downward is positive
        vehicle_height = self.vehicle.location.global_relative_frame.alt
        if vehicle_height > self.flight_ceiling:
            setpoint[2] = min(vehicle_height - self.flight_ceiling, 1.0)
        elif vehicle_height < self.flight_floor:
            setpoint[2] = max(vehicle_height - self.flight_floor, -1.0)

        self.setpoint_msg = self.vehicle.message_factory.set_position_target_local_ned_encode(
            # time_boot_ms (not used)
            0,
            # target system, target component
            0,
            0,
            # frame
            mavutil.mavlink.MAV_FRAME_BODY_OFFSET_NED,
            # type_mask, addressed in reversed, and used to indicate which components should be IGNORED
            # bit1:PosX, bit2:PosY, bit3:PosZ, bit4:VelX, bit5:VelY, bit6:VelZ, bit7:AccX, bit8:AccY, bit9:AccZ, bit11:yaw, bit12:yaw rate
            0b010111000111,
            # x, y, z positions (not used)
            0,
            0,
            0,
            # x, y, z velocity in m/s
            setpoint[0],
            setpoint[1],
            setpoint[2],
            # x, y, z acceleration (not used)
            0,
            0,
            0,
            # yaw, yaw_rate (only yaw rate used)
            0,
            setpoint[3],
        )

Are you using guided flight mode?

Hi! Thanks for the quick response, yes I am. There is good GPS, it’s in guided mode (no errors about position fix thrown), and can successfully take off and land. Just not responding to the mavlink message.

It might be that the bitmask you are sending is not implemented in ardupilot. Take a look at ardupilot’s code to see if it is.

If it’s not too difficult, could you point me to the relevant section where I can figure this out? Otherwise I will do the code dive manually.

Also, I would mention that I’ve tried the default bitmasks from ardupilot’s documentation, but no matter what I set the bitmask to, it won’t respond to it.

For context, I’m testing things out by immediately going into guided mode after arming, and sending a vertical z velocity of -3 to attempt a takeoff using velocity commands. The drone doesn’t respond to this at all, keeping motors at minimum throttle and then automatically disarming after awhile, probably due to land detection.

A minimal script for replicating this on my setup is below, just in case I’m doing anything obviously wrong:

import time
import dronekit
from pymavlink import mavutil


vehicle = dronekit.connect("/dev/ttyACM0", wait_ready=True)
vehicle.airspeed=3
print("arming")
vehicle.armed = True
print("guiding")
vehicle.mode = dronekit.VehicleMode("GUIDED")
msg = vehicle.message_factory.set_position_target_local_ned_encode(
    0,       # time_boot_ms (not used)
    0, 0,    # target system, target component
    mavutil.mavlink.MAV_FRAME_LOCAL_NED, # frame
    0b111111000111, # type_mask (only speeds enabled)
    0, 0, -5, # x, y, z positions (not used)
    0, 0, -5, # x, y, z velocity in m/s
    0, 0, -5, # x, y, z acceleration (not supported yet, ignored in GCS_Mavlink)
    0, 0)    # yaw, yaw_rate (not supported yet, ignored in GCS_Mavlink)


# send command to vehicle on 1 Hz cycle
while True:
    print("commanding")
    vehicle.send_mavlink(msg)
    time.sleep(1)

Hello @jjshoots,
I’ve tried your test script with SITL and it works well, I’ve just changed the connect string to the SITL UDP address.
I’m using python 3.9.2, dronekit 2.9.2 and AP 4.4.0 stable.
I remember that I’ve had issues running dronekit on Python 3.10, and for issues I mean that I wasn’t even able to run the connect() function. I don’t know if it’s related but there is still an open issue about it.

Thanks for getting back to me. I will try it again on Monday with your setup to see if it works.