|
|
|
@ -40,24 +40,47 @@
@@ -40,24 +40,47 @@
|
|
|
|
|
|
|
|
|
|
IMPLEMENT_QGC_SINGLETON(HomePositionManager, HomePositionManager) |
|
|
|
|
|
|
|
|
|
HomePositionManager::HomePositionManager(QObject* parent) : |
|
|
|
|
QObject(parent), |
|
|
|
|
homeLat(47.3769), |
|
|
|
|
homeLon(8.549444), |
|
|
|
|
homeAlt(470.0), |
|
|
|
|
homeFrame(MAV_FRAME_GLOBAL) |
|
|
|
|
const char* HomePositionManager::_settingsGroup = "HomePositionManager"; |
|
|
|
|
const char* HomePositionManager::_latitudeKey = "Latitude"; |
|
|
|
|
const char* HomePositionManager::_longitudeKey = "Longitude"; |
|
|
|
|
const char* HomePositionManager::_altitudeKey = "Altitude"; |
|
|
|
|
|
|
|
|
|
HomePositionManager::HomePositionManager(QObject* parent) |
|
|
|
|
: QObject(parent) |
|
|
|
|
, homeLat(47.3769) |
|
|
|
|
, homeLon(8.549444) |
|
|
|
|
, homeAlt(470.0) |
|
|
|
|
{ |
|
|
|
|
loadSettings(); |
|
|
|
|
_loadSettings(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
HomePositionManager::~HomePositionManager() |
|
|
|
|
{ |
|
|
|
|
storeSettings(); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void HomePositionManager::storeSettings() |
|
|
|
|
void HomePositionManager::_storeSettings(void) |
|
|
|
|
{ |
|
|
|
|
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.setValue("HOMELAT", homeLat); |
|
|
|
|
settings.setValue("HOMELON", homeLon); |
|
|
|
@ -65,9 +88,36 @@ void HomePositionManager::storeSettings()
@@ -65,9 +88,36 @@ void HomePositionManager::storeSettings()
|
|
|
|
|
settings.endGroup(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void HomePositionManager::loadSettings() |
|
|
|
|
void HomePositionManager::_loadSettings(void) |
|
|
|
|
{ |
|
|
|
|
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"); |
|
|
|
|
bool changed = setHomePosition(settings.value("HOMELAT", homeLat).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(homeAlt - alt) > 0.5f) changed = true; |
|
|
|
|
|
|
|
|
|
// Initialize conversion reference in any case
|
|
|
|
|
initReference(lat, lon, alt); |
|
|
|
|
|
|
|
|
|
if (changed) |
|
|
|
|
{ |
|
|
|
|
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; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void HomePositionManager::initReference(const double & latitude, const double & longitude, const double & altitude) |
|
|
|
|
void HomePositionManager::updateHomePosition(const QString& name, const QGeoCoordinate& coordinate) |
|
|
|
|
{ |
|
|
|
|
Eigen::Matrix3d R; |
|
|
|
|
double s_long, s_lat, c_long, c_lat; |
|
|
|
|
sincos(latitude * DEG2RAD, &s_lat, &c_lat); |
|
|
|
|
sincos(longitude * DEG2RAD, &s_long, &c_long); |
|
|
|
|
HomePosition * homePos = NULL; |
|
|
|
|
|
|
|
|
|
R(0, 0) = -s_long; |
|
|
|
|
R(0, 1) = c_long; |
|
|
|
|
R(0, 2) = 0; |
|
|
|
|
|
|
|
|
|
R(1, 0) = -s_lat * c_long; |
|
|
|
|
R(1, 1) = -s_lat * s_long; |
|
|
|
|
R(1, 2) = c_lat; |
|
|
|
|
|
|
|
|
|
R(2, 0) = c_lat * c_long; |
|
|
|
|
R(2, 1) = c_lat * s_long; |
|
|
|
|
R(2, 2) = s_lat; |
|
|
|
|
for (int i=0; i<_homePositions.count(); i++) { |
|
|
|
|
homePos = qobject_cast<HomePosition*>(_homePositions[i]); |
|
|
|
|
if (homePos->name() == name) { |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
homePos = NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
const double e_sq = 6.69437999014e-3; // first eccentricity squared
|
|
|
|
|
|
|
|
|
|
double s_long, s_lat, c_long, c_lat; |
|
|
|
|
sincos(latitude * DEG2RAD, &s_lat, &c_lat); |
|
|
|
|
sincos(longitude * DEG2RAD, &s_long, &c_long); |
|
|
|
|
// Don't allow delete of last position
|
|
|
|
|
if (_homePositions.count() == 1) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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; |
|
|
|
|
ecef[1] = (N + altitude) * c_lat * s_long; |
|
|
|
|
ecef[2] = (N * (1 - e_sq) + altitude) * s_lat; |
|
|
|
|
_storeSettings(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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); |
|
|
|
|
Eigen::Vector3d enu = ecefToEnu(ecef); |
|
|
|
|
*east = enu.x(); |
|
|
|
|
*north = enu.y(); |
|
|
|
|
*up = enu.z(); |
|
|
|
|
return objectName(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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; |
|
|
|
|
*lon=homeLon+x/MEAN_EARTH_DIAMETER*360./PI/cos(homeLat*UMR); |
|
|
|
|
*alt=homeAlt+z; |
|
|
|
|
setObjectName(name); |
|
|
|
|
HomePositionManager::instance()->_storeSettings(); |
|
|
|
|
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; |
|
|
|
|
*lon=homeLon+y/MEAN_EARTH_DIAMETER*360./PI/cos(homeLat*UMR); |
|
|
|
|
*alt=homeAlt-z; |
|
|
|
|
return _coordinate; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void HomePosition::setCoordinate(const QGeoCoordinate& coordinate) |
|
|
|
|
{ |
|
|
|
|
_coordinate = coordinate; |
|
|
|
|
HomePositionManager::instance()->_storeSettings(); |
|
|
|
|
emit coordinateChanged(coordinate); |
|
|
|
|
} |
|
|
|
|