This report covers MAVLink command-handling cases where PX4 accepts or completes a command path even though the downstream execution result is missing or rejected.
Tested environment:
PX4 SITL: sihsim_quadx
PX4 version: v1.14.0-6-g33aca30c93-dirty
PX4 git hash: 33aca30c93863efb0a73991c391756876663bb72
A. Payload mission command completion without execution confirmation
A1. MAV_CMD_DO_GRIPPER: mission advances after timeout when no payload executor/ack is present
Reproduction:
- Start PX4 SITL with the default
sihsim_quadxconfiguration. - Upload a mission containing:
seq 0: MAV_CMD_NAV_TAKEOFF
seq 1: MAV_CMD_DO_GRIPPER
seq 2: MAV_CMD_DO_WINCH
seq 3: MAV_CMD_NAV_WAYPOINT
- Start the mission and observe mission progress.
- Check
payload_deliverer statusin the PX4 shell.
Observed mission upload result:
MISSION_ACK: MAV_MISSION_ACCEPTED
Observed mission download:
seq 1: command=211 (MAV_CMD_DO_GRIPPER)
seq 2: command=42600 (MAV_CMD_DO_WINCH)
During execution, PX4 advanced through the payload items:
MISSION_CURRENT seq=1
MISSION_ITEM_REACHED seq=1
MISSION_CURRENT seq=2
MISSION_ITEM_REACHED seq=2
MISSION_CURRENT seq=3
PX4 shell output after the mission:
INFO [navigator] Mission finished, loitering
INFO [payload_deliverer] not running
In this configuration, no payload executor was running, but the mission still advanced past the MAV_CMD_DO_GRIPPER item after the payload timeout.
Expected behavior: if PX4 cannot execute a payload mission item or cannot obtain a successful execution acknowledgement, the mission should expose a failure state or keep the failure visible to the mission/GCS layer.
Actual behavior: the mission item is accepted and later treated as complete after a timeout, even though no payload execution acknowledgement was observed.
Relevant source in the tested PX4 version:
// mission_block.cpp
if (item.nav_cmd == NAV_CMD_DO_WINCH ||
item.nav_cmd == NAV_CMD_DO_GRIPPER) {
vehicle_command_s vcmd = {};
vcmd.command = item.nav_cmd;
...
_navigator->publish_vehicle_cmd(&vcmd);
_payload_deploy_ack_successful = false;
_payload_deployed_time = hrt_absolute_time();
}
Completion for DO_GRIPPER accepts either a successful payload ack or timeout:
// mission_block.cpp
case NAV_CMD_DO_GRIPPER: {
const float payload_deploy_elasped_time_s = (now - _payload_deployed_time) * 1E-6f;
if (_payload_deploy_ack_successful) {
return true;
} else if (payload_deploy_elasped_time_s > _payload_deploy_timeout_s) {
return true;
}
return false;
}
The class comment for the mission payload state also describes timeout-driven continuation:
// mission_block.h
// If the payload deployment takes longer than timeout, mission will
// continue into the next item automatically.
Impact:
- A mission can continue after a payload step even when the payload action did not execute.
- For gripper-based delivery or pickup missions, the vehicle can proceed to later waypoints or return-to-launch while the payload state is different from the mission plan.
- From the mission/GCS view, the mission step has completed; the missing executor or missing successful ack is not exposed as a mission failure.
A2. MAV_CMD_DO_WINCH: accepted mission item has no implemented winch executor and still completes by timeout
The same mission run also reproduced the winch path.
Observed mission upload and download:
MISSION_ACK: MAV_MISSION_ACCEPTED
seq 2: command=42600 (MAV_CMD_DO_WINCH)
Observed mission execution:
MISSION_CURRENT seq=2
MISSION_ITEM_REACHED seq=2
MISSION_CURRENT seq=3
INFO [navigator] Mission finished, loitering
The DO_WINCH mission item was accepted, stored, dispatched as a vehicle command, and later treated as complete. However, the payload deliverer implementation in this version only processes VEHICLE_CMD_DO_GRIPPER.
Relevant source:
// payload_deliverer.cpp
// Process DO_GRIPPER vehicle command
if (vehicle_command->command == vehicle_command_s::VEHICLE_CMD_DO_GRIPPER) {
...
}
The module documentation advertises winch support:
// payload_deliverer.h
// Activates a winch / gripper when the DO_WINCH or DO_GRIPPER vehicle command is received,
// after which the vehicle_command_ack command gets sent upon successful confirmation
The CLI description also mentions winch support:
// payload_deliverer.cpp
Handles payload delivery with either Gripper or a Winch with an appropriate timeout / feedback sensor setting
But no DO_WINCH command branch exists in payload_deliverer.cpp.
Mission completion for DO_WINCH also falls back to timeout:
// mission_block.cpp
case NAV_CMD_DO_WINCH: {
const float payload_deploy_elasped_time_s = (now - _payload_deployed_time) * 1E-6f;
if (_payload_deploy_ack_successful) {
return true;
} else if (payload_deploy_elasped_time_s > _payload_deploy_timeout_s) {
return true;
}
return false;
}
Expected behavior: PX4 should reject unsupported winch mission items, or provide an implemented executor and report execution failure when the winch action cannot be confirmed.
Actual behavior: PX4 accepts the winch mission item and advances after timeout even though the advertised winch executor path is not implemented in payload_deliverer.
Impact:
- A cargo/delivery mission can appear to complete a winch step while no winch action occurred.
- Later mission phases can run under the assumption that payload deployment succeeded.
- The documentation/implementation mismatch can cause operators to configure missions around a capability that is accepted by the mission layer but not actually executed.
B. Command ACK/mode result decoupled from Navigator rejection
B1. MAV_CMD_DO_REPOSITION: geofence-rejected destination returns MAV_RESULT_ACCEPTED and switches to Hold/Loiter
Reproduction:
- Configure geofence action and source:
GF_ACTION=2
GF_SOURCE=0
- Upload a four-vertex inclusion fence around the current vehicle position.
- Arm and run a short mission to get airborne.
- Send
MAV_CMD_DO_REPOSITIONwithparam2=1and a target location outside the inclusion fence.
Observed command result:
COMMAND_ACK command=192 result=0 MAV_RESULT_ACCEPTED
PX4 shell output:
WARN [navigator] Reposition is outside geofence
The vehicle mode changed to Hold/Loiter after the command while the requested reposition target was rejected by Navigator.
Relevant source behavior:
In Commander.cpp, VEHICLE_CMD_DO_REPOSITION validates the mode-switch flag in param2, requests NAVIGATION_STATE_AUTO_LOITER, and sets the command result to VEHICLE_CMD_RESULT_ACCEPTED when that mode request succeeds. Commander does not validate the target coordinates against the active geofence before returning the ACK.
Navigator later checks the target position against the geofence:
// navigator_main.cpp
if (have_geofence_position_data) {
reposition_valid = geofence_allows_position(position_setpoint);
}
if (reposition_valid) {
...
} else {
mavlink_log_critical(&_mavlink_log_pub, "Reposition is outside geofence\t");
}
// CMD_DO_REPOSITION is acknowledged by commander
Expected behavior: if the requested reposition setpoint is rejected by Navigator, the MAVLink result should not indicate full command acceptance without exposing the downstream rejection.
Actual behavior: the command returns MAV_RESULT_ACCEPTED and changes the vehicle mode, but Navigator rejects the requested destination due to geofence.
Impact:
- The geofence itself is enforced, but the command result is misleading.
- A ground station or companion computer can believe the reposition command succeeded while PX4 only changed mode and discarded the requested destination.
- The vehicle can be taken out of its previous navigation state into Hold/Loiter even though the requested reposition cannot be executed.
Suggested fixes
- For payload mission items, do not treat timeout as successful completion when no successful payload execution acknowledgement was received.
- Reject unsupported payload mission commands during mission upload, or require an available executor before accepting them.
- Either implement the advertised
DO_WINCHexecutor path or remove/reject winch support consistently across mission upload, documentation, and payload deliverer status. - For
MAV_CMD_DO_REPOSITION, include Navigator’s geofence/setpoint validation result in the command outcome, or send a later negative result when the accepted command cannot be applied. - Avoid changing the vehicle mode for a reposition request when the requested setpoint is known to be invalid or geofence-rejected.