MAVLINK Manual Commands

I am working on setting up code that will allow direct control over certain aspects of the APM during flight. Currently I am testing a simple sequence of commands through MAVLINK, starting with launch and land. The commands are as follows:

Launch Command

[code]master.mav.mission_count_send(master.target_system, master.target_component, 2)

# Dummy Waypoint
master.mav.mission_item_send(master.target_system, master.target_component, 
                             0, 0, mavutil.mavlink.MAV_CMD_NAV_TAKEOFF,
                             0, 0, 0,
                             0, 0, 0, 
                             0, 0, 0)

# Launch Waypoint
master.mav.mission_item_send(master.target_system, master.target_component, 
                             1,     # Waypoint Number
                             0, mavutil.mavlink.MAV_CMD_NAV_TAKEOFF,
                             1,     # Is Current Waypoint
                             0,     # Should Autocontinue to next wp
                             0,     # NAV Command: Radius for accept within range (meters)
                             0,     # NAV Command: Hold Time (ms)
                             0,     # LOITER Command: Orbit to circle (meters).  Positive clockwise, Negative counter-clockwise
                             0,     # NAV/LOITER Command: Yaw Orientation [o to 360 degrees]
                             0,     # local: x position, global: latitude
                             0,     # local: y position, global: longitude
                             20)    # local: z position, global: altitude   (meters)

# Set Launch Waypoint as Current Waypoint
set_current_waypoint()
receive_waypoint(1)

# Trigger auto mode for launch command
master.mav.set_mode_send(master.target_system, mavutil.mavlink.MAV_MODE_FLAG_CUSTOM_MODE_ENABLED, AUTO)
rospy.sleep(0.1)
master.mav.set_mode_send(master.target_system, mavutil.mavlink.MAV_MODE_FLAG_CUSTOM_MODE_ENABLED, AUTO)[/code]

Land Command

# Land Command master.mav.command_long_send(master.target_system, master.target_component, mavutil.mavlink.MAV_CMD_NAV_LAND, 0, 0, 0, 0, 0, 0, 0, 0)

During a test, I send the launch command. The vehicle ascended, however, it went to a height higher than I sent and once the launch was complete started to randomly wonder (I had a GPS Fix). I attempted to take control with the RC, however, I had no control trying all possible combinations. I then send the land command so the vehicle would at least land safely. As soon as the command was sent, all motors shut off and the vehicle fell to the ground (breaking the vehicle).

Are the methods I am using to send the Launch and Land command acceptable? Are there any ideas as to why this may have happened. Until this moment, all flight aspects were running great.

You set the take off to have zero height. It probably then headed to the next waypoint. if there was one? or there is a defect and the copter flew to a random height.

To instantly trigger a Land in Arducopter I use the do_set_mode_send method, not calling command.long

That said, I think you may have had a issue that the copter thought it was a zero above ground, so the land command triggered it to think it was on the ground, shutting the motors off. Would be useful to raise this as a defect to get checked out. github.com/diydrones/ardupilot/issues

[code] _message->custom_mode = customMode; // it’s 9 for LAND
_message->base_mode = baseMode; // Ardupilot use custome mode only, but base mode MAV_MODE_FLAG_CUSTOM_MODE_ENABLED needs to be set

mavlink_msg_set_mode_send(0, // Channel
                         _message->target_system, // Target System
                         _message->base_mode, // Target Component
                         _message->custom_mode);

[/code]

// Auto Pilot modes
// ----------------
#define STABILIZE 0                     // hold level position
#define ACRO 1                          // rate control
#define ALT_HOLD 2                      // AUTO control
#define AUTO 3                          // AUTO control
#define GUIDED 4                        // AUTO control
#define LOITER 5                        // Hold a single location
#define RTL 6                           // AUTO control
#define CIRCLE 7                        // AUTO control
#define POSITION 8                      // AUTO control
#define LAND 9                          // AUTO control
#define OF_LOITER 10                    // Hold a single location using optical flow
                                        // sensor
#define TOY_A 11                        // THOR Enum for Toy mode
#define TOY_M 12                        // THOR Enum for Toy mode
#define NUM_MODES 13

