def main(): parser = ArgumentParser(description = "A simulation of a flock of birds.") parser.add_argument('--config', '-c', default = 'config.cfg', help = 'select config file') arguments = parser.parse_args() config = ConfigParser.ConfigParser() with open(arguments.config) as config_file: config.readfp(config_file) no_of_boids = config.getint('boids_initiate', 'no_of_boids') position_limits = json.loads(config.get('boids_initiate', 'position_limits')) velocity_limits = json.loads(config.get('boids_initiate', 'velocity_limits')) move_to_middle_strength = config.getfloat('boids_initiate', 'move_to_middle_strength') alert_distance = config.getfloat('boids_initiate', 'alert_distance') formation_flying_distance = config.getfloat('boids_initiate', 'formation_flying_distance') formation_flying_strength = config.getfloat('boids_initiate', 'formation_flying_strength') xlim = json.loads(config.get('run_simulation','xlim')) ylim = json.loads(config.get('run_simulation', 'ylim')) frames = config.getint('run_simulation', 'frames') interval = config.getint('run_simulation', 'interval') boids = Boids(no_of_boids = no_of_boids, position_limits = position_limits, velocity_limits = velocity_limits, move_to_middle_strength = move_to_middle_strength, alert_distance = alert_distance, formation_flying_distance = formation_flying_distance, formation_flying_strength = formation_flying_strength) boids.run_simulation(xlim = tuple(xlim), ylim = tuple(ylim), frames = frames, interval = interval)
def test_new_flock(): boids = Boids() array = boids.new_flock(np.array([0, 50]), np.array([50, 100])) x_array = array[0, :] y_array = array[1, :] assert_equals(array.shape, (2, 50)) assert_true((x_array > 0).all() and (x_array < 50).all()) assert_true((y_array > 50).all() and (y_array < 100).all())
def process(): parser = ArgumentParser(description = "Boid simulator: Simulates birds flying in flocks using the boids model.") parser.add_argument('--config', '-c', type=str, default="", help="Boid simulator YAML configuration file. Defaults are shown and used if not specified.") parser.add_argument('--count', type=int, default=0, required=False, help="Overwrite bird count given in cfg file.") parser.add_argument('--fly_to_middle_strength', type=float, default=0, required=False, help="Overwrite settings given in cfg file.") parser.add_argument('--alert_distance', type=float,default=0, required=False, help="Overwrite settings given in cfg file.") parser.add_argument('--formation_flying_distance', type=float,default=0, required=False, help="Overwrite settings given in cfg file.") parser.add_argument('--formation_flying_strength', type=float,default=0, required=False, help="Overwrite settings given in cfg file.") arguments= parser.parse_args() #dictionary containing the configuration for the boids simulator cfg={} #default settings YAML default="""Boids: count: 50 vxlim: [0, 10] vylim: [-20, 20] xlim: [-450, 50] ylim: [300, 600] Dynamics: alert_distance: 100 fly_to_middle_strength: 0.01 formation_flying_strength: 0.125 formation_flying_distance: 10000 Animation: frames: 50 interval: 50 xlim: [-500, 1500] ylim: [-500, 1500]""" #open given cfg file within try block to catch wrong filename etc. try: with open(arguments.config) as cfg_file: cfg=yaml.load(cfg_file) #check if config fullfills requirements if not all (k in cfg.keys() for k in ('Boids', 'Dynamics', 'Animation')): raise Exception if not all (k in cfg['Boids'].keys() for k in ('count', 'vylim', 'vxlim', 'xlim', 'ylim')): raise Exception if not all (k in cfg['Dynamics'].keys() for k in ('formation_flying_distance','alert_distance','fly_to_middle_strength','formation_flying_strength')): raise Exception if not all (k in cfg['Animation'].keys() for k in ('frames', 'interval', 'ylim', 'xlim')): raise Exception except: #use default settings if no or wrong config file given! print "Something went wrong when reading the configuration file. Check that all needed configuration elements are given and that the filename is correct." print "Using the default settings! See below for the corresponding YAML file." print default cfg=yaml.load(StringIO(default)) #run boids simulation with given settings boids=Boids(cfg, arguments.count, arguments.fly_to_middle_strength, arguments.alert_distance, arguments.formation_flying_distance, arguments.formation_flying_strength) boids.simulate()
def test_animate(): with patch.object(Boids, 'update_boids') as mock_get: new_flock = Boids(2, config_filename) """new_flock.positions[0][0] = 0 new_flock.positions[1][0] = 0 new_flock.positions[0][1] = 1 new_flock.positions[1][1] = 0""" new_flock.animate() print mock_get.mock_calls mock_get.assert_called_with()
def test_fly_towards_the_middle(): data = yaml.load(open(os.path.join(os.path.dirname(__file__), 'fixtures', 'fixture_fly_towards_the_middle.yml'))) boid_data_before = np.array(data["before"]) boid_data_after = np.array(data["after"]) move_to_middle_strength = data["move_to_middle_strength"] boids = Boids() boids.boids = boid_data_before boids.fly_towards_the_middle(boids.boids, move_to_middle_strength) np.testing.assert_array_almost_equal(boids.boids, boid_data_after)
def test_fly_away_from_nearby_boids(): data = yaml.load( open(os.path.join(os.path.dirname(__file__), 'fixtures', 'fixture_fly_away_from_nearby_boids.yml'))) boid_data_before = np.array(data["before"]) boid_data_after = np.array(data["after"]) alert_distance = data["alert_distance"] boids = Boids() boids.boids = boid_data_before boids.fly_away_from_nearby_boids(boids.boids, alert_distance) np.testing.assert_array_almost_equal(boids.boids, boid_data_after)
def test_separation(): data = yaml.load(open(os.path.join(os.path.dirname(__file__), 'fixtures', 'fixture_separation.yml'))) xcoords = np.array(data["xcoords"]) ycoords = np.array(data["ycoords"]) x_separation = np.array(data["x_separation"]) y_separation = np.array(data["y_separation"]) separation_distance_squared = np.array(data["separation_distance_squared"]) boids = Boids(boid_count=data["boid_count"]) calc_separations, calc_separation_distance_squared = boids.separation((xcoords, ycoords)) np.testing.assert_array_almost_equal(calc_separations, (x_separation, y_separation)) np.testing.assert_array_almost_equal(calc_separation_distance_squared, separation_distance_squared)
def test_match_speed_with_nearby_boids(): data = yaml.load( open(os.path.join(os.path.dirname(__file__), 'fixtures', 'fixture_match_speed_with_nearby_boids.yml'))) boid_data_before = np.array(data["before"]) boid_data_after = np.array(data["after"]) formation_flying_distance = data["formation_flying_distance"] formation_flying_strength = data["formation_flying_strength"] boids = Boids() boids.boids = boid_data_before boids.match_speed_with_nearby_boids(boids.boids, formation_flying_distance, formation_flying_strength) np.testing.assert_array_almost_equal(boids.boids, boid_data_after)
def test_update_boids(): data = yaml.load(open(os.path.join(os.path.dirname(__file__), 'fixtures', 'fixture_update_boids_only.yml'))) boid_data_before = np.array(data["before"]) boid_data_after = np.array(data["after"]) boid_count = data["boid_count"] boids = Boids(boid_count=boid_count) boids.boids = boid_data_before with patch.object(boids, 'fly_towards_the_middle') as mocked1: with patch.object(boids, 'fly_away_from_nearby_boids') as mocked2: with patch.object(boids, 'match_speed_with_nearby_boids') as mocked3: boids.update_boids(boids.boids) np.testing.assert_almost_equal(boids.boids, boid_data_after)
def create_boids(dims): if dims == 3: bb = BigBoids( num_big_boids=1, dimensions=3, start_center=[1.6, 1.6, 0.5], max_velocity2= 0.001, # avoids ever-increasing velocity that causes it to escape the screen approach_factor=0.001 # velocity at which it approaches the boids ) b = Boids( num_boids=1000, big_boids=bb, dimensions=3, start_center=[0.1, 0.1, 0.5], rule1_factor=0.0003, # factor for going to the common center rule2_threshold=0.005, # threshold for birds being close rule2_factor= 0.08, # speed at which close birds should move outside the threshold rule3_factor= 0.04, # factor for going at the same velocity as average escape_threshold=0.03, # threshold for a big bird being close max_velocity2= 0.001, # avoids ever-increasing velocity that causes boids to escape the screen rule_direction=0.003 # factor for going to a random direction ) else: bb = BigBoids( num_big_boids=1, dimensions=2, start_center=[1.6, 1.6], max_velocity2= 0.0009, # avoids ever-increasing velocity that causes it to escape the screen approach_factor=0.001 # velocity at which it approaches the boids ) b = Boids( num_boids=1000, big_boids=bb, dimensions=2, start_center=[0.1, 0.1], rule1_factor=0.0003, # factor for going to the common center rule2_threshold=0.001, # threshold for birds being close rule2_factor= 0.08, # speed at which close birds should move outside the threshold rule3_factor= 0.06, # factor for going at the same velocity as average escape_threshold=0.01, # threshold for a big bird being close max_velocity2= 0.0008, # avoids ever-increasing velocity that causes boids to escape the screen rule_direction=0.003 # factor for going to a random direction ) bb.set_boids(b) return (b, bb)
def test_Boids(): maxlim = 100 minlim = -100 lims = [minlim,maxlim] for boid_count in (10, 2): boidobject = Boids(boid_count=boid_count,x_positions=lims) assert_equals(boidobject.boids_x.size, boid_count) assert_equals(boidobject.boids_y.size, boid_count) assert_equals(boidobject.boid_x_velocities.size, boid_count) assert_equals(boidobject.boid_y_velocities.size, boid_count) assert (boidobject.boids_x>=minlim).all() and (boidobject.boids_x<=maxlim).all() with assert_raises(ValueError): boidobject = Boids(boid_count=-2)
def main(): _ROOT = os.path.abspath(os.path.dirname(__file__)) defaultconfig = os.path.join(_ROOT, 'config.yml') parser = ArgumentParser(description="Boid Flocking Modelling") parser.add_argument('--config', default=defaultconfig, help="Configuration file", metavar="FILE") parser.add_argument('--saveto', help="Filename to save animation", metavar="FILE") args = parser.parse_args() try: with open(args.config, 'r') as ymlfile: configdata = yaml.load(ymlfile) boid_count = configdata['Boids_Setup']['boid_count'] x_positions = configdata['Boids_Setup']['x_positions'] y_positions = configdata['Boids_Setup']['y_positions'] x_velocities = configdata['Boids_Setup']['x_velocities'] y_velocities = configdata['Boids_Setup']['y_velocities'] move_to_middle_strength = configdata['Flock_Dynamics']['move_to_middle_strength'] alert_distance = configdata['Flock_Dynamics']['alert_distance'] formation_flying_distance = configdata['Flock_Dynamics']['formation_flying_distance'] formation_flying_strength = configdata['Flock_Dynamics']['formation_flying_strength'] xlim = configdata['Axis_Limits']['xlim'] ylim = configdata['Axis_Limits']['ylim'] frames = configdata['Animation']['frames'] interval = configdata['Animation']['interval'] saveto = args.saveto #works even if it is None boidsobject = Boids(boid_count=boid_count, x_positions=x_positions, y_positions=y_positions, x_velocities=x_velocities, y_velocities=y_velocities, move_to_middle_strength=move_to_middle_strength, alert_distance=alert_distance, formation_flying_distance=formation_flying_distance, formation_flying_strength=formation_flying_strength) boidsobject.model(xlim=xlim, ylim=ylim, frames=frames, interval=interval, savefile=saveto) except IOError as error: print('IOError: No such config file') except KeyError as error: print('KeyError: Missing parameters in config file')
def boid(config_name='config.yaml'): config = yaml.load( open(os.path.join(os.path.dirname(__file__), config_name))) flock_1 = Boids( Boids_total=config['boid_count'], dimension_limits=config['dimension_limits'], velocity_limits=config['velocity_limits'], Limits=config['Limits'], move_to_middle_strength=config['move_to_middle_strength'], alert_distance=config['alert_distance'], formation_flying_distance=config['formation_flying_distance'], formation_flying_strength=config['formation_flying_strength'], frames=config['frames'], interval=config['interval']) flock_1.show_sim()
def create_boids_3D(nboids=1000, nbig=1, use_process=False): bb = BigBoids( num_big_boids=nbig, dimensions=3, start_center=[-1.0, -1.0, 0.0], max_velocity2= 1.0, # avoids ever-increasing velocity that causes it to escape the screen approach_factor=1.0, # velocity at which it approaches the boids dt=dt) b = Boids( num_boids=nboids, big_boids=bb, dimensions=3, start_center=[0.5, 0.5, 0.5], rule1_factor=1.9, # factor for going to the common center rule2_threshold=0.01, # threshold for birds being close rule2_factor= 5.0, # speed at which close birds should move outside the threshold rule3_factor=8.0, # factor for going at the same velocity as average escape_threshold=0.014, # threshold for a big bird being close min_velocity2=0.2, # avoids too much passivity max_velocity2= 1.0, # avoids ever-increasing velocity that causes boids to escape the screen rule_direction=1.0, # factor for going to a random direction bounds_factor=1.1, dt=dt, num_neighbors=60, # escape_factor = 0.3, enforce_bounds=True, in_random_direction=False, use_global_velocity_average=False, use_process=use_process) bb.set_boids(b) return (b, bb)
def test_bad_boids_regression(): regression_data = yaml.load( open(os.path.join(os.path.dirname(__file__), 'fixtures', 'fixture.yml'))) boid_data = np.array(regression_data["before"]) Boids().update_boids(boid_data) after_data = np.array(regression_data["after"]) for after, before in zip(after_data, boid_data): for after_value, before_value in zip(after, before): np.testing.assert_almost_equal(after_value, before_value)
def main(): parser = ArgumentParser(description="A simulation of a flock of birds.") parser.add_argument('--config', '-c', default='config.cfg', help='select config file') arguments = parser.parse_args() config = ConfigParser.ConfigParser() with open(arguments.config) as config_file: config.readfp(config_file) no_of_boids = config.getint('boids_initiate', 'no_of_boids') position_limits = json.loads( config.get('boids_initiate', 'position_limits')) velocity_limits = json.loads( config.get('boids_initiate', 'velocity_limits')) move_to_middle_strength = config.getfloat('boids_initiate', 'move_to_middle_strength') alert_distance = config.getfloat('boids_initiate', 'alert_distance') formation_flying_distance = config.getfloat( 'boids_initiate', 'formation_flying_distance') formation_flying_strength = config.getfloat( 'boids_initiate', 'formation_flying_strength') xlim = json.loads(config.get('run_simulation', 'xlim')) ylim = json.loads(config.get('run_simulation', 'ylim')) frames = config.getint('run_simulation', 'frames') interval = config.getint('run_simulation', 'interval') boids = Boids(no_of_boids=no_of_boids, position_limits=position_limits, velocity_limits=velocity_limits, move_to_middle_strength=move_to_middle_strength, alert_distance=alert_distance, formation_flying_distance=formation_flying_distance, formation_flying_strength=formation_flying_strength) boids.run_simulation(xlim=tuple(xlim), ylim=tuple(ylim), frames=frames, interval=interval)
def test_bad_boids_regression(): # open(os.path.join(os.path.dirname(__file__),'boids.py')) config_filename = os.path.join(os.path.dirname(__file__),'fixtures/config.yaml') regression_data=yaml.load(open(os.path.join(os.path.dirname(__file__),'fixtures/fixture.yaml'))) boids = Boids(10, config_filename) boid_data = np.asarray(regression_data["before"]) boids.positions = np.array([boid_data[0], boid_data[1]]) boids.velocities = np.array([boid_data[2], boid_data[3]]) boids.update_boids() new_boid_data = np.asarray(regression_data["after"]) new_positions = np.asarray([new_boid_data[0], new_boid_data[1]]) new_velocities = np.asarray([new_boid_data[2], new_boid_data[3]]) new_boids = (new_positions, new_velocities) for after,before in zip(new_positions,boids.positions): for after_value,before_value in zip(after,before): assert_almost_equal(after_value,before_value,delta=0.06)
def process(): """ Description: A function to communicate with the command line. This function is linked with the setup.py file. """ parser = ArgumentParser(description="The Boids Flocking Bird Simulation") parser.add_argument("--config", "-c", help="Config file", default="config.cfg") args = parser.parse_args() config = ConfigParser.ConfigParser() with open(args.config) as f: config.readfp(f) # pull boids config data count = config.getint("Boids", "count") position_limits = json.loads(config.get("Boids", "position_limits")) velocity_limits = json.loads(config.get("Boids", "velocity_limits")) # pull boid dynamics config data move_to_middle_strength = config.getfloat("Dynamics", "move_to_middle_strength") alert_distance = config.getfloat("Dynamics", "alert_distance") formation_flying_distance = config.getfloat("Dynamics", "formation_flying_distance") formation_flying_strength = config.getfloat("Dynamics", "formation_flying_strength") # pull display config data (for animation) xlim = tuple(json.loads(config.get("Display", "xlim"))) ylim = tuple(json.loads(config.get("Display", "ylim"))) frames = config.getint("Display", "frames") # check if should be float! interval = config.getint("Display", "interval") # check if can be float! boids = Boids( count, position_limits, velocity_limits, move_to_middle_strength, alert_distance, formation_flying_distance, formation_flying_strength, ) boids.deploy_simulation(xlim, ylim, frames, interval)
def process(): parser = ArgumentParser(description='Simulate boids') parser.add_argument('boid_no', type=int, help='Number of boids') parser.add_argument('config_file', help='Configuration file') parser.add_argument('--example_view', '-ex', help='View config file example', action='store_true') #parser.add_argument('--generate_example', '-gen', type = str, help = 'Generate config.yaml example file in current directory.') #parser.add_argument('--save', '-s', type =str, help = 'Save animation as .mp4 file. Input is the filename.') arguments = parser.parse_args() # print 'Boids -- Simulating animal flocking behaviour. \n Input -h for help. ' #gen = (x for x in args_iterate if type(x) == None) #for x in gen: if arguments.example_view: print 'The following is an example yaml config file. Copy the test below and past it into a file called filename.yaml. Make sure that the indentation is preserved. \n \n - position: \n \t xmin: ' "-450" ' \n \t xmax: "50" \n \t ymin: "300" \n \t ymax: "600" \n \n - velocity: \n \t vxmin: "0" \n \t vxmax: "10" \n \t vymin: "-20"\n \t vymax: "20"' quit() """ if arguments.generate_example: __location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) if not os.path.exists(__location__ + arguments.generate_example): os.makedirs(path) quit() """ new_flock = Boids(arguments.boid_no, arguments.config_file) anim = animation.FuncAnimation(new_flock.figure, new_flock.animate, frames=50, interval=50) plt.show() """
def test_bad_boids_regression(): # open(os.path.join(os.path.dirname(__file__),'boids.py')) config_filename = os.path.join(os.path.dirname(__file__), 'fixtures/config.yaml') regression_data = yaml.load( open(os.path.join(os.path.dirname(__file__), 'fixtures/fixture.yaml'))) boids = Boids(10, config_filename) boid_data = np.asarray(regression_data["before"]) boids.positions = np.array([boid_data[0], boid_data[1]]) boids.velocities = np.array([boid_data[2], boid_data[3]]) boids.update_boids() new_boid_data = np.asarray(regression_data["after"]) new_positions = np.asarray([new_boid_data[0], new_boid_data[1]]) new_velocities = np.asarray([new_boid_data[2], new_boid_data[3]]) new_boids = (new_positions, new_velocities) for after, before in zip(new_positions, boids.positions): for after_value, before_value in zip(after, before): assert_almost_equal(after_value, before_value, delta=0.06)
from matplotlib import pyplot as plt from matplotlib import animation import yaml import os # Load plot config from plot_config.yml plot_config = yaml.load(open(os.path.join(os.path.dirname(__file__), 'plot_config.yml'))) xlim_max = plot_config["xlim_max"] xlim_min = plot_config["xlim_min"] ylim_max = plot_config["ylim_max"] ylim_min = plot_config["ylim_min"] framesT = plot_config["frames"] intervalT = plot_config["interval"] # Create a Boid object (ie a flock of boids) my_boids = Boids() # Create a plot figure figure = plt.figure() axes = plt.axes(xlim=(xlim_min, xlim_max), ylim=(ylim_min, ylim_max)) scatter = axes.scatter(my_boids.get_boids()[0], my_boids.get_boids()[1]) # A function to run the simulation and update the plot def animate(frame): my_boids.update_boids() scatter.set_offsets(zip(my_boids.get_boids()[0], my_boids.get_boids()[1])) # Animate the plot anim = animation.FuncAnimation(figure, animate, frames=framesT, interval=intervalT)
def test_negative_boid_no(): with assert_raises(ValueError) as exception: new_flock = Boids(-10, config_filename)
def test_initialise(): with patch.object(numpy.random, 'rand') as mock_get: new_flock = Boids(10, config_filename) print mock_get.mock_calls mock_get.assert_called_with(2, 10)
def test_zero_boids(): with assert_raises(ValueError) as exception: new_flock = Boids(0, config_filename)
if __name__ == '__main__': print("Starting boids.") parser = argparse.ArgumentParser( description="Implementing Craig Reynold's Boids.") # adding arguments parser.add_argument('--num-boids', dest='N', required=False) args = parser.parse_args() N = 100 if args.N: N = int(args.N) boids = Boids(N) fig = plt.figure() ax = plt.axes(xlim=(0, width), ylim=(0, height)) # plt.plot([300,20],[300,50]) body, = ax.plot([], [], markersize=10, c='k', marker='o', ls='None') head, = ax.plot([], [], markersize=4, c='r', marker='o', ls='None') ani = animation.FuncAnimation(fig, tick, fargs=(body, head, boids), interval=50) # cid = fig.canvas.mpl_connect('button_press_event', boids.button_press) plt.show()
def test_avoid_collissions(): new_flock = Boids(2, config_filename) new_flock.positions[0][0] = 0 new_flock.positions[1][0] = 0 new_flock.positions[0][1] = 1 new_flock.positions[1][1] = 0 new_flock.velocities[0][0] = 0 new_flock.velocities[0][1] = 0 new_flock.velocities[1][0] = 0 new_flock.velocities[1][1] = 0 old_velocities_x1 = new_flock.velocities[0][0] old_velocities_x2 = new_flock.velocities[0][1] old_velocities_y1 = new_flock.velocities[1][0] old_velocities_y2 = new_flock.velocities[1][1] new_flock.avoid_collisions() print new_flock.velocities assert (old_velocities_x1 > new_flock.velocities[0][0]) assert (old_velocities_x2 < new_flock.velocities[0][1]) assert (old_velocities_y1 == 0) assert (old_velocities_y2 == 0)
matplotlib.use('agg') import numpy as np import rendermpl from boids import Boids from rules import Separation, Alignment, Cohesion, Drag N = 400 dims = 2 boids = Boids( N, dims=dims, rules=[ Separation(.1, 1), #Drag(.5), Alignment(.1, 4), Cohesion(.1, 4), ]) #xx, yy = np.meshgrid(np.linspace(0,1,20), np.linspace(0,1,20)) #boids.velocity[(yy<.5).ravel(),0] = 1 #boids.velocity[(yy>=.5).ravel(),0] = -1 #boids.position = np.random.random((N,dims)).astype(float) boids['position'] = np.random.random((N, dims)).astype(float) boids['velocity'][boids['position'][:, 1] < 0.5, 0] = 1 boids['velocity'][boids['position'][:, 1] <= 0.5, 0] = -1
import yaml import sys sys.path.append("..") # Adds higher directory to python modules path. from boids import Boids boids=Boids({}) before=boids.positions.tolist() + boids.velocities.tolist() #boids.update_boids() boids.velocities += boids._match_speed_nearby(10000,0.125) boids.positions += boids.velocities after=boids.positions.tolist() + boids.velocities.tolist() fixture={"before":before,"after":after} fixture_file=open("fixtures/matchSpeed.yml",'w') fixture_file.write(yaml.dump(fixture)) fixture_file.close()
def test_bad_input_file(): with assert_raises(IOError) as exception: new_flock = Boids(10, 'file_that_does_not_exist')
def test_avoid_collissions(): new_flock = Boids(2, config_filename) new_flock.positions[0][0] = 0 new_flock.positions[1][0] = 0 new_flock.positions[0][1] = 1 new_flock.positions[1][1] = 0 new_flock.velocities[0][0] = 0 new_flock.velocities[0][1] = 0 new_flock.velocities[1][0] = 0 new_flock.velocities[1][1] = 0 old_velocities_x1 = new_flock.velocities[0][0] old_velocities_x2 = new_flock.velocities[0][1] old_velocities_y1 = new_flock.velocities[1][0] old_velocities_y2 = new_flock.velocities[1][1] new_flock.avoid_collisions() print new_flock.velocities assert(old_velocities_x1 > new_flock.velocities[0][0]) assert(old_velocities_x2 < new_flock.velocities[0][1]) assert(old_velocities_y1 == 0) assert(old_velocities_y2 == 0)
def test_wrong_boid_no_type(): with assert_raises(TypeError) as exception: new_flock = Boids('string', config_filename)
def test_match_speed(): # Check that velocities match. Should change in y-direction but stay constant in x-direction for input values. new_flock = Boids(2, config_filename) new_flock.positions[0][0] = 0 new_flock.positions[1][0] = 10 new_flock.positions[0][1] = 0 new_flock.positions[1][1] = 10 new_flock.velocities[0][0] = 0 new_flock.velocities[0][1] = 0 new_flock.velocities[1][0] = 0 new_flock.velocities[1][1] = 10 old_velocities_x1 = new_flock.velocities[0][0] old_velocities_x2 = new_flock.velocities[0][1] old_velocities_y1 = new_flock.velocities[1][0] old_velocities_y2 = new_flock.velocities[1][1] new_flock.match_velocity() assert(old_velocities_x1 == new_flock.velocities[0][0]) assert(old_velocities_x2 == new_flock.velocities[0][1]) assert(old_velocities_y1 < new_flock.velocities[1][0]) assert(old_velocities_y2 > new_flock.velocities[1][1])
def test_fly_towards_middle(): new_flock = Boids(2, config_filename) # Set initial positions new_flock.positions[0][0] = 0 new_flock.positions[1][0] = 0 new_flock.positions[0][1] = 0 new_flock.positions[1][1] = 10 new_flock.velocities[0][0] = 0 new_flock.velocities[0][1] = 0 new_flock.velocities[1][0] = 0 new_flock.velocities[1][1] = 0 old_position_x1 = new_flock.positions[0][0] old_position_x2 = new_flock.positions[0][1] old_position_y1 = new_flock.positions[1][0] old_position_y2 = new_flock.positions[1][1] old_velocities_x1 = new_flock.velocities[0][0] old_velocities_x2 = new_flock.velocities[0][1] old_velocities_y1 = new_flock.velocities[1][0] old_velocities_y2 = new_flock.velocities[1][1] new_flock.fly_to_middle() assert(old_velocities_x1 == new_flock.velocities[0][0]) assert(old_velocities_x2 == new_flock.velocities[0][1]) assert(old_velocities_y1 < new_flock.velocities[1][0]) assert(old_velocities_y2 > new_flock.velocities[1][1])
def boid(config_name = 'config.yaml'): config = yaml.load(open(os.path.join(os.path.dirname(__file__),config_name))) flock_1 = Boids(Boids_total =config['boid_count'], dimension_limits = config['dimension_limits'], velocity_limits = config['velocity_limits'], Limits = config['Limits'], move_to_middle_strength = config['move_to_middle_strength'], alert_distance = config['alert_distance'], formation_flying_distance = config['formation_flying_distance'], formation_flying_strength = config['formation_flying_strength'], frames = config['frames'], interval = config['interval']) flock_1.show_sim()
def test_fly_towards_middle(): new_flock = Boids(2, config_filename) # Set initial positions new_flock.positions[0][0] = 0 new_flock.positions[1][0] = 0 new_flock.positions[0][1] = 0 new_flock.positions[1][1] = 10 new_flock.velocities[0][0] = 0 new_flock.velocities[0][1] = 0 new_flock.velocities[1][0] = 0 new_flock.velocities[1][1] = 0 old_position_x1 = new_flock.positions[0][0] old_position_x2 = new_flock.positions[0][1] old_position_y1 = new_flock.positions[1][0] old_position_y2 = new_flock.positions[1][1] old_velocities_x1 = new_flock.velocities[0][0] old_velocities_x2 = new_flock.velocities[0][1] old_velocities_y1 = new_flock.velocities[1][0] old_velocities_y2 = new_flock.velocities[1][1] new_flock.fly_to_middle() assert (old_velocities_x1 == new_flock.velocities[0][0]) assert (old_velocities_x2 == new_flock.velocities[0][1]) assert (old_velocities_y1 < new_flock.velocities[1][0]) assert (old_velocities_y2 > new_flock.velocities[1][1])
# File to capture fixtures from boids import Boids import copy import yaml import numpy as np import os filename = os.path.join(os.path.dirname(__file__), 'new_fixtures.yaml') #yaml.load(open(filename)) new_flock = Boids(10, 'config.yaml') old_positions = copy.deepcopy(new_flock.positions) old_velocities = copy.deepcopy(new_flock.velocities) with open(filename, "w") as f: yaml.dump(old_positions, f, default_flow_style=True) yaml.dump(old_velocities, f, default_flow_style=True) doc = yaml.load(open(filename)) print doc #npzfile = np.load('new_fixtures.npz') #np.save(npzfile, old_positions) #np.save('new_fixtures.yml', old_velocities) #test = np.load('new_fixtures.npz')
def test_match_speed( ): # Check that velocities match. Should change in y-direction but stay constant in x-direction for input values. new_flock = Boids(2, config_filename) new_flock.positions[0][0] = 0 new_flock.positions[1][0] = 10 new_flock.positions[0][1] = 0 new_flock.positions[1][1] = 10 new_flock.velocities[0][0] = 0 new_flock.velocities[0][1] = 0 new_flock.velocities[1][0] = 0 new_flock.velocities[1][1] = 10 old_velocities_x1 = new_flock.velocities[0][0] old_velocities_x2 = new_flock.velocities[0][1] old_velocities_y1 = new_flock.velocities[1][0] old_velocities_y2 = new_flock.velocities[1][1] new_flock.match_velocity() assert (old_velocities_x1 == new_flock.velocities[0][0]) assert (old_velocities_x2 == new_flock.velocities[0][1]) assert (old_velocities_y1 < new_flock.velocities[1][0]) assert (old_velocities_y2 > new_flock.velocities[1][1])
# ----------------------------------------------------------------------------- # Setup world num_boids = 1000 WORLD_SIZE = [0, options['world_width'], 0, options['world_height']] world = World(WORLD_SIZE) filename = f"{num_boids}_plot.png" # Setup plot NUM_COLOURS = options['num_colours'] cmap = plotting.ColourMap(options) plot = plotting.Plotter(options, world) # Setup Boids boids = Boids(num_boids, world, options) boids.generate_boids(options, distribution='random') # ----------------------------------------------------------------------------- def triang_ver(): boids.triangulate_boids() boids.make_neighbourhoods() # ----------------------------------- Main ------------------------------------ triang_ver() for i in range(num_boids):
import yaml from boids import Boids from copy import deepcopy import numpy as np boids = Boids() before = deepcopy(boids.boids) move_to_middle = 0.01 boids.fly_towards_the_middle(boids.boids, move_to_middle) after = boids.boids fixture = { "before": np.array(before).tolist(), "after": np.array(after).tolist(), "move_to_middle_strength": move_to_middle } fixture_file = open("fixture_fly_towards_the_middle.yml", 'w') fixture_file.write(yaml.dump(fixture)) fixture_file.close() boids = Boids() before = deepcopy(boids.boids) alert_distance = 100 boids.fly_away_from_nearby_boids(boids.boids, alert_distance) after = boids.boids fixture = { "before": np.array(before).tolist(), "after": np.array(after).tolist(), "alert_distance": alert_distance } fixture_file = open("fixture_fly_away_from_nearby_boids.yml", 'w')
from matplotlib import pyplot as plt from matplotlib import animation from boids import Boids # Deliberately terrible code for teaching purposes repulsion = 100 attraction = 0.01 speed = 10000 acceleration = 0.125 model = Boids(50, repulsion, attraction, speed, acceleration) model.initialise_random() figure = plt.figure() axes = plt.axes(xlim=(-500,1500), ylim=(-500,1500)) scatter = axes.scatter( [boid.x for boid in model.boids],\ [boid.y for boid in model.boids] ) def animate(frame): model.update_boids() scatter.set_offsets(zip([boid.x for boid in model.boids], \ [boid.y for boid in model.boids])) anim = animation.FuncAnimation(figure, animate, frames=50, interval=50) if __name__ == "__main__": plt.show()
def main(): parser = ArgumentParser(description = "Simulation of flocking birds") parser.add_argument('--config', '-c', help = 'Config file', default='config.cfg') args = parser.parse_args() try: defaults = { 'count': '50', 'position_limits': '[-450, 300, 50, 600]', 'velocity_limits': '[0, -20, 10, 20]', 'xlim': '[-500, 1500]', 'ylim': '[-500, 1500]', 'frames' : '50', 'interval': '50', 'move_to_middle_strength': '0.01', 'alert_distance': '100', 'formation_flying_distance': '10000', 'formation_flying_strength': '0.125' } config = ConfigParser.SafeConfigParser(defaults) with open(args.config) as f: config.readfp(f) count = config.getint('Boids', 'count') position_limits = json.loads(config.get('Boids', 'position_limits')) velocity_limits = json.loads(config.get('Boids', 'velocity_limits')) frames = config.getint('Animation', 'frames') interval = config.getint('Animation', 'interval') xlim = json.loads(config.get('Axis', 'xlim')) ylim = json.loads(config.get('Axis', 'ylim')) move_to_middle_strength = config.getfloat('Dynamics', 'move_to_middle_strength') alert_distance = config.getfloat('Dynamics', 'alert_distance') formation_flying_distance = config.getfloat('Dynamics', 'formation_flying_distance') formation_flying_strength = config.getfloat('Dynamics', 'formation_flying_strength') boid = Boids(boid_count = count, position_limits = position_limits, velocity_limits = velocity_limits, move_to_middle_strength = move_to_middle_strength, alert_distance = alert_distance, formation_flying_distance = formation_flying_distance, formation_flying_strength = formation_flying_strength) boid.simulate(frames = frames, interval = interval, xlim = tuple(xlim), ylim = tuple(ylim)) except IOError as e: print 'Warning: Config file not found. Default: config.cfg. Can be changed with option --config' print 'Running with default values.' boid = Boids() boid.simulate() except ConfigParser.NoSectionError as e: print 'Warning: Invalid config file. Make sure all sections ([Boids], [Axis], [Animation], [Dynamics]) are present.' print e print 'Running with default values.' boid = Boids() boid.simulate()
# Python libraries import time # Code from local files from boids import Boids # ----------------------------------- setup ----------------------------------- num_points = 100 max_neighbour_dist = 100 world_size = [0, 1000, 0, 1000] boids = Boids(num_points, world_size, max_neighbour_dist) boids.generate_members() openmp_threads = 1 # ------------------------------------ main ----------------------------------- print('Comparing cython implementations of the linear search nearest ' 'neighbour algorithm') print(f'Finding the neighbours of {num_points} generated points...') print('Execution time for make_neighbourhoods function, pure python linear ' 'search algorithm:') START = time.time() boids.make_neighbourhoods() elapsed = time.time() - START print(f'\t {elapsed*1000:0.2f} ms') print('Execution time for make_neighbourhoods_cython function, cythonised ' 'linear search algorithm:')