17 , _planType (planType)
18 , _ackTimeoutTimer (
nullptr)
19 , _expectedAck (AckNone)
20 , _transactionInProgress (TransactionNone)
21 , _resumeMission (false)
22 , _lastMissionRequest (-1)
23 , _missionItemCountToRead (-1)
24 , _currentMissionIndex (-1)
25 , _lastCurrentIndex (-1)
27 _ackTimeoutTimer =
new QTimer(
this);
28 _ackTimeoutTimer->setSingleShot(
true);
30 connect(_ackTimeoutTimer, &QTimer::timeout,
this, &PlanManager::_ackTimeout);
66 qCDebug(PlanManagerLog) << QStringLiteral(
"writeMissionItems %1 called while transaction in progress").arg(
_planTypeString());
79 int firstIndex = skipFirstItem ? 1 : 0;
90 if (item->
command() == MAV_CMD_DO_JUMP) {
108 mavlink_msg_mission_count_pack_chan(
111 sharedLink->mavlinkChannel(),
114 MAV_COMP_ID_AUTOPILOT1,
131 qCDebug(PlanManagerLog) << QStringLiteral(
"loadFromVehicle %1 read sequence").arg(
_planTypeString());
134 qCDebug(PlanManagerLog) << QStringLiteral(
"loadFromVehicle %1 called while transaction in progress").arg(
_planTypeString());
157 sharedLink->mavlinkChannel(),
160 MAV_COMP_ID_AUTOPILOT1,
168void PlanManager::_ackTimeout(
void)
176 qCWarning(PlanManagerLog) << QStringLiteral(
"_ackTimeout %1 timeout with AckNone").arg(
_planTypeString());
177 _sendError(
InternalError, tr(
"Internal error occurred during Mission Item communication: _ackTimeOut:_expectedAck == AckNone"));
295 qCDebug(PlanManagerLog) <<
"_readTransactionComplete read sequence complete";
301 mavlink_msg_mission_ack_pack_chan(
304 sharedLink->mavlinkChannel(),
307 MAV_COMP_ID_AUTOPILOT1,
308 MAV_MISSION_ACCEPTED,
321 mavlink_mission_count_t missionCount;
323 mavlink_msg_mission_count_decode(&message, &missionCount);
325 if (missionCount.mission_type !=
_planType) {
328 qCDebug(PlanManagerLog) << QStringLiteral(
"_handleMissionCount %1 Incorrect mission_type received expected:actual").arg(
_planTypeString()) <<
_planType << missionCount.mission_type;
336 qCDebug(PlanManagerLog) << QStringLiteral(
"_handleMissionCount %1 count:").arg(
_planTypeString()) << missionCount.count;
340 if (missionCount.count == 0) {
344 for (
int i=0; i<missionCount.count; i++) {
355 _sendError(
InternalError, tr(
"Internal Error: Call to Vehicle _requestNextMissionItem with no more indices to read"));
367 sharedLink->mavlinkChannel(),
370 MAV_COMP_ID_AUTOPILOT1,
382 MAV_MISSION_TYPE missionType;
394 mavlink_mission_item_int_t missionItem;
395 mavlink_msg_mission_item_int_decode(&message, &missionItem);
397 command = (MAV_CMD)missionItem.command;
398 frame = (MAV_FRAME)missionItem.frame;
399 missionType = (MAV_MISSION_TYPE)missionItem.mission_type;
400 param1 = missionItem.param1;
401 param2 = missionItem.param2;
402 param3 = missionItem.param3;
403 param4 = missionItem.param4;
404 param5 = missionItem.frame == MAV_FRAME_MISSION ? (double)missionItem.x : (double)missionItem.x * 1e-7;
405 param6 = missionItem.frame == MAV_FRAME_MISSION ? (double)missionItem.y : (double)missionItem.y * 1e-7;
406 param7 = (double)missionItem.z;
407 autoContinue = missionItem.autocontinue;
408 isCurrentItem = missionItem.current;
409 seq = missionItem.seq;
414 qCDebug(PlanManagerLog) << QStringLiteral(
"_handleMissionItem %1 dropping spurious item seq:command:missionType").arg(
_planTypeString()) << seq << command << missionType;
419 if (frame == MAV_FRAME_GLOBAL_INT) {
420 frame = MAV_FRAME_GLOBAL;
421 }
else if (frame == MAV_FRAME_GLOBAL_RELATIVE_ALT_INT) {
422 frame = MAV_FRAME_GLOBAL_RELATIVE_ALT;
423 }
else if (frame == MAV_FRAME_GLOBAL_TERRAIN_ALT_INT) {
424 frame = MAV_FRAME_GLOBAL_TERRAIN_ALT;
427 bool ardupilotHomePositionUpdate =
false;
430 ardupilotHomePositionUpdate =
true;
432 qCDebug(PlanManagerLog) << QStringLiteral(
"_handleMissionItem %1 dropping spurious item seq:command:current").arg(
_planTypeString()) << seq << command << isCurrentItem;
437 qCDebug(PlanManagerLog) << QStringLiteral(
"_handleMissionItem %1 seq:command:current:ardupilotHomePositionUpdate").arg(
_planTypeString()) << seq << command << isCurrentItem << ardupilotHomePositionUpdate;
439 if (ardupilotHomePositionUpdate) {
440 QGeoCoordinate newHomePosition(param5, param6, param7);
469 qCDebug(PlanManagerLog) << QStringLiteral(
"_handleMissionItem %1 mission item received item index which was not requested, disregrarding:").arg(
_planTypeString()) << seq;
493 MAV_MISSION_TYPE missionRequestMissionType;
494 uint16_t missionRequestSeq;
496 mavlink_mission_request_int_t missionRequest;
497 mavlink_msg_mission_request_int_decode(&message, &missionRequest);
498 missionRequestMissionType =
static_cast<MAV_MISSION_TYPE
>(missionRequest.mission_type);
499 missionRequestSeq = missionRequest.seq;
501 if (missionRequestMissionType !=
_planType) {
504 qCDebug(PlanManagerLog) << QStringLiteral(
"_handleMissionRequest %1 Incorrect mission_type received expected:actual").arg(
_planTypeString()) <<
_planType << missionRequestMissionType;
512 qCDebug(PlanManagerLog) << QStringLiteral(
"_handleMissionRequest %1 sequenceNumber").arg(
_planTypeString()) << missionRequestSeq;
524 qCDebug(PlanManagerLog) << QStringLiteral(
"_handleMissionRequest %1 sequence number requested which has already been sent, sending again:").arg(
_planTypeString()) << missionRequestSeq;
530 qCDebug(PlanManagerLog) << QStringLiteral(
"_handleMissionRequest %1 sequenceNumber:command").arg(
_planTypeString()) << missionRequestSeq << item->
command();
538 sharedLink->mavlinkChannel(),
541 MAV_COMP_ID_AUTOPILOT1,
545 missionRequestSeq == 0,
562 mavlink_mission_ack_t missionAck;
564 mavlink_msg_mission_ack_decode(&message, &missionAck);
565 if (missionAck.mission_type !=
_planType) {
568 qCDebug(PlanManagerLog) << QStringLiteral(
"_handleMissionAck %1 Incorrect mission_type received expected:actual").arg(
_planTypeString()) <<
_planType << missionAck.mission_type;
576 qCDebug(PlanManagerLog) << QStringLiteral(
"_handleMissionAck ArduPilot sending possibly bogus MAV_MISSION_INVALID_SEQUENCE").arg(
_planTypeString()) <<
_planType;
593 switch (savedExpectedAck) {
596 qCDebug(PlanManagerLog) << QStringLiteral(
"Vehicle sent unexpected MISSION_ACK message, error: %1").arg(
_missionResultToString((MAV_MISSION_RESULT)missionAck.type));
612 if (missionAck.type == MAV_MISSION_ACCEPTED) {
614 qCDebug(PlanManagerLog) << QStringLiteral(
"_handleMissionAck write sequence complete %1").arg(
_planTypeString());
628 if (missionAck.type != MAV_MISSION_ACCEPTED) {
635 if (missionAck.type == MAV_MISSION_ACCEPTED) {
636 qCDebug(PlanManagerLog) << QStringLiteral(
"_handleMissionAck %1 guided mode item accepted").arg(
_planTypeString());
650 switch (message.msgid) {
651 case MAVLINK_MSG_ID_MISSION_COUNT:
655 case MAVLINK_MSG_ID_MISSION_ITEM_INT:
659 case MAVLINK_MSG_ID_MISSION_REQUEST:
660 case MAVLINK_MSG_ID_MISSION_REQUEST_INT:
664 case MAVLINK_MSG_ID_MISSION_ACK:
672 qCDebug(PlanManagerLog) << QStringLiteral(
"Sending error - _planTypeString(%1) errorCode(%2) errorMsg(%4)").arg(
_planTypeString()).arg(errorCode).arg(errorMsg);
674 emit
error(errorCode, errorMsg);
681 return QString(
"No Ack");
683 return QString(
"MISSION_COUNT");
685 return QString(
"MISSION_ITEM");
687 return QString(
"MISSION_REQUEST");
689 return QString(
"Guided Mode Item");
691 qCWarning(PlanManagerLog) << QStringLiteral(
"Fell off end of switch statement %1").arg(
_planTypeString());
692 return QString(
"QGC Internal Error");
707 case MAV_MISSION_UNSUPPORTED_FRAME:
708 postfix = tr(
"Frame: %1").arg(item->
frame());
710 case MAV_MISSION_UNSUPPORTED:
713 case MAV_MISSION_INVALID_PARAM1:
714 postfix = tr(
"Value: %1").arg(item->
param1());
716 case MAV_MISSION_INVALID_PARAM2:
717 postfix = tr(
"Value: %1").arg(item->
param2());
719 case MAV_MISSION_INVALID_PARAM3:
720 postfix = tr(
"Value: %1").arg(item->
param3());
722 case MAV_MISSION_INVALID_PARAM4:
723 postfix = tr(
"Value: %1").arg(item->
param4());
725 case MAV_MISSION_INVALID_PARAM5_X:
726 postfix = tr(
"Value: %1").arg(item->
param5());
728 case MAV_MISSION_INVALID_PARAM6_Y:
729 postfix = tr(
"Value: %1").arg(item->
param6());
731 case MAV_MISSION_INVALID_PARAM7:
732 postfix = tr(
"Value: %1").arg(item->
param7());
734 case MAV_MISSION_INVALID_SEQUENCE:
742 return prefix + (postfix.isEmpty() ? QStringLiteral(
"") : QStringLiteral(
" ")) + postfix;
750 case MAV_MISSION_ACCEPTED:
751 error = tr(
"Mission accepted.");
753 case MAV_MISSION_ERROR:
754 error = tr(
"Unspecified error.");
756 case MAV_MISSION_UNSUPPORTED_FRAME:
757 error = tr(
"Coordinate frame is not supported.");
759 case MAV_MISSION_UNSUPPORTED:
760 error = tr(
"Command is not supported.");
762 case MAV_MISSION_NO_SPACE:
763 error = tr(
"Mission item exceeds storage space.");
765 case MAV_MISSION_INVALID:
766 error = tr(
"One of the parameters has an invalid value.");
768 case MAV_MISSION_INVALID_PARAM1:
769 error = tr(
"Param 1 invalid value.");
771 case MAV_MISSION_INVALID_PARAM2:
772 error = tr(
"Param 2 invalid value.");
774 case MAV_MISSION_INVALID_PARAM3:
775 error = tr(
"Param 3 invalid value.");
777 case MAV_MISSION_INVALID_PARAM4:
778 error = tr(
"Param 4 invalid value.");
780 case MAV_MISSION_INVALID_PARAM5_X:
781 error = tr(
"Param 5 invalid value.");
783 case MAV_MISSION_INVALID_PARAM6_Y:
784 error = tr(
"Param 6 invalid value.");
786 case MAV_MISSION_INVALID_PARAM7:
787 error = tr(
"Param 7 invalid value.");
789 case MAV_MISSION_INVALID_SEQUENCE:
790 error = tr(
"Received mission item out of sequence.");
792 case MAV_MISSION_DENIED:
793 error = tr(
"Not accepting any mission commands.");
796 qCWarning(PlanManagerLog) << QStringLiteral(
"Fell off end of switch statement %1 %2").arg(
_planTypeString()).arg(result);
797 error = tr(
"Unknown error: %1.").arg(result);
802 if (!lastRequestString.isEmpty()) {
803 error += QStringLiteral(
" ") + lastRequestString;
821 switch (currentTransactionType) {
831 if (!apmGuidedItemWrite) {
834 if (
_planType == MAV_MISSION_TYPE_MISSION) {
876 qCDebug(PlanManagerLog) <<
"_removeAllWorker";
888 sharedLink->mavlinkChannel(),
891 MAV_COMP_ID_AUTOPILOT1,
904 qCDebug(PlanManagerLog) << QStringLiteral(
"removeAll %1").arg(
_planTypeString());
908 if (
_planType == MAV_MISSION_TYPE_MISSION) {
953 case MAV_MISSION_TYPE_MISSION:
954 return QStringLiteral(
"T:Mission");
955 case MAV_MISSION_TYPE_FENCE:
956 return QStringLiteral(
"T:GeoFence");
957 case MAV_MISSION_TYPE_RALLY:
958 return QStringLiteral(
"T:Rally");
960 qWarning() <<
"Unknown plan type" <<
_planType;
961 return QStringLiteral(
"T:Unknown");
965void PlanManager::_setTransactionInProgress(TransactionType_t type)
968 qCDebug(PlanManagerLog) <<
"_setTransactionInProgress" <<
_planTypeString() << type;
std::shared_ptr< LinkInterface > SharedLinkInterfacePtr
struct __mavlink_message mavlink_message_t
#define QGC_LOGGING_CATEGORY(name, categoryStr)
virtual bool sendHomePositionToVehicle() const
static int getComponentId()
static MAVLinkProtocol * instance()
static MissionCommandTree * instance()
MAV_CMD command(void) const
double param5(void) const
double param7(void) const
void setParam1(double param1)
MAV_FRAME frame(void) const
void setIsCurrentItem(bool isCurrentItem)
bool autoContinue(void) const
double param3(void) const
double param6(void) const
double param1(void) const
int sequenceNumber(void) const
double param4(void) const
void setSequenceNumber(int sequenceNumber)
double param2(void) const
The PlanManager class is the base class for the Mission, GeoFence and Rally Point managers....
QList< MissionItem * > _missionItems
Set of mission items on vehicle.
void resumeMissionUploadFail(void)
QList< int > _itemIndicesToRead
List of mission items which still need to be requested from vehicle.
int _lastMissionRequest
Index of item last requested by MISSION_REQUEST.
TransactionType_t _transactionInProgress
bool _checkForExpectedAck(AckType_t receivedAck)
void _handleMissionRequest(const mavlink_message_t &message)
void currentIndexChanged(int currentIndex)
void lastCurrentIndexChanged(int lastCurrentIndex)
void sendComplete(bool error)
void _handleMissionItem(const mavlink_message_t &message)
void resumeMissionReady(void)
void _clearAndDeleteWriteMissionItems(void)
QTimer * _ackTimeoutTimer
ErrorCode_t
Error codes returned in error signal.
@ AckTimeoutError
Timed out waiting for response from vehicle.
@ MaxRetryExceeded
Retry failed.
@ ProtocolError
Incorrect protocol sequence from vehicle.
@ RequestRangeError
Vehicle requested item out of range.
@ VehicleAckError
Vehicle returned error in ack.
int _missionItemCountToRead
Count of all mission items to read.
static constexpr int kTestAckTimeoutMs
Ack timeout used in unit tests (much shorter for faster tests)
void newMissionItemsAvailable(bool removeAllRequested)
MAV_MISSION_TYPE _planType
QString _missionResultToString(MAV_MISSION_RESULT result)
QString _lastMissionReqestString(MAV_MISSION_RESULT result)
static constexpr int _maxRetryCount
void _finishTransaction(bool success, bool apmGuidedItemWrite=false)
void _requestList(void)
Internal call to request list of mission items. May be called during a retry sequence.
void _writeMissionItemsWorker(void)
void _connectToMavlink(void)
static constexpr int _ackTimeoutMilliseconds
void _startAckTimeout(AckType_t ack)
void loadFromVehicle(void)
void _sendError(ErrorCode_t errorCode, const QString &errorMsg)
void removeAllComplete(bool error)
void writeMissionItems(const QList< MissionItem * > &missionItems)
QList< int > _itemIndicesToWrite
List of mission items which still need to be written to vehicle.
void _handleMissionAck(const mavlink_message_t &message)
void _removeAllWorker(void)
void _clearMissionItems(void)
bool inProgress(void) const
void inProgressChanged(bool inProgress)
QList< MissionItem * > _writeMissionItems
Set of mission items currently being written to vehicle.
void progressPctChanged(double progressPercentPct)
void _clearAndDeleteMissionItems(void)
@ AckMissionItem
MISSION_ITEM expected.
@ AckMissionRequest
MISSION_REQUEST is expected, or MISSION_ACK to end sequence.
@ AckMissionCount
MISSION_COUNT message expected.
@ AckMissionClearAll
MISSION_CLEAR_ALL sent, MISSION_ACK is expected.
@ AckNone
State machine is idle.
@ AckGuidedItem
MISSION_ACK expected in response to ArduPilot guided mode single item send.
QString _planTypeString(void)
static constexpr int _retryTimeoutMilliseconds
const QList< MissionItem * > & missionItems(void)
void _requestNextMissionItem(void)
void _writeMissionCount(void)
This begins the write sequence with the vehicle. This may be called during a retry.
QString _ackTypeToString(AckType_t ackType)
void _handleMissionCount(const mavlink_message_t &message)
void _disconnectFromMavlink(void)
void _readTransactionComplete(void)
WeakLinkInterfacePtr primaryLink() const
void _setHomePosition(QGeoCoordinate &homeCoord)
VehicleLinkManager * vehicleLinkManager()
FirmwarePlugin * firmwarePlugin()
Provides access to the Firmware Plugin for this Vehicle.
bool isOfflineEditingVehicle() const
bool sendMessageOnLinkThreadSafe(LinkInterface *link, mavlink_message_t message)
void mavlinkMessageReceived(const mavlink_message_t &message)