def burn(area_bounds, ignition_point, wind):
     """Burn some area from an ignition point with given wind conditions"""
     env = propagation.Environment(area_bounds,
                                   wind_speed=wind[0],
                                   wind_dir=wind[1])
     f_propagation = propagation.propagate_from_points(
         env, (ignition_point[0], ignition_point[1], 0), until=120 * 60)
     return f_propagation.ignitions()
    def test_vns(self):
        def pr(cpp_raster, blocking=False):  # plots a cpp raster
            return GeoData.from_cpp_raster(cpp_raster,
                                           "xx").plot(blocking=blocking)

        from fire_rs.firemodel import propagation
        env = propagation.Environment(
            [[480060.0, 485060.0], [6210074.0, 6214074.0]],
            wind_speed=4.11,
            wind_dir=0)
        prop = propagation.propagate_from_points(env,
                                                 TimedPoint(
                                                     482060, 6211074, 0),
                                                 until=14000)

        ignitions = prop.ignitions()
        # ax = ignitions.plot(blocking=False)
        elev = env.raster.slice('elevation')

        conf = {
            'min_time': 9500,
            'max_time': 12000,
            'save_every': 0,
            'save_improvements': False,
            'discrete_elevation_interval': 1,
            'vns': fire_rs.planning.benchmark.vns_configurations['base']
        }
        conf['vns']['configuration_name'] = 'base'

        wp = up.Waypoint(480060.0 + 100, 6210074.0 + 100, 0, 0)
        flight = up.TrajectoryConfig(uav, wp, wp, conf['min_time'], 1500)

        res = up.plan_vns([
            flight,
        ], ignitions.as_cpp_raster(), elev.as_cpp_raster(), json.dumps(conf))

        plan = res.final_plan()

        geodatadisplay = GeoDataDisplay.pyplot_figure(
            env.raster.combine(ignitions))
        geodatadisplay.add_extension(TrajectoryDisplayExtension, (None, ), {})

        plot_plan(plan, geodatadisplay, show=True)

        for intermediate_plan in res.intermediate_plans:
            geodatadisplay = GeoDataDisplay.pyplot_figure(
                env.raster.combine(ignitions))
            geodatadisplay.add_extension(TrajectoryDisplayExtension, (None, ),
                                         {})
            plot_plan(intermediate_plan, geodatadisplay, show=True)

        print("durations: ")
        for traj in plan.trajectories():
            print(traj.duration())
예제 #3
0
def wp_insertion() -> "fire_rs.geodata.display.GeoDataDisplay":
    """Plot a case with an small fire. Overlay arrows indicating fire propagation direction"""

    # Geographic environment (elevation, landcover, wind...)
    wind = (2., 0.)
    area = ((480000.0, 480200.0), (6210000.0, 6210200.0))
    env = PlanningEnvironment(area,
                              wind_speed=wind[0],
                              wind_dir=wind[1],
                              planning_elevation_mode='flat',
                              flat_altitude=0)

    ignition_points = [
        TimedPoint(area[0][0], area[1][0], 0),
    ]
    logging.info("Start of propagation")
    fire = propagation.propagate_from_points(env, ignition_points, 180 * 60)
    logging.info("End of propagation")

    fire1 = fire.ignitions()

    gdd = fire_rs.geodata.display.GeoDataDisplay.pyplot_figure(
        env.raster.combine(fire1), )
    gdd.add_extension(TrajectoryDisplayExtension, (None, ), {})

    # print(env.raster.x_offset)
    # gdd.axis.set_xticks(np.arange(area[0][0]-25, area[0][1], 22.22))
    # gdd.axis.set_yticks(np.arange(area[1][0]-25, area[1][1], 22.22))
    # gdd.axis.grid(True)
    gdd.axes.tick_params(
        axis='both',  # changes apply to the x-axis
        which='both',  # both major and minor ticks are affected
        bottom='off',  # ticks along the bottom edge are off
        left='off',  # ticks along the bottom edge are off
        top='off',  # ticks along the top edge are off
        labelleft='off',  # ticks along the bottom edge are off
        labelbottom='off')  # labels along the bottom edge are off
    gdd.axes.set_xlabel("")
    gdd.axes.set_ylabel("")
    t_range_fire = (0, np.inf)
    gdd.draw_ignition_contour(geodata=fire1,
                              time_range=t_range_fire,
                              cmap=matplotlib.cm.plasma)
    gdd.draw_ignition_shade(with_colorbar=False,
                            geodata=fire1,
                            vmin=0,
                            vmax=120 * 60,
                            cmap=matplotlib.cm.Reds)

    gdd.legend()
    return gdd
