int main(int argc, char *argv[]) { startRobogen(); // --------------------------------------- // verify usage and load configuration // --------------------------------------- if (argc > 1 && std::string(argv[1]) == "--help") { printUsage(argv); printHelp(); exitRobogen(EXIT_SUCCESS); } if ((argc < 4)) { printUsage(argv); std::cout << "RUN: " << std::endl << std::endl << " " << std::string(argv[0]) << " --help to see all configuration options." << std::endl << std::endl; exitRobogen(EXIT_FAILURE); } unsigned int seed = atoi(argv[1]); std::string outputDirectory = std::string(argv[2]); std::string confFileName = std::string(argv[3]); bool overwrite = false; bool saveAll = false; int currentArg = 4; for (; currentArg<argc; currentArg++) { if (std::string("--help").compare(argv[currentArg]) == 0) { printUsage(argv); printHelp(); return EXIT_SUCCESS; } else if (std::string("--overwrite").compare(argv[currentArg]) == 0) { overwrite = true; } else if (std::string("--save-all").compare(argv[currentArg]) == 0) { saveAll = true; } else { std::cerr << std::endl << "Invalid option: " << argv[currentArg] << std::endl << std::endl; printUsage(argv); exitRobogen(EXIT_FAILURE); } } // Create random number generator boost::random::mt19937 rng; rng.seed(seed); boost::shared_ptr<EvolverConfiguration> conf = boost::shared_ptr<EvolverConfiguration>(new EvolverConfiguration()); if (!conf->init(confFileName)) { std::cerr << "Problems parsing the evolution configuration file. Quit." << std::endl; exitRobogen(EXIT_FAILURE); } boost::shared_ptr<RobogenConfig> robotConf = ConfigurationReader::parseConfigurationFile( conf->simulatorConfFile); if (robotConf == NULL) { std::cerr << "Problems parsing the robot configuration file. Quit." << std::endl; exitRobogen(EXIT_FAILURE); } // --------------------------------------- // Set up evolution // --------------------------------------- boost::shared_ptr<Selector> selector; if (conf->selection == conf->DETERMINISTIC_TOURNAMENT) { selector.reset(new DeterministicTournament(conf->tournamentSize, rng)); } else { std::cerr << "Selection type id " << conf->selection << " unknown." << std::endl; exitRobogen(EXIT_FAILURE); } boost::shared_ptr<Mutator> mutator = boost::shared_ptr<Mutator>( new Mutator(conf, rng)); boost::shared_ptr<EvolverLog> log(new EvolverLog()); if (!log->init(conf, robotConf, outputDirectory, overwrite, saveAll)) { std::cout << "Error creating evolver log. Aborting." << std::endl; return EXIT_FAILURE; } // --------------------------------------- // parse robot from file & initialize population // --------------------------------------- boost::shared_ptr<RobotRepresentation> referenceBot( new RobotRepresentation()); bool growBodies = false; if (conf->evolutionMode == EvolverConfiguration::BRAIN_EVOLVER && conf->referenceRobotFile.compare("") == 0) { std::cerr << "Trying to evolve brain, but no robot file provided." << std::endl; exitRobogen(EXIT_FAILURE); } else if (conf->referenceRobotFile.compare("") != 0) { if (!referenceBot->init(conf->referenceRobotFile)) { std::cerr << "Failed interpreting robot from text file" << std::endl; exitRobogen(EXIT_FAILURE); } } else { //doing body evolution and don't have a reference robot if (referenceBot->init()) { growBodies = true; } else { std::cerr << "Failed creating base robot for body evolution" << std::endl; exitRobogen(EXIT_FAILURE); } } boost::shared_ptr<Population> population(new Population()); boost::shared_ptr<NeatContainer> neatContainer; bool neat = (conf->evolutionaryAlgorithm == EvolverConfiguration::HYPER_NEAT); if (!population->init(referenceBot, conf->mu, mutator, growBodies, (!(conf->useBrainSeed || neat)) ) ) { std::cerr << "Error when initializing population!" << std::endl; exitRobogen(EXIT_FAILURE); } if (neat) { neatContainer.reset(new NeatContainer(conf, population, seed, rng)); } // --------------------------------------- // open sockets for communication with simulator processes // --------------------------------------- std::vector<TcpSocket*> sockets(conf->sockets.size()); for (unsigned int i = 0; i < conf->sockets.size(); i++) { sockets[i] = new TcpSocket; #ifndef FAKEROBOTREPRESENTATION_H // do not bother with sockets when using // benchmark if (!sockets[i]->open(conf->sockets[i].first, conf->sockets[i].second)) { std::cerr << "Could not open connection to simulator" << std::endl; exitRobogen(EXIT_FAILURE); } #endif } // --------------------------------------- // run evolution TODO stopping criterion // --------------------------------------- if(neat) { if(!neatContainer->fillPopulationWeights(population)) { std::cerr << "Filling weights from NEAT failed." << std::endl; exitRobogen(EXIT_FAILURE); } } population->evaluate(robotConf, sockets); if (!log->logGeneration(1, *population.get())) { exitRobogen(EXIT_FAILURE); } for (unsigned int generation = 2; generation <= conf->numGenerations; ++generation) { // create children IndividualContainer children; if (neat) { //neatPopulation->Epoch(); if(!neatContainer->produceNextGeneration(population)) { std::cerr << "Producing next generation from NEAT failed." << std::endl; exitRobogen(EXIT_FAILURE); } population->evaluate(robotConf, sockets); population->sort(true); } else { selector->initPopulation(population); for (unsigned int i = 0; i < conf->lambda; i++) { std::pair<boost::shared_ptr<RobotRepresentation>, boost::shared_ptr<RobotRepresentation> > selection; if (!selector->select(selection)) { std::cerr << "Selector::select() failed." << std::endl; exitRobogen(EXIT_FAILURE); } children.push_back( mutator->mutate(selection.first, selection.second)); } // evaluate children children.evaluate(robotConf, sockets); // comma or plus? if (conf->replacement == conf->PLUS_REPLACEMENT) { children += *population.get(); } // replace population.reset(new Population()); if (!population->init(children, conf->mu)) { std::cerr << "Error when initializing population!" << std::endl; exitRobogen(EXIT_FAILURE); } } if (!log->logGeneration(generation, *population.get())) { exitRobogen(EXIT_FAILURE); } } // Clean up sockets for (unsigned int i = 0; i < conf->sockets.size(); i++) { delete sockets[i]; } exitRobogen(EXIT_SUCCESS); }
void mainEvolutionLoop() { #ifdef EMSCRIPTEN std::stringstream ss; double best, average, stddev; population->getStat(best, average, stddev); ss << "{best : " << best << ", average : " << average << ", stddev : " << stddev << ", generation : " << generation << "}"; sendJSEvent("stats", ss.str()); #endif std::cout << "mainEvolutionLoop" << std::endl; if (!log->logGeneration(generation, *population.get())) { exitRobogen(EXIT_FAILURE); } generation++; if (generation <= conf->numGenerations) { std::cout << "Generation " << generation << std::endl; children.clear(); // create children if (neat) { //neatPopulation->Epoch(); if(!neatContainer->produceNextGeneration(population)) { std::cerr << "Producing next generation from NEAT failed." << std::endl; exitRobogen(EXIT_FAILURE); } population->evaluate(robotConf, sockets); } else { selector->initPopulation(population); unsigned int numOffspring = 0; while (numOffspring < conf->lambda) { std::pair<boost::shared_ptr<RobotRepresentation>, boost::shared_ptr<RobotRepresentation> > selection; if (!selector->select(selection.first)) { std::cerr << "Selector::select() failed." << std::endl; exitRobogen(EXIT_FAILURE); } unsigned int tries = 0; do { if (tries > 10000) { std::cerr << "Selecting second parent failed after " "10000 tries, giving up."; exitRobogen(EXIT_FAILURE); } if (!selector->select(selection.second)) { std::cerr << "Selector::select() failed." << std::endl; exitRobogen(EXIT_FAILURE); } tries++; } while (selection.first == selection.second); std::vector<boost::shared_ptr<RobotRepresentation> > offspring = mutator->createOffspring(selection.first, selection.second); // no crossover, or can fit both new individuals if ( (numOffspring + offspring.size()) <= conf->lambda ) { children.insert(children.end(), offspring.begin(), offspring.end() ); numOffspring += offspring.size(); } else { // crossover, but can only fit one children.push_back(offspring[0]); numOffspring++; } } children.evaluate(robotConf, sockets); } #ifndef EMSCRIPTEN triggerPostEvaluate(); #endif } else { #ifdef EMSCRIPTEN sendJSEvent("evolutionTerminated", "{}"); #endif } }