Thanks for the response billbonney. I was setting the takeoff height to 20m in the code I posted. As for the land command, I will try the set mode, however, looking in the Arducopter code, it seemed as if doing the command long was just a roundabout way of doing the same thing.

The issue I had with the land command is that since I am trying to do all of this without the remote, since the stick was down, the vehicle disarmed and then fell out of the sky. From reading around, this should not be the case in 2.9.1b, but it still is for me. I found a small workaround for the time being by sending an RC Override command on throttle with a very small value, but I do not like this option as it does not allow me to use the RC throttle. I am currently looking for a better option.

As for the launch and land commands, I am also looking at how to send a single waypoint command, in which I use the following:

[code] # Number of waypoints (Plus Dummy Waypoint)
master.mav.mission_count_send(master.target_system, master.target_component, 2)

# Dummy Waypoint
master.mav.mission_item_send(master.target_system, master.target_component, 
                             0,     # Waypoint Number
                             0, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT,
                             0,     # Is Current Waypoint
                             0,     # Should Autocontinue to next wp
                             0,     # NAV Command: Radius for accept within range (meters)
                             0,     # NAV Command: Hold Time (ms)
                             0,     # LOITER Command: Orbit to circle (meters).  Positive clockwise, Negative counter-clockwise
                             0,     # NAV/LOITER Command: Yaw Orientation [o to 360 degrees]
                             gps_msg.latitude,  # local: x position, global: latitude
                             gps_msg.longitude, # local: y position, global: longitude
                             0)          # local: z position, global: altitude
rospy.sleep(1)

# Waypoint to be sent
print ("Waypoint to be sent: Lat=%f, Lon=%f, Alt=%f, posAcc=%f, holdTime=%f, yawFrom=%f"
        %(data.latitude, data.longitude, data.altitude, data.posAcc, data.holdTime,
          data.yawFrom))

master.mav.mission_item_send(master.target_system, master.target_component, 
                             1,     # Waypoint Number
                             0, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT,
                             1,     # Is Current Waypoint
                             0,     # Should Autocontinue to next wp
                             data.posAcc,     # NAV Command: Radius for accept within range (meters)
                             data.holdTime,     # NAV Command: Hold Time (ms)
                             0,     # LOITER Command: Orbit to circle (meters).  Positive clockwise, Negative counter-clockwise
                             data.yawFrom,     # NAV/LOITER Command: Yaw Orientation [o to 360 degrees]
                             data.latitude,     # local: x position, global: latitude
                             data.longitude,     # local: y position, global: longitude
                             data.altitude)    # local: z position, global: altitude

rospy.sleep(1)

# Set current waypoint to be waypoint 1
master.mav.mission_set_current_send(master.target_system, master.target_component, 1)
master.mav.mission_request_send(master.target_system, master.target_component, 1)
print ("Sending waypoint")

[/code]
This code also seems to be okay until the waypoint is reached, at which point the vehicle again falls out of the sky. I assume this is the same issue as the land command, however, I did not get to test that tonight as it was too dark.

Overall, I am simply trying to figure out a way that I can safely, launch the vehicle, send individual waypoints at a time, then land the vehicle, all while only using the remote as a safety measure. I feel I am close, but seem to be running into a major hurdle here.

Confirmed that I must have the remote at least with throttle slightly up for waypoints to work as well. Currently my only two options are have the remote in the loop constantly with thrust slightly up, or fake the signal with RC Override (not safe). Is there a way to remove this “failsafe” on the RC so I can still use it as a safety measure and not require it for the entire test?

epsilonorion:
Did you ever manage to sort out the problems with the waypoints?

We are working on a hexacopter and we want to include collisionavoidace.
The plan is that if a sonar in the front is activated the hexa gets a dummy waypoint somwhat to the side and then flies there and avoids the obstacle and from there continues on to the previous waypoint.

We have manage to get the front sonar working so if the hexa is about to collide we know about it. It only remains to make it avoid it in an orderly fashoin.

//Team ArchCopter