@ -40,7 +40,7 @@ FixedWingLandingComplexItem::FixedWingLandingComplexItem(Vehicle* vehicle, QObje
@@ -40,7 +40,7 @@ FixedWingLandingComplexItem::FixedWingLandingComplexItem(Vehicle* vehicle, QObje
, _dirty ( false )
, _landingCoordSet ( false )
, _ignoreRecalcSignals ( false )
, _loiterToL andDistanceFact ( 0 , _loiterToLandDistanceName , FactMetaData : : valueTypeDouble )
, _landing DistanceFact ( 0 , _loiterToLandDistanceName , FactMetaData : : valueTypeDouble )
, _loiterAltitudeFact ( 0 , _loiterAltitudeName , FactMetaData : : valueTypeDouble )
, _loiterRadiusFact ( 0 , _loiterRadiusName , FactMetaData : : valueTypeDouble )
, _landingHeadingFact ( 0 , _landingHeadingName , FactMetaData : : valueTypeDouble )
@ -55,24 +55,29 @@ FixedWingLandingComplexItem::FixedWingLandingComplexItem(Vehicle* vehicle, QObje
@@ -55,24 +55,29 @@ FixedWingLandingComplexItem::FixedWingLandingComplexItem(Vehicle* vehicle, QObje
_metaDataMap = FactMetaData : : createMapFromJsonFile ( QStringLiteral ( " :/json/FWLandingPattern.FactMetaData.json " ) , NULL /* metaDataParent */ ) ;
}
_loiterToL andDistanceFact . setMetaData ( _metaDataMap [ _loiterToLandDistanceName ] ) ;
_landing DistanceFact . setMetaData ( _metaDataMap [ _loiterToLandDistanceName ] ) ;
_loiterAltitudeFact . setMetaData ( _metaDataMap [ _loiterAltitudeName ] ) ;
_loiterRadiusFact . setMetaData ( _metaDataMap [ _loiterRadiusName ] ) ;
_landingHeadingFact . setMetaData ( _metaDataMap [ _landingHeadingName ] ) ;
_landingAltitudeFact . setMetaData ( _metaDataMap [ _landingAltitudeName ] ) ;
_loiterToL andDistanceFact . setRawValue ( _loiterToL andDistanceFact . rawDefaultValue ( ) ) ;
_landing DistanceFact . setRawValue ( _landing DistanceFact . rawDefaultValue ( ) ) ;
_loiterAltitudeFact . setRawValue ( _loiterAltitudeFact . rawDefaultValue ( ) ) ;
_loiterRadiusFact . setRawValue ( _loiterRadiusFact . rawDefaultValue ( ) ) ;
_landingHeadingFact . setRawValue ( _landingHeadingFact . rawDefaultValue ( ) ) ;
_landingAltitudeFact . setRawValue ( _landingAltitudeFact . rawDefaultValue ( ) ) ;
connect ( & _loiterAltitudeFact , & Fact : : valueChanged , this , & FixedWingLandingComplexItem : : _updateLoiterCoodinateAltitudeFromFact ) ;
connect ( & _landingAltitudeFact , & Fact : : valueChanged , this , & FixedWingLandingComplexItem : : _updateLandingCoodinateAltitudeFromFact ) ;
connect ( & _loiterToLandDistanceFact , & Fact : : valueChanged , this , & FixedWingLandingComplexItem : : _recalcLoiterCoordFromFacts ) ;
connect ( & _landingHeadingFact , & Fact : : valueChanged , this , & FixedWingLandingComplexItem : : _recalcLoiterCoordFromFacts ) ;
connect ( this , & FixedWingLandingComplexItem : : loiterCoordinateChanged , this , & FixedWingLandingComplexItem : : _recalcFactsFromCoords ) ;
connect ( this , & FixedWingLandingComplexItem : : landingCoordinateChanged , this , & FixedWingLandingComplexItem : : _recalcFactsFromCoords ) ;
connect ( & _landingAltitudeFact , & Fact : : valueChanged , this , & FixedWingLandingComplexItem : : _updateLandingCoodinateAltitudeFromFact ) ;
connect ( & _landingDistanceFact , & Fact : : valueChanged , this , & FixedWingLandingComplexItem : : _recalcFromHeadingAndDistanceChange ) ;
connect ( & _landingHeadingFact , & Fact : : valueChanged , this , & FixedWingLandingComplexItem : : _recalcFromHeadingAndDistanceChange ) ;
connect ( & _loiterRadiusFact , & Fact : : valueChanged , this , & FixedWingLandingComplexItem : : _recalcFromRadiusChange ) ;
connect ( this , & FixedWingLandingComplexItem : : loiterClockwiseChanged , this , & FixedWingLandingComplexItem : : _recalcFromRadiusChange ) ;
connect ( this , & FixedWingLandingComplexItem : : loiterCoordinateChanged , this , & FixedWingLandingComplexItem : : _recalcFromCoordinateChange ) ;
connect ( this , & FixedWingLandingComplexItem : : landingCoordinateChanged , this , & FixedWingLandingComplexItem : : _recalcFromCoordinateChange ) ;
}
int FixedWingLandingComplexItem : : lastSequenceNumber ( void ) const
@ -168,7 +173,7 @@ bool FixedWingLandingComplexItem::load(const QJsonObject& complexObject, int seq
@@ -168,7 +173,7 @@ bool FixedWingLandingComplexItem::load(const QJsonObject& complexObject, int seq
_landingAltitudeRelative = complexObject [ _jsonLandingAltitudeRelativeKey ] . toBool ( ) ;
_landingCoordSet = true ;
_recalcFactsFromCoords ( ) ;
_recalcFromHeadingAndDistanceChange ( ) ;
return true ;
}
@ -253,7 +258,7 @@ void FixedWingLandingComplexItem::setLandingCoordinate(const QGeoCoordinate& coo
@@ -253,7 +258,7 @@ void FixedWingLandingComplexItem::setLandingCoordinate(const QGeoCoordinate& coo
emit landingCoordinateChanged ( coordinate ) ;
_ignoreRecalcSignals = false ;
_landingCoordSet = true ;
_recalcLoiterCoordFromFacts ( ) ;
_recalcFromHeadingAndDistanceChange ( ) ;
emit landingCoordSetChanged ( true ) ;
}
}
@ -268,29 +273,81 @@ void FixedWingLandingComplexItem::setLoiterCoordinate(const QGeoCoordinate& coor
@@ -268,29 +273,81 @@ void FixedWingLandingComplexItem::setLoiterCoordinate(const QGeoCoordinate& coor
}
}
voi d FixedWingLandingComplexItem : : _recalcLoiterCoordFromFacts ( void )
double FixedWingLandingComplexItem : : _mathematicAngleToHeading ( double angle )
{
if ( ! _ignoreRecalcSignals & & _landingCoordSet ) {
double north , east , down ;
QGeoCoordinate tangentOrigin = _landingCoordinate ;
double heading = ( angle - 90 ) * - 1 ;
if ( heading < 0 ) {
heading + = 360 ;
}
return heading ;
}
double FixedWingLandingComplexItem : : _headingToMathematicAngle ( double heading )
{
return heading - 90 * - 1 ;
}
void FixedWingLandingComplexItem : : _recalcFromRadiusChange ( void )
{
// Fixed:
// land
// loiter tangent
// distance
// radius
// heading
// Adjusted:
// loiter
if ( ! _ignoreRecalcSignals ) {
// These are our known values
double radius = _loiterRadiusFact . rawValue ( ) . toDouble ( ) ;
double landToTangentDistance = _landingDistanceFact . rawValue ( ) . toDouble ( ) ;
double heading = _landingHeadingFact . rawValue ( ) . toDouble ( ) ;
double landToLoiterDistance = qSqrt ( qPow ( radius , 2 ) + qPow ( landToTangentDistance , 2 ) ) ;
double angleLoiterToTangent = qRadiansToDegrees ( qAsin ( radius / landToLoiterDistance ) ) * ( _loiterClockwise ? - 1 : 1 ) ;
_loiterCoordinate = _landingCoordinate . atDistanceAndAzimuth ( landToLoiterDistance , heading + 180 + angleLoiterToTangent ) ;
_ignoreRecalcSignals = true ;
emit loiterCoordinateChanged ( _loiterCoordinate ) ;
_ignoreRecalcSignals = false ;
}
}
convertGeoToNed ( _landingCoordinate , tangentOrigin , & north , & east , & down ) ;
void FixedWingLandingComplexItem : : _recalcFromHeadingAndDistanceChange ( void )
{
// Fixed:
// land
// heading
// distance
// radius
// Adjusted:
// loiter
// loiter tangent
// Heading is from loiter to land, so we need to rotate angle 180 degrees and go the opposite direction
if ( ! _ignoreRecalcSignals & & _landingCoordSet ) {
// These are our known values
double radius = _loiterRadiusFact . rawValue ( ) . toDouble ( ) ;
double landToTangentDistance = _landingDistanceFact . rawValue ( ) . toDouble ( ) ;
double heading = _landingHeadingFact . rawValue ( ) . toDouble ( ) ;
heading + = 180.0 ;
heading * = - 1.0 ;
QPointF originPoint ( east , north ) ;
north + = _loiterToLandDistanceFact . rawValue ( ) . toDouble ( ) ;
QPointF loiterPoint ( east , north ) ;
QPointF rotatedLoiterPoint = _rotatePoint ( loiterPoint , originPoint , heading ) ;
// Calculate loiter tangent coordinate
_loiterTangentCoordinate = _landingCoordinate . atDistanceAndAzimuth ( landToTangentDistance , heading + 180 ) ;
// Calculate the distance and angle to the loiter coordinate
QGeoCoordinate tangent = _landingCoordinate . atDistanceAndAzimuth ( landToTangentDistance , 0 ) ;
QGeoCoordinate loiter = tangent . atDistanceAndAzimuth ( radius , 90 ) ;
double loiterDistance = _landingCoordinate . distanceTo ( loiter ) ;
double loiterAzimuth = _landingCoordinate . azimuthTo ( loiter ) * ( _loiterClockwise ? - 1 : 1 ) ;
convertNedToGeo ( rotatedLoiterPoint . y ( ) , rotatedLoiterPoint . x ( ) , down , tangentOrigin , & _loiterCoordinate ) ;
// Use those values to get the new loiter point which takes heading into acount
_loiterCoordinate = _landingCoordinate . atDistanceAndAzimuth ( loiterDistance , heading + 180 + loiterAzimuth ) ;
_ignoreRecalcSignals = true ;
emit loiterTangentCoordinateChanged ( _loiterTangentCoordinate ) ;
emit loiterCoordinateChanged ( _loiterCoordinate ) ;
emit coordinateChanged ( _loiterCoordinate ) ;
_ignoreRecalcSignals = false ;
}
}
@ -306,42 +363,34 @@ QPointF FixedWingLandingComplexItem::_rotatePoint(const QPointF& point, const QP
@@ -306,42 +363,34 @@ QPointF FixedWingLandingComplexItem::_rotatePoint(const QPointF& point, const QP
return rotated ;
}
void FixedWingLandingComplexItem : : _recalcFactsFromCoords ( void )
void FixedWingLandingComplexItem : : _recalcFromCoordinateChange ( void )
{
if ( ! _ignoreRecalcSignals & & _landingCoordSet ) {
// Prevent signal recursion
_ignoreRecalcSignals = true ;
// Calc new distance
// Fixed:
// land
// loiter
// radius
// Adjusted:
// loiter tangent
// heading
// distance
double northLand , eastLand , down ;
double northLoiter , eastLoiter ;
QGeoCoordinate tangentOrigin = _landingCoordinate ;
convertGeoToNed ( _landingCoordinate , tangentOrigin , & northLand , & eastLand , & down ) ;
convertGeoToNed ( _loiterCoordinate , tangentOrigin , & northLoiter , & eastLoiter , & down ) ;
if ( ! _ignoreRecalcSignals & & _landingCoordSet ) {
// These are our known values
double radius = _loiterRadiusFact . rawValue ( ) . toDouble ( ) ;
double landToLoiterDistance = _landingCoordinate . distanceTo ( _loiterCoordinate ) ;
double landToLoiterHeading = _landingCoordinate . azimuthTo ( _loiterCoordinate ) ;
double newDistance = sqrt ( pow ( eastLoiter - eastLand , 2.0 ) + pow ( northLoiter - northLand , 2.0 ) ) ;
_loiterToLandDistanceFact . setRawValue ( newDistance ) ;
double loiterToTangentAngle = qRadiansToDegrees ( qAsin ( radius / landToLoiterDistance ) ) * ( _loiterClockwise ? 1 : - 1 ) ;
double landToTangentDistance = qSqrt ( qPow ( landToLoiterDistance , 2 ) - qPow ( radius , 2 ) ) ;
// Calc new heading
_loiterTangentCoordinate = _landingCoordinate . atDistanceAndAzimuth ( landToTangentDistance , landToLoiterHeading + loiterToTangentAngle ) ;
QPointF vector ( eastLand - eastLoiter , northLand - northLoiter ) ;
double radians = atan2 ( vector . y ( ) , vector . x ( ) ) ;
double degrees = qRadiansToDegrees ( radians ) ;
// Change angle to north up = 0 degrees
degrees - = 90 ;
// Reverse the angle direction to go from mathematic angle (counter-clockwise) to compass heading (clockwise)
degrees * = - 1.0 ;
// Bring with 0-360 range
if ( degrees < 0.0 ) {
degrees + = 360.0 ;
} else if ( degrees > 360.0 ) {
degrees - = 360.0 ;
}
_landingHeadingFact . setRawValue ( degrees ) ;
double heading = _loiterTangentCoordinate . azimuthTo ( _landingCoordinate ) ;
_ignoreRecalcSignals = true ;
_landingHeadingFact . setRawValue ( heading ) ;
_landingDistanceFact . setRawValue ( landToTangentDistance ) ;
emit loiterTangentCoordinateChanged ( _loiterTangentCoordinate ) ;
_ignoreRecalcSignals = false ;
}
}