|
@@ -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;
|
|
|
+}
|