/**
   * Check whether this intersection should be added to, or updated in, the warning manager
   *
   * @param airspace Airspace corresponding to current intersection
   */
  void Intersection(const AbstractAirspace& airspace) {
    if (!airspace.IsActive())
      return; // ignore inactive airspaces completely

    if (!warning_manager.GetConfig().IsClassEnabled(airspace.GetType()) ||
        ExcludeAltitude(airspace))
      return;

    AirspaceWarning *warning = warning_manager.GetWarningPtr(airspace);
    if (warning == NULL || warning->IsStateAccepted(warning_state)) {

      AirspaceInterceptSolution solution;

      if (mode_inside) {
        airspace.Intercept(state, perf, solution, state.location, state.location);
      } else {
        solution = Intercept(airspace, state, perf);
      }
      if (!solution.IsValid())
        return;
      if (solution.elapsed_time > max_time)
        return;

      if (warning == NULL)
        warning = warning_manager.GetNewWarningPtr(airspace);

      warning->UpdateSolution(warning_state, solution);
      found = true;
    }
  }
Beispiel #2
0
    void intersection(const AbstractAirspace &as) {
        *fout << "# intersection point\n";
        for (auto it = intersections.begin(); it != intersections.end(); ++it) {
            const GeoPoint start = (it->first);
            const GeoPoint end = (it->second);
            *fout << start.longitude << " " << start.latitude << " " << "\n";
            *fout << end.longitude << " " << end.latitude << " " << "\n\n";
        }

        AirspaceInterceptSolution solution = Intercept(as, m_state, m_perf);
        if (solution.IsValid()) {
            *iout << "# intercept " << solution.elapsed_time << " h " << solution.altitude << "\n";
            *iout << solution.location.longitude << " " << solution.location.latitude << " " << "\n\n";
        }
    }
Beispiel #3
0
 void closest(const AbstractAirspace &as) {
     GeoPoint c = as.ClosestPoint(state.location, projection);
     if (fout) {
         *fout << "# closest point\n";
         *fout << c.longitude << " " << c.latitude << " " << "\n";
         *fout << state.location.longitude << " " << state.location.latitude << " " << "\n\n";
     }
     GeoVector vec(state.location, c);
     vec.distance = fixed(20000); // set big distance (for testing)
     const AirspaceInterceptSolution solution =
         as.Intercept(state, vec.EndPoint(state.location), projection, m_perf);
     if (solution.IsValid()) {
         if (fout) {
             *fout << "# intercept in " << solution.elapsed_time << " h " << solution.altitude << "\n";
         }
     }
 }
Beispiel #4
0
AirspaceInterceptSolution
AbstractAirspace::Intercept(const AircraftState &state,
                            const AirspaceAircraftPerformance &perf,
                            const GeoPoint &loc_start,
                            const GeoPoint &loc_end) const
{
  const bool only_vertical = (loc_start == loc_end) &&
    (loc_start == state.location);

  const auto distance_start = only_vertical
    ? double(0)
    : state.location.Distance(loc_start);

  const auto distance_end = loc_start == loc_end
    ? distance_start
    : (only_vertical ? double(0) : state.location.Distance(loc_end));

  AirspaceInterceptSolution solution =
    AirspaceInterceptSolution::Invalid();

  // need to scan at least three sides, top, far, bottom (if not terrain)

  AirspaceInterceptSolution solution_candidate =
    AirspaceInterceptSolution::Invalid();

  if (!only_vertical) {
    solution_candidate = InterceptVertical(state, perf, distance_start);
    // search near wall
    if (solution_candidate.IsEarlierThan(solution))
      solution = solution_candidate;

    if (distance_end != distance_start) {
      // need to search far wall also
      solution_candidate = InterceptVertical(state, perf, distance_end);
      if (solution_candidate.IsEarlierThan(solution))
        solution = solution_candidate;
    }
  }

  solution_candidate = InterceptHorizontal(state, perf, distance_start,
                                           distance_end, false);
  // search top wall
  if (solution_candidate.IsEarlierThan(solution))
    solution = solution_candidate;

  // search bottom wall
  if (!altitude_base.IsTerrain()) {
    solution_candidate = InterceptHorizontal(state, perf, distance_start,
                                             distance_end, true);
    if (solution_candidate.IsEarlierThan(solution))
      solution = solution_candidate;
  }

  if (solution.IsValid()) {
    if (solution.distance == distance_start)
      solution.location = loc_start;
    else if (solution.distance == distance_end)
      solution.location = loc_end;
    else if (distance_end > 0)
      solution.location =
        state.location.Interpolate(loc_end, solution.distance / distance_end);
    else
      solution.location = loc_start;

    assert(solution.distance >= 0);
  }

  return solution;
}
 bool IsEarlierThan(const AirspaceInterceptSolution &other) const {
   return IsValid() && (!other.IsValid() ||
                        elapsed_time < other.elapsed_time);
 }