Move mavlink commands handlers to a separated function

It's more convenient to handle error that way.
This commit is contained in:
Oleg Kalachev
2026-08-29 17:50:29 +03:00
parent 9465c94d66
commit 5d670dcc69
5 changed files with 38 additions and 28 deletions
+17 -13
View File
@@ -245,38 +245,42 @@ void handleMavlink(const void *_msg) {
} }
} }
// Handle commands
if (msg.msgid == MAVLINK_MSG_ID_COMMAND_LONG) { if (msg.msgid == MAVLINK_MSG_ID_COMMAND_LONG) {
mavlink_command_long_t m; mavlink_command_long_t m;
mavlink_msg_command_long_decode(&msg, &m); mavlink_msg_command_long_decode(&msg, &m);
if (m.target_system && m.target_system != mavlinkSysId) return; if (m.target_system && m.target_system != mavlinkSysId) return;
mavlink_message_t response;
bool accepted = false; int result = handleMavlinkCommand(&m);
mavlink_message_t ack;
mavlink_msg_command_ack_pack(mavlinkSysId, MAV_COMP_ID_AUTOPILOT1, &ack, m.command, result, UINT8_MAX, 0, msg.sysid, msg.compid);
sendMessage(&ack);
}
}
int handleMavlinkCommand(const void *_m) {
const mavlink_command_long_t& m = *(mavlink_command_long_t *)_m;
if (m.command == MAV_CMD_REQUEST_MESSAGE && m.param1 == MAVLINK_MSG_ID_AUTOPILOT_VERSION) { if (m.command == MAV_CMD_REQUEST_MESSAGE && m.param1 == MAVLINK_MSG_ID_AUTOPILOT_VERSION) {
accepted = true; mavlink_message_t response;
mavlink_msg_autopilot_version_pack(mavlinkSysId, MAV_COMP_ID_AUTOPILOT1, &response, mavlink_msg_autopilot_version_pack(mavlinkSysId, MAV_COMP_ID_AUTOPILOT1, &response,
MAV_PROTOCOL_CAPABILITY_PARAM_FLOAT | MAV_PROTOCOL_CAPABILITY_MAVLINK2, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0); MAV_PROTOCOL_CAPABILITY_PARAM_FLOAT | MAV_PROTOCOL_CAPABILITY_MAVLINK2, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0);
sendMessage(&response); sendMessage(&response);
return MAV_RESULT_ACCEPTED;
} }
if (m.command == MAV_CMD_COMPONENT_ARM_DISARM) { if (m.command == MAV_CMD_COMPONENT_ARM_DISARM) {
if (m.param1 == 1 && controlThrottle > 0.05) return; // don't arm if throttle is not low if (m.param1 == 1 && controlThrottle > 0.05) return MAV_RESULT_DENIED; // don't arm if throttle is not low
accepted = true;
armed = m.param1 == 1; armed = m.param1 == 1;
return MAV_RESULT_ACCEPTED;
} }
if (m.command == MAV_CMD_DO_SET_MODE) { if (m.command == MAV_CMD_DO_SET_MODE) {
if (m.param2 < 0 || m.param2 > AUTO) return; // incorrect mode if (m.param2 < 0 || m.param2 > AUTO) return MAV_RESULT_DENIED; // incorrect mode
accepted = true;
mode = m.param2; mode = m.param2;
return MAV_RESULT_ACCEPTED;
} }
// send command ack return MAV_RESULT_UNSUPPORTED;
mavlink_message_t ack;
mavlink_msg_command_ack_pack(mavlinkSysId, MAV_COMP_ID_AUTOPILOT1, &ack, m.command, accepted ? MAV_RESULT_ACCEPTED : MAV_RESULT_UNSUPPORTED, UINT8_MAX, 0, msg.sysid, msg.compid);
sendMessage(&ack);
}
} }
// Send shell output to GCS // Send shell output to GCS
+1
View File
@@ -58,6 +58,7 @@ void sendMavlink();
void sendMessage(const void *msg); void sendMessage(const void *msg);
void receiveMavlink(); void receiveMavlink();
void handleMavlink(const void *_msg); void handleMavlink(const void *_msg);
int handleMavlinkCommand(const void *_m);
void mavlinkPrint(const char* str); void mavlinkPrint(const char* str);
void sendMavlinkPrint(); void sendMavlinkPrint();
inline Quaternion fluToFrd(const Quaternion &q); inline Quaternion fluToFrd(const Quaternion &q);
+1 -1
View File
@@ -1 +1 @@
from .flix import Flix from .flix import Flix, mavlink
+3 -1
View File
@@ -262,7 +262,9 @@ class Flix:
try: try:
logger.debug(f'Send command {command} with params {params} (attempt #{attempt + 1})') logger.debug(f'Send command {command} with params {params} (attempt #{attempt + 1})')
self.mavlink.command_long_send(self.system_id, 0, command, 0, *params) # type: ignore self.mavlink.command_long_send(self.system_id, 0, command, 0, *params) # type: ignore
self.wait('mavlink.COMMAND_ACK', value=lambda msg: msg.command == command and msg.result == mavlink.MAV_RESULT_ACCEPTED, timeout=0.1) ack = self.wait('mavlink.COMMAND_ACK', value=lambda msg: msg.command == command, timeout=0.1)
if ack.result != mavlink.MAV_RESULT_ACCEPTED:
raise RuntimeError(f'Command {command} failed with result {ack.result}')
return return
except TimeoutError: except TimeoutError:
continue continue
+5 -2
View File
@@ -2,10 +2,10 @@
# Script for testing pyflix and the simulation. # Script for testing pyflix and the simulation.
from pytest import approx from pytest import approx, raises
from math import isnan, isfinite from math import isnan, isfinite
import time import time
from pyflix import Flix from pyflix import Flix, mavlink
def test(): def test():
print('=== Connect...') print('=== Connect...')
@@ -45,3 +45,6 @@ def test():
flix.wait('mode', 'ACRO') flix.wait('mode', 'ACRO')
flix.set_mode('AUTO') flix.set_mode('AUTO')
flix.wait('mode', 'AUTO') flix.wait('mode', 'AUTO')
raises(RuntimeError, lambda: flix._command_send(mavlink.MAV_CMD_DO_SET_MODE, [0, 99, 0, 0, 0, 0, 0])) # invalid mode
raises(RuntimeError, lambda: flix._command_send(mavlink.MAV_CMD_DO_PARACHUTE, [0, 0, 0, 0, 0, 0, 0])) # unsupported command