Newer
Older
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009-2012 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/**
* @file
* @brief Implementation of the waypoint protocol handler
*
* @author Petri Tanskanen <mavteam@student.ethz.ch>
*
*/
#include "UASWaypointManager.h"
#include "UAS.h"
#include "mavlink_types.h"
#include "UASManager.h"
#define PROTOCOL_TIMEOUT_MS 2000 ///< maximum time to wait for pending messages until timeout
#define PROTOCOL_DELAY_MS 20 ///< minimum delay between sent messages
#define PROTOCOL_MAX_RETRIES 5 ///< maximum number of send retries (after timeout)
Michael Carpenter
committed
const float UASWaypointManager::defaultAltitudeHomeOffset = 30.0f;
UASWaypointManager::UASWaypointManager(UAS* _uas)
: uas(_uas),
current_retries(0),
current_wp_id(0),
current_count(0),
current_state(WP_IDLE),
current_partner_systemid(0),
current_partner_compid(0),
currentWaypointEditable(),
Franz
committed
protocol_timer(this),
_updateWPlist_timer(this)
_offlineEditingModeMessage = tr("You are in offline editing mode. Make sure to save your mission to a file before connecting to a system - you will need to load the file into the system, the offline list will be cleared on connect.");
uasid = uas->getUASID();
connect(&protocol_timer, SIGNAL(timeout()), this, SLOT(timeout()));
connect(uas, SIGNAL(localPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(handleLocalPositionChanged(UASInterface*,double,double,double,quint64)));
connect(uas, SIGNAL(globalPositionChanged(UASInterface*,double,double,double,double,quint64)), this, SLOT(handleGlobalPositionChanged(UASInterface*,double,double,double,double,quint64)));
// We signal to ourselves here so that tiemrs are started and stopped on correct thread
connect(this, SIGNAL(_startProtocolTimer(void)), this, SLOT(_startProtocolTimerOnThisThread(void)));
connect(this, SIGNAL(_stopProtocolTimer(void)), this, SLOT(_stopProtocolTimerOnThisThread(void)));
Franz
committed
_updateWPlist_timer.setInterval(1500);
_updateWPlist_timer.setSingleShot(true);
connect(&_updateWPlist_timer, SIGNAL(timeout()), this, SLOT(_updateWPonTimer()));
protocol_timer.start(PROTOCOL_TIMEOUT_MS);
current_retries--;
emit updateStatusString(tr("Timeout, retrying (retries left: %1)").arg(current_retries));
sendWaypointRequestList();
} else if (current_state == WP_GETLIST_GETWPS) {
sendWaypointRequest(current_wp_id);
} else if (current_state == WP_SENDLIST) {
sendWaypointCount();
} else if (current_state == WP_SENDLIST_SENDWPS) {
sendWaypoint(current_wp_id);
} else if (current_state == WP_CLEARLIST) {
sendWaypointClearAll();
} else if (current_state == WP_SETCURRENT) {
sendWaypointSetCurrent(current_wp_id);
}
protocol_timer.stop();
emit updateStatusString("Operation timed out.");
current_state = WP_IDLE;
current_count = 0;
current_wp_id = 0;
}
void UASWaypointManager::handleLocalPositionChanged(UASInterface* mav, double x, double y, double z, quint64 time)
{
Q_UNUSED(mav);
Q_UNUSED(time);
if (waypointsEditable.count() > 0 && !currentWaypointEditable.isNull() && (currentWaypointEditable->getFrame() == MAV_FRAME_LOCAL_NED || currentWaypointEditable->getFrame() == MAV_FRAME_LOCAL_ENU))
double xdiff = x-currentWaypointEditable->getX();
double ydiff = y-currentWaypointEditable->getY();
double zdiff = z-currentWaypointEditable->getZ();
double dist = sqrt(xdiff*xdiff + ydiff*ydiff + zdiff*zdiff);
emit waypointDistanceChanged(dist);
}
}
void UASWaypointManager::handleGlobalPositionChanged(UASInterface* mav, double lat, double lon, double altAMSL, double altWGS84, quint64 time)
Lorenz Meier
committed
Q_UNUSED(mav);
Q_UNUSED(time);
Q_UNUSED(altAMSL);
Q_UNUSED(altWGS84);
Q_UNUSED(lon);
Q_UNUSED(lat);
if (waypointsEditable.count() > 0 && !currentWaypointEditable.isNull() && (currentWaypointEditable->getFrame() == MAV_FRAME_GLOBAL || currentWaypointEditable->getFrame() == MAV_FRAME_GLOBAL_RELATIVE_ALT))
Lorenz Meier
committed
{
// TODO FIXME Calculate distance
double dist = 0;
emit waypointDistanceChanged(dist);
}
void UASWaypointManager::handleWaypointCount(quint8 systemId, quint8 compId, quint16 count)
{
if (current_state == WP_GETLIST && systemId == current_partner_systemid) {
emit _startProtocolTimer(); // Start timer on correct thread
current_retries = PROTOCOL_MAX_RETRIES;
//Clear the old edit-list before receiving the new one
if (read_to_edit == true){
while(waypointsEditable.count()>0) {
Waypoint *t = waypointsEditable[0];
delete t;
}
emit waypointEditableListChanged();
}
current_count = count;
current_wp_id = 0;
current_state = WP_GETLIST_GETWPS;
sendWaypointRequest(current_wp_id);
emit _stopProtocolTimer(); // Stop the time on our thread
QTime time = QTime::currentTime();
emit updateStatusString(tr("Done. (updated at %1)").arg(time.toString()));
current_state = WP_IDLE;
current_count = 0;
current_wp_id = 0;
Franz
committed
if (current_state != WP_GETLIST_GETWPS && systemId == current_partner_systemid)
{
qDebug("Requesting new waypoints. Propably changed onboard.");
if (!_updateWPlist_timer.isActive())
{
current_state = WP_IDLE;
_updateWPlist_timer.start();
}
}
else
{
qDebug("Rejecting waypoint count message, check mismatch: current_state: %d == %d, system id %d == %d, comp id %d == %d", current_state, WP_GETLIST, current_partner_systemid, systemId, current_partner_compid, compId);
}
}
void UASWaypointManager::handleWaypoint(quint8 systemId, quint8 compId, mavlink_mission_item_t *wp)
if (systemId == current_partner_systemid && current_state == WP_GETLIST_GETWPS && wp->seq == current_wp_id) {
emit _startProtocolTimer(); // Start timer on our thread
current_retries = PROTOCOL_MAX_RETRIES;
Waypoint *lwp_vo = new Waypoint(
NULL,
wp->seq, wp->x,
wp->y,
wp->z,
wp->param1,
wp->param2,
wp->param3,
wp->param4,
wp->autocontinue,
wp->current,
(MAV_FRAME) wp->frame,
(MAV_CMD) wp->command);
Waypoint *lwp_ed = new Waypoint(
NULL,
wp->seq,
wp->x,
wp->y,
wp->z,
wp->param1,
wp->param2,
wp->param3,
wp->param4,
wp->autocontinue,
wp->current,
(MAV_FRAME) wp->frame,
(MAV_CMD) wp->command);
addWaypointEditable(lwp_ed, false);
if (wp->current == 1) currentWaypointEditable = lwp_ed;
}
if(current_wp_id < current_count) {
sendWaypointRequest(current_wp_id);
sendWaypointAck(0);
current_state = WP_IDLE;
current_count = 0;
current_wp_id = 0;
emit _stopProtocolTimer(); // Stop timer on our thread
emit updateStatusString(tr("Done. (updated at %1)").arg(time.toString()));
emit updateStatusString(tr("Waypoint ID mismatch, rejecting waypoint"));
} else if (systemId == current_partner_systemid
&& wp->seq < waypointsViewOnly.size() && waypointsViewOnly[wp->seq]->getAction()) {
// accept single sent waypoints because they can contain updates about remaining DO_JUMP repetitions
// but only update view only side
Waypoint *lwp_vo = new Waypoint(
NULL,
wp->seq,
wp->x,
wp->y,
wp->z,
wp->param1,
wp->param2,
wp->param3,
wp->param4,
wp->autocontinue,
wp->current,
(MAV_FRAME) wp->frame,
(MAV_CMD) wp->command);
waypointsViewOnly.replace(wp->seq, lwp_vo);
emit waypointViewOnlyListChanged();
emit waypointViewOnlyListChanged(uasid);
Bryant Mairs
committed
qDebug("Rejecting waypoint message, check mismatch: current_state: %d == %d, system id %d == %d, comp id %d == %d", current_state, WP_GETLIST_GETWPS, current_partner_systemid, systemId, current_partner_compid, compId);
void UASWaypointManager::handleWaypointAck(quint8 systemId, quint8 compId, mavlink_mission_ack_t *wpa)
if (systemId != current_partner_systemid) {
return;
}
// Check if the current partner component ID is generic. If it is, we might need to update
if (current_partner_compid == MAV_COMP_ID_MISSIONPLANNER) {
current_partner_compid = compId;
}
if (compId == current_partner_compid || compId == MAV_COMP_ID_ALL) {
if((current_state == WP_SENDLIST || current_state == WP_SENDLIST_SENDWPS) && (current_wp_id == waypoint_buffer.count()-1 && wpa->type == 0)) {
//all waypoints sent and ack received
emit _stopProtocolTimer(); // Stop timer on our thread
current_state = WP_IDLE;
readWaypoints(false); //Update "Onboard Waypoints"-tab immediately after the waypoint list has been sent.
QTime time = QTime::currentTime();
emit updateStatusString(tr("Done. (updated at %1)").arg(time.toString()));
} else if((current_state == WP_SENDLIST || current_state == WP_SENDLIST_SENDWPS) && wpa->type != 0) {
//give up transmitting if a WP is rejected
Bryant Mairs
committed
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
switch (wpa->type)
{
case MAV_MISSION_UNSUPPORTED_FRAME:
emit updateStatusString(tr("ERROR: Coordinate frame unsupported."));
break;
case MAV_MISSION_UNSUPPORTED:
emit updateStatusString(tr("ERROR: Unsupported command."));
break;
case MAV_MISSION_NO_SPACE:
emit updateStatusString(tr("ERROR: Mission count exceeds storage."));
break;
case MAV_MISSION_INVALID:
case MAV_MISSION_INVALID_PARAM1:
case MAV_MISSION_INVALID_PARAM2:
case MAV_MISSION_INVALID_PARAM3:
case MAV_MISSION_INVALID_PARAM4:
case MAV_MISSION_INVALID_PARAM5_X:
case MAV_MISSION_INVALID_PARAM6_Y:
case MAV_MISSION_INVALID_PARAM7:
emit updateStatusString(tr("ERROR: A specified parameter was invalid."));
break;
case MAV_MISSION_INVALID_SEQUENCE:
emit updateStatusString(tr("ERROR: Mission received out of sequence."));
break;
case MAV_MISSION_DENIED:
emit updateStatusString(tr("ERROR: UAS not accepting missions."));
break;
case MAV_MISSION_ERROR:
default:
emit updateStatusString(tr("ERROR: Unspecified error"));
break;
emit _stopProtocolTimer(); // Stop timer on our thread
current_state = WP_IDLE;
} else if(current_state == WP_CLEARLIST) {
emit _stopProtocolTimer(); // Stop timer on our thread
current_state = WP_IDLE;
QTime time = QTime::currentTime();
emit updateStatusString(tr("Done. (updated at %1)").arg(time.toString()));
void UASWaypointManager::handleWaypointRequest(quint8 systemId, quint8 compId, mavlink_mission_request_t *wpr)
if (systemId == current_partner_systemid && ((current_state == WP_SENDLIST && wpr->seq == 0) || (current_state == WP_SENDLIST_SENDWPS && (wpr->seq == current_wp_id || wpr->seq == current_wp_id + 1)))) {
emit _startProtocolTimer(); // Start timer on our thread
current_retries = PROTOCOL_MAX_RETRIES;
if (wpr->seq < waypoint_buffer.count()) {
current_state = WP_SENDLIST_SENDWPS;
current_wp_id = wpr->seq;
sendWaypoint(current_wp_id);
Bryant Mairs
committed
qDebug("Rejecting waypoint request message, check mismatch: current_state: %d == %d, system id %d == %d, comp id %d == %d", current_state, WP_SENDLIST_SENDWPS, current_partner_systemid, systemId, current_partner_compid, compId);
void UASWaypointManager::handleWaypointReached(quint8 systemId, quint8 compId, mavlink_mission_item_reached_t *wpr)
if (systemId == uasid) {
emit updateStatusString(tr("Reached waypoint %1").arg(wpr->seq));
void UASWaypointManager::handleWaypointCurrent(quint8 systemId, quint8 compId, mavlink_mission_current_t *wpc)
Lorenz Meier
committed
Q_UNUSED(compId);
if (systemId == uasid) {
if (current_state == WP_SETCURRENT) {
emit _stopProtocolTimer(); // Stop timer on our thread
current_state = WP_IDLE;
// update the local main storage
if (wpc->seq < waypointsViewOnly.size()) {
for(int i = 0; i < waypointsViewOnly.size(); i++) {
if (waypointsViewOnly[i]->getId() == wpc->seq) {
waypointsViewOnly[i]->setCurrent(true);
}
}
}
emit updateStatusString(tr("New current waypoint %1").arg(wpc->seq));
//emit update to UI widgets
emit currentWaypointChanged(wpc->seq);
pixhawk
committed
void UASWaypointManager::notifyOfChangeEditable(Waypoint* wp)
pixhawk
committed
{
// If only one waypoint was changed, emit only WP signal
emit waypointEditableChanged(uasid, wp);
pixhawk
committed
emit waypointEditableListChanged();
emit waypointEditableListChanged(uasid);
pixhawk
committed
}
void UASWaypointManager::notifyOfChangeViewOnly(Waypoint* wp)
{
if (wp != NULL) {
emit waypointViewOnlyChanged(uasid, wp);
} else {
emit waypointViewOnlyListChanged();
emit waypointViewOnlyListChanged(uasid);
}
}
pixhawk
committed
int UASWaypointManager::setCurrentWaypoint(quint16 seq)
//send change to UAS - important to note: if the transmission fails, we have inconsistencies
emit _startProtocolTimer(); // Start timer on our thread
current_retries = PROTOCOL_MAX_RETRIES;
current_state = WP_SETCURRENT;
current_wp_id = seq;
current_partner_systemid = uasid;
current_partner_compid = MAV_COMP_ID_MISSIONPLANNER;
sendWaypointSetCurrent(current_wp_id);
return 0;
}
}
return -1;
}
int UASWaypointManager::setCurrentEditable(quint16 seq)
{
if (seq < waypointsEditable.count()) {
if(current_state == WP_IDLE) {
//update local main storage
for (int i = 0; i < waypointsEditable.count(); i++) {
if (waypointsEditable[i]->getId() == seq) {
waypointsEditable[i]->setCurrent(true);
} else {
waypointsEditable[i]->setCurrent(false);
}
}
return 0;
}
}
return -1;
}
void UASWaypointManager::addWaypointViewOnly(Waypoint *wp)
{
if (wp)
{
waypointsViewOnly.insert(waypointsViewOnly.size(), wp);
connect(wp, SIGNAL(changed(Waypoint*)), this, SLOT(notifyOfChangeViewOnly(Waypoint*)));
emit waypointViewOnlyListChanged();
emit waypointViewOnlyListChanged(uasid);
* @warning Make sure the waypoint stays valid for the whole application lifecycle!
* @param enforceFirstActive Enforces that the first waypoint is set as active
* @see createWaypoint() is more suitable for most use cases
pixhawk
committed
void UASWaypointManager::addWaypointEditable(Waypoint *wp, bool enforceFirstActive)
// Check if this is the first waypoint in an offline list
if (waypointsEditable.count() == 0 && uas == NULL) {
QGCMessageBox::critical(tr("Waypoint Manager"), _offlineEditingModeMessage);
}
wp->setId(waypointsEditable.count());
if (enforceFirstActive && waypointsEditable.count() == 0)
{
wp->setCurrent(true);
waypointsEditable.insert(waypointsEditable.count(), wp);
pixhawk
committed
connect(wp, SIGNAL(changed(Waypoint*)), this, SLOT(notifyOfChangeEditable(Waypoint*)));
pixhawk
committed
emit waypointEditableListChanged();
emit waypointEditableListChanged(uasid);
/**
* @param enforceFirstActive Enforces that the first waypoint is set as active
*/
Waypoint* UASWaypointManager::createWaypoint(bool enforceFirstActive)
{
// Check if this is the first waypoint in an offline list
if (waypointsEditable.count() == 0 && uas == NULL) {
QGCMessageBox::critical(tr("Waypoint Manager"), _offlineEditingModeMessage);
}
wp->setId(waypointsEditable.count());
wp->setFrame((MAV_FRAME)getFrameRecommendation());
wp->setAltitude(getAltitudeRecommendation());
wp->setAcceptanceRadius(getAcceptanceRadiusRecommendation());
if (enforceFirstActive && waypointsEditable.count() == 0)
{
wp->setCurrent(true);
waypointsEditable.append(wp);
pixhawk
committed
connect(wp, SIGNAL(changed(Waypoint*)), this, SLOT(notifyOfChangeEditable(Waypoint*)));
pixhawk
committed
emit waypointEditableListChanged();
emit waypointEditableListChanged(uasid);
int UASWaypointManager::removeWaypoint(quint16 seq)
if (seq < waypointsEditable.count())
pixhawk
committed
if (t->getCurrent() == true) //trying to remove the current waypoint
{
if (seq+1 < waypointsEditable.count()) // setting the next waypoint as current
pixhawk
committed
{
waypointsEditable[seq+1]->setCurrent(true);
}
else if (seq-1 >= 0) // if deleting the last on the list, then setting the previous waypoint as current
pixhawk
committed
{
waypointsEditable[seq-1]->setCurrent(true);
}
}
t = NULL;
for(int i = seq; i < waypointsEditable.count(); i++)
pixhawk
committed
emit waypointEditableListChanged();
emit waypointEditableListChanged(uasid);
return 0;
}
return -1;
}
void UASWaypointManager::moveWaypoint(quint16 cur_seq, quint16 new_seq)
if (cur_seq != new_seq && cur_seq < waypointsEditable.count() && new_seq < waypointsEditable.count())
for (int i = cur_seq; i < new_seq; i++)
{
waypointsEditable[i]->setId(i);
}
else
{
for (int i = cur_seq; i > new_seq; i--)
{
waypointsEditable[i]->setId(i);
waypointsEditable[new_seq]->setId(new_seq);
pixhawk
committed
emit waypointEditableListChanged();
emit waypointEditableListChanged(uasid);
}
}
void UASWaypointManager::saveWaypoints(const QString &saveFile)
{
QFile file(saveFile);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
return;
QTextStream out(&file);
//write the waypoint list version to the first line for compatibility check
out << "QGC WPL 120\r\n";
for (int i = 0; i < waypointsEditable.count(); i++)
waypointsEditable[i]->setId(i);
waypointsEditable[i]->save(out);
}
file.close();
}
void UASWaypointManager::loadWaypoints(const QString &loadFile)
{
QFile file(loadFile);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
while(waypointsEditable.count()>0) {
delete t;
}
QTextStream in(&file);
const QStringList &version = in.readLine().split(" ");
if (!(version.size() == 3 && version[0] == "QGC" && version[1] == "WPL" && version[2] == "120"))
emit updateStatusString(tr("The waypoint file is not compatible with the current version of QGroundControl."));
}
else
{
while (!in.atEnd())
{
Waypoint *t = new Waypoint();
if(t->load(in))
{
//Use the existing function to add waypoints to the map instead of doing it manually
//Indeed, we should connect our waypoints to the map in order to synchronize them
//t->setId(waypointsEditable.count());
// waypointsEditable.insert(waypointsEditable.count(), t);
addWaypointEditable(t, false);
emit updateStatusString(tr("The waypoint file is corrupted. Load operation only partly succesful."));
break;
}
file.close();
pixhawk
committed
emit waypointEditableListChanged();
emit waypointEditableListChanged(uasid);
}
void UASWaypointManager::clearWaypointList()
if (current_state == WP_IDLE)
emit _startProtocolTimer(); // Start timer on our thread
current_retries = PROTOCOL_MAX_RETRIES;
current_state = WP_CLEARLIST;
current_wp_id = 0;
current_partner_systemid = uasid;
current_partner_compid = MAV_COMP_ID_MISSIONPLANNER;
sendWaypointClearAll();
const QList<Waypoint *> UASWaypointManager::getGlobalFrameWaypointList()
{
// TODO Keep this global frame list up to date
// with complete waypoint list
// instead of filtering on each request
{
if (wp->getFrame() == MAV_FRAME_GLOBAL || wp->getFrame() == MAV_FRAME_GLOBAL_RELATIVE_ALT)
{
wps.append(wp);
}
}
return wps;
}
const QList<Waypoint *> UASWaypointManager::getGlobalFrameAndNavTypeWaypointList()
{
// TODO Keep this global frame list up to date
// with complete waypoint list
// instead of filtering on each request
{
if ((wp->getFrame() == MAV_FRAME_GLOBAL || wp->getFrame() == MAV_FRAME_GLOBAL_RELATIVE_ALT) && wp->isNavigationType())
{
const QList<Waypoint *> UASWaypointManager::getNavTypeWaypointList()
{
// TODO Keep this global frame list up to date
// with complete waypoint list
// instead of filtering on each request
{
if (wp->isNavigationType())
{
int UASWaypointManager::getIndexOf(Waypoint* wp)
{
int UASWaypointManager::getGlobalFrameIndexOf(Waypoint* wp)
{
// counting only those in global frame
int i = 0;
if (p->getFrame() == MAV_FRAME_GLOBAL || wp->getFrame() == MAV_FRAME_GLOBAL_RELATIVE_ALT)
{
if (p == wp)
{
return i;
}
i++;
}
}
return -1;
}
int UASWaypointManager::getGlobalFrameAndNavTypeIndexOf(Waypoint* wp)
{
if ((p->getFrame() == MAV_FRAME_GLOBAL || wp->getFrame() == MAV_FRAME_GLOBAL_RELATIVE_ALT) && p->isNavigationType())
{
if (p->isNavigationType())
{
if (p == wp)
{
int UASWaypointManager::getGlobalFrameCount()
{
// counting only those in global frame
int i = 0;
if (p->getFrame() == MAV_FRAME_GLOBAL || p->getFrame() == MAV_FRAME_GLOBAL_RELATIVE_ALT)
{
i++;
}
}
return i;
}
if ((p->getFrame() == MAV_FRAME_GLOBAL || p->getFrame() == MAV_FRAME_GLOBAL_RELATIVE_ALT) && p->isNavigationType())
if (p->isNavigationType()) {
i++;
}
}
return i;
}
int UASWaypointManager::getLocalFrameCount()
{
// counting only those in global frame
int i = 0;
if (p->getFrame() == MAV_FRAME_LOCAL_NED || p->getFrame() == MAV_FRAME_LOCAL_ENU)
i++;
}
}
return i;
}
int UASWaypointManager::getLocalFrameIndexOf(Waypoint* wp)
{
// counting only those in local frame
int i = 0;
{
if (p->getFrame() == MAV_FRAME_LOCAL_NED || p->getFrame() == MAV_FRAME_LOCAL_ENU)
{
if (p == wp)
{
return i;
}
i++;
}
}
return -1;
}
int UASWaypointManager::getMissionFrameIndexOf(Waypoint* wp)
{
// counting only those in mission frame
int i = 0;
if (p->getFrame() == MAV_FRAME_MISSION)
{
if (p == wp)
{
return i;
}
i++;
}
}
return -1;
}
/**
* @param readToEdit If true, incoming waypoints will be copied both to "edit"-tab and "view"-tab. Otherwise, only to "view"-tab.
*/
void UASWaypointManager::readWaypoints(bool readToEdit)
//Clear the old view-list before receiving the new one
while(waypointsViewOnly.size()>0) {
Waypoint *t = waypointsViewOnly[0];
delete t;
}
emit waypointViewOnlyListChanged();
/* THIS PART WAS MOVED TO handleWaypointCount. THE EDIT-LIST SHOULD NOT BE CLEARED UNLESS THERE IS A RESPONSE FROM UAV.
//Clear the old edit-list before receiving the new one
if (read_to_edit == true){
while(waypointsEditable.count()>0) {
Waypoint *t = waypointsEditable[0];
waypointsEditable.remove(0);
delete t;
}
emit waypointEditableListChanged();
// We are signalling ourselves here so that the timer gets started on the right thread
emit _startProtocolTimer();
current_retries = PROTOCOL_MAX_RETRIES;
current_partner_systemid = uasid;
current_partner_compid = MAV_COMP_ID_MISSIONPLANNER;
sendWaypointRequestList();
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
bool UASWaypointManager::guidedModeSupported()
{
return (uas->getAutopilotType() == MAV_AUTOPILOT_ARDUPILOTMEGA);
}
void UASWaypointManager::goToWaypoint(Waypoint *wp)
{
//Don't try to send a guided mode message to an AP that does not support it.
if (uas->getAutopilotType() == MAV_AUTOPILOT_ARDUPILOTMEGA)
{
mavlink_mission_item_t mission;
memset(&mission, 0, sizeof(mavlink_mission_item_t)); //initialize with zeros
//const Waypoint *cur_s = waypointsEditable.at(i);
mission.autocontinue = 0;
mission.current = 2; //2 for guided mode
mission.param1 = wp->getParam1();
mission.param2 = wp->getParam2();
mission.param3 = wp->getParam3();
mission.param4 = wp->getParam4();
mission.frame = wp->getFrame();
mission.command = wp->getAction();
mission.seq = 0; // don't read out the sequence number of the waypoint class
mission.x = wp->getX();
mission.y = wp->getY();
mission.z = wp->getZ();
mavlink_message_t message;
mission.target_system = uasid;
mission.target_component = MAV_COMP_ID_MISSIONPLANNER;
mavlink_msg_mission_item_encode(uas->mavlink->getSystemId(), uas->mavlink->getComponentId(), &message, &mission);
uas->sendMessage(message);
QGC::SLEEP::msleep(PROTOCOL_DELAY_MS);
}
}
void UASWaypointManager::writeWaypoints()
emit _startProtocolTimer(); // Start timer on our thread
current_retries = PROTOCOL_MAX_RETRIES;
current_state = WP_SENDLIST;
current_wp_id = 0;
current_partner_systemid = uasid;
current_partner_compid = MAV_COMP_ID_MISSIONPLANNER;
// Why not replace with waypoint_buffer.clear() ?
// because this will lead to memory leaks, the waypoint-structs
// have to be deleted, clear() would only delete the pointers.
delete waypoint_buffer.back();
waypoint_buffer.pop_back();
}
bool noCurrent = true;
for (int i=0; i < current_count; i++) {
waypoint_buffer.push_back(new mavlink_mission_item_t);
mavlink_mission_item_t *cur_d = waypoint_buffer.back();
memset(cur_d, 0, sizeof(mavlink_mission_item_t)); //initialize with zeros