Browse Source

fix some issues with the path prediction and add some addional information

Sven Czarnian 3 years ago
parent
commit
e108d3de57
2 changed files with 63 additions and 41 deletions
  1. 9 2
      include/aman/types/Inbound.h
  2. 54 39
      src/types/Inbound.cpp

+ 9 - 2
include/aman/types/Inbound.h

@@ -36,14 +36,17 @@ namespace aman {
         std::size_t                  m_nextStarWaypoint;
         std::vector<ArrivalWaypoint> m_arrivalRoute;
         Time                         m_timeToLose;
+        UtcTime::Point               m_waypointEstimatedTimeOfArrival;
+        Length                       m_trackmiles;
+        Time                         m_flighttime;
 
-        void updatePrediction(EuroScopePlugIn::CRadarTarget& target, const aman::AircraftSchedule& inbound, bool forceUpdate);
+        void updatePrediction(EuroScopePlugIn::CRadarTarget& target, const aman::AircraftSchedule& inbound);
         Velocity indicatedAirspeed(const Length& altitude) const noexcept;
         Velocity groundSpeed(const Length& altitude, const Velocity& ias, const Angle& heading);
         void createWindTables(const google::protobuf::RepeatedPtrField<aman::WindData>& wind);
         static int matchToPredictedPath(const EuroScopePlugIn::CFlightPlanPositionPredictions& predictions, const GeoCoordinate& position,
                                         Length& trackmiles);
-        void predictETA(const EuroScopePlugIn::CRadarTarget& target, const EuroScopePlugIn::CFlightPlanPositionPredictions& predictions, bool resetTTL);
+        void predictETA(const EuroScopePlugIn::CRadarTarget& target, const EuroScopePlugIn::CFlightPlanPositionPredictions& predictions);
 
     public:
         Inbound(EuroScopePlugIn::CRadarTarget& target, const aman::AircraftSchedule& inbound, const google::protobuf::RepeatedPtrField<aman::WindData>& wind);
@@ -52,6 +55,10 @@ namespace aman {
         void update(EuroScopePlugIn::CRadarTarget& target);
         void update(EuroScopePlugIn::CFlightPlan& plan);
         bool fixedPlan() const noexcept;
+        UtcTime::Point eta() const;
+        UtcTime::Point pta() const;
         const Time& timeToLose() const noexcept;
+        const Length& trackmiles() const noexcept;
+        const Time& flighttime() const noexcept;
     };
 }

+ 54 - 39
src/types/Inbound.cpp

