bool NeatContainer::fillBrain(NEAT::Genome *genome, boost::shared_ptr<RobotRepresentation> &robotRepresentation) { NEAT::NeuralNetwork net; genome->BuildPhenotype(net); typedef std::map<std::string, boost::weak_ptr<NeuronRepresentation> > NeuronMap; std::map<std::string, std::vector<double> > neuronToPositionMap; NeuronMap neuronMap; // FIRST NEED TO CREATE PHYSICAL ROBOT REP TO DETERMINE POSITIONS // parse robot message robogenMessage::Robot robotMessage = robotRepresentation->serialize(); // parse robot boost::shared_ptr<Robot> robot(new Robot); // Initialize ODE dInitODE(); dWorldID odeWorld = dWorldCreate(); dWorldSetGravity(odeWorld, 0, 0, 0); dSpaceID odeSpace = dHashSpaceCreate(0); if (!robot->init(odeWorld, odeSpace, robotMessage)) { std::cout << "Problem when initializing robot in " << "NeatContainer::fillBrain!" << std::endl; return false; } RobotRepresentation::IdPartMap body = robotRepresentation->getBody(); boost::shared_ptr<NeuralNetworkRepresentation> brain = robotRepresentation->getBrain(); // For each body part, get its position then create an entry for every // neuron by adding a 4th coordinate that is the neurons ioID. for(RobotRepresentation::IdPartMap::iterator i = body.begin(); i != body.end(); i++) { std::string id = i->first; boost::shared_ptr<PartRepresentation> part = i->second.lock(); std::vector<boost::weak_ptr<NeuronRepresentation> > neurons = brain->getBodyPartNeurons(part->getId()); osg::Vec3 pos = robot->getBodyPart(id)->getRootPosition(); for (unsigned int j = 0; j<neurons.size(); j++) { std::vector<double> position; position.push_back(pos.x() * 10.0); //roughly something in [-1,1] position.push_back(pos.y() * 10.0); //position.push_back(pos.z()); float io = neurons[j].lock()->getIoPair().second; position.push_back((io/10.0)); neuronToPositionMap[neurons[j].lock()->getId()] = position; neuronMap[neurons[j].lock()->getId()] = neurons[j]; } } // Now go through all neurons and query for weights and params with // the obtained coordinates for(NeuronMap::iterator i = neuronMap.begin(); i != neuronMap.end(); i++) { std::vector<double> positionI = neuronToPositionMap[i->first]; boost::shared_ptr<NeuronRepresentation> neuronI = i->second.lock(); for(NeuronMap::iterator j = neuronMap.begin(); j != neuronMap.end(); j++) { std::vector<double> positionJ = neuronToPositionMap[j->first]; boost::shared_ptr<NeuronRepresentation> neuronJ = j->second.lock(); if (brain->connectionExists(neuronI->getId(), neuronJ->getId())) { // only set weights on existing connections net.Flush(); std::vector<double> inputs; for (unsigned int k = 0; k < positionI.size(); k++) { inputs.push_back(positionI[k]); } for (unsigned int k = 0; k < positionJ.size(); k++) { inputs.push_back(positionJ[k]); } inputs.push_back(1.0); //bias net.Input(inputs); for(int t=0; t<10; t++) { net.Activate(); } std::vector<double> outputs = net.Output(); if (outputs[0] < 0.5) { // if first output is under threshold, // connection "does not exist" according to genome so set // weight to 0 brain->setWeight(neuronI->getIoPair(), neuronJ->getIoPair(), 0.0); } else { // otherwise use the second output // translate from [0,1] to [min, max] double weight = outputs[1] * (evoConf_->maxBrainWeight - evoConf_->minBrainWeight) + evoConf_->minBrainWeight; brain->setWeight(neuronI->getIoPair(), neuronJ->getIoPair(), weight); } } } // now query for parameters if (neuronI->getLayer() != NeuronRepresentation::INPUT) { // input neurons don't have params net.Flush(); std::vector<double> inputs; for (unsigned int k = 0; k < positionI.size(); k++) { inputs.push_back(positionI[k]); } for (unsigned int k = 0; k < positionI.size(); k++) { inputs.push_back(0.0); // 0 for second set of coords } inputs.push_back(1.0); //bias net.Input(inputs); for(int t=0; t<10; t++) { net.Activate(); } std::vector<double> outputs = net.Output(); std::vector<double> params; if(neuronI->getType() == NeuronRepresentation::SIGMOID || neuronI->getType() == NeuronRepresentation::CTRNN_SIGMOID){ // bias params.push_back(outputs[2] * (evoConf_->maxBrainBias - evoConf_->minBrainBias) + evoConf_->minBrainBias); if(neuronI->getType() == NeuronRepresentation::CTRNN_SIGMOID) { // tau params.push_back(outputs[3] * (evoConf_->maxBrainTau - evoConf_->minBrainTau) + evoConf_->minBrainTau); } } else if(neuronI->getType() == NeuronRepresentation::OSCILLATOR) { // period params.push_back( outputs[2] * (evoConf_->maxBrainPeriod - evoConf_->minBrainPeriod) + evoConf_->minBrainPeriod); // phase offset params.push_back( outputs[3] * (evoConf_->maxBrainPhaseOffset - evoConf_->minBrainPhaseOffset) + evoConf_->minBrainPhaseOffset); // amplitude params.push_back( outputs[4] * (evoConf_->maxBrainAmplitude - evoConf_->minBrainAmplitude) + evoConf_->minBrainAmplitude); } else { std::cout << "INVALID TYPE ENCOUNTERED " << neuronI->getType() << std::endl; } neuronI->setParams(params); } } return true; }