def remove_highlights(world, hls): """ :param world: :return: """ futures = [] for hl in hls: fut = yield From(world.delete_model(hl.name)) futures.append(fut) yield From(multi_future(futures))
def build_arena(self): """ Initializes the arena by building square arena wall blocks. :return: Future that resolves when arena building is done. """ logger.debug("Building the arena...") n = self.conf.num_wall_segments futs = [] r = self.conf.world_diameter * 0.5 frac = 2 * math.pi / n points = [Vector3(r * math.cos(i * frac), r * math.sin(i * frac), 0) for i in range(n)] fut = yield From(self.build_walls(points)) futs.append(fut) raise Return(multi_future(futs))
def insert_population(self, trees, poses): """ :param trees: :type trees: list[Tree] :param poses: Iterable of (x, y, z) positions to insert. :type poses: list[Pose] :return: """ futures = [] for tree, pose in itertools.izip(trees, poses): future = yield From(self.insert_robot(tree, pose)) futures.append(future) future = multi_future(futures) future.add_done_callback(lambda _: logger.debug("Done inserting population.")) raise Return(future)
def build_walls(self, points): """ Builds a wall defined by the given points, used to shield the arena. :param points: :return: Future that resolves when all walls have been inserted. """ futures = [] l = len(points) for i in range(l): start = points[i] end = points[(i + 1) % l] wall = Wall("wall_%d" % i, start, end, constants.WALL_THICKNESS, constants.WALL_HEIGHT) future = yield From(self.insert_model(SDF(elements=[wall]))) futures.append(future) raise Return(multi_future(futures))
def run_server(): conf = parser.parse_args() conf.enable_light_sensor = False conf.output_directory = None conf.max_lifetime = 999999 conf.initial_age_mu = 500 conf.initial_age_sigma = 500 world = yield From(World.create(conf)) yield From(world.pause(False)) trees, bboxes = yield From(world.generate_population(30)) insert_queue = zip(trees, bboxes) for tree, bbox in insert_queue[:15]: fut = yield From(birth(world, tree, bbox, None)) yield From(fut) yield From(sleep_sim_time(world, 1.0)) sim_time_sec = 5.0 while True: bots = [] for tree, bbox in insert_queue[15:]: fut = yield From(birth(world, tree, bbox, None)) bot = yield From(fut) bots.append(bot) yield From(sleep_sim_time(world, 1.0)) print("Inserted all robots") before = time.time() yield From(sleep_sim_time(world, sim_time_sec)) after = time.time() diff = after - before print(sim_time_sec / diff) futs = [] for robot in bots: fut = yield From(world.delete_robot(robot)) futs.append(fut) yield From(multi_future(futs)) yield From(trollius.sleep(0.1)) print("Deleted all robots")
def create_highlights(world, pa, pb, pc): """ :param world: :param pa: :type pa: Vector3 :param pb: :type pb: Vector3 :param pc: :type pc: Vector3 :return: """ fut1, ha = yield From(world.add_highlight(pa, parent_color)) fut2, hb = yield From(world.add_highlight(pb, parent_color)) fut3, hc = yield From(world.add_highlight(pc, child_color)) yield From(multi_future([fut1, fut2, fut3])) raise Return(ha, hb, hc)
def run_single(self): """ :return: """ conf = self.conf insert_queue = [] if not self.do_restore or not self.do_restore['running']: # Set initial battery charge self.births = 0 self.deaths = 0 # Generate a starting population trees, bboxes = yield From(self.generate_population(conf.population_size)) insert_queue = zip(trees, bboxes, [None for _ in range(len(trees))]) # Simple loop timing mechanism timers = {} this = self def timer(name, t): """ :param t: :param name: :return: """ if this.last_time is None: return False if name not in timers: timers[name] = this.last_time return False if float(this.last_time - timers[name]) > t: timers[name] = this.last_time return True return False # Some variables real_time = time.time() rtf_interval = 10.0 sleep_time = 0.1 started = False t_eval = self.conf.evaluation_time + self.conf.warmup_time robot_limit = self.conf.population_limit birth_interval = t_eval kill_interval = 2 * birth_interval while True: if insert_queue and (not started or timer('insert_queue', 1.0)): tree, bbox, parents = insert_queue.pop() res = yield From(self.birth(tree, bbox, parents)) if res: yield From(res) if not started: # Start the world yield From(wait_for(self.pause(False))) started = True # Perform operations only if there are no items # in the insert queue, makes snapshotting easier. if insert_queue: # Space out robot inserts with one simulation second # to allow them to drop in case they are too close. # Sleep for a very small interval every time until # all inserts are done yield From(trollius.sleep(0.01)) continue # Book keeping if timer('snapshot', 100.0): # Snapshot the world every 100 simulation seconds yield From(self.create_snapshot()) yield From(wait_for(self.pause(False))) if timer('log_fitness', 5.0): # Log overall fitness every 5 simulation seconds self.log_fitness() self.log_summary() if timer('rtf', rtf_interval): # Print RTF to screen every so often nw = time.time() diff = nw - real_time real_time = nw print("RTF: %f" % (rtf_interval / diff)) if timer('death', kill_interval): futs = yield From(self.kill_robots()) if futs: yield From(multi_future(futs)) if timer('birth', birth_interval) and len(self.robots) < robot_limit: if self.births >= self.conf.birth_limit: # Stop the experiment break triplet = yield From(self.produce_individual()) if triplet: insert_queue.append(triplet) yield From(trollius.sleep(sleep_time)) # Delete all robots and reset the world, just in case a new run # will be started. yield From(wait_for(self.delete_all_robots())) yield From(wait_for(self.reset())) yield From(wait_for(self.pause(True))) yield From(trollius.sleep(0.5))
def run_single(self): """ :return: """ conf = self.conf insert_queue = [] if not self.do_restore: if self.current_run == 0: # Only build arena on first run yield From(wait_for(self.build_arena())) # Set initial battery charge self.current_charge = self.conf.initial_charge self.last_charge_update = 0.0 self.births = 0 self.deaths = 0 # Generate a starting population trees, bboxes = yield From(self.generate_population(conf.initial_population_size)) insert_queue = zip(trees, bboxes, [None for _ in range(len(trees))]) # Simple loop timing mechanism timers = {k: Time() for k in ['reproduce', 'death', 'snapshot', 'log_fitness', 'rtf', 'insert_queue']} this = self def timer(name, t): """ :param t: :param name: :return: """ if this.last_time is not None and float(this.last_time - timers[name]) > t: timers[name] = this.last_time return True return False # Some variables real_time = time.time() rtf_interval = 10.0 sleep_time = 0.1 run_result = 'unknown' started = False while True: if insert_queue and (not started or timer('insert_queue', 1.0)): tree, bbox, parents = insert_queue.pop() res = yield From(self.birth(tree, bbox, parents)) if res: yield From(res) if not started: # Start the world yield From(wait_for(self.pause(False))) started = True # Perform operations only if there are no items # in the insert queue, makes snapshotting easier. if insert_queue: # Space out robot inserts with one simulation second # to allow them to drop in case they are too close. # Sleep for a very small interval every time until # all inserts are done yield From(trollius.sleep(0.01)) continue if timer('snapshot', 100.0): # Snapshot the world every 100 simulation seconds yield From(self.create_snapshot()) yield From(wait_for(self.pause(False))) if timer('death', 3.0): # Kill off robots over their age every 5 simulation seconds futs = yield From(self.kill_old_robots()) if futs: yield From(multi_future(futs)) if timer('reproduce', 3.0): # Attempt a reproduction every 3 simulation seconds potential_parents = self.select_parents() if potential_parents: ra = random.choice(potential_parents) rb = self.select_optimal_mate(ra) result = yield From(self.attempt_mate(ra, rb)) if result: child, bbox = result insert_queue.append((child, bbox, (ra, rb))) if timer('log_fitness', 2.0): # Log overall fitness every 2 simulation seconds self.log_fitness() self.log_summary() if timer('rtf', rtf_interval): # Print RTF to screen every so often nw = time.time() diff = nw - real_time real_time = nw print("RTF: %f" % (rtf_interval / diff)) # Stop conditions num_bots = len(self.robots) age = float(self.age()) if num_bots <= conf.extinction_cutoff: print("%d or fewer robots left in population - extinction." % conf.extinction_cutoff) run_result = 'extinction' break elif age > conf.stability_cutoff: print("World older than %f seconds, stable." % conf.stability_cutoff) run_result = 'stable' break yield From(trollius.sleep(sleep_time)) # Delete all robots and reset the world, just in case a new run # will be started. self.write_result(run_result) yield From(wait_for(self.delete_all_robots())) yield From(wait_for(self.reset())) yield From(wait_for(self.pause(True))) yield From(trollius.sleep(0.5))
def run(self): """ :return: """ conf = self.conf insert_queue = [] if not self.do_restore: # Build the arena yield From(wait_for(self.build_arena())) # Generate a starting population trees, bboxes = yield From(self.generate_population(conf.initial_population_size)) insert_queue = zip(trees, bboxes, [None for _ in range(len(trees))]) # Simple loop timing mechanism timers = {k: Time() for k in ['reproduce', 'death', 'snapshot', 'log_fitness', 'rtf']} this = self def timer(name, t): """ :param t: :param name: :return: """ if this.last_time is not None and float(this.last_time - timers[name]) > t: timers[name] = this.last_time return True return False # Start the world real_time = time.time() yield From(wait_for(self.pause(False))) while True: if insert_queue: tree, bbox, parents = insert_queue.pop() yield From(wait_for(self.birth(tree, bbox, parents))) # Perform operations only if there are no items # in the insert queue, makes snapshotting easier. if insert_queue: yield From(trollius.sleep(0.2)) continue if timer('snapshot', 10.0): # Snapshot the world every 10 simulation seconds yield From(self.create_snapshot()) yield From(wait_for(self.pause(False))) if timer('death', 5.0): # Kill off robots over their age every 5 simulation seconds futs = yield From(self.kill_old_robots()) if futs: yield From(multi_future(futs)) if len(self.robots) <= 1: print("Less than two robots left in population - extinction.") break if timer('reproduce', 3.0) and len(self.robots) < conf.max_population_size: # Attempt a reproduction every 3 simulation seconds potential_mates = self.select_mates() if potential_mates: ra, rb = random.choice(potential_mates) result = yield From(self.attempt_mate(ra, rb)) if result: ra.did_mate_with(rb) rb.did_mate_with(ra) child, bbox = result insert_queue.append((child, bbox, (ra, rb))) if timer('log_fitness', 2.0): # Log overall fitness every 2 simulation seconds self.log_fitness() if timer('rtf', 1.0): # Print RTF to screen every second nw = time.time() diff = nw - real_time real_time = nw print("RTF: %f" % (1.0 / diff)) yield From(trollius.sleep(0.2))
def run(self): """ :return: """ conf = self.conf insert_queue = [] if not self.do_restore: # Build the arena yield From(wait_for(self.build_arena())) # Generate a starting population trees, bboxes = yield From( self.generate_population(conf.initial_population_size)) insert_queue = zip(trees, bboxes, [None for _ in range(len(trees))]) # Simple loop timing mechanism timers = { k: Time() for k in ['reproduce', 'death', 'snapshot', 'log_fitness', 'rtf'] } this = self def timer(name, t): """ :param t: :param name: :return: """ if this.last_time is not None and float(this.last_time - timers[name]) > t: timers[name] = this.last_time return True return False # Start the world real_time = time.time() yield From(wait_for(self.pause(False))) while True: if insert_queue: tree, bbox, parents = insert_queue.pop() yield From(wait_for(self.birth(tree, bbox, parents))) # Perform operations only if there are no items # in the insert queue, makes snapshotting easier. if insert_queue: yield From(trollius.sleep(0.2)) continue if timer('snapshot', 10.0): # Snapshot the world every 10 simulation seconds yield From(self.create_snapshot()) yield From(wait_for(self.pause(False))) if timer('death', 5.0): # Kill off robots over their age every 5 simulation seconds futs = yield From(self.kill_old_robots()) if futs: yield From(multi_future(futs)) if len(self.robots) <= 1: print("Less than two robots left in population - extinction.") break if timer('reproduce', 3.0) and len(self.robots) < conf.max_population_size: # Attempt a reproduction every 3 simulation seconds potential_mates = self.select_mates() if potential_mates: ra, rb = random.choice(potential_mates) result = yield From(self.attempt_mate(ra, rb)) if result: ra.did_mate_with(rb) rb.did_mate_with(ra) child, bbox = result insert_queue.append((child, bbox, (ra, rb))) if timer('log_fitness', 2.0): # Log overall fitness every 2 simulation seconds self.log_fitness() if timer('rtf', 1.0): # Print RTF to screen every second nw = time.time() diff = nw - real_time real_time = nw print("RTF: %f" % (1.0 / diff)) yield From(trollius.sleep(0.2))