10 changed files with 262 additions and 288 deletions
@ -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 @@ |
|||||||
|
/****************************************************************************
|
||||||
|
* |
||||||
|
* (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