29 #include "homelocation.h"
31 #include <QDomDocument>
32 #include <QMainWindow>
33 #include <QMessageBox>
44 : QAbstractTableModel(parent)
52 modeNames.insert(Waypoint::MODE_VECTOR, tr(
"Vector"));
53 modeNames.insert(Waypoint::MODE_CIRCLELEFT, tr(
"Circle Left"));
54 modeNames.insert(Waypoint::MODE_CIRCLERIGHT, tr(
"Circle Right"));
55 modeNames.insert(Waypoint::MODE_ENDPOINT, tr(
"Endpoint"));
56 modeNames.insert(Waypoint::MODE_CIRCLEPOSITIONLEFT, tr(
"Circle Position Left"));
57 modeNames.insert(Waypoint::MODE_CIRCLEPOSITIONRIGHT, tr(
"Circle Position Right"));
58 modeNames.insert(Waypoint::MODE_LAND, tr(
"Land"));
64 return dataStorage.length();
83 if (role == Qt::DisplayRole || role == Qt::EditRole || role == Qt::UserRole) {
85 if (!index.isValid() || index.row() > dataStorage.length() - 1)
86 return QVariant::Invalid;
99 switch (index.column()) {
128 return QVariant::Invalid;
140 if (role == Qt::DisplayRole) {
141 if (orientation == Qt::Vertical) {
142 return QString::number(section + 1);
143 }
else if (orientation == Qt::Horizontal) {
146 return QString(
"Description");
148 return QString(
"Latitude");
150 return QString(
"Longitude");
152 return QString(
"Altitude");
154 return QString(
"Relative North");
156 return QString(
"Relative East");
158 return QString(
"Relative Down");
160 return QString(
"Velocity");
162 return QString(
"Mode");
164 return QString(
"Mode parameters");
166 return QString(
"Locked");
168 return QVariant::Invalid;
173 return QAbstractTableModel::headerData(section, orientation, role);
185 if (index.isValid() && role == Qt::EditRole) {
193 QModelIndex otherIndex;
194 switch (index.column()) {
202 emit dataChanged(otherIndex, otherIndex);
208 emit dataChanged(otherIndex, otherIndex);
214 emit dataChanged(otherIndex, otherIndex);
218 NED.North = value.toDouble();
222 emit dataChanged(otherIndex, otherIndex);
225 NED = getNED(index.row());
226 NED.East = value.toDouble();
230 emit dataChanged(otherIndex, otherIndex);
233 NED = getNED(index.row());
234 NED.Down = value.toDouble();
238 emit dataChanged(otherIndex, otherIndex);
244 row->
mode = value.toInt();
250 row->
locked = value.toBool();
258 emit dataChanged(index, index);
272 return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;
277 return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
279 return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;
291 beginInsertRows(QModelIndex(), row, row + count - 1);
292 for (
int x = 0;
x < count; ++
x) {
309 data->
mode = Waypoint::MODE_VECTOR;
313 dataStorage.insert(row, data);
331 beginRemoveRows(QModelIndex(), row, row + count - 1);
332 for (
int x = 0;
x < count; ++
x) {
333 delete dataStorage.at(row);
334 dataStorage.removeAt(row);
352 QFile
file(fileName);
354 if (!file.open(QIODevice::WriteOnly)) {
356 tr(
"Unable to open file"), file.errorString());
359 QDataStream
out(&file);
360 QDomDocument doc(
"PathPlan");
362 QDomElement root = doc.createElement(
"pathplan");
363 doc.appendChild(root);
368 QDomElement homeloc = doc.createElement(
"homelocation");
369 root.appendChild(homeloc);
370 getHomeLocation(homeLLA);
371 QDomElement field = doc.createElement(
"field");
372 field.setAttribute(
"value", homeLLA[0]);
373 field.setAttribute(
"name",
"latitude");
374 homeloc.appendChild(field);
376 field = doc.createElement(
"field");
377 field.setAttribute(
"value", homeLLA[1]);
378 field.setAttribute(
"name",
"longitude");
379 homeloc.appendChild(field);
381 field = doc.createElement(
"field");
382 field.setAttribute(
"value", homeLLA[2]);
383 field.setAttribute(
"name",
"altitude");
384 homeloc.appendChild(field);
386 QDomElement wpts = doc.createElement(
"waypoints");
387 root.appendChild(wpts);
395 QDomElement waypoint = doc.createElement(
"waypoint");
396 waypoint.setAttribute(
"number", dataStorage.indexOf(obj));
397 wpts.appendChild(waypoint);
398 QDomElement field = doc.createElement(
"field");
400 field.setAttribute(
"name",
"description");
401 waypoint.appendChild(field);
403 field = doc.createElement(
"field");
404 field.setAttribute(
"value", NED[0]);
405 field.setAttribute(
"name",
"north");
406 waypoint.appendChild(field);
408 field = doc.createElement(
"field");
409 field.setAttribute(
"value", NED[1]);
410 field.setAttribute(
"name",
"east");
411 waypoint.appendChild(field);
413 field = doc.createElement(
"field");
414 field.setAttribute(
"value", NED[2]);
415 field.setAttribute(
"name",
"down");
416 waypoint.appendChild(field);
418 field = doc.createElement(
"field");
419 field.setAttribute(
"value", obj->
velocity);
420 field.setAttribute(
"name",
"velocity");
421 waypoint.appendChild(field);
423 field = doc.createElement(
"field");
424 field.setAttribute(
"value", obj->
mode);
425 field.setAttribute(
"name",
"mode");
426 waypoint.appendChild(field);
428 field = doc.createElement(
"field");
430 field.setAttribute(
"name",
"mode_params");
431 waypoint.appendChild(field);
433 field = doc.createElement(
"field");
434 field.setAttribute(
"value", obj->
locked);
435 field.setAttribute(
"name",
"is_locked");
436 waypoint.appendChild(field);
438 file.write(doc.toString().toLatin1());
443 void FlightDataModel::showErrorDialog(
const char *title,
const char *message)
446 msgBox.setText(tr(title));
447 msgBox.setInformativeText(tr(message));
448 msgBox.setStandardButtons(QMessageBox::Ok);
480 case Waypoint::MODE_CIRCLELEFT:
481 case Waypoint::MODE_CIRCLERIGHT:
482 row->
mode = Waypoint::MODE_VECTOR;
484 showErrorDialog(
"Waypoint corrected",
485 "First waypoint may not be the endpoint of an arc");
495 sqrt(pow(thisNED.North - prevNED.North, 2) + pow(thisNED.East - prevNED.East, 2));
497 if (distance > 600) {
506 setNED(row, thisNED);
509 showErrorDialog(
"Waypoint corrected",
"Over-long leg shortened.");
515 case Waypoint::MODE_CIRCLELEFT:
516 case Waypoint::MODE_CIRCLERIGHT:
520 showErrorDialog(
"Waypoint corrected",
"Radius of circle increased to minimum");
526 case Waypoint::MODE_CIRCLEPOSITIONLEFT:
527 case Waypoint::MODE_CIRCLEPOSITIONRIGHT:
531 showErrorDialog(
"Waypoint corrected",
"Radius of circle increased to minimum");
537 showErrorDialog(
"Waypoint corrected",
"Radius of circle decreased to maximum");
552 QModelIndex leftIndex, rightIndex;
557 emit dataChanged(leftIndex, rightIndex);
573 QFile
file(fileName);
574 if (!file.open(QIODevice::ReadOnly)) {
575 showErrorDialog(
"Unable to open file",
"Unable to open file");
579 QDomDocument doc(
"PathPlan");
580 QByteArray array = file.readAll();
585 if (!doc.setContent(array, &error)) {
586 showErrorDialog(
"File Parsing Failure",
"This file is not a correct XML file");
590 QDomElement root = doc.documentElement();
594 if (root.isNull() || root.tagName() !=
"pathplan") {
595 showErrorDialog(
"Wrong file contents",
"This is not a valid flight plan file");
602 QDomNodeList hlist = root.elementsByTagName(
"homelocation");
603 if (hlist.length() != 1) {
604 showErrorDialog(
"Wrong file contents",
"File format is incorrect (missing home location)");
608 QDomNode homelocField = hlist.at(0).firstChild();
609 while (!homelocField.isNull()) {
610 QDomElement field = homelocField.toElement();
611 if (field.tagName() ==
"field") {
612 if (field.attribute(
"name") ==
"latitude") {
613 HomeLLA[0] = field.attribute(
"value").toDouble();
614 }
else if (field.attribute(
"name") ==
"longitude") {
615 HomeLLA[1] = field.attribute(
"value").toDouble();
616 }
else if (field.attribute(
"name") ==
"altitude") {
617 HomeLLA[2] = field.attribute(
"value").toDouble();
620 homelocField = homelocField.nextSibling();
626 if (!setHomeLocation(HomeLLA)) {
627 showErrorDialog(
"Home location error",
"Home location coordinates invalid");
631 hlist = root.elementsByTagName(
"waypoints");
632 if (hlist.length() != 1) {
633 showErrorDialog(
"Wrong file contents",
"File format is incorrect (missing waypoints)");
635 QDomNode node = hlist.at(0).firstChild();
636 while (!node.isNull()) {
637 QDomElement
e = node.toElement();
638 if (e.tagName() ==
"waypoint") {
639 QDomNode fieldNode = e.firstChild();
644 while (!fieldNode.isNull()) {
645 QDomElement field = fieldNode.toElement();
646 if (field.tagName() ==
"field") {
647 if (field.attribute(
"name") ==
"down") {
648 wpNED[2] = field.attribute(
"value").toDouble();
650 }
else if (field.attribute(
"name") ==
"description") {
653 }
else if (field.attribute(
"name") ==
"north") {
654 wpNED[0] = field.attribute(
"value").toDouble();
656 }
else if (field.attribute(
"name") ==
"east") {
657 wpNED[1] = field.attribute(
"value").toDouble();
659 }
else if (field.attribute(
"name") ==
"velocity") {
660 data->
velocity = field.attribute(
"value").toFloat();
662 }
else if (field.attribute(
"name") ==
"mode") {
663 data->
mode = field.attribute(
"value").toInt();
665 }
else if (field.attribute(
"name") ==
"mode_params") {
666 data->
mode_params = field.attribute(
"value").toFloat();
668 }
else if (field.attribute(
"name") ==
"is_locked") {
669 data->
locked = field.attribute(
"value").toInt();
673 fieldNode = fieldNode.nextSibling();
679 showErrorDialog(
"Waypoint error",
"Waypoint coordinates invalid");
687 beginInsertRows(QModelIndex(), dataStorage.length(), dataStorage.length());
688 dataStorage.append(data);
691 node = node.nextSibling();
703 bool FlightDataModel::getHomeLocation(
double *homeLLA)
const
710 HomeLocation *home = HomeLocation::GetInstance(objMngr);
714 HomeLocation::DataFields homeLocation = home->getData();
715 homeLLA[0] = homeLocation.Latitude / 1e7;
716 homeLLA[1] = homeLocation.Longitude / 1e7;
717 homeLLA[2] = homeLocation.Altitude;
728 bool FlightDataModel::setHomeLocation(
double *homeLLA)
735 HomeLocation *home = HomeLocation::GetInstance(objMngr);
740 if (homeLLA[0] < -90 || homeLLA[0] > 90 || homeLLA[1] < -180 || homeLLA[1] > 180)
743 HomeLocation::DataFields homeLocation = home->getData();
744 homeLocation.Latitude = homeLLA[0] * 1e7;
745 homeLocation.Longitude = homeLLA[1] * 1e7;
746 homeLocation.Altitude = homeLLA[2];
748 home->setData(homeLocation);
757 double LLA[3] = { row->latPosition, row->lngPosition, row->altitude };
759 getHomeLocation(homeLLA);
763 NED.North = f_NED[0];
786 double f_NED[3] = { NED.North, NED.East, NED.Down };
788 getHomeLocation(homeLLA);
808 return setNED(row, NED);
823 for (
int j = 0; j < newModel->
columnCount(); j++) {
825 setData(index(
i, j), newModel->
data(newModel->index(
i, j), Qt::UserRole));
bool insertRows(int row, int count, const QModelIndex &parent=QModelIndex())
FlightDataModel::insertRows Create a new waypoint.
double lngPosition
Longitude of the waypoint.
FlightDataModel(QObject *parent)
Initialize an empty flight plan.
int mode
Navigation mode for this waypoint.
double altitude
Altitude of the waypoint (m above ellipsoid)
static QMap< int, QString > modeNames
Core plugin system that manages the plugins, their life cycle and their registered objects...
axis equal end function NED
Qt::ItemFlags flags(const QModelIndex &index) const
FlightDataModel::flags Tell QT MVC which flags are supported for items.
float velocity
Velocity associated with this waypoint.
void LLA2NED_HomeLLA(double LLA[3], double homeLLA[3], double NED[3])
double latPosition
Latitude of the waypoint.
bool writeToFile(QString filename)
FlightDataModel::writeToFile Write the waypoints to an xml file.
int rowCount(const QModelIndex &parent=QModelIndex()) const
Return the number of waypoints.
QString wpDescription
Description for the waypoint.
void readFromFile(QString fileName)
FlightDataModel::readFromFile Read into the model from a flight plan xml file.
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex())
FlightDataModel::removeRows Remove waypoints from the model.
static ICore * instance()
bool replaceData(FlightDataModel *newModel)
Replace a model data with another model.
int columnCount(const QModelIndex &parent=QModelIndex()) const
Return the number of fields in the model.
int NED2LLA_HomeLLA(double homeLLA[3], double NED[3], double LLA[3])
The PathPlanData struct is the internal representation of the waypoints. Notice this is in absolute t...
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole)
FlightDataModel::setData Set the data at a given location.
QVariant headerData(int section, Qt::Orientation orientation, int role) const
FlightDataModel::headerData Get the names of the columns.
void pauseValidation(bool pausing)
Prevent validation/correction of data.
void fixupValidationErrors()
else error('Your technical computing program does not support file choosers.Please input the file name in the argument. ') end elseif nargin >0 logfile
bool locked
Lock a waypoint.
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const
FlightDataModel::data Fetch the data from the model.
float mode_params
Optional parameters associated with this waypoint.