17 (void) connect(&_missionItemResponseTimer, &QTimer::timeout,
this, &MockLinkMissionItemHandler::_missionItemResponseTimeout);
25void MockLinkMissionItemHandler::_startMissionItemResponseTimer()
27 _missionItemResponseTimer.start(500);
32 _missionItems.clear();
34 constexpr double homeLatitude = 47.397;
35 constexpr double homeLongitude = 8.5455;
36 constexpr float relativeAltitude = 50.0f;
38 const auto makeItem = [](uint16_t seq, uint16_t command,
bool current,
double latitude,
double longitude,
float altitude) {
39 mavlink_mission_item_int_t item{};
41 item.frame = MAV_FRAME_GLOBAL_RELATIVE_ALT;
42 item.command = command;
43 item.current = current ? 1 : 0;
44 item.autocontinue = 1;
45 item.x =
static_cast<int32_t
>(latitude * 1e7);
46 item.y =
static_cast<int32_t
>(longitude * 1e7);
48 item.mission_type = MAV_MISSION_TYPE_MISSION;
53 _missionItems[0] = makeItem(0, MAV_CMD_NAV_TAKEOFF,
true, homeLatitude, homeLongitude, relativeAltitude);
55 _missionItems[1] = makeItem(1, MAV_CMD_NAV_WAYPOINT,
false, homeLatitude + 0.001, homeLongitude + 0.001, relativeAltitude);
57 _missionItems[2] = makeItem(2, MAV_CMD_NAV_RETURN_TO_LAUNCH,
false, 0.0, 0.0, 0.0);
59 qCDebug(MockLinkMissionItemHandlerLog) <<
"loadSimpleMultirotorMission seeded" << _missionItems.count() <<
"items";
65 case MAVLINK_MSG_ID_MISSION_REQUEST_LIST:
66 _handleMissionRequestList(msg);
68 case MAVLINK_MSG_ID_MISSION_REQUEST_INT:
69 _handleMissionRequest(msg);
71 case MAVLINK_MSG_ID_MISSION_ITEM_INT:
72 _handleMissionItem(msg);
74 case MAVLINK_MSG_ID_MISSION_COUNT:
75 _handleMissionCount(msg);
77 case MAVLINK_MSG_ID_MISSION_ACK:
80 case MAVLINK_MSG_ID_MISSION_SET_CURRENT:
83 case MAVLINK_MSG_ID_MISSION_CLEAR_ALL:
84 _handleMissionClearAll(msg);
93void MockLinkMissionItemHandler::_handleMissionClearAll(
const mavlink_message_t &msg)
95 mavlink_mission_clear_all_t clearAll{};
96 mavlink_msg_mission_clear_all_decode(&msg, &clearAll);
98 Q_ASSERT(clearAll.target_system == _mockLink->
vehicleId());
100 _requestType =
static_cast<MAV_MISSION_TYPE
>(clearAll.mission_type);
101 qCDebug(MockLinkMissionItemHandlerLog) <<
"_handleMissionClearAll" << _requestType;
103 switch (_requestType) {
104 case MAV_MISSION_TYPE_MISSION:
105 _missionItems.clear();
107 case MAV_MISSION_TYPE_FENCE:
110 case MAV_MISSION_TYPE_RALLY:
113 case MAV_MISSION_TYPE_ALL:
114 _missionItems.clear();
122 _sendAck(MAV_MISSION_ACCEPTED);
125void MockLinkMissionItemHandler::_handleMissionRequestList(
const mavlink_message_t &msg)
127 qCDebug(MockLinkMissionItemHandlerLog) <<
"_handleMissionRequestList read sequence";
129 _failReadRequest1FirstResponse =
true;
131 mavlink_mission_request_list_t request{};
132 mavlink_msg_mission_request_list_decode(&msg, &request);
135 qCDebug(MockLinkMissionItemHandlerLog) <<
"_handleMissionRequestList not responding due to failure mode FailReadRequestListNoResponse";
140 _failReadRequestListFirstResponse =
false;
141 qCDebug(MockLinkMissionItemHandlerLog) <<
"_handleMissionRequestList not responding due to failure mode FailReadRequestListFirstResponse";
145 _failReadRequestListFirstResponse =
true;
147 Q_ASSERT(request.target_system == _mockLink->
vehicleId());
148 _requestListCounts[
static_cast<MAV_MISSION_TYPE
>(request.mission_type)]++;
150 _requestType =
static_cast<MAV_MISSION_TYPE
>(request.mission_type);
153 switch (_requestType) {
154 case MAV_MISSION_TYPE_MISSION:
155 itemCount = _missionItems.count();
156 if (itemCount == 0 && _sendHomePositionOnEmptyList) {
160 case MAV_MISSION_TYPE_FENCE:
161 itemCount = _fenceItems.count();
163 case MAV_MISSION_TYPE_RALLY:
164 itemCount = _rallyItems.count();
171 (void) mavlink_msg_mission_count_pack_chan(
173 MAV_COMP_ID_AUTOPILOT1,
186void MockLinkMissionItemHandler::_handleMissionRequest(
const mavlink_message_t &msg)
188 qCDebug(MockLinkMissionItemHandlerLog) <<
"_handleMissionRequest read sequence";
190 mavlink_mission_request_int_t request{};
191 mavlink_msg_mission_request_int_decode(&msg, &request);
193 Q_ASSERT(request.target_system == _mockLink->
vehicleId());
196 qCDebug(MockLinkMissionItemHandlerLog) <<
"_handleMissionRequest not responding due to failure mode FailReadRequest0NoResponse";
201 qCDebug(MockLinkMissionItemHandlerLog) <<
"_handleMissionRequest not responding due to failure mode FailReadRequest1NoResponse";
206 _failReadRequest1FirstResponse =
false;
207 qCDebug(MockLinkMissionItemHandlerLog) <<
"_handleMissionRequest not responding due to failure mode FailReadRequest1FirstResponse";
216 qCDebug(MockLinkMissionItemHandlerLog) <<
"_handleMissionRequest sending bad sequence number";
222 _sendAck(_failureAckResult);
226 mavlink_mission_item_int_t missionItemInt{};
228 switch (request.mission_type) {
229 case MAV_MISSION_TYPE_MISSION:
230 if (_missionItems.isEmpty() && _sendHomePositionOnEmptyList) {
231 (void) memset(&missionItemInt, 0,
sizeof(missionItemInt));
232 missionItemInt.frame = MAV_FRAME_GLOBAL_RELATIVE_ALT;
233 missionItemInt.command = MAV_CMD_NAV_WAYPOINT;
234 missionItemInt.autocontinue =
true;
236 missionItemInt = _missionItems[request.seq];
239 case MAV_MISSION_TYPE_FENCE:
240 missionItemInt = _fenceItems[request.seq];
242 case MAV_MISSION_TYPE_RALLY:
243 missionItemInt = _rallyItems[request.seq];
250 (void) mavlink_msg_mission_item_int_pack_chan(
252 MAV_COMP_ID_AUTOPILOT1,
258 missionItemInt.frame,
259 missionItemInt.command,
260 missionItemInt.current,
261 missionItemInt.autocontinue,
262 missionItemInt.param1, missionItemInt.param2, missionItemInt.param3, missionItemInt.param4,
263 missionItemInt.x, missionItemInt.y, missionItemInt.z,
270void MockLinkMissionItemHandler::_handleMissionCount(
const mavlink_message_t &msg)
272 mavlink_mission_count_t missionCount{};
273 mavlink_msg_mission_count_decode(&msg, &missionCount);
274 Q_ASSERT(missionCount.target_system == _mockLink->
vehicleId());
276 _requestType = (MAV_MISSION_TYPE)missionCount.mission_type;
277 _writeSequenceCount = missionCount.count;
278 Q_ASSERT(_writeSequenceCount >= 0);
280 qCDebug(MockLinkMissionItemHandlerLog) <<
"_handleMissionCount write sequence _writeSequenceCount:" << _writeSequenceCount;
282 switch (missionCount.mission_type) {
283 case MAV_MISSION_TYPE_MISSION:
284 _missionItems.clear();
286 case MAV_MISSION_TYPE_FENCE:
289 case MAV_MISSION_TYPE_RALLY:
294 if (_writeSequenceCount == 0) {
295 _sendAck(MAV_MISSION_ACCEPTED);
300 qCDebug(MockLinkMissionItemHandlerLog) <<
"_handleMissionCount not responding due to failure mode FailWriteMissionCountNoResponse";
305 _failWriteMissionCountFirstResponse =
false;
306 qCDebug(MockLinkMissionItemHandlerLog) <<
"_handleMissionCount not responding due to failure mode FailWriteMissionCountNoResponse";
310 _failWriteMissionCountFirstResponse =
true;
311 _writeSequenceIndex = 0;
312 _requestNextMissionItem(_writeSequenceIndex);
315void MockLinkMissionItemHandler::_requestNextMissionItem(
int sequenceNumber)
317 qCDebug(MockLinkMissionItemHandlerLog) <<
"write sequence sequenceNumber:" << sequenceNumber <<
"_failureMode:" << _failureMode;
320 qCDebug(MockLinkMissionItemHandlerLog) <<
"_requestNextMissionItem not responding due to failure mode FailWriteRequest1NoResponse";
324 if (sequenceNumber >= _writeSequenceCount) {
325 qCWarning(MockLinkMissionItemHandlerLog) <<
"_requestNextMissionItem requested seqeuence number > write count sequenceNumber::_writeSequenceCount" << sequenceNumber << _writeSequenceCount;
336 qCDebug(MockLinkMissionItemHandlerLog) <<
"_requestNextMissionItem sending ack error due to failure mode";
337 _sendAck(_failureAckResult);
342 (void) mavlink_msg_mission_request_int_pack_chan(
344 MAV_COMP_ID_AUTOPILOT1,
355 _startMissionItemResponseTimer();
358void MockLinkMissionItemHandler::_sendAck(MAV_MISSION_RESULT ackType)
const
360 qCDebug(MockLinkMissionItemHandlerLog) <<
"_sendAck write sequence complete ackType:" << ackType;
363 (void) mavlink_msg_mission_ack_pack_chan(
365 MAV_COMP_ID_AUTOPILOT1,
380 qCDebug(MockLinkMissionItemHandlerLog) <<
"_handleMissionItem write sequence";
382 _missionItemResponseTimer.stop();
384 mavlink_mission_item_int_t missionItemInt{};
385 mavlink_msg_mission_item_int_decode(&msg, &missionItemInt);
387 const MAV_MISSION_TYPE missionType =
static_cast<MAV_MISSION_TYPE
>(missionItemInt.mission_type);
388 const uint16_t seq = missionItemInt.seq;
390 switch (missionType) {
391 case MAV_MISSION_TYPE_MISSION:
392 _missionItems[seq] = missionItemInt;
394 case MAV_MISSION_TYPE_FENCE:
395 _fenceItems[seq] = missionItemInt;
397 case MAV_MISSION_TYPE_RALLY:
398 _rallyItems[seq] = missionItemInt;
400 case MAV_MISSION_TYPE_ENUM_END:
401 case MAV_MISSION_TYPE_ALL:
402 qCWarning(MockLinkMissionItemHandlerLog) <<
"Internal error";
406 _writeSequenceIndex++;
407 if (_writeSequenceIndex < _writeSequenceCount) {
410 _sendAck(MAV_MISSION_ACCEPTED);
412 _requestNextMissionItem(_writeSequenceIndex);
419 MAV_MISSION_RESULT ack = MAV_MISSION_ACCEPTED;
422 ack = MAV_MISSION_ERROR;
429void MockLinkMissionItemHandler::_missionItemResponseTimeout()
431 qCWarning(MockLinkMissionItemHandlerLog) <<
"Timeout waiting for next MISSION_ITEM_INT";
454 _failureMode = failureMode;
455 _failureAckResult = failureAckResult;
460 _missionItemResponseTimer.stop();
struct __mavlink_message mavlink_message_t
#define QGC_LOGGING_CATEGORY(name, categoryStr)
uint8_t mavlinkChannel() const
static int getComponentId()
static MAVLinkProtocol * instance()
void sendUnexpectedMissionAck(MAV_MISSION_RESULT ackType)
Called to send a MISSION_ACK message while the MissionManager is in idle state.
bool handleMavlinkMessage(const mavlink_message_t &msg)
void setFailureMode(FailureMode_t failureMode, MAV_MISSION_RESULT failureAckResult)
void loadSimpleMultirotorMission()
void sendUnexpectedMissionRequest()
Called to send a MISSION_REQUEST message while the MissionManager is in idle state.
@ FailWriteFinalAckMissingRequests
@ FailWriteFinalAckNoResponse
@ FailWriteRequest1IncorrectSequence
@ FailWriteMissionCountFirstResponse
@ FailWriteRequest1ErrorAck
@ FailWriteRequest0ErrorAck
@ FailReadRequest1IncorrectSequence
@ FailReadRequest0IncorrectSequence
@ FailWriteMissionCountNoResponse
@ FailWriteRequest1NoResponse
@ FailReadRequest1ErrorAck
@ FailWriteFinalAckErrorAck
@ FailReadRequest0NoResponse
@ FailReadRequest1NoResponse
@ FailReadRequestListFirstResponse
@ FailReadRequest0ErrorAck
@ FailWriteRequest0IncorrectSequence
@ FailReadRequestListNoResponse
@ FailReadRequest1FirstResponse
void sendUnexpectedMissionItem()
Called to send a MISSION_ITEM message while the MissionManager is in idle state.
~MockLinkMissionItemHandler()
void respondWithMavlinkMessage(const mavlink_message_t &msg)
Sends the specified mavlink message to QGC.