knowledge representation
The DNA of our individuals is a Vector of integers
Each integer is a key mapped to a Robot action in VREP
... but it is also mapped to another int that defines a "Step" which is a value for any action
{
{ "LeftWheelJoint", "Move left wheel forward", 1 },
{ "LeftWheelJoint", "Move left wheel backward", -1 },
{ "RightWheelJoint", "Move right wheel forward", 1 },
{ "RightWheelJoint", "Move right wheel backward", -1 },
{ "ShoulderMotor", "Move shoulder forward", 1 },
{ "ShoulderMotor", "Move shoulder backward", -1 },
{ "ElbowMotor", "Move elbow forward", 1 },
{ "ElbowMotor", "Move elbow backward", -1 },
{ "WristMotor", "Move wrist forward", 1 },
{ "WristMotor", "Move wrist backward", -1 }
}What we propose
CPP implementation using the remote API of VREP
Robot object to push commands and retrieve information to/from VREP
Simulation object to run the loop of the algorithm and GA components
An Individual object that stores its DNA data and can mutate (5%) and compute itself
A Population object which do operations on whole individuals -> sort, get the best and worst, mutate and evaluate everything, provide easy accessors
Logger object to write data structure into files
Parallelism with OpenMP to fully use your processor cores
Gnuplot to provide data visualisation
What we do
Our big fat Simulation::run method
int Simulation::run() {
Individual best, worst;
double averageFitness = 0.0f;
for (int generationIter = 0; generationIter < _maxGenerations; ++generationIter) {
for (uint i = 0; i < _population.size();) {
// Retrieving batch of individuals to run simulation on
population_t individualsBatch;
for (int robotId = 0; (robotId < _maxRobots) && (i + robotId < _population.size()); ++robotId) {
individualsBatch.push_back(_population.at(i + robotId));
}
// Start the simulation
if (simxStartSimulation(_clientID, simx_opmode_oneshot_wait) == -1) {
throw "Failed to start simulation";
}
// Each robot processing an individual in parallel
#pragma omp parallel for
for (uint batchIter = 0; batchIter < individualsBatch.size(); ++batchIter) {
auto &individual = individualsBatch.at(batchIter);
const auto &robot = _robots[omp_get_thread_num()];
simxFloat prevPos[3];
robot.getPosition(prevPos, _floorHandler);
robot.doActions(individual.getDna());
simxFloat nextPos[3];
robot.getPosition(nextPos, _floorHandler);
double fitness = individual.evaluate(prevPos, nextPos);
#pragma omp critical
{
averageFitness += fitness;
}
_population[i + batchIter].setScore(fitness);
}
i += _maxRobots;
// Stop the simulation
if (simxStopSimulation(_clientID, simx_opmode_oneshot_wait) == -1) {
throw "Fail to stop simulation";
}
}
averageFitness /= _population.size();
_population.sort();
// Finding the worst of the current generation
worst = _population.at(_population.size() - 1);
// Finding the best of the current generation
best = _population.at(0);
logStats(generationIter, best, worst, averageFitness);
logPopulation(generationIter);
// Replacing worst of this generation by best of this generation
if (generationIter)
worst = best;
// Selection
Population newPopulationGeneration;
#pragma omp parallel for shared(newPopulationGeneration)
for (unsigned int i = 0; i < _population.size(); i++) {
couple_t selected = (this->*(selections.at("tournament")))();
const Individual child = ((this->*crossovers.at("SinglePoint"))(selected.first, selected.second)).first;
newPopulationGeneration.addIndividual(child);
}
_population = newPopulationGeneration;
// Mutation
_population.mutateBatch();
}
return (0);
}vrep-ga-ppt
By mb1475963
vrep-ga-ppt
- 462