예제 #1
0
 void synchronise(const Airspaces& master,
                  const AGeoPoint& origin,
                  const AGeoPoint& destination) {
   m_planner.Synchronise(master, origin, destination);
 }
예제 #2
0
static bool
test_route(const unsigned n_airspaces, const RasterMap& map)
{
  Airspaces airspaces;
  setup_airspaces(airspaces, map.GetMapCenter(), n_airspaces);

  {
    Directory::Create(Path(_T("output/results")));
    std::ofstream fout("output/results/terrain.txt");

    unsigned nx = 100;
    unsigned ny = 100;
    GeoPoint origin(map.GetMapCenter());

    for (unsigned i = 0; i < nx; ++i) {
      for (unsigned j = 0; j < ny; ++j) {
        auto fx = (double)i / (nx - 1) * 2 - 1;
        auto fy = (double)j / (ny - 1) * 2 - 1;
        GeoPoint x(origin.longitude + Angle::Degrees(0.2 + 0.7 * fx),
                   origin.latitude + Angle::Degrees(0.9 * fy));
        auto h = map.GetInterpolatedHeight(x);
        fout << x.longitude.Degrees() << " " << x.latitude.Degrees()
             << " " << h.GetValue() << "\n";
      }

      fout << "\n";
    }

    fout << "\n";
  }

  {
    // local scope, see what happens when we go out of scope
    GeoPoint p_start(Angle::Degrees(-0.3), Angle::Degrees(0.0));
    p_start += map.GetMapCenter();

    GeoPoint p_dest(Angle::Degrees(0.8), Angle::Degrees(-0.7));
    p_dest += map.GetMapCenter();

    AGeoPoint loc_start(p_start, map.GetHeight(p_start).GetValueOr0() + 100);
    AGeoPoint loc_end(p_dest, map.GetHeight(p_dest).GetValueOr0() + 100);

    AircraftState state;
    GlidePolar glide_polar(0.1);
    const AirspaceAircraftPerformance perf(glide_polar);

    GeoVector vec(loc_start, loc_end);
    auto range = 10000 + vec.distance / 2;

    state.location = loc_start;
    state.altitude = loc_start.altitude;

    {
      Airspaces as_route(false);
      // dummy

      // real one, see if items changed
      as_route.SynchroniseInRange(airspaces, vec.MidPoint(loc_start), range,
                                  AirspacePredicateTrue());
      int size_1 = as_route.GetSize();
      if (verbose)
        printf("# route airspace size %d\n", size_1);

      as_route.SynchroniseInRange(airspaces, vec.MidPoint(loc_start), 1,
                                  AirspacePredicateTrue());
      int size_2 = as_route.GetSize();
      if (verbose)
        printf("# route airspace size %d\n", size_2);

      ok(size_2 < size_1, "shrink as", 0);

      // go back
      as_route.SynchroniseInRange(airspaces, vec.MidPoint(loc_end), range,
                                  AirspacePredicateTrue());
      int size_3 = as_route.GetSize();
      if (verbose)
        printf("# route airspace size %d\n", size_3);

      ok(size_3 >= size_2, "grow as", 0);

      // and again
      as_route.SynchroniseInRange(airspaces, vec.MidPoint(loc_start), range,
                                  AirspacePredicateTrue());
      int size_4 = as_route.GetSize();
      if (verbose)
        printf("# route airspace size %d\n", size_4);

      ok(size_4 >= size_3, "grow as", 0);

      scan_airspaces(state, as_route, perf, true, loc_end);
    }

    // try the solver
    SpeedVector wind(Angle::Degrees(0), 0);
    GlidePolar polar(1);

    GlideSettings settings;
    settings.SetDefaults();
    RoutePlannerConfig config;
    config.mode = RoutePlannerConfig::Mode::BOTH;

    AirspaceRoute route;
    route.UpdatePolar(settings, config, polar, polar, wind);
    route.SetTerrain(&map);

    AirspacePredicateTrue predicate;

    bool sol = false;
    for (int i = 0; i < NUM_SOL; i++) {
      loc_end.latitude += Angle::Degrees(0.1);
      loc_end.altitude = map.GetHeight(loc_end).GetValueOr0() + 100;
      route.Synchronise(airspaces, predicate, loc_start, loc_end);
      if (route.Solve(loc_start, loc_end, config)) {
        sol = true;
        if (verbose) {
          PrintHelper::print_route(route);
        }
      } else {
        if (verbose) {
          printf("# fail\n");
        }
        sol = false;
      }
      char buffer[80];
      sprintf(buffer, "route %d solution", i);
      ok(sol, buffer, 0);
    }
  }

  return true;
}