@@ -33,9 +33,11 @@ Inbound::Inbound(EuroScopePlugIn::CRadarTarget& target, const aman::AircraftSche
         m_runway(inbound.arrivalrunway()),
         m_nextStarWaypoint(),
         m_arrivalRoute(),
-        m_timeToLose() {
+        m_timeToLose(),
+        m_trackmiles(),
+        m_flighttime() {
     this->createWindTables(wind);
-    this->updatePrediction(target, inbound, true);
+    this->updatePrediction(target, inbound);
     auto flightplan = target.GetCorrelatedFlightPlan();
     this->update(flightplan);
 }
@@ -58,7 +60,7 @@ void Inbound::createWindTables(const google::protobuf::RepeatedPtrField<aman::Wi
     }
 }
 
-void Inbound::updatePrediction(EuroScopePlugIn::CRadarTarget& target, const aman::AircraftSchedule& inbound, bool forceUpdate) {
+void Inbound::updatePrediction(EuroScopePlugIn::CRadarTarget& target, const aman::AircraftSchedule& inbound) {
     bool updatedFlightplan = false;
 
     this->m_performanceData.speedAboveFL240 = static_cast<float>(inbound.performance().iasabovefl240()) * knot;
@@ -66,7 +68,7 @@ void Inbound::updatePrediction(EuroScopePlugIn::CRadarTarget& target, const aman
     this->m_performanceData.speedBelowFL100 = static_cast<float>(inbound.performance().iasbelowfl100()) * knot;
     this->m_performanceData.speedApproach = static_cast<float>(inbound.performance().iasapproach()) * knot;
 
-    bool updateEuroscopePlan = true == forceUpdate && 0 != this->m_star.length() && 0 != this->m_runway.length();
+    bool updateEuroscopePlan = 0 != this->m_star.length() && 0 != this->m_runway.length();
     updateEuroscopePlan &= this->m_star != target.GetCorrelatedFlightPlan().GetFlightPlanData().GetStarName() || this->m_runway.length() && this->m_runway != target.GetCorrelatedFlightPlan().GetFlightPlanData().GetArrivalRwy();
 
     if (true == updateEuroscopePlan) {
@@ -95,33 +97,31 @@ void Inbound::updatePrediction(EuroScopePlugIn::CRadarTarget& target, const aman
         updatedFlightplan = true;
     }
 
-    if (true == forceUpdate || true == updatedFlightplan) {
-        this->m_arrivalRoute.clear();
-        this->m_arrivalRoute.reserve(inbound.waypoints_size());
-        auto route = target.GetCorrelatedFlightPlan().GetExtractedRoute();
-        int lastExtractedIndex = 0;
-
-        for (int i = 0; i < inbound.waypoints_size(); ++i) {
-            const auto& plannedPoint = inbound.waypoints(i);
-
-            const auto pta = UtcTime::stringToTime(plannedPoint.pta());
-            const auto altitude = static_cast<float>(plannedPoint.altitude()) * feet;
-            const auto ias = static_cast<float>(plannedPoint.indicatedairspeed()) * knot;
-            GeoCoordinate coordinate;
-
-            bool found = false;
-            for (int c = lastExtractedIndex; c < route.GetPointsNumber(); ++c) {
-                if (route.GetPointName(c) == plannedPoint.name()) {
-                    coordinate = __convert(route.GetPointPosition(c));
-                    lastExtractedIndex = c;
-                    found = true;
-                    break;
-                }
+    this->m_arrivalRoute.clear();
+    this->m_arrivalRoute.reserve(inbound.waypoints_size());
+    auto route = target.GetCorrelatedFlightPlan().GetExtractedRoute();
+    int lastExtractedIndex = 0;
+
+    for (int i = 0; i < inbound.waypoints_size(); ++i) {
+        const auto& plannedPoint = inbound.waypoints(i);
+
+        const auto pta = UtcTime::stringToTime(plannedPoint.pta());
+        const auto altitude = static_cast<float>(plannedPoint.altitude()) * feet;
+        const auto ias = static_cast<float>(plannedPoint.indicatedairspeed()) * knot;
+        GeoCoordinate coordinate;
+
+        bool found = false;
+        for (int c = lastExtractedIndex; c < route.GetPointsNumber(); ++c) {
+            if (route.GetPointName(c) == plannedPoint.name()) {
+                coordinate = __convert(route.GetPointPosition(c));
+                lastExtractedIndex = c;
+                found = true;
+                break;
             }
-
-            if (true == found)
-                this->m_arrivalRoute.push_back(ArrivalWaypoint(plannedPoint.name(), coordinate, altitude, ias, pta));
         }
+
+        if (true == found)
+            this->m_arrivalRoute.push_back(ArrivalWaypoint(plannedPoint.name(), coordinate, altitude, ias, pta));
     }
 }
 
@@ -132,7 +132,7 @@ void Inbound::update(EuroScopePlugIn::CRadarTarget& target, const aman::Aircraft
     this->m_runway = inbound.arrivalrunway();
     this->createWindTables(wind);
 
-    this->updatePrediction(target, inbound, false);
+    this->updatePrediction(target, inbound);
     auto flightplan = target.GetCorrelatedFlightPlan();
     this->update(flightplan);
 }
@@ -243,7 +243,7 @@ int Inbound::matchToPredictedPath(const EuroScopePlugIn::CFlightPlanPositionPred
         const auto prev = lastPosition.bearingTo(position);
         const auto next = coordinate.bearingTo(position);
         const auto delta = __normalize(prev - next);
-        if (100_deg <= delta.abs()) {
+        if (90_deg <= delta.abs() || 2.0_nm >= lastPosition.distanceTo(position)) {
             trackmiles += lastPosition.distanceTo(position);
             return i - 1;
         }
@@ -255,7 +255,7 @@ int Inbound::matchToPredictedPath(const EuroScopePlugIn::CFlightPlanPositionPred
     return predictions.GetPointsNumber();
 }
 
-void Inbound::predictETA(const EuroScopePlugIn::CRadarTarget& target, const EuroScopePlugIn::CFlightPlanPositionPredictions& predictions, bool resetTTL) {
+void Inbound::predictETA(const EuroScopePlugIn::CRadarTarget& target, const EuroScopePlugIn::CFlightPlanPositionPredictions& predictions) {
     if (this->m_arrivalRoute.size() <= this->m_nextStarWaypoint || 1 >= predictions.GetPointsNumber()) {
         this->m_timeToLose = 0_s;
         return;
@@ -264,6 +264,7 @@ void Inbound::predictETA(const EuroScopePlugIn::CRadarTarget& target, const Euro
     const auto& destination = gsl::at(this->m_arrivalRoute, this->m_nextStarWaypoint);
     Length distanceToNextWaypoint = 0_m;
     Inbound::matchToPredictedPath(predictions, destination.position(), distanceToNextWaypoint);
+    this->m_trackmiles = distanceToNextWaypoint;
 
     /* predict the flight and the descend */
     Velocity groundSpeed = static_cast<float>(target.GetPosition().GetReportedGS()) * knot;
@@ -292,22 +293,20 @@ void Inbound::predictETA(const EuroScopePlugIn::CRadarTarget& target, const Euro
         flightTime += 1_s;
     }
 
+    this->m_waypointEstimatedTimeOfArrival = UtcTime::currentUtc() + std::chrono::seconds(static_cast<long long>(flightTime.convert(second)));
     const auto delta = std::chrono::duration_cast<std::chrono::seconds>(destination.plannedArrivalTime() - UtcTime::currentUtc());
     const auto plannedFlightTime = static_cast<float>(delta.count()) * second;
     const auto newTTL = plannedFlightTime - flightTime;
+    this->m_flighttime = flightTime;
 
-    if (true == resetTTL)
-        this->m_timeToLose = newTTL;
-    else
-        this->m_timeToLose = 0.9f * this->m_timeToLose + 0.1f * newTTL;
+    this->m_timeToLose = newTTL;
 }
 
 void Inbound::update(EuroScopePlugIn::CRadarTarget& target) {
-    this->predictETA(target, target.GetCorrelatedFlightPlan().GetPositionPredictions(), false);
+    this->predictETA(target, target.GetCorrelatedFlightPlan().GetPositionPredictions());
 }
 
 void Inbound::update(EuroScopePlugIn::CFlightPlan& plan) {
-    const auto lastStarWaypoint = this->m_nextStarWaypoint;
     this->m_nextStarWaypoint = 0;
 
     if (0 == this->m_arrivalRoute.size()) {
@@ -383,13 +382,29 @@ void Inbound::update(EuroScopePlugIn::CFlightPlan& plan) {
     }
 
     const auto target = plan.GetCorrelatedRadarTarget();
-    this->predictETA(target, plan.GetPositionPredictions(), this->m_nextStarWaypoint != lastStarWaypoint);
+    this->predictETA(target, plan.GetPositionPredictions());
 }
 
 bool Inbound::fixedPlan() const noexcept {
     return this->m_fixedPlan;
 }
 
+UtcTime::Point Inbound::eta() const {
+    return this->m_waypointEstimatedTimeOfArrival;
+}
+
+UtcTime::Point Inbound::pta() const {
+    return gsl::at(this->m_arrivalRoute, this->m_nextStarWaypoint).plannedArrivalTime();
+}
+
 const Time& Inbound::timeToLose() const noexcept {
     return this->m_timeToLose;
 }
+
+const Length& Inbound::trackmiles() const noexcept {
+    return this->m_trackmiles;
+}
+
+const Time& Inbound::flighttime() const noexcept {
+    return this->m_flighttime;
+}