예제 #4
0
    from fire_rs.firemodel import propagation
    from fire_rs.geodata.geo_data import TimedPoint, GeoData
    from fire_rs.planning.planning import FireMapper, FlightConf, Planner, PlanningEnvironment, \
        UAVConf, Waypoint
    from fire_rs.planning.display import TrajectoryDisplayExtension, plot_plan_trajectories

    # Geographic environment (elevation, landcover, wind...)
    wind = (10., 0.)
    area = ((480000.0, 485000.0), (6210000.0, 6215000.0))
    env = PlanningEnvironment(area, wind_speed=wind[0], wind_dir=wind[1],
                              planning_elevation_mode='flat', flat_altitude=0)

    # Fire applied to the previous environment
    ignition_point = TimedPoint(area[0][0] + 1000.0, area[1][0] + 2000.0, 0)
    logging.info("Start of propagation")
    fire = propagation.propagate_from_points(env, ignition_point, 240 * 60)
    logging.info("End of propagation")

    # Configure some flight
    base_wp = Waypoint(area[0][0] + 100., area[1][0] + 100., 0., 0.)
    start_t = 120 * 60  # 30 minutes after the ignition
    uavconf = UAVConf.slow_x8()
    fgconf = FlightConf(uavconf, start_t, base_wp)

    # Write down the desired VNS configuration
    conf_vns = {
        "full": {
            "max_restarts": 5,
            "max_time": 15.0,
            "neighborhoods": [
                {"name": "dubins-opt",
예제 #5
0
def threefire_twouav_figure(
        wind_speed=5.,
        wind_dir=np.pi / 2) -> "fire_rs.geodata.display.GeoDataDisplay":
    """Plot a generic case with wind, multiple UAV from multiple bases, and multiple fire."""

    # Geographic environment (elevation, landcover, wind...)
    wind = (wind_speed, wind_dir)
    area = ((480000.0, 485000.0), (6210000.0, 6215000.0))
    env = PlanningEnvironment(area,
                              wind_speed=wind[0],
                              wind_dir=wind[1],
                              planning_elevation_mode='flat',
                              flat_altitude=0)

    # Fire applied to the previous environment
    ignition_points = [
        TimedPoint(area[0][0] + 1000.0, area[1][0] + 1000.0, 0.),
        TimedPoint(area[0][0] + 4000.0, area[1][0] + 2000.0, 0.),
        TimedPoint(area[0][0] + 2000.0, area[1][0] + 3500.0, 0.)
    ]
    logging.info("Start of propagation")
    fire = propagation.propagate_from_points(env, ignition_points, 120 * 60)
    logging.info("End of propagation")

    # Configure some flight
    start_t = 90 * 60
    uav = UAVConf.x8()
    uav.max_flight_time /= 3
    f_confs = [
        FlightConf(uav, start_t,
                   Waypoint(area[0][0] + 100., area[1][0] + 100., 0., 0.),
                   None, wind),
        FlightConf(uav, start_t,
                   Waypoint(area[0][0] + 100., area[1][0] + 100., 0., 0.),
                   None, wind),
    ]

    conf = SAOP_conf(start_t, start_t + uav.max_flight_time)

    fire1 = fire.ignitions()
    pl = Planner(env, fire1, f_confs, conf)
    pl.compute_plan()
    sr_1 = pl.search_result
    fmapper = FireMapper(env, fire1)

    gdd = fire_rs.geodata.display.GeoDataDisplay.pyplot_figure(
        env.raster.combine(fire1), frame=(0, 0))
    gdd.add_extension(TrajectoryDisplayExtension, (None, ), {})

    # Draw expected fire contour
    t_range = (sr_1.final_plan().trajectories()[0].start_time(0),
               sr_1.final_plan().trajectories()[0].end_time(
                   len(sr_1.final_plan().trajectories()[0]) - 1))
    t_range_fire = (0, np.inf)
    gdd.draw_ignition_contour(geodata=fire1,
                              time_range=t_range_fire,
                              cmap=matplotlib.cm.Reds,
                              alpha=1)

    # Draw observed fire
    for i in range(len(f_confs)):
        executed_path = sr_1.final_plan().trajectories()[i].sampled_with_time(
            step_size=10)
        fmapper.observe(executed_path, pl.flights[i].uav)
    gdd.draw_ignition_shade(geodata=fmapper.firemap,
                            cmap=matplotlib.cm.summer,
                            vmin=t_range[0],
                            vmax=t_range[1],
                            with_colorbar=False)

    # Draw trajectory
    colors = ['blue', 'darkgreen', 'magenta']
    labels = ["UAV " + str(i) for i in range(len(f_confs))]

    for i in range(len(f_confs)):
        plot_plan_trajectories(sr_1.final_plan(),
                               gdd,
                               trajectories=i,
                               draw_path=True,
                               draw_flighttime_path=False,
                               colors=[colors[i]],
                               labels=[labels[i]],
                               linestyles=['-'])
    gdd.legend()
    return gdd
예제 #6
0
def detail_case_figure(
        wind_speed=5.,
        wind_dir=0.) -> "fire_rs.geodata.display.GeoDataDisplay":
    """Plot a case with an small fire
     we can make a zoom and observe a dubinswind path and observed cells."""

    # Geographic environment (elevation, landcover, wind...)
    wind = (wind_speed, wind_dir)
    wind_xy = (wind[0] * np.cos(wind[1]), wind[0] * np.sin(wind[1]))
    area = ((480000.0, 485000.0), (6210000.0, 6215000.0))
    env = PlanningEnvironment(area,
                              wind_speed=10,
                              wind_dir=wind[1],
                              planning_elevation_mode='flat',
                              flat_altitude=0)

    # Fire applied to the previous environment
    ignition_points = [
        TimedPoint(area[0][0] + 2000.0, area[1][0] + 2000.0, 0),
    ]
    logging.info("Start of propagation")
    fire = propagation.propagate_from_points(env, ignition_points, 180 * 60)
    logging.info("End of propagation")

    # Configure some flight
    base_wp = Waypoint(area[0][0] + 100., area[1][0] + 100., 0., 0.)
    start_t = 120 * 60
    uav = UAVConf.x8()

    f_confs = [
        FlightConf(uav, start_t,
                   Waypoint(area[0][0] + 100., area[1][0] + 100., 0., 0.),
                   None, wind_xy),
    ]

    conf = SAOP_conf(start_t, start_t + uav.max_flight_time)

    fire1 = fire.ignitions()
    pl = Planner(env, fire1, f_confs, conf)
    pl.compute_plan()
    sr_1 = pl.search_result
    fmapper = FireMapper(env, fire1)

    gdd = fire_rs.geodata.display.GeoDataDisplay.pyplot_figure(
        env.raster.combine(fire1), frame=(0, 0))
    gdd.add_extension(TrajectoryDisplayExtension, (None, ), {})

    gdd.axes.grid(True)

    # Draw expected fire contour
    t_range = (sr_1.final_plan().trajectories()[0].start_time(0) - 120,
               sr_1.final_plan().trajectories()[0].end_time(
                   len(sr_1.final_plan().trajectories()[0]) - 1) + 120)
    t_range_fire = (0, np.inf)
    gdd.draw_ignition_contour(geodata=fire1,
                              time_range=t_range_fire,
                              cmap=matplotlib.cm.Reds)

    # Draw observed fire
    executed_path_1 = sr_1.final_plan().trajectories()[0].sampled_with_time(
        step_size=10)
    fmapper.observe(executed_path_1, pl.flights[0].uav)
    gdd.TrajectoryDisplayExtension.draw_observation_map(
        obs_map=fmapper.observed, layer='ignition', color='gray')
    gdd.TrajectoryDisplayExtension.draw_observation_map(
        obs_map=fmapper.firemap, layer='ignition', color='green')

    # Draw trajectory
    colors = ['blue', 'green', 'magenta']
    labels = ["UAV " + str(i) for i in range(len(f_confs))]

    for i in range(len(f_confs)):
        plot_plan_trajectories(sr_1.final_plan(),
                               gdd,
                               trajectories=i,
                               draw_path=True,
                               draw_segments=False,
                               draw_flighttime_path=False,
                               colors=[colors[i]],
                               labels=None)
    gdd.legend()
    return gdd
예제 #7
0
 def test_propagate_full(self):
     env = propagation.Environment(self.test_area,
                                   wind_speed=4.11,
                                   wind_dir=0)
     prop = propagation.propagate_from_points(env, [self.ignition_point])
예제 #8
0
from fire_rs.firemodel import propagation
from fire_rs.geodata.display import GeoDataDisplay
from fire_rs.geodata.geo_data import TimedPoint


if __name__ == "__main__":
    output_format = "svg"

    # Uncomment below to use latex for typesetting
    # matplotlib.rcParams['font.family'] = 'sans-serif'
    # matplotlib.rcParams['text.usetex'] = True
    # output_format="pdf"

    area = ((480000.0, 485000.0), (6210000.0, 6215000.0))
    env = propagation.Environment(area, wind_speed=5., wind_dir=0.)
    ignition_point = TimedPoint(area[0][0] + 1000.0, area[1][0] + 2000.0, 0)
    fire = propagation.propagate_from_points(env, ignition_point, 90000)

    # Figure terrain + ignition contour + ignition point
    gdd = GeoDataDisplay.pyplot_figure(env.raster.combine(fire.ignitions().slice(["ignition"])),
                                       frame=(0., 0.))
    # gdd.draw_elevation_shade(with_colorbar=False, cmap=matplotlib.cm.terrain)
    # gdd.draw_wind_quiver()
    gdd.draw_ignition_shade(cmap=matplotlib.cm.Reds)
    gdd.draw_ignition_contour(with_labels=True,cmap=matplotlib.cm.plasma)
    gdd.draw_ignition_points(ignition_point)

    gdd.figure.show()

    gdd.figure.savefig(".".join(("demo_propagation", output_format)), dpi=150, bbox_inches='tight')
from fire_rs.geodata.geo_data import TimedPoint, GeoData

if __name__ == "__main__":
    output_format = "svg"

    # Uncomment below to use latex for typesetting
    # matplotlib.rcParams['font.family'] = 'sans-serif'
    # matplotlib.rcParams['text.usetex'] = True
    # output_format="pdf"

    area = ((481000.0, 484000.0), (6211000.0, 6213500.0))

    expected_env = propagation.Environment(area, wind_speed=5., wind_dir=0.)
    now = datetime.datetime.now().timestamp()
    ignition_point = TimedPoint(area[0][0] + 1000.0, area[1][0] + 1000.0, now)
    expected_fire = propagation.propagate_from_points(
        expected_env, ignition_point, now + datetime.timedelta(hours=2).total_seconds())

    env = propagation.Environment(area, wind_speed=6., wind_dir=0.)
    fire = propagation.propagate_from_points(
        env, ignition_point, now + datetime.timedelta(hours=2).total_seconds())

    # Create fire perimeter geodata
    fire_perimeter = GeoData.full_like(fire.prop_data.slice("ignition"), np.nan)
    # Create contour with scikit-image
    contours = skimage.measure.find_contours(fire.prop_data.data["ignition"],
                                             now + datetime.timedelta(hours=1).total_seconds())
    # Draw contour in the geodata
    for contour in contours:
        for pt_i in range(len(contour)):
            if pt_i < len(contour) / 3:
                continue
예제 #10
0
    ignition_point = TimedPoint(area[0][0] + 2500.0, area[1][0] + 2100.0, 0)

    terrain_figure = fire_rs.geodata.display.GeoDataDisplay.pyplot_figure(
        env.raster, frame=(0, 0))
    terrain_figure.draw_elevation_shade()
    terrain_figure.draw_ignition_points(ignition_point)
    terrain_figure.figure.show()

    wind_figure = fire_rs.geodata.display.GeoDataDisplay.pyplot_figure(
        env.raster, frame=(0, 0))
    wind_figure.draw_wind_quiver()
    wind_figure.draw_ignition_points(ignition_point)
    wind_figure.figure.show()

    logging.info("Start of propagation")
    fire = propagation.propagate_from_points(env, ignition_point,
                                             120 * 60)  # 60 minutes
    logging.info("End of propagation")

    fire_figure = fire_rs.geodata.display.GeoDataDisplay.pyplot_figure(
        fire.prop_data, frame=(0, 0))
    fire_figure.draw_ignition_contour(with_labels=True)
    fire_figure.draw_ignition_points(ignition_point, zorder=100000)
    fire_figure.figure.show()
    print()

    # ANIMATION OF FIRE
    import matplotlib.animation as animation

    anim_fire_figure = fire_rs.geodata.display.GeoDataDisplay.pyplot_figure(
        fire.prop_data, frame=(0, 0))
    def give_me_a_plan():
        import numpy as np
        import fire_rs.uav_planning as op
        from fire_rs.firemodel import propagation
        from fire_rs.geodata.geo_data import TimedPoint, GeoData
        from fire_rs.planning.planning import FireMapper, FlightConf, Planner, PlanningEnvironment, \
            UAVConf, Waypoint
        from fire_rs.planning.display import TrajectoryDisplayExtension, plot_plan_trajectories

        # Geographic environment (elevation, landcover, wind...)
        wind = (10., np.pi / 4)  # 10m/s = 36km/h
        area = ((478500.0, 483500.0), (6210000.0, 6215000.0))
        env = PlanningEnvironment(area,
                                  wind_speed=wind[0],
                                  wind_dir=wind[1],
                                  planning_elevation_mode='flat',
                                  flat_altitude=0)

        # Fire applied to the previous environment
        ignition_point = TimedPoint(area[0][0] + 2500.0, area[1][0] + 2100.0,
                                    0)
        fire = propagation.propagate_from_points(env, ignition_point,
                                                 120 * 60)  # 60 minutes
        # Configure some flight
        base_wp_1 = Waypoint(area[0][1] - 150., area[1][1] - 100., 0., 0.)
        start_t = 60 * 60  # 30 minutes after the ignition
        uavconf = UAVConf.x8()
        uavconf.max_flight_time = 30 * 60
        fgconf_1 = FlightConf(uavconf, start_t, base_wp_1)

        # Write down the desired VNS configuration
        conf_vns = {
            "full": {
                "max_restarts":
                5,
                "max_time":
                10.0,
                "neighborhoods": [
                    {
                        "name":
                        "dubins-opt",
                        "max_trials":
                        100,
                        "generators": [{
                            "name": "MeanOrientationChangeGenerator"
                        }, {
                            "name":
                            "RandomOrientationChangeGenerator"
                        }, {
                            "name": "FlipOrientationChangeGenerator"
                        }]
                    },
                    {
                        "name": "one-insert",
                        "max_trials": 100,
                        "select_arbitrary_trajectory": True,
                        "select_arbitrary_position": False
                    },
                ]
            }
        }

        conf = {
            'min_time': fgconf_1.start_time,
            'max_time': fgconf_1.start_time + fgconf_1.uav.max_flight_time,
            'save_every': 1,
            'save_improvements': True,
            'discrete_elevation_interval': 0,
            'vns': conf_vns['full']
        }
        conf['vns']['configuration_name'] = 'full'

        ####################################
        # 1st PLAN
        fire1 = fire.ignitions()
        pl = Planner(env, fire1, [fgconf_1], conf)
        pl.compute_plan()
        return pl.search_result.final_plan()
예제 #12
0
    def draw_scenario(i, scen, a):
        # Fetch scenario environment data with additional elevation mode for planning
        env = propagation.Environment(
            scen.area,
            wind_speed=scen.wind_speed,
            wind_dir=scen.wind_direction,
            world=fire_rs.geodata.environment.World(
                landcover_to_fuel_remap=fire_rs.geodata.environment.
                EVERYTHING_FUELMODEL_REMAP))

        # Propagate fires in the environment
        propagation_end_time = scen.time_window_end + 60 * 10
        _logger.debug("Propagating fire ignitions %s until %s",
                      str(scen.ignitions), str(propagation_end_time))
        prop = propagation.propagate_from_points(env,
                                                 scen.ignitions,
                                                 until=propagation_end_time)
        ignitions = prop.ignitions()

        # Transform altitude of UAV bases from agl (above ground level) to absolute
        for f in scen.flights:
            base_h = 0.  # If flat, start at the default segment insertion h
            f.base_waypoint = Waypoint(f.base_waypoint.x, f.base_waypoint.y,
                                       base_h, f.base_waypoint.dir)

        # Define the flight window
        flight_window = TimeWindow(scen.time_window_start,
                                   scen.time_window_end)

        # Create utility map
        utility = make_utility_map(ignitions,
                                   flight_window,
                                   layer='ignition',
                                   output_layer='utility')
        utility_cpp = utility.as_cpp_raster('utility')

        # Make a FireData object
        fire_data = make_fire_data(ignitions,
                                   env.raster,
                                   elevation_map_layer='elevation')

        # Create an initial plan
        initial_plan = Plan(str(i), [f.as_cpp() for f in scen.flights],
                            fire_data, flight_window, utility_cpp)

        final_plan = initial_plan

        # Propagation was running more time than desired in order to reduce edge effect.
        # Now we need to filter out-of-range ignition times. Crop range is rounded up to the next
        # 10-minute mark (minus 1). This makes color bar ranges and fire front contour plots nicer
        ignitions['ignition'][ignitions['ignition'] > \
                              int(scen.time_window_end / 60. + 5) * 60. - 60] = _DBL_MAX
        # Representation of unburned cells using max double is not suitable for display,
        # so those values must be converted to NaN
        ignitions_nan = ignitions['ignition'].copy()
        ignitions_nan[ignitions_nan == _DBL_MAX] = np.nan
        first_ignition = np.nanmin(ignitions_nan)
        last_ignition = np.nanmax(ignitions_nan)

        # Create the geodatadisplay object & extensions that are going to be used
        geodatadisplay = GeoDataDisplay.pyplot_figure(
            env.raster.combine(ignitions), frame=(0, 0))
        geodatadisplay.add_extension(TrajectoryDisplayExtension, (None, ), {})

        plot_plan_with_background(final_plan, geodatadisplay,
                                  (first_ignition, last_ignition), {
                                      'colorbar': a.colorbar,
                                      'background': a.background,
                                      'foreground': []
                                  })

        # Save the picture
        filepath = os.path.join(a.output, str(i) + "." + a.format)
        _logger.info("Saving as figure as: %s", str(filepath))
        geodatadisplay.axes.get_figure().set_size_inches(a.size)
        geodatadisplay.axes.get_figure().savefig(filepath,
                                                 dpi=a.dpi,
                                                 bbox_inches='tight')
        geodatadisplay.close()
예제 #13
0
def run_benchmark(scenario: Scenario, save_directory: str, instance_name: str,
                  output_options_plot: ty.Mapping[str, ty.Any],
                  output_options_planning: ty.Mapping[str,
                                                      ty.Any], snapshots: bool,
                  vns_name: str, output_options_data: ty.Mapping[str, ty.Any]):
    _logger.info("Starting benchmark instance %s", instance_name)

    # Fetch scenario environment data with additional elevation mode for planning
    env = PlanningEnvironment(
        scenario.area,
        wind_speed=scenario.wind_speed,
        wind_dir=scenario.wind_direction,
        planning_elevation_mode=output_options_planning['elevation_mode'],
        discrete_elevation_interval=DISCRETE_ELEVATION_INTERVAL,
        world=fire_rs.geodata.environment.World(
            landcover_to_fuel_remap=fire_rs.geodata.environment.
            EVERYTHING_FUELMODEL_REMAP))

    # Propagate fires in the environment
    propagation_end_time = scenario.time_window_end + 60 * 10
    _logger.debug("Propagating fire ignitions %s until %s",
                  str(scenario.ignitions), str(propagation_end_time))
    prop = propagation.propagate_from_points(env,
                                             scenario.ignitions,
                                             until=propagation_end_time)
    ignitions = prop.ignitions()

    # Transform altitude of UAV bases from agl (above ground level) to absolute
    for f in scenario.flights:
        base_h = 0.  # If flat, start at the default segment insertion h
        if output_options_planning['elevation_mode'] != 'flat':
            base_h = base_h + env.raster["elevation"][env.raster.array_index(
                (f.base_waypoint.x, f.base_waypoint.y))]
        # The new WP is (old_x, old_y, old_z + elevation[old_x, old_y], old_dir)
        f.base_waypoint = Waypoint(f.base_waypoint.x, f.base_waypoint.y,
                                   base_h, f.base_waypoint.dir)

    conf = {
        'min_time': scenario.time_window_start,
        'max_time': scenario.time_window_end,
        'save_every': 0,
        'save_improvements': snapshots,
        'vns': vns_configurations[vns_name]
    }
    conf['vns']['configuration_name'] = vns_name

    # Define the flight window
    flight_window = TimeWindow(scenario.time_window_start,
                               scenario.time_window_end)

    # Create utility map
    utility = make_utility_map(ignitions,
                               flight_window,
                               layer='ignition',
                               output_layer='utility')
    utility_cpp = utility.as_cpp_raster('utility')

    # Make a FireData object
    fire_data = make_fire_data(ignitions,
                               env.raster,
                               elevation_map_layer='elevation_planning')

    # Create an initial plan
    initial_plan = Plan(instance_name, [f.as_cpp() for f in scenario.flights],
                        fire_data, flight_window, utility_cpp)

    # Set up a Planner object from the initial Plan
    pl = Planner(initial_plan, vns_configurations[vns_name])
    pl.save_improvements = snapshots
    pl.save_every = 0

    search_result = pl.compute_plan()
    final_plan = search_result.final_plan()

    # Propagation was running more time than desired in order to reduce edge effect.
    # Now we need to filter out-of-range ignition times. Crop range is rounded up to the next
    # 10-minute mark (minus 1). This makes color bar ranges and fire front contour plots nicer
    ignitions['ignition'][ignitions['ignition'] > \
                          int(scenario.time_window_end / 60. + 5) * 60. - 60] = _DBL_MAX
    # Representation of unburned cells using max double is not suitable for display,
    # so those values must be converted to NaN
    ignitions_nan = ignitions['ignition'].copy()
    ignitions_nan[ignitions_nan == _DBL_MAX] = np.nan
    first_ignition = np.nanmin(ignitions_nan)
    last_ignition = np.nanmax(ignitions_nan)

    # Create the geodatadisplay object & extensions that are going to be used
    geodatadisplay = GeoDataDisplay.pyplot_figure(
        env.raster.combine(ignitions), frame=(0, 0))
    geodatadisplay.add_extension(TrajectoryDisplayExtension, (None, ), {})

    plot_plan_with_background(final_plan, geodatadisplay,
                              (first_ignition, last_ignition),
                              output_options_plot)

    # Save the picture
    filepath = os.path.join(
        save_directory,
        instance_name + "." + str(output_options_plot.get('format', 'png')))
    _logger.info("Saving as figure as: %s", str(filepath))
    geodatadisplay.axes.get_figure().set_size_inches(
        *output_options_plot.get('size', (15, 10)))
    geodatadisplay.axes.get_figure().savefig(filepath,
                                             dpi=output_options_plot.get(
                                                 'dpi', 150),
                                             bbox_inches='tight')

    # Save rasters
    if output_options_data['save_rasters']:
        raster_data_dir = os.path.join(save_directory, instance_name + "_data")
        if not os.path.exists(raster_data_dir):
            os.makedirs(raster_data_dir)
        env.raster.write_to_file(
            os.path.join(
                raster_data_dir, ".".join(("_".join(
                    (instance_name, "elevation_planning")), 'tif'))),
            'elevation_planning')
        env.raster.write_to_file(
            os.path.join(
                raster_data_dir, ".".join(("_".join(
                    (instance_name, "wind_velocity")), 'tif'))),
            'wind_velocity')
        env.raster.write_to_file(
            os.path.join(
                raster_data_dir, ".".join(("_".join(
                    (instance_name, "wind_angle")), 'tif'))), 'wind_angle')
        prop.ignitions().write_to_file(os.path.join(
            raster_data_dir, ".".join(("_".join(
                (instance_name, "ignition")), 'tif'))),
                                       'ignition',
                                       nodata=np.inf)
        u_initial_map = GeoData.from_cpp_raster(initial_plan.utility_map(),
                                                "utility",
                                                projection=utility.projection)
        u_initial_map.write_to_file(
            os.path.join(
                raster_data_dir, ".".join(("_".join(
                    (instance_name, "utility_initial")), 'tif'))), 'utility')
        u_final_map = GeoData.from_cpp_raster(final_plan.utility_map(),
                                              "utility",
                                              projection=utility.projection)
        u_final_map.write_to_file(
            os.path.join(
                raster_data_dir, ".".join(("_".join(
                    (instance_name, "utility_final")), 'tif'))), 'utility')

    # print([o.as_tuple() for o in final_plan.observations()])

    # Log planned trajectories metadata
    for i, t in enumerate(final_plan.trajectories()):
        _logger.debug("traj #{} duration: {} / {}".format(
            i, t.duration(), t.conf.max_flight_time))

    # save metadata to file
    with open(os.path.join(save_directory, instance_name + ".json"),
              "w") as metadata_file:
        import json
        parsed = json.loads(search_result.metadata())
        parsed["benchmark_id"] = instance_name
        parsed["date"] = datetime.datetime.now().isoformat()
        metadata_file.write(json.dumps(parsed, indent=4))

    matplotlib.pyplot.close(geodatadisplay.axes.get_figure())

    # If intermediate plans are available, save them
    for i, plan in enumerate(search_result.intermediate_plans):
        geodatadisplay = GeoDataDisplay.pyplot_figure(
            env.raster.combine(ignitions))
        geodatadisplay.add_extension(TrajectoryDisplayExtension, (None, ), {})
        plot_plan_with_background(plan, geodatadisplay,
                                  (first_ignition, last_ignition),
                                  output_options_plot)

        i_plan_dir = os.path.join(save_directory, instance_name)
        if not os.path.exists(i_plan_dir):
            os.makedirs(i_plan_dir)

        filepath = os.path.join(
            i_plan_dir,
            str(i) + "." + str(output_options_plot.get('format', 'png')))

        _logger.info("Saving intermediate plan as: %s", str(filepath))
        geodatadisplay.axes.get_figure().set_size_inches(
            *output_options_plot.get('size', (15, 10)))
        geodatadisplay.axes.get_figure().savefig(filepath,
                                                 dpi=output_options_plot.get(
                                                     'dpi', 150),
                                                 bbox_inches='tight')
        matplotlib.pyplot.close(geodatadisplay.axes.get_figure())

    del search_result
예제 #14
0
        conf['vns']['configuration_name'] = 'demo'
        return conf

    # Prepare initial run
    # - VNS params: some_vns_conf
    # - elevation: pl_env
    # - wind: pl_env
    # - Trajectory config: flight_confs_cpp
    # - Firemap: ignitions
    # - Initial plan: Not necessary (c++ plan_vns do it for us)
    scene = benchmark.generate_scenario_singlefire_singleuav_3d()
    pl_env = get_initial_planning_environment(scene)
    some_vns_conf = get_some_vns_conf(scene)
    flight_confs_cpp = [f.as_cpp() for f in scene.flights]
    prop = wildfire.propagate_from_points(pl_env,
                                          scene.ignitions,
                                          until=scene.time_window_end +
                                          60 * 10)
    ignitions = prop.ignitions()

    observation_planner = planning.Planner(
        pl_env,
        ignitions,
        scene.flights,
        some_vns_conf,
    )
    search_result = observation_planner.compute_plan()

    # TODO: Implement a LSTSsim class that receives a plan and when run:
    # TODO: Obs fire, actual trajectory, plan execution report
    # TODO: The called function must preempt the main loop.
    # neptus.send_plan_to_dune(search_result.final_plan())