def generate_scenario_singlefire_singleuav(): # 9 by 7 km area area = Area(480060.0, 489060.0, 6210074.0, 6217074.0) uav_speed = 18. # m/s uav_max_pitch_angle = 6. / 180. * np.pi uav_max_turn_rate = 32. * np.pi / 180 / 2 # Consider a more conservative turn rate uav_bases = [Waypoint(area.xmin + 100, area.ymin + 100, 0, 0)] wind_speed = 15. wind_dir = 0. num_ignitions = 1 ignitions = [ TimedPoint(random.uniform(area.xmin, area.xmax), random.uniform(area.ymin, area.ymax), random.uniform(0, 3000)) for i in range(num_ignitions) ] # start once all fires are ignited start = max([igni.time for igni in ignitions]) num_flights = 1 flights = [] for i in range(num_flights): uav_start = random.uniform(start, start + 4000.) max_flight_time = random.uniform(1000, 1500) name = " ".join(("UAV", str(i))) uav = UAV("x8-06", uav_speed, uav_max_turn_rate, uav_max_pitch_angle) flights.append( FlightConf(name, uav, uav_start, max_flight_time, random.choice(uav_bases))) scenario = Scenario(((area.xmin, area.xmax), (area.ymin, area.ymax)), wind_speed, wind_dir, ignitions, flights) return scenario
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())
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
def propagate_from_cell(env: Environment, cell: Cell, until=np.inf) -> 'FirePropagation': """Set the environment on fire in (x, y) at time 0 and returns the ignition times of other points of the environment. :param env: Environment model :param cell: (x,y) coordinates of the ignition point (as array index) :param until: Wall-clock time at which to stop the propagation :return: A matrix of ignition time. The size of the matrix is given by the size of the environment """ fp = FirePropagation(env) pt = env.raster.coordinates(cell) fp.set_ignition_point(TimedPoint(pt.x, pt.y, 0)) fp.propagate(until=until) return fp
def generate_scenario_big_fire(): """A dozen UAVs monitoring a dozen fires""" # 9 by 7 km area area = Area(532000.0, 540000.0, 4567000.0, 4575000.0) uav_speed = 18. # m/s uav_max_pitch_angle = 6. / 180. * np.pi uav_max_turn_rate = 32. * np.pi / 180 uav_bases = [ # four corners of the map Waypoint(area.xmin + 100, area.ymin + 100, 0, 0), Waypoint(area.xmin + 100, area.ymax - 100, 0, 0), Waypoint(area.xmax - 100, area.ymin + 100, 0, 0), Waypoint(area.xmax - 100, area.ymax - 100, 0, 0) ] wind_speed = random.uniform(1., 2.) # wind speed in [10,20] km/h wind_dir = random.random() * 2 * np.pi num_ignitions = random.randint(1, 1) # Calculate a safe area for the ignitions allowed_range_x = (area.xmax - area.xmin) * 0.25 allowed_range_y = (area.ymax - area.ymin) * 0.25 ignitions = [ TimedPoint( random.uniform(area.xmin + allowed_range_x, area.xmax - allowed_range_x), random.uniform(area.ymin + allowed_range_y, area.ymax - allowed_range_y), random.uniform(0, 0)) for i in range(num_ignitions) ] # start once all fires are ignited start = max([igni.time for igni in ignitions]) num_flights = random.randint(1, 5) flights = [] for i in range(num_flights): uav_start = random.uniform(start + 50000., start + 50000.) max_flight_time = random.uniform(500, 1200) name = " ".join(("UAV", str(i))) uav = UAV("x8-06", uav_speed, uav_max_turn_rate, uav_max_pitch_angle) flights.append( FlightConf(name, uav, uav_start, max_flight_time, random.choice(uav_bases))) scenario = Scenario(((area.xmin, area.xmax), (area.ymin, area.ymax)), wind_speed, wind_dir, ignitions, flights) return scenario
def generate_scenario_newsletter(): # 9 by 7 km area area = Area(545000.0, 548000.0, 6211000.0, 6214000.0) uav_max_pitch_angle = 6. / 180. * np.pi # aka gamma_max=0.11rad for 2m/s rate of climb and 18m/s cruise air speed uav_speed = 18. # m/s uav_max_turn_rate = 32. * np.pi / 180 / 2 # Consider a more conservative turn rate uav_bases = [Waypoint(area.xmin + 100, area.ymax - 100, 100., 0.)] num_ignitions = 1 wind_speed = random.choice([ 10., ]) # 18 km/h, 36 km/h, 54 km/h, 72 km/h wind_dir = random.choice([ np.pi / 4, ]) area_range = (area.xmax - area.xmin, area.ymax - area.ymin) ignitions = [ TimedPoint( random.uniform(area.xmin + area_range[0] * .2, area.xmax - area_range[0] * .4), random.uniform(area.ymin + area_range[1] * .4, area.ymax - area_range[1] * .6), random.uniform(0, 3000)) for i in range(num_ignitions) ] # start once all fires are ignited start = max([igni.time for igni in ignitions]) num_flights = 1 flights = [] for i in range(num_flights): uav_start = start + 3000 max_flight_time = 450 name = " ".join(("UAV", str(i))) uav = UAV("x8-06", uav_speed, uav_max_turn_rate, uav_max_pitch_angle) flights.append( FlightConf(name, uav, uav_start, max_flight_time, random.choice(uav_bases))) scenario = Scenario(((area.xmin, area.xmax), (area.ymin, area.ymax)), wind_speed, wind_dir, ignitions, flights) return scenario
def scenario_a(): # 9 by 7 km area area = Area(532000.0, 540000.0, 4567000.0, 4575000.0) uav_speed = 18. # m/s uav_max_pitch_angle = 6. / 180. * np.pi uav_max_turn_rate = 32. * np.pi / 180 uav_bases = [ # four corners of the map Waypoint(area.xmin + 100, area.ymin + 100, 0, 0), Waypoint(area.xmin + 100, area.ymax - 100, 0, 0), Waypoint(area.xmax - 100, area.ymin + 100, 0, 0), Waypoint(area.xmax - 100, area.ymax - 100, 0, 0) ] wind_speed = 15. # random.uniform(10., 20.) # wind speed in [10,20] km/h wind_dir = 0. # random.random() * 2 * np.pi num_ignitions = random.randint(1, 3) ignitions = [ TimedPoint(random.uniform(area.xmin, area.xmax), random.uniform(area.ymin, area.ymax), random.uniform(0, 3000)) for i in range(num_ignitions) ] # start once all fires are ignited start = max([igni.time for igni in ignitions]) num_flights = random.randint(1, 3) flights = [] for i in range(num_flights): uav_start = random.uniform(start, start + 4000.) max_flight_time = random.uniform(500, 1200) name = " ".join(("UAV", str(i))) uav = UAV("x8-06", uav_speed, uav_max_turn_rate, uav_max_pitch_angle) flights.append( FlightConf(name, uav, uav_start, max_flight_time, random.choice(uav_bases))) scenario = Scenario(((area.xmin, area.xmax), (area.ymin, area.ymax)), wind_speed, wind_dir, ignitions, flights) return scenario
def generate_scenario_utility_test(): # 2 by 2 km area area = Area(480060.0, 482060.0, 6210074.0, 6212074.0) uav_max_pitch_angle = 6. / 180. * np.pi # aka gamma_max=0.11rad for 2m/s rate of climb and 18m/s cruise air speed uav_speed = 18. # m/s uav_max_turn_rate = 32. * np.pi / 180 / 2 # Consider a more conservative turn rate uav_bases = [Waypoint(area.xmin + 100, area.ymin + 100, 0., 0.)] num_ignitions = 1 wind_speed = random.choice([5., 10., 15., 20.]) # 18 km/h, 36 km/h, 54 km/h, 72 km/h wind_dir = random.choice([0., np.pi / 2, np.pi, 3 * np.pi / 4]) area_range = (area.xmax - area.xmin, area.ymax - area.ymin) ignitions = [ TimedPoint( random.uniform(area.xmin + area_range[0] * .1, area.xmax - area_range[0] * .1), random.uniform(area.ymin + area_range[1] * .1, area.ymax - area_range[1] * .1), random.uniform(0, 3000)) for i in range(num_ignitions) ] # start once all fires are ignited start = max([igni.time for igni in ignitions]) num_flights = 1 flights = [] for i in range(num_flights): uav_start = random.uniform(start + 2500, start + 7500.) max_flight_time = random.uniform(1000, 1500) name = " ".join(("UAV", str(i))) uav = UAV("x8-06", uav_speed, uav_max_turn_rate, uav_max_pitch_angle) flights.append( FlightConf(name, uav, uav_start, max_flight_time, random.choice(uav_bases))) scenario = Scenario(((area.xmin, area.xmax), (area.ymin, area.ymax)), wind_speed, wind_dir, ignitions, flights) return scenario
import fire_rs.geodata.display 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,
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
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
def setUp(self): self.test_area = [[480060.0, 485060.0], [6210074.0, 6215074.0]] self.ignition_point = TimedPoint(480060 + 800, 6210074 + 2500, 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()