void MedeaSpAgentObserver::checkGenomeList() { if (_wm->_agentId == gAgentIndexFocus && gVerbose) // debug { std::cout << "agent #" << gAgentIndexFocus << " is renewed" << std::endl; std::cout << "agent #" << gAgentIndexFocus << " imported " << _wm->_genomesList.size() << " genomes. Energy is " << _wm->getEnergyLevel() << ". Status is " << _wm->getActiveStatus() << "." <<std::endl; } // note: at this point, agent got energy, wether because it was revived or because of remaining energy. if (_wm->_genomesList.size() > 0) { // case: 1+ genome(s) imported, random pick. _wm->setDateOfBirth(gWorld->getIterations()); // // if((int)MedeaSpSharedData::gTournamentSize < 0) selectFitnessProp(); // else elitSelection(); // _wm->setRobotLED_status(true); //Print the new genome on the logFile //gLogFile << gWorld->getIterations() <<" : "<< _wm->_agentId << " use "<<_wm->getAbilityToForage(); //gLogFile << " at "<<_wm->getXReal()<< std::endl; switch ( MedeaSpSharedData::gSelectionMethod ) { case 0: pickRandomGenome(); break; case 1: elitSelection(); //elite break; case 2: selectFitnessProp(); break; case 3: selectRankProp(); break; default: std::cerr << "[ERROR] unknown selection method (gSelectionMethod = " << MedeaSpSharedData::gSelectionMethod << ")\n"; exit(-1); } _wm->setWaitForGenome(false); // !N.20100407 : revive takes imported genome if any _wm->setActiveStatus(true); } else { // case: no imported genome - wait for new genome. _wm->resetActiveGenome(); // optional -- could be set to zeroes. _wm->setWaitForGenome(true); // inactive robot *must* import a genome from others (ie. no restart). _wm->setActiveStatus(false);//The robot is waiting for genome but not active yet } }
void BasicProjectMedeaAgentObserver::step() { // debug verbose if ( gVerbose && gInspectAgent && gAgentIndexFocus == _wm->_agentId ) { std::cout << "target: " << _wm->getEnergyPointDirectionAngleValue() << std::endl; } // * genome spreading (current agent broadcasts its genome to all neighbors - ie. write its own genome in genomeList on neighboring agents) // note: could be move in WorldObserver to go from N^2 to Summation(N) complexity if ( _wm->getActiveStatus() == true ) // broadcast only if agent is active (ie. not just revived) and deltaE>0. { for (int i = 0 ; i < gAgentCounter ; i++) { if ( ( i != _wm->_agentId ) && ( gRadioNetworkArray[_wm->_agentId][i] ) ) //&& (_wm->getEnergyLevel() > 0.0) ) --> always true as status is active { BasicProjectMedeaAgentObserver* targetAgentObserver = dynamic_cast<BasicProjectMedeaAgentObserver*>(gWorld->getAgent(i)->getObserver()); if ( ! targetAgentObserver ) { std::cerr << "Error from robot " << _wm->_agentId << " : the observer of robot " << i << " isn't a SwarmOnlineObserver" << std::endl; exit(1); } if ( BasicProjectMedeaSharedData::gDynamicSigma == true ) { float dice = float(rand() %100) / 100.0; float sigmaSendValue = 0.0; if ( ( dice >= 0.0 ) && ( dice < BasicProjectMedeaSharedData::gProbAdd) ) { sigmaSendValue = _wm->_currentSigma * ( 1 + BasicProjectMedeaSharedData::gDynaStep ); if (sigmaSendValue > BasicProjectMedeaSharedData::gSigmaMax) { sigmaSendValue = BasicProjectMedeaSharedData::gSigmaMax; } } else if ( ( dice >= BasicProjectMedeaSharedData::gProbAdd ) && ( dice < BasicProjectMedeaSharedData::gProbAdd+BasicProjectMedeaSharedData::gProbSub) ) { sigmaSendValue = _wm->_currentSigma * ( 1 - BasicProjectMedeaSharedData::gDynaStep ); if (sigmaSendValue < BasicProjectMedeaSharedData::gSigmaMin) { sigmaSendValue = BasicProjectMedeaSharedData::gSigmaMin; } } else { std::cerr << "Error : In SwarmOnlineObserver, the rand value is out of bound. The sum of BasicProjectMedeaSharedData::gProbRef and BasicProjectMedeaSharedData::gProbMax is probably not equal to one" << std::endl; exit(1); } targetAgentObserver->writeGenome(_wm->_currentGenome, _wm->_agentId, sigmaSendValue); } else { targetAgentObserver->writeGenome(_wm->_currentGenome, _wm->_agentId, _wm->_currentSigma); } } } } // * Genome selection/replacement if( dynamic_cast<BasicProjectMedeaWorldObserver*>(gWorld->getWorldObserver())->getLifeIterationCount() >= BasicProjectMedeaSharedData::gEvaluationTime-1 ) // at the end of a generation { if (_wm->_agentId == gAgentIndexFocus && gVerbose) // debug { std::cout << "agent #" << gAgentIndexFocus << " is renewed" << std::endl; std::cout << "agent #" << gAgentIndexFocus << " imported " << _wm->_genomesList.size() << " genomes. Energy is " << _wm->getEnergyLevel() << ". Status is " << _wm->getActiveStatus() << "." <<std::endl; } // Display the current state of the controller gLogFile << "#GIteration: " << gWorld->getIterations() << " #Robot: " << _wm->_agentId << " #Energy: " << _wm->getEnergyLevel() << " #DeltaEnergy: " << _wm->getDeltaEnergy() << " #GenomeListSize: " << _wm->_genomesList.size() <<std::endl; // note: at this point, agent got energy, whether because it was revived or because of remaining energy. if (_wm->_genomesList.size() > 0) { // case: 1+ genome(s) imported, random pick. pickRandomGenome(); _wm->setActiveStatus(true); // !N.20100407 : revive takes imported genome if any } else { // case: no imported genome - wait for new genome. gLogFile << "Info(" << gWorld->getIterations() << ") : robot nb." << _wm->_agentId // << " is trying a whole new genome" << std::endl; << " is waiting for a new genome" << std::endl; _wm->resetActiveGenome(); // optional -- could be set to zeroes. _wm->setActiveStatus(false); // inactive robot *must* import a genome from others (ie. no restart). } //log the genome if ( _wm->getActiveStatus() == true ) { gLogFile << "Info("<< gWorld->getIterations() <<") : robot nb."<< _wm->_agentId << " use genome :"; for(unsigned int i=0; i<_wm->_genome.size(); i++) { gLogFile << std::fixed << std::showpoint << _wm->_genome[i] << " "; } gLogFile << std::endl; } //Re-initialize the main parameters if ( BasicProjectMedeaSharedData::gExperimentNumber == 1 || BasicProjectMedeaSharedData::gExperimentNumber == 2 ) { _wm->setDeltaEnergy(0.0); // !n : used to be 10.0 } } }
void MedeaAltUtilityBattleAgentObserver::step() { _iterationCount++; if ( _wm->_agentId == 0 ) { if ( MedeaAltUtilitySharedData::gExperimentNumber == 2 ) { if (_wm->_agentId == gAgentIndexFocus ) // && gVerbose ) // debug { std::cout << std::endl << "#### Experiment no.2 starts now. ####" << std::endl; } // * remove energy points. for(std::vector<EnergyPoint>::iterator it = gEnergyPoints.begin(); it != gEnergyPoints.end(); it++) { it->hide(); } gEnergyPoints.clear(); // * setup new energy zone Uint32 colorShown = 0xeab71fff; Uint32 colorZone = 0xAAAAAAFF; // for floor sensor. for (Sint16 xColor = MedeaAltUtilitySharedData::g_xStart_EnergyZone ; xColor < MedeaAltUtilitySharedData::g_xEnd_EnergyZone ; xColor++) { for (Sint16 yColor = Sint16 (MedeaAltUtilitySharedData::g_yStart_EnergyZone) ; yColor < Sint16 (MedeaAltUtilitySharedData::g_yEnd_EnergyZone) ; yColor ++) { pixelColor(gBackgroundImage, xColor, yColor, colorShown); pixelColor(gZoneImage, xColor, yColor, colorZone); } } } } // std::cout << "robot #" << _wm->_agentId << "\n" ; MedeaAltUtilityPerceptronControlArchitecture* currentBehavior = dynamic_cast<MedeaAltUtilityPerceptronControlArchitecture*>(gWorld->getAgent(_wm->_agentId)->getBehavior()); if ( ! currentBehavior ) { std::cerr << "Error from robot " << _wm->_agentId << " : the behavior architecture of this robot isn't a MedeaAltUtilityPerceptronControlArchitecture" << std::endl; exit(1); } /*if (_wm->_agentId == 1) { std::cout << _key <<std::endl; }*/ if ( gVerbose && gInspectAgent && gAgentIndexFocus == _wm->_agentId ) { //std::cout << "target: " << _wm->getEnergyPointDirectionAngleValue() << std::endl;// " (" << _wm->_agentAbsoluteOrientation << "," << angleToClosestEnergyPoint << ")" << std::endl; } if ( MedeaAltUtilitySharedData::gExperimentNumber == 1 ) { // * update the energy of the robot (if needed) Point2d posRobot(_wm->_xReal,_wm->_yReal); if ( gEnergyMode ) { for(std::vector<EnergyPoint>::iterator it = gEnergyPoints.begin(); it != gEnergyPoints.end(); it++) { if( (getEuclidianDistance (posRobot,it->getPosition()) < gEnergyPointRadius) && (it->getActiveStatus())) { float loadingEnergy = gEnergyPointValue; // test? //float loadingEnergy = 5*(1.0/(2.0*sqrt(2.0*M_PI)))*gEnergyPointValue; // test? //float loadingEnergy = 5*(1.0/(2.0*sqrt(2.0*M_PI)))*exp(-(pow((_key - it->getKey()),2.0)/(pow(2.0,2.0))))*gEnergyPointValue; // update energy level _wm->setEnergyLevel(_wm->getEnergyLevel() + loadingEnergy); _wm->setDeltaEnergy(_wm->getDeltaEnergy() + loadingEnergy); //saturate if ( _wm->getEnergyLevel() > MedeaAltUtilitySharedData::gEnergyMax ) // should be at least one lifetime _wm->setEnergyLevel(MedeaAltUtilitySharedData::gEnergyMax); if ( _wm->getDeltaEnergy() > MedeaAltUtilitySharedData::gEnergyMax ) _wm->setDeltaEnergy(MedeaAltUtilitySharedData::gEnergyMax); gLogFile << "Info(" << gWorld->getIterations() << ") : " << _wm->_agentId << "(" << posRobot.x << "," << posRobot.y << ")" << " get an energy point at " << it->getPosition().x << "," << it->getPosition().y << " :: Value : " << loadingEnergy << std::endl; it->setActiveStatus(false); } } } } else { if ( MedeaAltUtilitySharedData::gExperimentNumber == 2 ) { // * once per world update (TODO: move to worldobserver) if (_wm->_agentId == 0 ) // debug { int agentsOnZone = 0; for ( int i = 0 ; i != gAgentCounter ; i++ ) { int x = (int)(gWorld->getAgent(i)->getWorldModel()->getXReal()); int y = (int)(gWorld->getAgent(i)->getWorldModel()->getYReal()); // std::cout << "x =" << x << " , y = " << y << std::endl; if ( x >= MedeaAltUtilitySharedData::g_xStart_EnergyZone && y >= MedeaAltUtilitySharedData::g_yStart_EnergyZone && x <= MedeaAltUtilitySharedData::g_xEnd_EnergyZone && y <= MedeaAltUtilitySharedData::g_yEnd_EnergyZone ) agentsOnZone++; } // update MedeaAltUtilitySharedData::gZoneEnergy_harvestValue //MedeaAltUtilitySharedData::gZoneEnergy_harvestValue = 10; // TODO :: TEMPORARY !!!!!!!!!!TEMPORARY !!!!!!!!!!TEMPORARY !!!!!!!!!!TEMPORARY !!!!!!!!!!TEMPORARY !!!!!!!!!! if ( gVerbose ) std::cout << "There are " << agentsOnZone << " agents on the energy zone" << std::endl; /**/ if ( agentsOnZone <= MedeaAltUtilitySharedData::gZoneEnergy_maxFullCapacity ) { // best case MedeaAltUtilitySharedData::gZoneEnergy_harvestValue = MedeaAltUtilitySharedData::gZoneEnergy_maxHarvestValue; } else { if ( agentsOnZone <= MedeaAltUtilitySharedData::gZoneEnergy_saturateCapacityLevel ) { double energyValueSpan = MedeaAltUtilitySharedData::gZoneEnergy_maxHarvestValue - MedeaAltUtilitySharedData::gZoneEnergy_minHarvestValue; int agentsOverheadCount = MedeaAltUtilitySharedData::gZoneEnergy_saturateCapacityLevel - MedeaAltUtilitySharedData::gZoneEnergy_maxFullCapacity; double costPerAgents = energyValueSpan / (double)agentsOverheadCount; MedeaAltUtilitySharedData::gZoneEnergy_harvestValue = MedeaAltUtilitySharedData::gZoneEnergy_maxHarvestValue - costPerAgents * ( agentsOnZone- MedeaAltUtilitySharedData::gZoneEnergy_maxFullCapacity ) ; } else { // worst case MedeaAltUtilitySharedData::gZoneEnergy_harvestValue = MedeaAltUtilitySharedData::gZoneEnergy_minHarvestValue; } } /**/ // debug : MedeaAltUtilitySharedData::gZoneEnergy_harvestValue = MedeaAltUtilitySharedData::gZoneEnergy_maxHarvestValue; } // * for each agent -- TODO: could be optimized by merging with previous block in the worldobserve if ( _wm->_xReal >= MedeaAltUtilitySharedData::g_xStart_EnergyZone && _wm->_xReal <= MedeaAltUtilitySharedData::g_xEnd_EnergyZone && _wm->_yReal >= MedeaAltUtilitySharedData::g_yStart_EnergyZone && _wm->_yReal <= MedeaAltUtilitySharedData::g_yEnd_EnergyZone ) { float loadingEnergy = MedeaAltUtilitySharedData::gZoneEnergy_harvestValue; // update energy level _wm->setEnergyLevel(_wm->getEnergyLevel() + loadingEnergy); _wm->setDeltaEnergy(_wm->getDeltaEnergy() + loadingEnergy); // saturate if ( _wm->getEnergyLevel() > MedeaAltUtilitySharedData::gEnergyMax ) // assume: need MedeaAltUtilitySharedData::gEvaluationTime to live full life _wm->setEnergyLevel(MedeaAltUtilitySharedData::gEnergyMax); if ( _wm->getDeltaEnergy() > MedeaAltUtilitySharedData::gEnergyMax ) // assume: need MedeaAltUtilitySharedData::gEvaluationTime to live full life _wm->setDeltaEnergy(MedeaAltUtilitySharedData::gEnergyMax); Point2d posRobot(_wm->_xReal,_wm->_yReal); gLogFile << "Info(" << gWorld->getIterations() << ") : " << _wm->_agentId << "(" << posRobot.x << "," << posRobot.y << ")" << " get an energy point at 0,0 :: Value : " << loadingEnergy << std::endl; // hack to comply with python log analyser } } } // * check energy level if ( MedeaAltUtilitySharedData::gExperimentNumber == 1 || MedeaAltUtilitySharedData::gExperimentNumber == 2 ) { if ( _wm->getEnergyLevel() <= 0 ) { _wm->setDeltaEnergy(0); // must be set to zero to avoid broadcasting. _wm->setActiveStatus(false); } } // * broadcast the genome (current agent writes its genome to all neighbors // broadcast only if agent is active (ie. not just revived) and deltaE>0. if ( /*( _wm->getDeltaEnergy()>0.0 && _wm->getActiveStatus() == true ) || ( MedeaAltUtilitySharedData::gExperimentNumber == 0 && _wm->getActiveStatus() == true )*/ _wm->getActiveStatus() == true ) { for (int i = 0 ; i < gAgentCounter ; i++) { if ( ( i != _wm->_agentId ) && ( gRadioNetworkArray[_wm->_agentId][i] ) ) //&& (_wm->getEnergyLevel() > 0.0) ) --> always true as status is active { MedeaAltUtilityBattleAgentObserver* agentObserver = dynamic_cast<MedeaAltUtilityBattleAgentObserver*>(gWorld->getAgent(i)->getObserver()); if ( ! agentObserver ) { std::cerr << "Error from robot " << _wm->_agentId << " : the observer of robot " << i << " isn't a MedeaAltUtilityBattleAgentObserver" << std::endl; exit(1); } agentObserver->writeGenome(_currentGenome, _wm->_agentId); } } } // * handle genome renewal //"restart" the robot in case it runs out of energy -- case: no synchronisation /* if ( ( _wm->getEnergyLevel() <= 0.0 ) && ( MedeaAltUtilitySharedData::gSynchronization == false ) ){ logStatus(); //resetActiveGenome(); _wm->setEnergyLevel( currentBehavior->getInitialEnergy()); _wm->setDeltaEnergy(0.0); gLogFile << "Info(" << gWorld->getIterations() << ") : Human intervention on robot " << _wm->_agentId << " (Energy)" << std::endl; _iterationCount = 0; _wm->setActiveStatus(false); // !N.20100407 : inactive robot should get a new genome and move until it imports one from neighbors. } */ // case: default for Medea, synchronised if( _iterationCount >= MedeaAltUtilitySharedData::gEvaluationTime ) { /**/ if (_wm->_agentId == gAgentIndexFocus && gVerbose) // debug { std::cout << "agent #" << gAgentIndexFocus << " is renewed" << std::endl; std::cout << "agent #" << gAgentIndexFocus << " imported " << _genomesList.size() << " genomes. Energy is " << _wm->getEnergyLevel() << ". Status is " << _wm->getActiveStatus() << "." <<std::endl; } /**/ logStatus(); //"revive" the robot in case it runs out of energy if ( MedeaAltUtilitySharedData::gExperimentNumber == 1 || MedeaAltUtilitySharedData::gExperimentNumber == 2 ) { if ( _wm->getEnergyLevel() <= 0.0 ) { gLogFile << "Info(" << gWorld->getIterations() << ") : Human intervention on robot " << _wm->_agentId << " (Energy)" << std::endl; // reformulate (check python script compatibility before): gLogFile << "Info(" << gWorld->getIterations() << ") : robot " << _wm->_agentId << " was revived (human intervention)" << std::endl; if (_wm->_agentId == gAgentIndexFocus && gVerbose) // debug { std::cout << "agent #" << gAgentIndexFocus << " is revived (energy was 0)." << std::endl; } logStatus(); //resetActiveGenome(); _wm->setEnergyLevel(MedeaAltUtilitySharedData::gEnergyRevive); // !n : too few? _wm->setActiveStatus(false); // true: restart, false: no-restart _genomesList.empty(); } } //else // uncomment if restart // note: at this point, agent got energy, wether because it was revived or because of remaining energy. // case: genome(s) imported, random pick. if (_genomesList.size() > 0) { pickRandomGenome(); _wm->setActiveStatus(true); // !N.20100407 : revive takes imported genome if any } // case: no imported genome - wait for new genome. else { gLogFile << "Info(" << gWorld->getIterations() << ") : robot nb." << _wm->_agentId // << " is trying a whole new genome" << std::endl; << " is waiting for a new genome" << std::endl; //resetActiveGenome(); // optional -- could be set to zeroes. _wm->setActiveStatus(false); // !N.20100407 : inactive robot must import a genome from others. } //log the genome gLogFile << "get active status" << std::endl ; if ( _wm->getActiveStatus() == true ) { gLogFile << "Info("<< gWorld->getIterations() <<") : robot nb."<< _wm->_agentId << " use genome :"; for(unsigned int i=0; i<_wm->_genome.size(); i++) { gLogFile << std::fixed << std::showpoint<< _wm->_genome[i] << " "; } gLogFile << std::endl; } //Re-initialize the main parameters if ( MedeaAltUtilitySharedData::gExperimentNumber == 1 || MedeaAltUtilitySharedData::gExperimentNumber == 2 ) { _wm->setDeltaEnergy(0.0); // !n : avant: 10.0 } _iterationCount = 0; _generationCount ++; if ( _wm->_agentId == 0 ) { if ( !gVerbose ) { //std::cout << "."; int activeCount = 0; for ( int i = 0 ; i != gAgentCounter ; i++ ) { if ( _wm->getActiveStatus() == true ) activeCount++; } std::cout << "[" << activeCount << "]"; } } } }