10 changed files with 262 additions and 288 deletions
@ -0,0 +1,96 @@
@@ -0,0 +1,96 @@
|
||||
/****************************************************************************
|
||||
* |
||||
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
|
||||
* |
||||
* QGroundControl is licensed according to the terms in the file |
||||
* COPYING.md in the root of the source code directory. |
||||
* |
||||
****************************************************************************/ |
||||
|
||||
#include "LandingComplexItem.h" |
||||
#include "JsonHelper.h" |
||||
#include "MissionController.h" |
||||
#include "QGCGeo.h" |
||||
#include "SimpleMissionItem.h" |
||||
#include "PlanMasterController.h" |
||||
#include "FlightPathSegment.h" |
||||
|
||||
#include <QPolygonF> |
||||
|
||||
QGC_LOGGING_CATEGORY(LandingComplexItemLog, "LandingComplexItemLog") |
||||
|
||||
LandingComplexItem::LandingComplexItem(PlanMasterController* masterController, bool flyView, QObject* parent) |
||||
: ComplexMissionItem (masterController, flyView, parent) |
||||
{ |
||||
_isIncomplete = false; |
||||
|
||||
// The follow is used to compress multiple recalc calls in a row to into a single call.
|
||||
connect(this, &LandingComplexItem::_updateFlightPathSegmentsSignal, this, &LandingComplexItem::_updateFlightPathSegmentsDontCallDirectly, Qt::QueuedConnection); |
||||
qgcApp()->addCompressedSignal(QMetaMethod::fromSignal(&LandingComplexItem::_updateFlightPathSegmentsSignal)); |
||||
} |
||||
|
||||
double LandingComplexItem::complexDistance(void) const |
||||
{ |
||||
return loiterCoordinate().distanceTo(loiterTangentCoordinate()) + loiterTangentCoordinate().distanceTo(landingCoordinate()); |
||||
} |
||||
|
||||
// Never call this method directly. If you want to update the flight segments you emit _updateFlightPathSegmentsSignal()
|
||||
void LandingComplexItem::_updateFlightPathSegmentsDontCallDirectly(void) |
||||
{ |
||||
if (_cTerrainCollisionSegments != 0) { |
||||
_cTerrainCollisionSegments = 0; |
||||
emit terrainCollisionChanged(false); |
||||
} |
||||
|
||||
_flightPathSegments.beginReset(); |
||||
_flightPathSegments.clearAndDeleteContents(); |
||||
_appendFlightPathSegment(loiterCoordinate(), amslEntryAlt(), loiterTangentCoordinate(), amslEntryAlt()); |
||||
_appendFlightPathSegment(loiterTangentCoordinate(), amslEntryAlt(), landingCoordinate(), amslEntryAlt()); |
||||
_appendFlightPathSegment(landingCoordinate(), amslEntryAlt(), landingCoordinate(), amslExitAlt()); |
||||
_flightPathSegments.endReset(); |
||||
|
||||
if (_cTerrainCollisionSegments != 0) { |
||||
emit terrainCollisionChanged(true); |
||||
} |
||||
|
||||
_masterController->missionController()->recalcTerrainProfile(); |
||||
} |
||||
|
||||
void LandingComplexItem::setLandingCoordinate(const QGeoCoordinate& coordinate) |
||||
{ |
||||
if (coordinate != _landingCoordinate) { |
||||
_landingCoordinate = coordinate; |
||||
if (_landingCoordSet) { |
||||
emit exitCoordinateChanged(coordinate); |
||||
emit landingCoordinateChanged(coordinate); |
||||
} else { |
||||
_ignoreRecalcSignals = true; |
||||
emit exitCoordinateChanged(coordinate); |
||||
emit landingCoordinateChanged(coordinate); |
||||
_ignoreRecalcSignals = false; |
||||
_landingCoordSet = true; |
||||
_recalcFromHeadingAndDistanceChange(); |
||||
emit landingCoordSetChanged(true); |
||||
} |
||||
} |
||||
} |
||||
|
||||
void LandingComplexItem::setLoiterCoordinate(const QGeoCoordinate& coordinate) |
||||
{ |
||||
if (coordinate != _loiterCoordinate) { |
||||
_loiterCoordinate = coordinate; |
||||
emit coordinateChanged(coordinate); |
||||
emit loiterCoordinateChanged(coordinate); |
||||
} |
||||
} |
||||
|
||||
QPointF LandingComplexItem::_rotatePoint(const QPointF& point, const QPointF& origin, double angle) |
||||
{ |
||||
QPointF rotated; |
||||
double radians = (M_PI / 180.0) * angle; |
||||
|
||||
rotated.setX(((point.x() - origin.x()) * cos(radians)) - ((point.y() - origin.y()) * sin(radians)) + origin.x()); |
||||
rotated.setY(((point.x() - origin.x()) * sin(radians)) + ((point.y() - origin.y()) * cos(radians)) + origin.y()); |
||||
|
||||
return rotated; |
||||
} |
@ -0,0 +1,86 @@
@@ -0,0 +1,86 @@
|
||||
/****************************************************************************
|
||||
* |
||||
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
|
||||
* |
||||
* QGroundControl is licensed according to the terms in the file |
||||
* COPYING.md in the root of the source code directory. |
||||
* |
||||
****************************************************************************/ |
||||
|
||||
#pragma once |
||||
|
||||
#include "ComplexMissionItem.h" |
||||
#include "MissionItem.h" |
||||
#include "Fact.h" |
||||
#include "QGCLoggingCategory.h" |
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(LandingComplexItemLog) |
||||
|
||||
class PlanMasterController; |
||||
|
||||
// Base class for landing patterns complex items.
|
||||
class LandingComplexItem : public ComplexMissionItem |
||||
{ |
||||
Q_OBJECT |
||||
|
||||
public: |
||||
LandingComplexItem(PlanMasterController* masterController, bool flyView, QObject* parent); |
||||
|
||||
Q_PROPERTY(Fact* loiterAltitude READ loiterAltitude CONSTANT) |
||||
Q_PROPERTY(Fact* loiterRadius READ loiterRadius CONSTANT) |
||||
Q_PROPERTY(Fact* landingAltitude READ landingAltitude CONSTANT) |
||||
Q_PROPERTY(Fact* landingHeading READ landingHeading CONSTANT) |
||||
Q_PROPERTY(Fact* landingDistance READ landingDistance CONSTANT) |
||||
Q_PROPERTY(bool loiterClockwise MEMBER _loiterClockwise NOTIFY loiterClockwiseChanged) |
||||
Q_PROPERTY(bool altitudesAreRelative MEMBER _altitudesAreRelative NOTIFY altitudesAreRelativeChanged) |
||||
Q_PROPERTY(Fact* stopTakingPhotos READ stopTakingPhotos CONSTANT) |
||||
Q_PROPERTY(Fact* stopTakingVideo READ stopTakingVideo CONSTANT) |
||||
Q_PROPERTY(QGeoCoordinate loiterCoordinate READ loiterCoordinate WRITE setLoiterCoordinate NOTIFY loiterCoordinateChanged) |
||||
Q_PROPERTY(QGeoCoordinate loiterTangentCoordinate READ loiterTangentCoordinate NOTIFY loiterTangentCoordinateChanged) |
||||
Q_PROPERTY(QGeoCoordinate landingCoordinate READ landingCoordinate WRITE setLandingCoordinate NOTIFY landingCoordinateChanged) |
||||
Q_PROPERTY(bool landingCoordSet MEMBER _landingCoordSet NOTIFY landingCoordSetChanged) |
||||
|
||||
virtual Fact* loiterAltitude (void) = 0; |
||||
virtual Fact* loiterRadius (void) = 0; |
||||
virtual Fact* landingAltitude (void) = 0; |
||||
virtual Fact* landingDistance (void) = 0; |
||||
virtual Fact* landingHeading (void) = 0; |
||||
virtual Fact* stopTakingPhotos (void) = 0; |
||||
virtual Fact* stopTakingVideo (void) = 0; |
||||
|
||||
QGeoCoordinate landingCoordinate (void) const { return _landingCoordinate; } |
||||
QGeoCoordinate loiterCoordinate (void) const { return _loiterCoordinate; } |
||||
QGeoCoordinate loiterTangentCoordinate (void) const { return _loiterTangentCoordinate; } |
||||
|
||||
void setLandingCoordinate (const QGeoCoordinate& coordinate); |
||||
void setLoiterCoordinate (const QGeoCoordinate& coordinate); |
||||
|
||||
// Overrides from ComplexMissionItem
|
||||
double complexDistance(void) const final; |
||||
|
||||
signals: |
||||
void loiterCoordinateChanged (QGeoCoordinate coordinate); |
||||
void loiterTangentCoordinateChanged (QGeoCoordinate coordinate); |
||||
void landingCoordinateChanged (QGeoCoordinate coordinate); |
||||
void landingCoordSetChanged (bool landingCoordSet); |
||||
void loiterClockwiseChanged (bool loiterClockwise); |
||||
void altitudesAreRelativeChanged (bool altitudesAreRelative); |
||||
void _updateFlightPathSegmentsSignal(void); |
||||
|
||||
protected slots: |
||||
virtual void _recalcFromHeadingAndDistanceChange(void) = 0; |
||||
void _updateFlightPathSegmentsDontCallDirectly(void); |
||||
|
||||
protected: |
||||
QPointF _rotatePoint(const QPointF& point, const QPointF& origin, double angle); |
||||
|
||||
int _sequenceNumber = 0; |
||||
bool _dirty = false; |
||||
QGeoCoordinate _loiterCoordinate; |
||||
QGeoCoordinate _loiterTangentCoordinate; |
||||
QGeoCoordinate _landingCoordinate; |
||||
bool _landingCoordSet = false; |
||||
bool _ignoreRecalcSignals = false; |
||||
bool _loiterClockwise = true; |
||||
bool _altitudesAreRelative = true; |
||||
}; |
Loading…
Reference in new issue