3#include <QtPositioning/QGeoCoordinate>
19 (void) connect(&_missionItemResponseTimer, &QTimer::timeout,
this, &MockLinkMissionItemHandler::_missionItemResponseTimeout);
27void MockLinkMissionItemHandler::_startMissionItemResponseTimer()
29 _missionItemResponseTimer.start(500);
34 _missionItems.clear();
37 const double homeLatitude = home.latitude();
38 const double homeLongitude = home.longitude();
39 constexpr float relativeAltitude = 50.0f;
41 const auto makeItem = [](uint16_t seq, uint16_t command,
bool current,
double latitude,
double longitude,
float altitude) {
42 mavlink_mission_item_int_t item{};
44 item.frame = MAV_FRAME_GLOBAL_RELATIVE_ALT;
45 item.command = command;
46 item.current = current ? 1 : 0;
47 item.autocontinue = 1;
48 item.x =
static_cast<int32_t
>(
latitude * 1e7);
49 item.y =
static_cast<int32_t
>(
longitude * 1e7);
51 item.mission_type = MAV_MISSION_TYPE_MISSION;
56 _missionItems[0] = makeItem(0, MAV_CMD_NAV_TAKEOFF,
true, homeLatitude, homeLongitude, relativeAltitude);
58 _missionItems[1] = makeItem(1, MAV_CMD_NAV_WAYPOINT,
false, homeLatitude + 0.001, homeLongitude + 0.001, relativeAltitude);
60 _missionItems[2] = makeItem(2, MAV_CMD_NAV_RETURN_TO_LAUNCH,
false, 0.0, 0.0, 0.0);
62 qCDebug(MockLinkMissionItemHandlerLog) <<
"loadSimpleMultirotorMission seeded" << _missionItems.count() <<
"items";
68 case MAVLINK_MSG_ID_MISSION_REQUEST_LIST:
69 _handleMissionRequestList(msg);
71 case MAVLINK_MSG_ID_MISSION_REQUEST_INT:
72 _handleMissionRequest(msg);
74 case MAVLINK_MSG_ID_MISSION_ITEM_INT:
75 _handleMissionItem(msg);
77 case MAVLINK_MSG_ID_MISSION_COUNT:
78 _handleMissionCount(msg);
80 case MAVLINK_MSG_ID_MISSION_ACK:
83 case MAVLINK_MSG_ID_MISSION_SET_CURRENT:
86 case MAVLINK_MSG_ID_MISSION_CLEAR_ALL:
87 _handleMissionClearAll(msg);
96void MockLinkMissionItemHandler::_handleMissionClearAll(
const mavlink_message_t &msg)
98 mavlink_mission_clear_all_t clearAll{};
99 mavlink_msg_mission_clear_all_decode(&msg, &clearAll);
101 Q_ASSERT(clearAll.target_system == _mockLink->
vehicleId());
103 _requestType =
static_cast<MAV_MISSION_TYPE
>(clearAll.mission_type);
104 qCDebug(MockLinkMissionItemHandlerLog) <<
"_handleMissionClearAll" << _requestType;
106 switch (_requestType) {
107 case MAV_MISSION_TYPE_MISSION:
108 _missionItems.clear();
110 case MAV_MISSION_TYPE_FENCE:
113 case MAV_MISSION_TYPE_RALLY:
116 case MAV_MISSION_TYPE_ALL:
117 _missionItems.clear();
125 _sendAck(MAV_MISSION_ACCEPTED);
128void MockLinkMissionItemHandler::_handleMissionRequestList(
const mavlink_message_t &msg)
130 qCDebug(MockLinkMissionItemHandlerLog) <<
"_handleMissionRequestList read sequence";
132 _failReadRequest1FirstResponse =
true;
134 mavlink_mission_request_list_t request{};
135 mavlink_msg_mission_request_list_decode(&msg, &request);
138 qCDebug(MockLinkMissionItemHandlerLog) <<
"_handleMissionRequestList not responding due to failure mode FailReadRequestListNoResponse";
143 _failReadRequestListFirstResponse =
false;
144 qCDebug(MockLinkMissionItemHandlerLog) <<
"_handleMissionRequestList not responding due to failure mode FailReadRequestListFirstResponse";
148 _failReadRequestListFirstResponse =
true;
150 Q_ASSERT(request.target_system == _mockLink->
vehicleId());
151 _requestListCounts[
static_cast<MAV_MISSION_TYPE
>(request.mission_type)]++;
153 _requestType =
static_cast<MAV_MISSION_TYPE
>(request.mission_type);
156 switch (_requestType) {
157 case MAV_MISSION_TYPE_MISSION:
158 itemCount = _missionItems.count();
159 if (itemCount == 0 && _sendHomePositionOnEmptyList) {
163 case MAV_MISSION_TYPE_FENCE:
164 itemCount = _fenceItems.count();
166 case MAV_MISSION_TYPE_RALLY:
167 itemCount = _rallyItems.count();
174 (void) mavlink_msg_mission_count_pack_chan(
176 MAV_COMP_ID_AUTOPILOT1,
189void MockLinkMissionItemHandler::_handleMissionRequest(
const mavlink_message_t &msg)
191 qCDebug(MockLinkMissionItemHandlerLog) <<
"_handleMissionRequest read sequence";
193 mavlink_mission_request_int_t request{};
194 mavlink_msg_mission_request_int_decode(&msg, &request);
196 Q_ASSERT(request.target_system == _mockLink->
vehicleId());
199 qCDebug(MockLinkMissionItemHandlerLog) <<
"_handleMissionRequest not responding due to failure mode FailReadRequest0NoResponse";
204 qCDebug(MockLinkMissionItemHandlerLog) <<
"_handleMissionRequest not responding due to failure mode FailReadRequest1NoResponse";
209 _failReadRequest1FirstResponse =
false;
210 qCDebug(MockLinkMissionItemHandlerLog) <<
"_handleMissionRequest not responding due to failure mode FailReadRequest1FirstResponse";
219 qCDebug(MockLinkMissionItemHandlerLog) <<
"_handleMissionRequest sending bad sequence number";
225 _sendAck(_failureAckResult);
229 mavlink_mission_item_int_t missionItemInt{};
231 switch (request.mission_type) {
232 case MAV_MISSION_TYPE_MISSION:
233 if (_missionItems.isEmpty() && _sendHomePositionOnEmptyList) {
234 (void) memset(&missionItemInt, 0,
sizeof(missionItemInt));
235 missionItemInt.frame = MAV_FRAME_GLOBAL_RELATIVE_ALT;
236 missionItemInt.command = MAV_CMD_NAV_WAYPOINT;
237 missionItemInt.autocontinue =
true;
239 missionItemInt = _missionItems[request.seq];
242 case MAV_MISSION_TYPE_FENCE:
243 missionItemInt = _fenceItems[request.seq];
245 case MAV_MISSION_TYPE_RALLY:
246 missionItemInt = _rallyItems[request.seq];
253 (void) mavlink_msg_mission_item_int_pack_chan(
255 MAV_COMP_ID_AUTOPILOT1,
261 missionItemInt.frame,
262 missionItemInt.command,
263 missionItemInt.current,
264 missionItemInt.autocontinue,
265 missionItemInt.param1, missionItemInt.param2, missionItemInt.param3, missionItemInt.param4,
266 missionItemInt.x, missionItemInt.y, missionItemInt.z,
273void MockLinkMissionItemHandler::_handleMissionCount(
const mavlink_message_t &msg)
275 mavlink_mission_count_t missionCount{};
276 mavlink_msg_mission_count_decode(&msg, &missionCount);
277 Q_ASSERT(missionCount.target_system == _mockLink->
vehicleId());
279 _requestType = (MAV_MISSION_TYPE)missionCount.mission_type;
280 _writeSequenceCount = missionCount.count;
281 Q_ASSERT(_writeSequenceCount >= 0);
283 qCDebug(MockLinkMissionItemHandlerLog) <<
"_handleMissionCount write sequence _writeSequenceCount:" << _writeSequenceCount;
285 switch (missionCount.mission_type) {
286 case MAV_MISSION_TYPE_MISSION:
287 _missionItems.clear();
289 case MAV_MISSION_TYPE_FENCE:
292 case MAV_MISSION_TYPE_RALLY:
297 if (_writeSequenceCount == 0) {
298 _sendAck(MAV_MISSION_ACCEPTED);
303 qCDebug(MockLinkMissionItemHandlerLog) <<
"_handleMissionCount not responding due to failure mode FailWriteMissionCountNoResponse";
308 _failWriteMissionCountFirstResponse =
false;
309 qCDebug(MockLinkMissionItemHandlerLog) <<
"_handleMissionCount not responding due to failure mode FailWriteMissionCountNoResponse";
313 _failWriteMissionCountFirstResponse =
true;
314 _writeSequenceIndex = 0;
315 _requestNextMissionItem(_writeSequenceIndex);
318void MockLinkMissionItemHandler::_requestNextMissionItem(
int sequenceNumber)
320 qCDebug(MockLinkMissionItemHandlerLog) <<
"write sequence sequenceNumber:" << sequenceNumber <<
"_failureMode:" << _failureMode;
323 qCDebug(MockLinkMissionItemHandlerLog) <<
"_requestNextMissionItem not responding due to failure mode FailWriteRequest1NoResponse";
327 if (sequenceNumber >= _writeSequenceCount) {
328 qCWarning(MockLinkMissionItemHandlerLog) <<
"_requestNextMissionItem requested seqeuence number > write count sequenceNumber::_writeSequenceCount" << sequenceNumber << _writeSequenceCount;
339 qCDebug(MockLinkMissionItemHandlerLog) <<
"_requestNextMissionItem sending ack error due to failure mode";
340 _sendAck(_failureAckResult);
345 (void) mavlink_msg_mission_request_int_pack_chan(
347 MAV_COMP_ID_AUTOPILOT1,
358 _startMissionItemResponseTimer();
361void MockLinkMissionItemHandler::_sendAck(MAV_MISSION_RESULT ackType)
const
363 qCDebug(MockLinkMissionItemHandlerLog) <<
"_sendAck write sequence complete ackType:" << ackType;
366 (void) mavlink_msg_mission_ack_pack_chan(
368 MAV_COMP_ID_AUTOPILOT1,
383 qCDebug(MockLinkMissionItemHandlerLog) <<
"_handleMissionItem write sequence";
385 _missionItemResponseTimer.stop();
387 mavlink_mission_item_int_t missionItemInt{};
388 mavlink_msg_mission_item_int_decode(&msg, &missionItemInt);
390 const MAV_MISSION_TYPE missionType =
static_cast<MAV_MISSION_TYPE
>(missionItemInt.mission_type);
391 const uint16_t seq = missionItemInt.seq;
393 switch (missionType) {
394 case MAV_MISSION_TYPE_MISSION:
395 _missionItems[seq] = missionItemInt;
397 case MAV_MISSION_TYPE_FENCE:
398 _fenceItems[seq] = missionItemInt;
400 case MAV_MISSION_TYPE_RALLY:
401 _rallyItems[seq] = missionItemInt;
403 case MAV_MISSION_TYPE_ENUM_END:
404 case MAV_MISSION_TYPE_ALL:
405 qCWarning(MockLinkMissionItemHandlerLog) <<
"Internal error";
409 _writeSequenceIndex++;
410 if (_writeSequenceIndex < _writeSequenceCount) {
413 _sendAck(MAV_MISSION_ACCEPTED);
415 _requestNextMissionItem(_writeSequenceIndex);
422 MAV_MISSION_RESULT ack = MAV_MISSION_ACCEPTED;
425 ack = MAV_MISSION_ERROR;
432void MockLinkMissionItemHandler::_missionItemResponseTimeout()
434 qCWarning(MockLinkMissionItemHandlerLog) <<
"Timeout waiting for next MISSION_ITEM_INT";
457 _failureMode = failureMode;
458 _failureAckResult = failureAckResult;
463 _missionItemResponseTimer.stop();
struct __mavlink_message mavlink_message_t
#define QGC_LOGGING_CATEGORY(name, categoryStr)
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()
QGeoCoordinate homeCoordinate() const
Configured home position, before the per-vehicle offset applied to the vehicle position.
uint8_t outgoingMavlinkChannel() const
Vehicle-side channel used to encode outgoing (mock vehicle -> QGC) messages. Signing state lives here...
void respondWithMavlinkMessage(const mavlink_message_t &msg)
Sends the specified mavlink message to QGC.