Commit ade4b924 authored by DonLakeFlyer's avatar DonLakeFlyer

Fix MISSION_CURRENT handling

Also fixed bug with ArduPilot guided waypoint write which would trash
existing mission.
parent ba940e91
...@@ -22,9 +22,10 @@ ...@@ -22,9 +22,10 @@
QGC_LOGGING_CATEGORY(MissionManagerLog, "MissionManagerLog") QGC_LOGGING_CATEGORY(MissionManagerLog, "MissionManagerLog")
MissionManager::MissionManager(Vehicle* vehicle) MissionManager::MissionManager(Vehicle* vehicle)
: PlanManager(vehicle, MAV_MISSION_TYPE_MISSION) : PlanManager (vehicle, MAV_MISSION_TYPE_MISSION)
, _cachedLastCurrentIndex (-1)
{ {
connect(_vehicle, &Vehicle::mavlinkMessageReceived, this, &MissionManager::_mavlinkMessageReceived);
} }
MissionManager::~MissionManager() MissionManager::~MissionManager()
...@@ -219,3 +220,54 @@ void MissionManager::generateResumeMission(int resumeIndex) ...@@ -219,3 +220,54 @@ void MissionManager::generateResumeMission(int resumeIndex)
resumeMission[i]->deleteLater(); resumeMission[i]->deleteLater();
} }
} }
/// Called when a new mavlink message for out vehicle is received
void MissionManager::_mavlinkMessageReceived(const mavlink_message_t& message)
{
switch (message.msgid) {
case MAVLINK_MSG_ID_MISSION_CURRENT:
_handleMissionCurrent(message);
break;
case MAVLINK_MSG_ID_HEARTBEAT:
_handleHeartbeat(message);
break;
}
}
void MissionManager::_handleMissionCurrent(const mavlink_message_t& message)
{
mavlink_mission_current_t missionCurrent;
mavlink_msg_mission_current_decode(&message, &missionCurrent);
if (missionCurrent.seq != _currentMissionIndex) {
qCDebug(MissionManagerLog) << "_handleMissionCurrent currentIndex:" << missionCurrent.seq;
_currentMissionIndex = missionCurrent.seq;
emit currentIndexChanged(_currentMissionIndex);
}
if (_currentMissionIndex != _lastCurrentIndex) {
// We have to be careful of an RTL sequence causing a change of index to the DO_LAND_START sequence. This also triggers
// a flight mode change away from mission flight mode. So we only update _lastCurrentIndex when the flight mode is mission.
// But we can run into problems where we may get the MISSION_CURRENT message for the RTL/DO_LAND_START sequenc change prior
// to the HEARTBEAT message which contains the flight mode change which will cause things to work incorrectly. To fix this
// We force the sequencing of HEARTBEAT following by MISSION_CURRENT by caching the possible _lastCurrentIndex update until
// the next HEARTBEAT comes through.
qCDebug(MissionManagerLog) << "_handleMissionCurrent caching _lastCurrentIndex for possible update:" << _currentMissionIndex;
_cachedLastCurrentIndex = _currentMissionIndex;
}
}
void MissionManager::_handleHeartbeat(const mavlink_message_t& message)
{
Q_UNUSED(message);
if (_cachedLastCurrentIndex != -1 && _vehicle->flightMode() == _vehicle->missionFlightMode()) {
qCDebug(MissionManagerLog) << "_handleHeartbeat updating lastCurrentIndex from cached value:" << _cachedLastCurrentIndex;
_lastCurrentIndex = _cachedLastCurrentIndex;
_cachedLastCurrentIndex = -1;
emit lastCurrentIndexChanged(_lastCurrentIndex);
}
}
...@@ -22,7 +22,13 @@ class MissionManager : public PlanManager ...@@ -22,7 +22,13 @@ class MissionManager : public PlanManager
public: public:
MissionManager(Vehicle* vehicle); MissionManager(Vehicle* vehicle);
~MissionManager(); ~MissionManager();
/// Current mission item as reported by MISSION_CURRENT
int currentIndex(void) const { return _currentMissionIndex; }
/// Last current mission item reported while in Mission flight mode
int lastCurrentIndex(void) const { return _lastCurrentIndex; }
/// Writes the specified set mission items to the vehicle as an ArduPilot guided mode mission item. /// Writes the specified set mission items to the vehicle as an ArduPilot guided mode mission item.
/// @param gotoCoord Coordinate to move to /// @param gotoCoord Coordinate to move to
/// @param altChangeOnly true: only altitude change, false: lat/lon/alt change /// @param altChangeOnly true: only altitude change, false: lat/lon/alt change
...@@ -31,6 +37,19 @@ public: ...@@ -31,6 +37,19 @@ public:
/// Generates a new mission which starts from the specified index. It will include all the CMD_DO items /// Generates a new mission which starts from the specified index. It will include all the CMD_DO items
/// from mission start to resumeIndex in the generate mission. /// from mission start to resumeIndex in the generate mission.
void generateResumeMission(int resumeIndex); void generateResumeMission(int resumeIndex);
signals:
void currentIndexChanged (int currentIndex);
void lastCurrentIndexChanged (int lastCurrentIndex);
private slots:
void _mavlinkMessageReceived(const mavlink_message_t& message);
private:
void _handleMissionCurrent(const mavlink_message_t& message);
void _handleHeartbeat(const mavlink_message_t& message);
int _cachedLastCurrentIndex;
}; };
#endif #endif
...@@ -634,6 +634,7 @@ void PlanManager::_handleMissionAck(const mavlink_message_t& message) ...@@ -634,6 +634,7 @@ void PlanManager::_handleMissionAck(const mavlink_message_t& message)
break; break;
} }
} }
/// Called when a new mavlink message for out vehicle is received /// Called when a new mavlink message for out vehicle is received
void PlanManager::_mavlinkMessageReceived(const mavlink_message_t& message) void PlanManager::_mavlinkMessageReceived(const mavlink_message_t& message)
{ {
...@@ -661,14 +662,6 @@ void PlanManager::_mavlinkMessageReceived(const mavlink_message_t& message) ...@@ -661,14 +662,6 @@ void PlanManager::_mavlinkMessageReceived(const mavlink_message_t& message)
case MAVLINK_MSG_ID_MISSION_ACK: case MAVLINK_MSG_ID_MISSION_ACK:
_handleMissionAck(message); _handleMissionAck(message);
break; break;
case MAVLINK_MSG_ID_MISSION_ITEM_REACHED:
// FIXME: NYI
break;
case MAVLINK_MSG_ID_MISSION_CURRENT:
_handleMissionCurrent(message);
break;
} }
} }
...@@ -800,7 +793,7 @@ QString PlanManager::_missionResultToString(MAV_MISSION_RESULT result) ...@@ -800,7 +793,7 @@ QString PlanManager::_missionResultToString(MAV_MISSION_RESULT result)
return resultString + lastRequestString; return resultString + lastRequestString;
} }
void PlanManager::_finishTransaction(bool success) void PlanManager::_finishTransaction(bool success, bool apmGuidedItemWrite)
{ {
emit progressPct(1); emit progressPct(1);
_disconnectFromMavlink(); _disconnectFromMavlink();
...@@ -826,22 +819,27 @@ void PlanManager::_finishTransaction(bool success) ...@@ -826,22 +819,27 @@ void PlanManager::_finishTransaction(bool success)
emit newMissionItemsAvailable(false); emit newMissionItemsAvailable(false);
break; break;
case TransactionWrite: case TransactionWrite:
if (success) { // No need to do anything for ArduPilot guided go to waypoint write
// Write succeeded, update internal list to be current if (!apmGuidedItemWrite) {
_currentMissionIndex = -1; if (success) {
_lastCurrentIndex = -1; // Write succeeded, update internal list to be current
emit currentIndexChanged(-1); if (_planType == MAV_MISSION_TYPE_MISSION) {
emit lastCurrentIndexChanged(-1); _currentMissionIndex = -1;
_clearAndDeleteMissionItems(); _lastCurrentIndex = -1;
for (int i=0; i<_writeMissionItems.count(); i++) { emit currentIndexChanged(-1);
_missionItems.append(_writeMissionItems[i]); emit lastCurrentIndexChanged(-1);
}
_clearAndDeleteMissionItems();
for (int i=0; i<_writeMissionItems.count(); i++) {
_missionItems.append(_writeMissionItems[i]);
}
_writeMissionItems.clear();
} else {
// Write failed, throw out the write list
_clearAndDeleteWriteMissionItems();
} }
_writeMissionItems.clear(); emit sendComplete(!success /* error */);
} else {
// Write failed, throw out the write list
_clearAndDeleteWriteMissionItems();
} }
emit sendComplete(!success /* error */);
break; break;
case TransactionRemoveAll: case TransactionRemoveAll:
emit removeAllComplete(!success /* error */); emit removeAllComplete(!success /* error */);
...@@ -865,25 +863,6 @@ bool PlanManager::inProgress(void) const ...@@ -865,25 +863,6 @@ bool PlanManager::inProgress(void) const
return _transactionInProgress != TransactionNone; return _transactionInProgress != TransactionNone;
} }
void PlanManager::_handleMissionCurrent(const mavlink_message_t& message)
{
mavlink_mission_current_t missionCurrent;
mavlink_msg_mission_current_decode(&message, &missionCurrent);
if (missionCurrent.seq != _currentMissionIndex) {
qCDebug(PlanManagerLog) << QStringLiteral("_handleMissionCurrent %1 currentIndex:").arg(_planTypeString()) << missionCurrent.seq;
_currentMissionIndex = missionCurrent.seq;
emit currentIndexChanged(_currentMissionIndex);
}
if (_vehicle->flightMode() == _vehicle->missionFlightMode() && _currentMissionIndex != _lastCurrentIndex) {
qCDebug(PlanManagerLog) << QStringLiteral("_handleMissionCurrent %1 lastCurrentIndex:").arg(_planTypeString()) << _currentMissionIndex;
_lastCurrentIndex = _currentMissionIndex;
emit lastCurrentIndexChanged(_lastCurrentIndex);
}
}
void PlanManager::_removeAllWorker(void) void PlanManager::_removeAllWorker(void)
{ {
mavlink_message_t message; mavlink_message_t message;
...@@ -915,10 +894,12 @@ void PlanManager::removeAll(void) ...@@ -915,10 +894,12 @@ void PlanManager::removeAll(void)
_clearAndDeleteMissionItems(); _clearAndDeleteMissionItems();
_currentMissionIndex = -1; if (_planType == MAV_MISSION_TYPE_MISSION) {
_lastCurrentIndex = -1; _currentMissionIndex = -1;
emit currentIndexChanged(-1); _lastCurrentIndex = -1;
emit lastCurrentIndexChanged(-1); emit currentIndexChanged(-1);
emit lastCurrentIndexChanged(-1);
}
_transactionInProgress = TransactionRemoveAll; _transactionInProgress = TransactionRemoveAll;
_retryCount = 0; _retryCount = 0;
......
...@@ -112,13 +112,12 @@ protected: ...@@ -112,13 +112,12 @@ protected:
void _handleMissionItem(const mavlink_message_t& message, bool missionItemInt); void _handleMissionItem(const mavlink_message_t& message, bool missionItemInt);
void _handleMissionRequest(const mavlink_message_t& message, bool missionItemInt); void _handleMissionRequest(const mavlink_message_t& message, bool missionItemInt);
void _handleMissionAck(const mavlink_message_t& message); void _handleMissionAck(const mavlink_message_t& message);
void _handleMissionCurrent(const mavlink_message_t& message);
void _requestNextMissionItem(void); void _requestNextMissionItem(void);
void _clearMissionItems(void); void _clearMissionItems(void);
void _sendError(ErrorCode_t errorCode, const QString& errorMsg); void _sendError(ErrorCode_t errorCode, const QString& errorMsg);
QString _ackTypeToString(AckType_t ackType); QString _ackTypeToString(AckType_t ackType);
QString _missionResultToString(MAV_MISSION_RESULT result); QString _missionResultToString(MAV_MISSION_RESULT result);
void _finishTransaction(bool success); void _finishTransaction(bool success, bool apmGuidedItemWrite = false);
void _requestList(void); void _requestList(void);
void _writeMissionCount(void); void _writeMissionCount(void);
void _writeMissionItemsWorker(void); void _writeMissionItemsWorker(void);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment