async def run(): """ The main coroutine, which is started below. """ # File with the yaml file robot_file_path = "../test/centipede.yaml" # Parse command line / file input arguments settings = parser.parse_args() # Load interface with factory: gets the factory services and the available modules factory_info = FactoryInfo() # Load the robot from yaml robot = rmevo_bot.RMEvoBot(self_factory=factory_info) logger.info("Loading Robot.") robot.load_file(robot_file_path) # Parse the robot back to yaml # This means the core has imported correctly the robot structure robot_yaml = robot.to_yaml() # Calls the service and passes the robot yaml factory_info.send_robot_to_factory('basic_test_robot', robot_yaml)
def export_snapshots(self, individuals, gen_num): if self.settings.recovery_enabled: path = os.path.join(self.experiment_folder, f'selectedpop_{gen_num}') if os.path.exists(path): shutil.rmtree(path) os.mkdir(path) for ind in individuals: self.export_phenotype_images(f'selectedpop_{str(gen_num)}', ind) logger.info( f'Exported snapshot {str(gen_num)} with {str(len(individuals))} individuals' )
def standard_crossover(parent_individuals, genotype_conf, crossover_conf): """ Creates an child (individual) through crossover with two parents. :param parent_genotypes: genotypes of the parents to be used for crossover :return: genotype result of the crossover """ parent_genotypes = [p.genotype for p in parent_individuals] new_genotype = generate_child_genotype(parent_genotypes, genotype_conf, crossover_conf) logger.info( f'crossover: for genome {new_genotype.id} - p1: {parent_genotypes[0].id} p2: {parent_genotypes[1].id}.' ) return new_genotype
def get_gazebo_services(self): """ Finds and creates ServiceProxys for the services needed, advertised by the :ros:pkg:`rmevo_gazebo`. """ # Try to find the services from gazebo (has to be running) try: logger.info("Looking for gazebo services.") self.reset_service = rospy.ServiceProxy('/gazebo/reset_simulation', Empty) self.fitness_service = rospy.ServiceProxy( '/worldcontrol/evaluate_fitness', FitnessEvaluation) self.delete_model_service = rospy.ServiceProxy( '/gazebo/delete_model', DeleteModel) except: raise RuntimeError( "Service not found, check if factory is running.")
def get_factory_services(self): """ Find the services that the :ros:pkg:`factory_ros` advertises. Store the ROS proxies used to call this services later in the program. """ # Try to find the service from the factory (has to be running) try: logger.info("Looking for factory services.") self.generate_service = rospy.ServiceProxy( '/factory/generate_robot', RobotConfiguration) self.list_modules_services = rospy.ServiceProxy( 'factory/list_modules', OutputString) except: raise RuntimeError( "Service not found, check if factory is running.")
def delete_robot(self, robot_name): """ Deletes the robot with the given name of the simulation, calling a :ros:pkg:`rmevo_gazebo` service. :param robot_name: Name of the robot to be deleted :type robot_name: String """ serv_res = self.delete_model_service(robot_name) if serv_res.success is True: logger.info("Robot with name " + robot_name + " deleted sucessfully.") return True else: logger.error("An error occurred while deleting the model: " + serv_res.status_message) return 0
def evaluate_robot_fitness(self, robot_name): """ Calls the :ros:pkg:`rmevo_gazebo` service that evaluates the fitness of the given robot. :param robot_name: Name of the robot to be evaluated :type robot_name: String :return: Fitness value of the robot evaluated """ logger.info("Asking for fitness of robot " + robot_name) serv_res = self.fitness_service(robot_name) if serv_res.success is True: logger.info("Fitness of robot " + robot_name + " is " + str(serv_res.robot_fitness)) return serv_res.robot_fitness else: logger.error("An error occurred while asking for the fitness: " + serv_res.status_message) return 0
def send_robot_to_factory(self, name, robot): """ Calls the service :func:`/factory_ros/generate_robot()` using the proxy obtained by :meth:`get_factory_services()`. Through this service this method sends a robot and its morphological configuration to the factory and commands it to spawn it in Gazebo. :param name: Name of the robot. Used as ID in the program. :type name: String :param robot: String with yaml format that contains the genotype of the robot, represented as a tree structure with the modules as nodes. :type robot: String """ logger.info("Spawning robot " + name) serv_res = self.generate_service(name, robot) if serv_res.success is True: logger.info("Robot spawned correctly") else: logger.error("Error spawning robot")
async def run(): """ The main coroutine, which is started below. """ # Load interface with factory: gets the factory services and the available modules factory_manager = FactoryManager() # Load interface with gazebo: gets services gazebo_manager = GazeboManager() # experiment params # num_generations = 5 population_size = 10 offspring_size = 5 genotype_conf = PlasticodingConfig( max_depth=2, factory=factory_manager, axiom_w='Core', empty_child_prob=0.5 ) mutation_conf = MutationConfig( mutation_prob=0.8, genotype_conf=genotype_conf, ) crossover_conf = CrossoverConfig( crossover_prob=0.8, ) fitness_conf = fitness.FitnessManager( gazebo_manager=gazebo_manager, factory_manager=factory_manager ) # experiment params # # Parse command line / file input arguments settings = parser.parse_args() settings.experiment_name = "Test2" settings.evaluation_time = 1 experiment_management = ExperimentManagement(settings) # do_recovery = settings.recovery_enabled and not experiment_management.experiment_is_new() # logger.info('Activated run '+settings.run+' of experiment '+settings.experiment_name) # if do_recovery: # gen_num, has_offspring, next_robot_id = experiment_management.read_recovery_state(population_size, offspring_size) # # if gen_num == num_generations-1: # logger.info('Experiment is already complete.') # return # else: gen_num = 0 next_robot_id = 1 population_conf = PopulationConfig( population_size=population_size, genotype_constructor=rmevo_random_initialization, #genotype_constructor=random_initialization, genotype_conf=genotype_conf, fitness_conf=fitness_conf, mutation_operator=null_mutation, mutation_conf=mutation_conf, crossover_operator=rmevo_crossovers.standard_crossover, # crossover_operator=None, crossover_conf=crossover_conf, selection=lambda individuals: tournament_selection(individuals, 2), parent_selection=lambda individuals: multiple_selection(individuals, 2, tournament_selection), population_management=steady_state_population_management, population_management_selector=tournament_selection, evaluation_time=settings.evaluation_time, offspring_size=offspring_size, experiment_name=settings.experiment_name, experiment_management=experiment_management, ) settings.output_directory = 'file' settings.simulator_cmd = 'gazebo' settings.world = 'worlds/plane.realtime.world' population = Population(population_conf, next_robot_id) # starting a new experiment experiment_management.create_exp_folders() population.init_pop() while gen_num < num_generations-1: gen_num += 1 population = population.next_gen(gen_num) # output result after completing all generations... fittest_robot = population.get_fittest_robot() logger.info("Evolution finished") logger.info("Fittest robot is " + fittest_robot.id + " with a fitness of " + str(fittest_robot.fitness)) logger.info("Process finished")
async def run(): """ The main coroutine, which is started below. """ # Load modules from files logger.info("Starting Factory.") factory = rmevo_bot.Factory() logger.info("Importing module.") module_file_dir = 'rmevo/test/modules/basic' factory.import_modules_from_dir(module_file_dir) # experiment params # num_generations = 5 population_size = 10 offspring_size = 5 genotype_conf = PlasticodingConfig( max_structural_modules=10, factory=factory, axiom_w='Core', ) mutation_conf = MutationConfig( mutation_prob=0.8, genotype_conf=genotype_conf, ) crossover_conf = CrossoverConfig(crossover_prob=0.8, ) # experiment params # # Parse command line / file input arguments settings = parser.parse_args() settings.recovery_enabled = False settings.evaluation_time = 1 experiment_management = ExperimentManagement(settings) do_recovery = settings.recovery_enabled and not experiment_management.experiment_is_new( ) logger.info('Activated run ' + settings.run + ' of experiment ' + settings.experiment_name) if do_recovery: gen_num, has_offspring, next_robot_id = experiment_management.read_recovery_state( population_size, offspring_size) if gen_num == num_generations - 1: logger.info('Experiment is already complete.') return else: gen_num = 0 next_robot_id = 1 population_conf = PopulationConfig( population_size=population_size, genotype_constructor=rmevo_random_initialization, #genotype_constructor=random_initialization, genotype_conf=genotype_conf, fitness_function=fitness.maximum_weight, mutation_operator=standard_mutation, mutation_conf=mutation_conf, #crossover_operator=rmevo_crossovers.standard_crossover, crossover_operator=None, crossover_conf=crossover_conf, selection=lambda individuals: tournament_selection(individuals, 2), parent_selection=lambda individuals: multiple_selection( individuals, 2, tournament_selection), population_management=steady_state_population_management, population_management_selector=tournament_selection, evaluation_time=settings.evaluation_time, offspring_size=offspring_size, experiment_name=settings.experiment_name, experiment_management=experiment_management, ) n_cores = settings.n_cores settings.output_directory = 'file' settings.simulator_cmd = 'gazebo' settings.world = 'worlds/plane.realtime.world' simulator_queue = SimulatorQueue(n_cores, settings, settings.port_start) await simulator_queue.start() analyzer_queue = AnalyzerQueue(1, settings, settings.port_start + n_cores) await analyzer_queue.start() population = Population(population_conf, simulator_queue, analyzer_queue, next_robot_id) if do_recovery: # loading a previous state of the experiment await population.load_snapshot(gen_num) if gen_num >= 0: logger.info('Recovered snapshot ' + str(gen_num) + ', pop with ' + str(len(population.individuals)) + ' individuals') if has_offspring: individuals = await population.load_offspring( gen_num, population_size, offspring_size, next_robot_id) gen_num += 1 logger.info('Recovered unfinished offspring ' + str(gen_num)) if gen_num == 0: await population.init_pop(individuals) else: population = await population.next_gen(gen_num, individuals) experiment_management.export_snapshots(population.individuals, gen_num) else: # starting a new experiment experiment_management.create_exp_folders() await population.init_pop() experiment_management.export_snapshots(population.individuals, gen_num) while gen_num < num_generations - 1: gen_num += 1 population = await population.next_gen(gen_num) experiment_management.export_snapshots(population.individuals, gen_num)
try: exc = context['exception'] except KeyError: print(context['message']) return if isinstance(exc, ConnectionResetError): print("Got disconnect / connection reset - shutting down.") sys.exit(0) if isinstance(exc, OSError) and exc.errno == 9: print(exc) traceback.print_exc() return # traceback.print_exc() raise exc try: arguments = parser.parse_args() loop = asyncio.get_event_loop() loop.set_exception_handler(handler) RMEvoNode(loop, arguments) except KeyboardInterrupt: print("Got CtrlC, shutting down.") if __name__ == '__main__': logger.info("Starting rmevo process") main()