Commit 143bb616 authored by Don Gagne's avatar Don Gagne

Add Home Position Manager support to Mission Editor

Also:
- Remove unused code
parent 079d2fed
...@@ -40,24 +40,47 @@ ...@@ -40,24 +40,47 @@
IMPLEMENT_QGC_SINGLETON(HomePositionManager, HomePositionManager) IMPLEMENT_QGC_SINGLETON(HomePositionManager, HomePositionManager)
HomePositionManager::HomePositionManager(QObject* parent) : const char* HomePositionManager::_settingsGroup = "HomePositionManager";
QObject(parent), const char* HomePositionManager::_latitudeKey = "Latitude";
homeLat(47.3769), const char* HomePositionManager::_longitudeKey = "Longitude";
homeLon(8.549444), const char* HomePositionManager::_altitudeKey = "Altitude";
homeAlt(470.0),
homeFrame(MAV_FRAME_GLOBAL) HomePositionManager::HomePositionManager(QObject* parent)
: QObject(parent)
, homeLat(47.3769)
, homeLon(8.549444)
, homeAlt(470.0)
{ {
loadSettings(); _loadSettings();
} }
HomePositionManager::~HomePositionManager() HomePositionManager::~HomePositionManager()
{ {
storeSettings();
} }
void HomePositionManager::storeSettings() void HomePositionManager::_storeSettings(void)
{ {
QSettings settings; QSettings settings;
settings.remove(_settingsGroup);
settings.beginGroup(_settingsGroup);
for (int i=0; i<_homePositions.count(); i++) {
HomePosition* homePos = qobject_cast<HomePosition*>(_homePositions[i]);
qDebug() << "Saving" << homePos->name();
settings.beginGroup(homePos->name());
settings.setValue(_latitudeKey, homePos->coordinate().latitude());
settings.setValue(_longitudeKey, homePos->coordinate().longitude());
settings.setValue(_altitudeKey, homePos->coordinate().altitude());
settings.endGroup();
}
settings.endGroup();
// Deprecated settings for old editor
settings.beginGroup("QGC_UASMANAGER"); settings.beginGroup("QGC_UASMANAGER");
settings.setValue("HOMELAT", homeLat); settings.setValue("HOMELAT", homeLat);
settings.setValue("HOMELON", homeLon); settings.setValue("HOMELON", homeLon);
...@@ -65,9 +88,36 @@ void HomePositionManager::storeSettings() ...@@ -65,9 +88,36 @@ void HomePositionManager::storeSettings()
settings.endGroup(); settings.endGroup();
} }
void HomePositionManager::loadSettings() void HomePositionManager::_loadSettings(void)
{ {
QSettings settings; QSettings settings;
_homePositions.clear();
settings.beginGroup(_settingsGroup);
foreach(QString name, settings.childGroups()) {
QGeoCoordinate coordinate;
qDebug() << "Load setting" << name;
settings.beginGroup(name);
coordinate.setLatitude(settings.value(_latitudeKey).toDouble());
coordinate.setLongitude(settings.value(_longitudeKey).toDouble());
coordinate.setAltitude(settings.value(_altitudeKey).toDouble());
settings.endGroup();
_homePositions.append(new HomePosition(name, coordinate, this));
}
settings.endGroup();
if (_homePositions.count() == 0) {
_homePositions.append(new HomePosition("ETH Campus", QGeoCoordinate(47.3769, 8.549444, 470.0)));
}
// Deprecated settings for old editor
settings.beginGroup("QGC_UASMANAGER"); settings.beginGroup("QGC_UASMANAGER");
bool changed = setHomePosition(settings.value("HOMELAT", homeLat).toDouble(), bool changed = setHomePosition(settings.value("HOMELAT", homeLat).toDouble(),
settings.value("HOMELON", homeLon).toDouble(), settings.value("HOMELON", homeLon).toDouble(),
...@@ -97,9 +147,6 @@ bool HomePositionManager::setHomePosition(double lat, double lon, double alt) ...@@ -97,9 +147,6 @@ bool HomePositionManager::setHomePosition(double lat, double lon, double alt)
if (fabs(homeLon - lon) > 1e-7) changed = true; if (fabs(homeLon - lon) > 1e-7) changed = true;
if (fabs(homeAlt - alt) > 0.5f) changed = true; if (fabs(homeAlt - alt) > 0.5f) changed = true;
// Initialize conversion reference in any case
initReference(lat, lon, alt);
if (changed) if (changed)
{ {
homeLat = lat; homeLat = lat;
...@@ -125,75 +172,81 @@ bool HomePositionManager::setHomePositionAndNotify(double lat, double lon, doubl ...@@ -125,75 +172,81 @@ bool HomePositionManager::setHomePositionAndNotify(double lat, double lon, doubl
return changed; return changed;
} }
void HomePositionManager::initReference(const double & latitude, const double & longitude, const double & altitude) void HomePositionManager::updateHomePosition(const QString& name, const QGeoCoordinate& coordinate)
{ {
Eigen::Matrix3d R; HomePosition * homePos = NULL;
double s_long, s_lat, c_long, c_lat;
sincos(latitude * DEG2RAD, &s_lat, &c_lat);
sincos(longitude * DEG2RAD, &s_long, &c_long);
R(0, 0) = -s_long; for (int i=0; i<_homePositions.count(); i++) {
R(0, 1) = c_long; homePos = qobject_cast<HomePosition*>(_homePositions[i]);
R(0, 2) = 0; if (homePos->name() == name) {
break;
R(1, 0) = -s_lat * c_long; }
R(1, 1) = -s_lat * s_long; homePos = NULL;
R(1, 2) = c_lat; }
R(2, 0) = c_lat * c_long;
R(2, 1) = c_lat * s_long;
R(2, 2) = s_lat;
ecef_ref_orientation_ = Eigen::Quaterniond(R); if (homePos == NULL) {
HomePosition* homePos = new HomePosition(name, coordinate, this);
_homePositions.append(homePos);
} else {
homePos->setName(name);
homePos->setCoordinate(coordinate);
}
ecef_ref_point_ = wgs84ToEcef(latitude, longitude, altitude); _storeSettings();
} }
Eigen::Vector3d HomePositionManager::wgs84ToEcef(const double & latitude, const double & longitude, const double & altitude) void HomePositionManager::deleteHomePosition(const QString& name)
{ {
const double a = 6378137.0; // semi-major axis // Don't allow delete of last position
const double e_sq = 6.69437999014e-3; // first eccentricity squared if (_homePositions.count() == 1) {
return;
double s_long, s_lat, c_long, c_lat; }
sincos(latitude * DEG2RAD, &s_lat, &c_lat);
sincos(longitude * DEG2RAD, &s_long, &c_long);
const double N = a / sqrt(1 - e_sq * s_lat * s_lat); qDebug() << "Attempting delete" << name;
Eigen::Vector3d ecef; for (int i=0; i<_homePositions.count(); i++) {
if (qobject_cast<HomePosition*>(_homePositions[i])->name() == name) {
qDebug() << "Deleting" << name;
_homePositions.removeAt(i);
break;
}
}
ecef[0] = (N + altitude) * c_lat * c_long; _storeSettings();
ecef[1] = (N + altitude) * c_lat * s_long; }
ecef[2] = (N * (1 - e_sq) + altitude) * s_lat;
return ecef; HomePosition::HomePosition(const QString& name, const QGeoCoordinate& coordinate, QObject* parent)
: QObject(parent)
, _coordinate(coordinate)
{
setObjectName(name);
} }
Eigen::Vector3d HomePositionManager::ecefToEnu(const Eigen::Vector3d & ecef) HomePosition::~HomePosition()
{ {
return ecef_ref_orientation_ * (ecef - ecef_ref_point_);
} }
void HomePositionManager::wgs84ToEnu(const double& lat, const double& lon, const double& alt, double* east, double* north, double* up) QString HomePosition::name(void)
{ {
Eigen::Vector3d ecef = wgs84ToEcef(lat, lon, alt); return objectName();
Eigen::Vector3d enu = ecefToEnu(ecef);
*east = enu.x();
*north = enu.y();
*up = enu.z();
} }
void HomePositionManager::enuToWgs84(const double& x, const double& y, const double& z, double* lat, double* lon, double* alt) void HomePosition::setName(const QString& name)
{ {
*lat=homeLat+y/MEAN_EARTH_DIAMETER*360./PI; setObjectName(name);
*lon=homeLon+x/MEAN_EARTH_DIAMETER*360./PI/cos(homeLat*UMR); HomePositionManager::instance()->_storeSettings();
*alt=homeAlt+z; emit nameChanged(name);
} }
void HomePositionManager::nedToWgs84(const double& x, const double& y, const double& z, double* lat, double* lon, double* alt) QGeoCoordinate HomePosition::coordinate(void)
{ {
*lat=homeLat+x/MEAN_EARTH_DIAMETER*360./PI; return _coordinate;
*lon=homeLon+y/MEAN_EARTH_DIAMETER*360./PI/cos(homeLat*UMR);
*alt=homeAlt-z;
} }
void HomePosition::setCoordinate(const QGeoCoordinate& coordinate)
{
_coordinate = coordinate;
HomePositionManager::instance()->_storeSettings();
emit coordinateChanged(coordinate);
}
...@@ -21,21 +21,41 @@ This file is part of the QGROUNDCONTROL project ...@@ -21,21 +21,41 @@ This file is part of the QGROUNDCONTROL project
======================================================================*/ ======================================================================*/
#ifndef _UASMANAGER_H_ #ifndef HomePositionManager_H
#define _UASMANAGER_H_ #define HomePositionManager_H
#include "UASInterface.h" #include "QGCSingleton.h"
#include "QmlObjectListModel.h"
#include <QGeoCoordinate>
#include <QList> class HomePosition : public QObject
#include <QMutex> {
Q_OBJECT
#include <Eigen/Eigen> public:
HomePosition(const QString& name, const QGeoCoordinate& coordinate, QObject* parent = NULL);
~HomePosition();
#include "QGCGeo.h" Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
#include "QGCSingleton.h" Q_PROPERTY(QGeoCoordinate coordinate READ coordinate WRITE setCoordinate NOTIFY coordinateChanged)
// Property accessors
QString name(void);
void setName(const QString& name);
QGeoCoordinate coordinate(void);
void setCoordinate(const QGeoCoordinate& coordinate);
signals:
void nameChanged(const QString& name);
void coordinateChanged(const QGeoCoordinate& coordinate);
private:
QGeoCoordinate _coordinate;
};
/// Manages an offline home position as well as performance coordinate transformations
/// around a home position.
class HomePositionManager : public QObject class HomePositionManager : public QObject
{ {
Q_OBJECT Q_OBJECT
...@@ -43,6 +63,40 @@ class HomePositionManager : public QObject ...@@ -43,6 +63,40 @@ class HomePositionManager : public QObject
DECLARE_QGC_SINGLETON(HomePositionManager, HomePositionManager) DECLARE_QGC_SINGLETON(HomePositionManager, HomePositionManager)
public: public:
Q_PROPERTY(QmlObjectListModel* homePositions READ homePositions CONSTANT)
/// If name is not already a home position a new one will be added, otherwise the existing
/// home position will be updated
Q_INVOKABLE void updateHomePosition(const QString& name, const QGeoCoordinate& coordinate);
Q_INVOKABLE void deleteHomePosition(const QString& name);
// Property accesors
QmlObjectListModel* homePositions(void) { return &_homePositions; }
// Should only be called by HomePosition
void _storeSettings(void);
private:
/// @brief All access to HomePositionManager singleton is through HomePositionManager::instance
HomePositionManager(QObject* parent = NULL);
~HomePositionManager();
void _loadSettings(void);
QmlObjectListModel _homePositions;
static const char* _settingsGroup;
static const char* _latitudeKey;
static const char* _longitudeKey;
static const char* _altitudeKey;
// Everything below is deprecated and will be removed once old Map code is removed
public:
// Deprecated methods
/** @brief Get home position latitude */ /** @brief Get home position latitude */
double getHomeLatitude() const { double getHomeLatitude() const {
return homeLat; return homeLat;
...@@ -56,24 +110,10 @@ public: ...@@ -56,24 +110,10 @@ public:
return homeAlt; return homeAlt;
} }
/** @brief Get the home position coordinate frame */ public slots:
int getHomeFrame() const
{
return homeFrame;
}
/** @brief Convert WGS84 coordinates to earth centric frame */ // Deprecated methods
Eigen::Vector3d wgs84ToEcef(const double & latitude, const double & longitude, const double & altitude);
/** @brief Convert earth centric frame to EAST-NORTH-UP frame (x-y-z directions */
Eigen::Vector3d ecefToEnu(const Eigen::Vector3d & ecef);
/** @brief Convert WGS84 lat/lon coordinates to carthesian coordinates with home position as origin */
void wgs84ToEnu(const double& lat, const double& lon, const double& alt, double* east, double* north, double* up);
/** @brief Convert x,y,z coordinates to lat / lon / alt coordinates in east-north-up frame */
void enuToWgs84(const double& x, const double& y, const double& z, double* lat, double* lon, double* alt);
/** @brief Convert x,y,z coordinates to lat / lon / alt coordinates in north-east-down frame */
void nedToWgs84(const double& x, const double& y, const double& z, double* lat, double* lon, double* alt);
public slots:
/** @brief Set the current home position, but do not change it on the UAVs */ /** @brief Set the current home position, but do not change it on the UAVs */
bool setHomePosition(double lat, double lon, double alt); bool setHomePosition(double lat, double lon, double alt);
...@@ -81,11 +121,6 @@ public slots: ...@@ -81,11 +121,6 @@ public slots:
bool setHomePositionAndNotify(double lat, double lon, double alt); bool setHomePositionAndNotify(double lat, double lon, double alt);
/** @brief Load settings */
void loadSettings();
/** @brief Store settings */
void storeSettings();
signals: signals:
/** @brief Current home position changed */ /** @brief Current home position changed */
void homePositionChanged(double lat, double lon, double alt); void homePositionChanged(double lat, double lon, double alt);
...@@ -94,23 +129,6 @@ protected: ...@@ -94,23 +129,6 @@ protected:
double homeLat; double homeLat;
double homeLon; double homeLon;
double homeAlt; double homeAlt;
int homeFrame;
Eigen::Quaterniond ecef_ref_orientation_;
Eigen::Vector3d ecef_ref_point_;
void initReference(const double & latitude, const double & longitude, const double & altitude);
private:
/// @brief All access to HomePositionManager singleton is through HomePositionManager::instance
HomePositionManager(QObject* parent = NULL);
~HomePositionManager();
public:
/* Need to align struct pointer to prevent a memory assertion:
* See http://eigen.tuxfamily.org/dox-devel/TopicUnalignedArrayAssert.html
* for details
*/
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
}; };
#endif // _UASMANAGER_H_ #endif
This diff is collapsed.
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <QDebug> #include <QDebug>
const int QmlObjectListModel::ObjectRole = Qt::UserRole; const int QmlObjectListModel::ObjectRole = Qt::UserRole;
const int QmlObjectListModel::TextRole = Qt::UserRole + 1;
QmlObjectListModel::QmlObjectListModel(QObject* parent) QmlObjectListModel::QmlObjectListModel(QObject* parent)
: QAbstractListModel(parent) : QAbstractListModel(parent)
...@@ -60,6 +61,8 @@ QVariant QmlObjectListModel::data(const QModelIndex &index, int role) const ...@@ -60,6 +61,8 @@ QVariant QmlObjectListModel::data(const QModelIndex &index, int role) const
if (role == ObjectRole) { if (role == ObjectRole) {
return QVariant::fromValue(_objectList[index.row()]); return QVariant::fromValue(_objectList[index.row()]);
} else if (role == TextRole) {
return QVariant::fromValue(_objectList[index.row()]->objectName());
} else { } else {
return QVariant(); return QVariant();
} }
...@@ -70,6 +73,7 @@ QHash<int, QByteArray> QmlObjectListModel::roleNames(void) const ...@@ -70,6 +73,7 @@ QHash<int, QByteArray> QmlObjectListModel::roleNames(void) const
QHash<int, QByteArray> hash; QHash<int, QByteArray> hash;
hash[ObjectRole] = "object"; hash[ObjectRole] = "object";
hash[TextRole] = "text";
return hash; return hash;
} }
......
...@@ -65,6 +65,7 @@ private: ...@@ -65,6 +65,7 @@ private:
QList<QObject*> _objectList; QList<QObject*> _objectList;
static const int ObjectRole; static const int ObjectRole;
static const int TextRole;
}; };
#endif #endif
...@@ -38,6 +38,7 @@ This file is part of the QGROUNDCONTROL project ...@@ -38,6 +38,7 @@ This file is part of the QGROUNDCONTROL project
#include <QMessageBox> #include <QMessageBox>
#include <iostream> #include <iostream>
#include <Eigen/Eigen>
#include "QGCFlightGearLink.h" #include "QGCFlightGearLink.h"
#include "QGC.h" #include "QGC.h"
......
...@@ -33,10 +33,13 @@ This file is part of the QGROUNDCONTROL project ...@@ -33,10 +33,13 @@ This file is part of the QGROUNDCONTROL project
#include <QDebug> #include <QDebug>
#include <QMutexLocker> #include <QMutexLocker>
#include <QNetworkInterface> #include <QNetworkInterface>
#include <QHostInfo>
#include <iostream> #include <iostream>
#include <Eigen/Eigen>
#include "QGCXPlaneLink.h" #include "QGCXPlaneLink.h"
#include "QGC.h" #include "QGC.h"
#include <QHostInfo>
#include "UAS.h" #include "UAS.h"
#include "UASInterface.h" #include "UASInterface.h"
#include "QGCMessageBox.h" #include "QGCMessageBox.h"
......
...@@ -2784,9 +2784,8 @@ void UAS::home() ...@@ -2784,9 +2784,8 @@ void UAS::home()
double latitude = HomePositionManager::instance()->getHomeLatitude(); double latitude = HomePositionManager::instance()->getHomeLatitude();
double longitude = HomePositionManager::instance()->getHomeLongitude(); double longitude = HomePositionManager::instance()->getHomeLongitude();
double altitude = HomePositionManager::instance()->getHomeAltitude(); double altitude = HomePositionManager::instance()->getHomeAltitude();
int frame = HomePositionManager::instance()->getHomeFrame();
mavlink_msg_command_long_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, uasId, MAV_COMP_ID_ALL, MAV_CMD_OVERRIDE_GOTO, 1, MAV_GOTO_DO_CONTINUE, MAV_GOTO_HOLD_AT_CURRENT_POSITION, frame, 0, latitude, longitude, altitude); mavlink_msg_command_long_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, uasId, MAV_COMP_ID_ALL, MAV_CMD_OVERRIDE_GOTO, 1, MAV_GOTO_DO_CONTINUE, MAV_GOTO_HOLD_AT_CURRENT_POSITION, MAV_FRAME_GLOBAL, 0, latitude, longitude, altitude);
_vehicle->sendMessage(msg); _vehicle->sendMessage(msg);
} }
......
...@@ -609,7 +609,6 @@ void MainWindow::closeEvent(QCloseEvent *event) ...@@ -609,7 +609,6 @@ void MainWindow::closeEvent(QCloseEvent *event)
_storeCurrentViewState(); _storeCurrentViewState();
storeSettings(); storeSettings();
HomePositionManager::instance()->storeSettings();
event->accept(); event->accept();
} }
......
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