Why ArduPlane cannot successfully use MAV_CMD_NAV_WAYPOINT

When I use pymavlink to send the MAV_CMD_NAV_WAYPOINT command to ArduPlane in SITL, Plane cannot receive this command(Although this command is clearly stated in the documentation to be used by Plane).
The result returned: Got COMMAND_ACK: NAV_WAYPOINT: UNSUPPORTED
And I tried other navigation commands: MAV_CMD_NAV_LOITER_TIME, MAV_CMD_NAV_LOITER_TURNS but they were unable to control Plane. What step did I miss?

My code is as follows:

import time
import sys
from pymavlink import mavutil, mavwp

def change_mode(modename, the_connection):
    # Choose a mode and check whether the mode is available
    mode = modename
    if mode not in the_connection.mode_mapping():
        print('Unknown mode : {}'.format(mode))
        print('Try:', list(the_connection.mode_mapping().keys()))
        exit(1)
    # Get mode ID and set new mode
    mode_id = the_connection.mode_mapping()[mode]
    the_connection.mav.set_mode_send(
        the_connection.target_system,
        mavutil.mavlink.MAV_MODE_FLAG_CUSTOM_MODE_ENABLED,
        mode_id)

def planeflyto(go_lat, go_lon, ref_alt, master):
        master.mav.command_long_send(
        master.target_system,  # target_system
        master.target_component,  # target_component
        mavutil.mavlink.MAV_CMD_NAV_WAYPOINT,  
        0,
        0, 5, 0, 0, go_lat, go_lon, ref_alt
    )  
    msg = master.recv_match(type='COMMAND_ACK', blocking=True)
    print(msg)

def main():
    master = mavutil.mavlink_connection('udp:127.0.0.1:14550')
    master.wait_heartbeat()
    print("=============Takeoff started===============")
    change_mode('GUIDED', master)
    master.mav.command_long_send(master.target_system, master.target_component,
                                 mavutil.mavlink.MAV_CMD_COMPONENT_ARM_DISARM, 0, 1, 0, 0, 0, 0, 0, 0)
    msg = master.recv_match(type='COMMAND_ACK', blocking=True)
    print(msg)
    change_mode('TAKEOFF', master)
    time.sleep(15)
    change_mode('GUIDED', master)
    wp1 = [-353655751, 1491689962, 50]
    print("fly to WP1")
    planeflyto(wp1[0], wp1[1], wp1[2], master)

Hello @yichVon welcome to the community,

What ArduPlane firmware version are you using?
On newer version you should only use COMMAND_INT and never COMMAND_LONG

Thank you @amilcarlucas
I am using Plane 4.1. I just tried COMMAND_INT and the result is still ’NAV_WAYPOINT: UNSUPPORTED‘.
I replaced the long command in planeflyto() with the following code

master.mav.command_int_send(
        master.target_system,  # target_system
        master.target_component,  # target_component
        0, # frame
        mavutil.mavlink.MAV_CMD_NAV_WAYPOINT,
        0,0, # unused
        0, 5, 0, 0, go_lat, go_lon, ref_alt)

Update to ArduPlane 4.5.1 and COMMAND_INT and it will all work fine.

Thanks :smiley:
But I just upgraded ArduPlane to the latest version and tried it and found that I still can’t use the MAV_CMD_NAV_XXXs command.
After I send the command with COMMAND_INT, the result is still Got COMMAND_ACK: NAV_WAYPOINT: UNSUPPORTED

What flight controller are you using?

Hi @Oli1 I’m not quite sure what you’re referring to (I’ve only recently started getting into drones).
Specifically, I built ArduPilot locally and then executed a Plane SITL simulator using the following command:
~/ArduPilot$ ./Tools/autotest/sim_vehicle.py -v ArduPlane --console --map -w
Then I used mavlink’s python library to write scripts to interact with the Plane.

Should I create a MISSION first instead of executing NAV_WAYPOINT directly after takeoff?

Sorry I’m an idiot, didn’t see the SITL part. Can’t help with that I’m afraid…

Yes, I think you must create a MISSION first instead of executing NAV_WAYPOINT directly after takeoff.

Thanks :clap:, I’ll try this later

I found that it works to specify MAV_CMD_NAV_WAYPOINT in the mission and upload this mission to ArduPlane.
However, after loading the mission, using mav.command_int_send to send MAV_CMD_NAV_WAYPOINT to Plane(loitering) still fails. Instead, I found that using the MAV_CMD_DO_REPOSITION command can achieve this.

master.mav.command_int_send(
        master.target_system,  # target_system
        master.target_component,  # target_component
        6,  # coordinate frame
        mavutil.mavlink.MAV_CMD_DO_REPOSITION,
        0, 0,  # unused
        0, 5, 0, 0, lat, lon, alt)

But this still cannot achieve my purpose: I want to control the flying Plane to fly to the specified point through separate MAV_CMD_NAV_WAYPOINT and MAV_CMD_NAV_LOITER_TURNS commands.

Is there any way to send a MAV_CMD_NAV_LOITER_TURNS command to the ArduPlane loitering in RTL mode? Sending MAV_CMD_NAV_LOITER_TURNS using the command_long defined in the mavlink documentation causes ArduPlane to return the following error:
Got COMMAND_ACK: NAV_LOITER_TURNS: UNSUPPORTED

Oh guys, by chance I realized I had overlooked a sentence in the document:
To command a plane to move to a particular lat, lon, alt send a MAV_CMD_NAV_WAYPOINT (16) within a MISSION_ITEM_INT
This means that MAV_CMD_NAV_WAYPOINT must be sent using mav.mission_item_int_send

I think this problem should be solved

1 Like