class AgentAgentInteractions(LogicNode): sight_soc = Float( default_value=3.0, min=0, help='') max_agent_radius = Float( default_value=0.3, min=0, help='') f_soc_max = Float( default_value=2e3, min=0, help='') cell_size = Float( min=0, help='') @default('cell_size') def _default_cell_size(self): return self.sight_soc + 2 * self.max_agent_radius def update(self): agents = self.simulation.agents.array mask = agents['active'] agent_agent_block_list(agents, self.cell_size, mask)
class Navigation(LogicNode): step = Float( default_value=0.1, min=0, help='Step size for meshgrid used for discretization.') radius = Float( default_value=0.5, min=0, help='') strength = Float( default_value=0.3, min=0, max=1, help='') def update(self): agents = self.simulation.agents.array field = self.simulation.field for target in range(len(field.targets)): #has_target = np.nonzero(agents['target'] == target) has_target = np.nonzero(agents['active'] & (agents['target'] == target)) # The cognitive map for other agents if len(has_target) != 0: mgrid_f, distance_map_f, direction_map_f = field.navigation_to_target(target, self.step, self.radius, self.strength) # Flip x and y to array index i and j indices_f = np.fliplr(mgrid_f.indicer(agents[has_target]['position'])) new_direction_f = getdefault( indices_f, direction_map_f, agents[has_target]['target_direction']) agents['target_direction'][has_target] = new_direction_f
class AvoidObstacle(Field): width = Float( default_value=10.0, min=0) height = Float( default_value=10.0, min=0) exit_width = Float( default_value=3.0, min=1.0) ratio_obs = Float( default_value=0.6, min=0, max=1) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) domain = rectangle(0, 0, self.width, self.height) spawn_follower = rectangle(0, 0, self.ratio_obs * self.width, self.height) spawn_leader = rectangle(0, 0.5 * self.height, self.ratio_obs * self.width, 0.5 * self.height) target = LineString([(self.width, 0), (self.width, self.exit_width)]) self.obstacles = (domain.exterior - target | LineString([(self.ratio_obs * self.width, 0), (self.ratio_obs * self.width, 0.5 * self.height)])) self.targets = [target] self.spawns = [spawn_leader, spawn_follower] self.domain = domain
class Rounding(Field): width = Float( default_value=10.0, min=0) height = Float( default_value=10.0, min=0) ratio = Float( default_value=0.6, min=0, max=1) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) height = self.height width = self.width domain = Polygon([(0, 0), (0, height), (width, height), (width, 0)]) target = LineString([(0, height / 2), (0, height)]) spawn = Polygon([(0, 0), (0, height / 2), (width / 2, height / 2), (width / 2, 0)]) obstacles = LineString([(0, height / 2), (width * self.ratio, height / 2)]) | \ domain.exterior - target self.obstacles = obstacles self.targets = [target] self.spawns = [spawn] self.domain = domain
class OutdoorField(Field): width = Float( default_value=10.0, min=0) height = Float( default_value=10.0, min=0) @default('domain') def _default_domain(self): return Polygon([ (0, 0), (0, self.height), (self.width, self.height), (self.width, 0) ]) @default('spawns') def _default_spawns(self): return [self.domain] @observe('width', 'height') def _observe_field(self, change): self.domain = Polygon([ (0, 0), (0, self.height), (self.width, self.height), (self.width, 0) ]) self.spawns = [self.domain]
class Integrator(LogicNode): dt_min = Float(default_value=0.01, min=0, help='Minimum timestep') dt_max = Float(default_value=0.01, min=0, help='Maximum timestep') def update(self): agents = self.simulation.agents.array dt = velocity_verlet_integrator(agents, self.dt_min, self.dt_max) self.simulation.data['dt'] = dt self.simulation.data['time_tot'] += dt
class RoomWithOneExit(MultiAgentSimulation): size = Int(default_value=100, min=1) agent_type = Enum(default_value=Circular, values=(Circular, ThreeCircle)) body_type = Enum(default_value='adult', values=('adult', )) width = Float(default_value=10.0, min=0) height = Float(default_value=10.0, min=0) exit_width = Float(default_value=1.25, min=0, max=10) exit_hall_width = Float(default_value=2.0, min=0) def attributes(self): orientation = 0.0 d = dict(target=0, body_type=self.body_type, orientation=orientation, velocity=1.0 * unit_vector(orientation), angular_velocity=0.0, target_direction=unit_vector(orientation), target_orientation=orientation) return d @default('logic') def _default_logic(self): return Reset(self) << \ InsideDomain(self) << ( Integrator(self) << ( Fluctuation(self), Adjusting(self) << ( Navigation(self), Orientation(self) ), AgentAgentInteractions(self), AgentObstacleInteractions(self) ) ) @default('field') def _default_field(self): return fields.RoomWithOneExit(width=self.width, height=self.height, exit_width=self.exit_width, exit_hall_width=self.exit_hall_width) @default('agents') def _default_agents(self): agents = Agents(agent_type=self.agent_type) group = AgentGroup(agent_type=self.agent_type, size=self.size, attributes=self.attributes) agents.add_non_overlapping_group( group, position_gen=self.field.sample_spawn(0)) return agents
class Bar(Foo): b = Unicode('gotit', help="The string b.").tag(config=False) c = Float(help="The string c.").tag(config=True) bset = Set([]).tag(config=True, multiplicity='+') bset_values = Set([2,1,5]).tag(config=True, multiplicity='+') bdict = Dict().tag(config=True, multiplicity='+') bdict_values = Dict({1:'a','0':'b',5:'c'}).tag(config=True, multiplicity='+')
class HallwayField(Field): width = Float( default_value=10.0, min=0) height = Float( default_value=10.0, min=0) ratio = Float( default_value=1 / 3, min=0, max=1) @default('obstacles') def _default_obstacles(self): return LineString([(0, 0), (self.width, 0)]) | \ LineString([(0, self.height), (self.width, self.height)]) @default('targets') def _default_targets(self): return [LineString([(0, 0), (0, self.height)]), LineString([(self.width, 0), (self.width, self.height)])] @default('spawns') def _default_spawns(self): return [rectangle(0, 0, self.ratio * self.width, self.height), rectangle((1 - self.ratio) * self.width, 0, self.ratio * self.width, self.height)] @default('domain') def _default_domain(self): return self.convex_hull() @observe('width', 'height', 'ratio') def _observe_field(self, change): obstacles = LineString([(0, 0), (self.width, 0)]) | \ LineString([(0, self.height), (self.width, self.height)]) spawn0 = rectangle(0, 0, self.ratio * self.width, self.height) spawn1 = rectangle((1 - self.ratio) * self.width, 0, self.ratio * self.width, self.height) target0 = LineString([(0, 0), (0, self.height)]) target1 = LineString([(self.width, 0), (self.width, self.height)]) self.obstacles = obstacles self.spawns = [spawn0, spawn1] self.targets = [target0, target1] self.domain = self.convex_hull()
class RotationalMotion(HasTraits): orientation = Float(default_value=0.0, min=-np.pi, max=np.pi, help='Orientation', symbol=r'\varphi') angular_velocity = Float(default_value=0.0, help='Angular velocity', symbol=r'\omega') target_orientation = Float(default_value=0.0, help='Target orientation', symbol=r'\varphi_0') torque = Float(default_value=0.0, help='Torque', symbol=r'M') torque_prev = Float(default_value=0.0, help='Previous torque', symbol=r'M_{prev}') tau_rot = Float( default_value=0.2, min=0, help='Characteristic time for agent adjusting its rotational movement', symbol=r'\tau_{adjrot}') std_rand_torque = Float(default_value=0.1, min=0, help='Standard deviation for fluctuation torque', symbol=r'\eta / I{rot}')
class AvoidPillar(Field): width = Float( default_value=10.0, min=0) height = Float( default_value=20.0, min=0) pillar_type = Enum( values=('ellipse', 'rectangle'), default_value='ellipse') width_pillar = Float( default_value=2.0, min=0) height_pillar = Float( default_value=2.0, min=0) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs)
class Outdoor(MultiAgentSimulation): r"""Simulation for visualizing collision avoidance.""" size = Int(default_value=100, min=1) agent_type = Enum(default_value=Circular, values=(Circular, ThreeCircle)) body_type = Enum(default_value='adult', values=('adult', )) width = Float(default_value=20.0, min=0) height = Float(default_value=20.0, min=0) def attributes(self): orientation = np.random.uniform(-np.pi, np.pi) d = dict(body_type=self.body_type, orientation=orientation, velocity=1.0 * unit_vector(orientation), angular_velocity=0.0, target_direction=unit_vector(orientation), target_orientation=orientation) return d @default('logic') def _default_logic(self): return Reset(self) << (Integrator(self) << ( Fluctuation(self), Adjusting(self) << Orientation(self), AgentAgentInteractions(self), )) @default('field') def _default_field(self): return fields.OutdoorField(width=self.width, height=self.height) @default('agents') def _default_agents(self): agents = Agents(agent_type=self.agent_type) group = AgentGroup(agent_type=self.agent_type, size=self.size, attributes=self.attributes) agents.add_non_overlapping_group( group, position_gen=self.field.sample_spawn(0)) return agents
class ClosedRoom(Field): width = Float( default_value=10.0, min=0) height = Float( default_value=10.0, min=0) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) domain = Polygon([ (0, 0), (0, self.height), (self.width, self.height), (self.width, 0) ]) obstacles = domain.exterior spawn = domain self.obstacles = obstacles self.spawns = [spawn] self.domain = domain
class Bar(Foo): b = Unicode("gotit", help="The string b.").tag(config=False) c = Float(help="The string c.").tag(config=True) bset = Set([]).tag(config=True, multiplicity="+") bset_values = Set([2, 1, 5]).tag(config=True, multiplicity="+") bdict = Dict().tag(config=True, multiplicity="+") bdict_values = Dict({ 1: "a", "0": "b", 5: "c" }).tag(config=True, multiplicity="+")
class Body(HasTraits): radius = Float(min=0, help='Radius', symbol='r') r_t = Float(min=0, help='Torso radius', symbol='r_t') r_s = Float(min=0, help='Shoulder radius', symbol='r_s') r_ts = Float(min=0, help='Distance from torso to shoulder', symbol='r_{ts}') mass = Float(min=0, help='Mass', symbol='m') inertia_rot = Float(min=0, help='Rotational moment', symbol='I_{rot}') target_velocity = Float(min=0, help='Target velocity', symbol='v_0') target_angular_velocity = Float(min=0, help='Target angular velocity', symbol=r'\omega_0')
class FourExitsRandomPlacing(MultiAgentSimulation): size = Int(default_value=100, min=0, help='Amount of herding agents') agent_type = Enum(default_value=Circular, values=(Circular, ThreeCircle)) body_type = Enum(default_value='adult', values=('adult', )) exit_width = Float(default_value=1.25, min=0, max=10) def attributes(self): def wrapper(): target = np.random.randint(0, len(self.field.targets)) orientation = np.random.uniform(-np.pi, np.pi) d = dict(target=target, body_type=self.body_type, orientation=orientation, velocity=np.zeros(2), angular_velocity=0.0, target_direction=np.zeros(2), target_orientation=orientation, familiar_exit=np.random.randint(0, len(self.field.targets))) return d return wrapper @default('logic') def _default_logic(self): return Reset(self) << \ InsideDomain(self) << ( Integrator(self) << ( Fluctuation(self), Adjusting(self) << ( Navigation(self), Orientation(self)), AgentAgentInteractions(self), AgentObstacleInteractions(self))) @default('field') def _default_field(self): return fields.FourExitsField(exit_width=self.exit_width) @default('agents') def _default_agents(self): agents = Agents(agent_type=self.agent_type) group = AgentGroup(agent_type=self.agent_type, size=self.size, attributes=self.attributes()) agents.add_non_overlapping_group( group, position_gen=self.field.sample_spawn(0), obstacles=geom_to_linear_obstacles(self.field.obstacles)) return agents
class PillarInTheMiddle(Field): width = Float( default_value=20.0, min=0) height = Float( default_value=20.0, min=0) radius_pillar = Float( default_value=1.0, min=0) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) domain = rectangle(self.width / 2, self.height / 2, self.width / 2, self.height / 2) obstacles = Point(0, 0).buffer(self.radius_pillar) self.domain = domain self.obstacles = obstacles self.spawns = [domain]
class LeaderFollower(LogicNode): sight = Float( default_value=10, min=0, help='Maximum distance between agents that are accounted as neighbours ' 'that can be followed.') def update(self): agents = self.simulation.agents.array field = self.simulation.field obstacles = geom_to_linear_obstacles(field.obstacles) #direction = leader_follower_interaction(agents, obstacles, self.sight) value = leader_follower_interaction(agents, obstacles, self.sight)
class TranslationalMotion(HasTraits): position = Array(default_value=(0, 0), dtype=np.float64, help='Position', symbol=r'\mathbf{x}').valid(shape_validator(2)) velocity = Array(default_value=(0, 0), dtype=np.float64, help='Velocity', symbol=r'\mathbf{v}').valid(shape_validator(2)) target_direction = Array(default_value=(0, 0), dtype=np.float64, help='Target direction', symbol='\mathbf{\hat{e}}_0').valid( shape_validator(2), length_validator(0, 1)) force = Array(default_value=(0, 0), dtype=np.float64, help='Force', symbol='\mathbf{f}').valid(shape_validator(2)) force_prev = Array(default_value=(0, 0), dtype=np.float64, help='Previous force', symbol='\mathbf{f}_{prev}').valid(shape_validator(2)) tau_adj = Float( default_value=0.5, min=0, help='Characteristic time for agent adjusting its movement', symbol=r'\tau_{adj}') k_soc = Float(default_value=1.5, min=0, help='Social force scaling constant', symbol=r'k_{soc}') tau_0 = Float(default_value=3.0, min=0, help='Interaction time horizon', symbol=r'\tau_{0}') mu = Float(default_value=1.2e5, min=0, help='Compression counteraction constant', symbol=r'\mu') kappa = Float(default_value=4e4, min=0, help='Sliding friction constant', symbol=r'\kappa') damping = Float(default_value=500, min=0, help='Damping coefficient for contact force', symbol=r'c_{d}') std_rand_force = Float(default_value=0.1, min=0, help='Standard deviation for fluctuation force', symbol=r'\xi / m')
class RoomWithOneExit(Field): width = Float( default_value=10.0, min=0) height = Float( default_value=10.0, min=0) exit_width = Float( default_value=1.25, min=0, max=10) exit_hall_width = Float( default_value=2.0, min=0) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) width = self.width height = self.height exit_width = self.exit_width exit_hall_width = self.exit_hall_width self.room = LineString( [(width, 0), (0, 0), (0, height), (width, height)]) self.hall = rectangle(width, (height + exit_width) / 2, exit_hall_width, (height - exit_width) / 2) | \ rectangle(width, 0, exit_hall_width, (height - exit_width) / 2) target = LineString( [(width + exit_hall_width, (height - exit_width) / 2), (width + exit_hall_width, (height + exit_width) / 2)]) # Field attributes self.obstacles = self.room | self.hall self.targets = [target] self.spawns = [self.room.convex_hull] self.domain = self.convex_hull()
class Navigation(LogicNode): step = Float(default_value=0.1, min=0, help='Step size for meshgrid used for discretization.') radius = Float(default_value=0.5, min=0, help='') strength = Float(default_value=0.3, min=0, max=1, help='') def update(self): agents = self.simulation.agents.array field = self.simulation.field for target in range(len(field.targets)): has_target = agents['target'] == target if not has_target.size: continue mgrid, distance_map, direction_map = field.navigation_to_target( target, self.step, self.radius, self.strength) # Flip x and y to array index i and j indices = np.fliplr(mgrid.indicer(agents[has_target]['position'])) new_direction = getdefault(indices, direction_map, agents[has_target]['target_direction']) agents['target_direction'][has_target] = new_direction
class ExitDetection(LogicNode): """Herding agents can detect an exit that is within exit detection range""" detection_range = Float(default_value=20.0, min=1.0) def update(self): agents = self.simulation.agents.array field = self.simulation.field center_door = np.stack( [np.mean(np.asarray(target), axis=0) for target in field.targets]) obstacles = geom_to_linear_obstacles(field.obstacles) targets, has_detected = exit_detection(center_door, agents['position'], obstacles, self.detection_range) mask = agents['is_follower'] & has_detected agents['target'][mask] = targets[mask] agents['is_follower'][mask] = False
class LeaderFollowerWithHerding(LogicNode): sight_follower = Float( default_value=10.0, min=0, help='Maximum distance between agents that are accounted as neighbours ' 'that can be followed.') size_nearest_other = Int( default_value=5, min=0, help='Maximum number of nearest agents inside sight_herding radius ' 'that herding agent are following.') # step = Float( # default_value=0.05, # min=0, # help='Step size for meshgrid used for discretization.') # radius = Float( # default_value=0.5, # min=0, # help='') # strength = Float( # default_value=0.3, # min=0, max=1, # help='') def update(self): agents = self.simulation.agents.array field = self.simulation.field # FIXME: virtual obstacles add too much computational overhead # obstacles = geom_to_linear_obstacles( # field.obstacles.buffer(0.3, resolution=3)) obstacles = geom_to_linear_obstacles(field.obstacles) direction_herding = leader_follower_with_herding_interaction( agents, obstacles, self.sight_follower, self.size_nearest_other) is_follower = agents['is_follower'] agents['target_direction'][is_follower] = direction_herding[ is_follower]
class TargetReached(LogicNode): """Detects if agents reached any of the targets in the field and updates count for that target. """ prefix = 'target_{index}' epsilon = Float( 0.02, min=0, help='Consider target reached when we are closer than this value') def __init__(self, simulation, *args, **kwargs): super().__init__(simulation, *args, **kwargs) self.names = [] targets = self.simulation.field.targets[0:4] # this should be updated if more exits are set self.simulation.data['n_agents'] = len(self.simulation.agents.array) # store init. # of agents so base.py knows for index, target in enumerate(targets): name = self.prefix.format(index=index) self.names.append(name) self.simulation.data[name] = 0 def update(self): targets = self.simulation.field.targets #print(targets) agents = self.simulation.agents.array mask = agents['active'] & ~agents['target_reached'] #print(np.sum(agents['active'])) #print(agents['target'][np.nonzero(agents['is_leader'])]) for i in range(len(agents)): if not mask[i]: continue x, y = agents[i]['position'] point = Point(x, y) for target, name in zip(targets, self.names): if point.distance(target) < self.epsilon: self.simulation.data[name] += 1 agents['target_reached'][i] = True agents['active'][i] = False
class HydraKernelProvisioner(KernelProvisionerBase): subkernel_name = Unicode() poll_interval = Float(1.0) @property def binding(self) -> "Binding": km: "HydraKernelManager" = self.parent assert hasattr(km, "binding") return km.binding async def kill(self, restart: bool = False) -> None: await self.send_signal(int(signal.SIGKILL)) async def terminate(self, restart: bool = False) -> None: await self.send_signal(int(signal.SIGTERM)) async def wait(self) -> "Optional[int]": ret = 0 if self.has_process: while await self.poll() is None: await asyncio.sleep(self.poll_interval) self.reset() return ret async def cleanup(self, restart: bool = False) -> None: """No-op cleanup default implementation to satisfy base class.""" pass def reset(self) -> None: """Reset the has_process state. In general, this function should modify the state of the provisioner such that has_process returns false. """ pass
class MyConfigurable(Configurable): a = Integer(1, help="The integer a.").tag(config=True) b = Float(1.0, help="The integer b.").tag(config=True) c = Unicode('no config')
class Bar(Foo): b = Unicode('gotit', help="The string b.").tag(config=False) c = Float(help="The string c.").tag(config=True) bset = Set([]).tag(config=True, multiplicity='+') bdict = Dict().tag(config=True, multiplicity='+')
class Bar(Foo): b = Unicode('gotit', help="The string b.").tag(config=False) c = Float(help="The string c.").tag(config=True)
class BodyType(Body): body_type = Unicode(help='Selected body type') body_types = Instance(ConfigObj, help='Mapping of body type names to values') # Ratios of radii for shoulders and torso ratio_rt = Float(default_value=0, min=0, max=1, help='Ratio between total radius and torso radius') ratio_rs = Float(default_value=0, min=0, max=1, help='Ratio between total radius and shoulder radius') ratio_ts = Float( default_value=0, min=0, max=1, help='Ratio between total radius and distance from torso to shoulder') # Scales for settings values from truncated normal distribution # TODO: Distributions class as instance traits radius_mean = Float(default_value=0, min=0) radius_scale = Float(default_value=0, min=0) target_velocity_mean = Float(default_value=0, min=0) target_velocity_scale = Float(default_value=0, min=0) mass_mean = Float(default_value=0, min=0) mass_scale = Float(default_value=0, min=0) @staticmethod def _truncnorm(mean, abs_scale): """Individual value from truncnorm""" return np.asscalar(truncnorm(-3.0, 3.0, loc=mean, abs_scale=abs_scale)) @default('body_types') def _default_body_types(self): return load_config(BODY_TYPES_CFG, BODY_TYPES_CFG_SPEC) @observe('body_type') def _observe_body_type(self, change): if change['old'] == '': new = change['new'] for k, v in self.body_types[new].items(): setattr(self, k, v) else: raise TraitError('Body type can only be set once.') @observe('radius_mean', 'radius_scale') def _observe_radius_truncnorm(self, change): if self.radius == 0 and self.radius_mean > 0 and self.radius_scale > 0: self.radius = self._truncnorm(self.radius_mean, self.radius_scale) @observe('radius', 'ratio_rt', 'ratio_rs', 'ratio_ts') def _observe_radius(self, change): """Set torso radius if ratio_rt changes and radius is defined or if radius changes and ratio_rt is defined.""" name = change['name'] if name == 'radius': if self.ratio_rt > 0: self.r_t = self.ratio_rt * self.radius if self.ratio_rs > 0: self.r_s = self.ratio_rs * self.radius if self.ratio_ts > 0: self.r_ts = self.ratio_ts * self.radius elif self.radius > 0: if name == 'ratio_rt': self.r_t = self.ratio_rt * self.radius elif name == 'ratio_rs': self.r_s = self.ratio_rs * self.radius elif name == 'ratio_ts': self.r_ts = self.ratio_ts * self.radius @observe('mass_mean', 'mass_scale') def _observe_mass_truncnorm(self, change): if self.mass == 0 and self.mass_mean > 0 and self.mass_scale > 0: self.mass = self._truncnorm(self.mass_mean, self.mass_scale) @observe('target_velocity_mean', 'target_velocity_scale') def _observe_target_velocity_truncnorm(self, change): if self.target_velocity == 0 and self.target_velocity_mean > 0 and self.target_velocity_scale > 0: self.target_velocity = self._truncnorm(self.target_velocity_mean, self.target_velocity_scale) @observe('mass', 'radius') def _observe_inertia_rot(self, change): if self.inertia_rot == 0 and self.mass > 0 and self.radius > 0: inertia = 4.0 * np.pi mass = 80.0 radius = 0.27 self.inertia_rot = inertia * (self.mass / mass) * (self.radius / radius)**2
class Agents(AgentsBase): """Set groups of agents Examples: >>> agent = Agents(agent_type=Circular) >>> agent.add_non_overlapping_group(...) """ agent_type = Type( klass=AgentType, help='Instance of AgentType. This will be used to create attributes ' 'for the agent.') size_max = Int( allow_none=None, help='Maximum number of agents that can be created.None allows the ' 'size grow dynamically.') cell_size = Float( default_value=0.6, min=0, help='Cell size for block list. Value should be little over the ' 'maximum of agent radii') def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.index = 0 self.array = np.zeros(0, dtype=self.agent_type.dtype()) # Block list for speeding up overlapping checks self._neighbours = MutableBlockList(cell_size=self.cell_size) def add_non_overlapping_group(self, speed, groupname, group, position_gen, position_iter, spawn, obstacles=None): """Add group of agents Args: group (AgentGroup): position_gen (Generator|Callable): obstacles (numpy.ndarray): """ if self.agent_type is not group.agent_type: raise CrowdDynamicsException # resize self.array to fit new agents array = np.zeros(group.size, dtype=group.agent_type.dtype()) self.array = np.concatenate((self.array, array)) index = 0 spawn_data = np.load("complex/spawn_complex.npy") while index < group.size: new_agent = group.members[index] if position_gen: new_agent.position = next(position_iter) new_agent.radius = 0.27 new_agent.mass = 80.0 new_agent.target_velocity = 1.15 else: if groupname == "spawn_left": new_agent.radius = spawn_data[index][7] new_agent.mass = spawn_data[index][11] #new_agent.target_velocity = spawn_data[index][13] if speed == "slow": new_agent.target_velocity = 0.5 elif speed == "fast": new_agent.target_velocity = 1.55 new_agent.position = spawn_data[index][15] if groupname == "spawn_lower": new_agent.radius = spawn_data[index + 50][7] new_agent.mass = spawn_data[index + 50][11] #new_agent.target_velocity = spawn_data[index+50][13] if speed == "slow": new_agent.target_velocity = 0.5 elif speed == "fast": new_agent.target_velocity = 1.55 new_agent.position = spawn_data[index + 50][15] if groupname == "spawn_right": new_agent.radius = spawn_data[index + 100][7] new_agent.mass = spawn_data[index + 100][11] #new_agent.target_velocity = spawn_data[index+100][13] if speed == "slow": new_agent.target_velocity = 0.5 elif speed == "fast": new_agent.target_velocity = 1.55 new_agent.position = spawn_data[index + 100][15] if groupname == "spawn_upper": new_agent.radius = spawn_data[index + 150][7] new_agent.mass = spawn_data[index + 150][11] #new_agent.target_velocity = spawn_data[index+150][13] if speed == "slow": new_agent.target_velocity = 0.5 elif speed == "fast": new_agent.target_velocity = 1.55 new_agent.position = spawn_data[index + 150][15] # Agent can be successfully placed self.array[self.index] = np.array(new_agent) self._neighbours[new_agent.position] = self.index self.index += 1 index += 1 # TODO: remove agents that didn't fit from self.array #if self.index + 1 < self.array.size: # pass # Array should remain contiguous assert self.array.flags.c_contiguous