コード例 #1
0
// * 
// * update energy level for each agents (ONLY active agents) (only in experimental setups featuring energy items)
// *
void MedeaAltruismReplayWorldObserver::updateAllAgentsEnergyLevel()
{	
	
	for ( int i = 0 ; i != gAgentCounter ; i++ ) // for each agent
	{
		MedeaAltruismAgentWorldModel *currentAgentWorldModel = dynamic_cast<MedeaAltruismAgentWorldModel*>(gWorld->getAgent(i)->getWorldModel());
		
		// * check energy level. Becomes inactive if zero.
	/*	
		if ( currentAgentWorldModel->getEnergyLevel() <= 0 )
		{
			currentAgentWorldModel->setDeltaEnergy(0);
			currentAgentWorldModel->setActiveStatus(false);
			currentAgentWorldModel->setWaitingAfterLifeSynchronization(true);
		}*/

		// * if active, check if agent harvests energy. (experimental setup dependant)
		
		if ( currentAgentWorldModel->getActiveStatus() == true )
		{
			// * update agent energy (if needed) - agent should be on an active energy point location to get energy
		
			Point2d posRobot(currentAgentWorldModel->_xReal,currentAgentWorldModel->_yReal);
			if ( gEnergyMode && currentAgentWorldModel->getActiveStatus())
			{
				for(std::vector<EnergyPoint>::iterator it = gEnergyPoints.begin(); it != gEnergyPoints.end(); it++)
				{
					if( (getEuclidianDistance (posRobot,it->getPosition()) < gEnergyPointRadius) && (it->getActiveStatus()))
					{
						float loadingEnergy = currentAgentWorldModel->getEnergyHarvestingRate() * gEnergyPointValue;
						//float loadingEnergy = std::max( 0.0 , std::min( double(gEnergyPointValue), MedeaAltruismSharedData::gEnergyMax - currentAgentWorldModel->getEnergyLevel() ) - fixedCost);
						//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;

						double energyMissing = MedeaAltruismSharedData::gEnergyMax-currentAgentWorldModel->getEnergyLevel();
						double costMeasure = 0.0;

						if ( currentAgentWorldModel->getEnergyLevel() + loadingEnergy < MedeaAltruismSharedData::gEnergyMax )
						{
							if (gEnergyPointValue > energyMissing)
							{
								costMeasure = energyMissing - loadingEnergy;
							}
							else
							{
								costMeasure = gEnergyPointValue - loadingEnergy;
							}
						}
	
						gLogFile << gWorld->getIterations() << " : " << currentAgentWorldModel->_agentId << " c "  << costMeasure << std::endl;

						// update energy level
						currentAgentWorldModel->setEnergyLevel(currentAgentWorldModel->getEnergyLevel() + loadingEnergy);
						currentAgentWorldModel->setDeltaEnergy(currentAgentWorldModel->getDeltaEnergy() + loadingEnergy);
	
						//saturate
						if ( currentAgentWorldModel->getEnergyLevel() > MedeaAltruismSharedData::gEnergyMax ) // assume: need MedeaAltruismSharedData::gEvaluationTime to live full life
							currentAgentWorldModel->setEnergyLevel(MedeaAltruismSharedData::gEnergyMax);
	
						double loadingRatio = loadingEnergy/gEnergyPointValue;
						double exponentialRespawn = exp(loadingRatio*exponentialFactor)*(MedeaAltruismSharedData::gHighestBoundRespawn/exp(exponentialFactor));
						it->setRespawnLag(exponentialRespawn);
						//it->setRespawnLag((loadingEnergy/gEnergyPointValue)*MedeaAltruismSharedData::gHighestBoundRespawn);
						it->setActiveStatus(false);
					}
				}
			}
		}
		
		
		// * update agent energy consumption -- if inactive, "revive" the agent (ie. it ran out of energy)
		
		// decrease the energyLevel and deltaEnergyLevel

		if (currentAgentWorldModel->getActiveStatus() == true )
		{
		
			if ( currentAgentWorldModel->getEnergyLevel() > 0.0 ) 
			{
				currentAgentWorldModel->setEnergyLevel(currentAgentWorldModel->getEnergyLevel()-1); 
			}
			currentAgentWorldModel->setDeltaEnergy(currentAgentWorldModel->getDeltaEnergy()-1); 
		}
	

		if  ( currentAgentWorldModel->getEnergyLevel()  <= 0.0 )
		{
			//gLogFile << gWorld->getIterations() << " : " << currentAgentWorldModel->_agentId << " die" << std::endl;
			
			currentAgentWorldModel->resetActiveGenome();
			currentAgentWorldModel->setMaturity(1);
		
			currentAgentWorldModel->setEnergyLevel(MedeaAltruismSharedData::gEnergyRevive); 
			currentAgentWorldModel->setDeltaEnergy(0.0); 
			currentAgentWorldModel->setLifeTime(0);

			currentAgentWorldModel->setActiveStatus(false);
			currentAgentWorldModel->setWaitForGenome(false);
		
			currentAgentWorldModel->_genomesList.empty();
		}
	}	
}
コード例 #2
0
// perform one controller update
// set motor value using motor format.
void MedeaSpPerceptronControlArchitecture::step()
{
	_iteration++;

	if ( _wm->getNewGenomeStatus() ) // check for new NN parameters
	{
		reset();
		_wm->setNewGenomeStatus(false);
	}

/*	if ( _wm->_age < 0 ) // problem: _age is nowhere to be incremented
	{
		// ** security control (prior to a new behavior, get out of crash situation) -- random noise to avoid "STALL" status
		_wm->_desiredTranslationalValue = ( ranf()*2.-1. ) * gMaxTranslationalSpeed ;
		_wm->_desiredRotationalVelocity =( ranf()*2.-1. ) * gMaxRotationalSpeed ;
		currentObserver->setKey( ( ranf()*2.-1. ) * MedeaSpSharedData::gMaxKeyRange);
		return;
	}
*/
	_wm->_desiredTranslationalValue = 0.0;
	_wm->_desiredRotationalVelocity = 0.0;
	
	//We take the world observer which store now the energypoints vector! 
	/////////// NO MORE "gEnergyPoints"!!!!!!!
	
	MedeaSpWorldObserver * wo = dynamic_cast<MedeaSpWorldObserver * >(_wm->_world->getWorldObserver());

	std::vector< MedeaSpEnergyPoint*> * allEP=wo->getEnergyPoints();
	
	if ( _wm->getActiveStatus() == true && !MedeaSpSharedData::gExperimentNoMovements)
	{
		double angleToClosestEnergyPoint = 0.0;
		double shortestDistance = 0.0; //search the current active energy point
		Point2d posRobot(_wm->_xReal,_wm->_yReal);
		
		for(int i = 0; i<MedeaSpSharedData::gNbTypeResource ; i++)
		{
		    //Could be better : trying to generalise for n type of energy point
			std::vector<MedeaSpEnergyPoint*>::iterator closestPoint = allEP->begin();
			//Look for the first point of the good type
			while( (int)((*closestPoint)->getType()) != i ){
				closestPoint++;
			}
			
			shortestDistance = getEuclidianDistance (posRobot,(*closestPoint)->getPosition());
			
			for(std::vector<MedeaSpEnergyPoint*>::iterator it = allEP->begin(); it < allEP->end(); it++)//Can be optimised and starting with "closest point"would allow us not to check previous points again.j
			{
				if (((*it)->getType() == i))
				{
					double newDistance = getEuclidianDistance (posRobot,(*it)->getPosition());
					if(newDistance < shortestDistance)
					{
						shortestDistance = newDistance;
						closestPoint = it;
					}
				}
			}	
			//compute the orientation of the active sun ( in degree between 0 and 360 )
			//compute the orientation of the closest energy point ( in degree between 0 and 360 )
			angleToClosestEnergyPoint = (atan2((*closestPoint)->getPosition().y-posRobot.y,(*closestPoint)->getPosition().x-	posRobot.x)/M_PI)*180.0;
			angleToClosestEnergyPoint += 360.0 ;
			angleToClosestEnergyPoint = computeModulo(angleToClosestEnergyPoint,360.0);
			if ( angleToClosestEnergyPoint > 180 ) // force btw -180 and 180
				angleToClosestEnergyPoint -= 360.0;

			//compute the angle between the actual orientation of the robot and the orientation of the closest energy point ( in degree between -180 and 180 )
			double diffAngleToClosestEnergyPoint= angleToClosestEnergyPoint -  _wm->_agentAbsoluteOrientation ;
			if ( diffAngleToClosestEnergyPoint< -180.0 )
			{
				diffAngleToClosestEnergyPoint+= 360.0 ; 
			}
			if ( diffAngleToClosestEnergyPoint> 180.0 )
			{
				diffAngleToClosestEnergyPoint-= 360.0 ;
			}

			//cast the diffAngle between -1 and 1
			diffAngleToClosestEnergyPoint= diffAngleToClosestEnergyPoint/ 180.0 ; 
			_wm->setEnergyPointDirectionAngleValue(i,diffAngleToClosestEnergyPoint);
			
			//cast the shortest distance between 0 and 1
			if ( shortestDistance > gSensorRange )
				shortestDistance = 1.0;
			else
				shortestDistance = shortestDistance / (double)gSensorRange;
			_wm->setEnergyPointDistanceValue(i,shortestDistance);

	//		if ( gAgentIndexFocus == _wm->_agentId )
			if ( gVerbose && gInspectAgent && gAgentIndexFocus == _wm->_agentId )
			{
				std::cout << "SunSensorValue: " << _wm->getEnergyPointDirectionAngleValue(i) << " , " << _wm->getEnergyPointDistanceValue(i) << std::endl;			
			}
		}
		
		std::vector<double> hiddenLayer;
		hiddenLayer.resize(_nbHiddenNeurons);
		for (int j= 0 ; j < _nbHiddenNeurons ; j++ )
		{
			hiddenLayer[j] = 0.0;
		}

		int geneToUse = 0;

		// inputs to hidden Layer

		// distance sensors
		for ( int i = 0 ; i < _wm->_sensorCount ; i++ )
		{
			for (int j= 0 ; j < _nbHiddenNeurons ; j++ )
			{
				hiddenLayer[j] += (_wm->getSensorDistanceValue(i)/_wm->getSensorMaximumDistanceValue(i)) * _parameters[geneToUse] ;  // !N - corrected BUG di0319 - use normalized sensor value in 0...1
				geneToUse ++;
			}
		}

		//floor sensor
		for (int j= 0 ; j < _nbHiddenNeurons ; j++ )
		{
			if ( _wm->_floorSensor != 0 )		// binary detector -- either something, or nothing.
				hiddenLayer[j] += 1.0  * _parameters[geneToUse];
			//hiddenLayer[j] += _wm->_floorSensor/255.0  * _parameters[geneToUse];
			geneToUse ++;
		}
		
		//direction of the closest energy point of each type 		
// 		gLogFile << "nress,"<<MedeaSpSharedData::gNbTypeResource<<std::endl;
		
		for(int i=0 ; i < MedeaSpSharedData::gNbTypeResource ; i++)
		{
			for (int j= 0 ; j < _nbHiddenNeurons ; j++ )
			{
				hiddenLayer[j] += _wm->getEnergyPointDirectionAngleValue(i)  * _parameters[geneToUse];		// ??? !N - should be angle. naming problem, code correct.
				geneToUse ++;
			}
		}

		//direction of the closest energy point
		for(int i=0 ; i < MedeaSpSharedData::gNbTypeResource ; i++)
		{
// 		    std::cout<<"i:"<< i<<", energydistancevalue: "<<_wm->getEnergyPointDistanceValue(i)<<std::endl  ;
			for (int j= 0 ; j < _nbHiddenNeurons ; j++ )
			{
				hiddenLayer[j] += _wm->getEnergyPointDistanceValue(i)  * _parameters[geneToUse];		// ??? !N - should be angle. naming problem, code correct.
				geneToUse ++;
			}
		}
			
		//energy level
		for (int j= 0 ; j < _nbHiddenNeurons ; j++ )
		{
			hiddenLayer[j] +=  (_wm->getEnergyLevel()/MedeaSpSharedData::gEnergyMax)  * _parameters[geneToUse];  // !N : added: energy value normalization btw 0 and 1.
			geneToUse ++;
		}

		//bias
		for (int j= 0 ; j < _nbHiddenNeurons ; j++ )
		{
			hiddenLayer[j] += 1.0  * _parameters[geneToUse];
			geneToUse ++;
		}

		//activation function on hidden layer
// 		for (int j= 0 ; j < _nbHiddenNeurons ; j++ )
// 		{
// 			hiddenLayer[j] = tanh(hiddenLayer[j]);
// 		}
		
		//hiddenLayer to output
		_wm->_desiredTranslationalValue = 0;
		_wm->_desiredRotationalVelocity = 0;
		for (int j= 0 ; j < _nbHiddenNeurons ; j++ )
		{
			_wm->_desiredTranslationalValue += hiddenLayer[j] * _parameters[geneToUse] ;
			geneToUse ++;
		}
		for (int j= 0 ; j < _nbHiddenNeurons ; j++ )
		{
			_wm->_desiredRotationalVelocity += hiddenLayer[j] * _parameters[geneToUse] ;
			geneToUse ++;
		}
		
		_wm->_desiredTranslationalValue += 1.0 * _parameters[geneToUse] ;
		geneToUse ++;
// gLogFile<<geneToUse<<" ability "<<_parameters[87]<< " vs "<<_parameters[geneToUse] <<" vs "<<_wm->getAbilityToForage()<<" size"<<_wm->_genome.size()<< std::endl;
		_wm->_desiredRotationalVelocity += 1.0 * _parameters[geneToUse] ;
	

		//activation function on output
		_wm->_desiredTranslationalValue = tanh( _wm->_desiredTranslationalValue ) ;  // !N note that tanh is optional for ANN outputs.
		_wm->_desiredRotationalVelocity = tanh( _wm->_desiredRotationalVelocity );
	
		// normalize to motor interval values
		_wm->_desiredTranslationalValue = _wm->_desiredTranslationalValue * gMaxTranslationalSpeed;
		_wm->_desiredRotationalVelocity = _wm->_desiredRotationalVelocity * gMaxRotationalSpeed;
		

	}

}
コード例 #3
0
// * 
// * update energy level for each agents (ONLY active agents) (only in experimental setups featuring energy items)
// *
//TODO : randomize the order
void MedeaSpWorldObserver::updateAllAgentsEnergyLevel()
{	
	// --- Take from src/world.cpp
	// * create an array that contains shuffled indexes. Used afterwards for randomly update agents.
	//    This is very important to avoid possible nasty effect from ordering such as "agents with low indexes moves first"
	//    outcome: among many iterations, the effect of ordering is reduced.
	//    As a results, roborobo is turn-based, with sotchastic updates within one turn
	
        int shuffledIndex[gAgentCounter];

        for ( int i = 0 ; i < gAgentCounter ; i++ ) 
	    shuffledIndex[i] = i;
	
        for ( int i = 0 ; i < gAgentCounter-1 ; i++ ) // exchange randomly indexes with one other
		{	
            int r = i + (rand() % (gAgentCounter-i)); // Random remaining position.
            int tmp = shuffledIndex[i];
			shuffledIndex[i] = shuffledIndex[r]; 
			shuffledIndex[r] = tmp;
        }
        
        
	for ( int i = 0 ; i != gAgentCounter ; i++ ) // for each agent
	{
		MedeaSpAgentWorldModel *currentAgentWorldModel = dynamic_cast<MedeaSpAgentWorldModel*>(gWorld->getAgent(shuffledIndex[i])->getWorldModel());
		
		// * check energy level. Becomes inactive if zero.
		

		// * if active, check if agent harvests energy. 
		if(gWorld->getIterations() > MedeaSpSharedData::gNoEnergy){
			if ( currentAgentWorldModel->getActiveStatus() == true )
			{
				// * update agent energy (if needed) - agent should be on an active energy point location to get energy
				
				Point2d posRobot(currentAgentWorldModel->_xReal,currentAgentWorldModel->_yReal);
				for(std::vector<MedeaSpEnergyPoint*>::iterator it = coopEnergyPoints->begin(); it<coopEnergyPoints->end(); it++) 
				{
					if( (getEuclidianDistance (posRobot,(*it)->getPosition()) < gEnergyPointRadius) && (*it)->getActiveStatus())
					{
						double energyReachable =forageReward(currentAgentWorldModel->getAbilityToForage(),(*it)->getType());
						
						if(gWorld->getIterations() > MedeaSpSharedData::gNoDenPenTime && energyReachable>0 )
						{
							(*it)->setQ_E((*it)->getQ_E()-1);
							if((*it)->getQ_E()<=0 ) energyReachable=0;
						}
						
						double energyAdded;
						// update energy level
						if(currentAgentWorldModel->getEnergyLevel() + energyReachable > MedeaSpSharedData::gEnergyMax)
						{
							currentAgentWorldModel->setEnergyLevel(MedeaSpSharedData::gEnergyMax);
							
							energyAdded=currentAgentWorldModel->getEnergyCounterOfOneRessource((*it)->getType()) + double(MedeaSpSharedData::gEnergyMax) - currentAgentWorldModel->getEnergyLevel();
							
							
						}
						else{
							currentAgentWorldModel->setEnergyLevel(currentAgentWorldModel->getEnergyLevel() + energyReachable);
							
							energyAdded=currentAgentWorldModel->getEnergyCounterOfOneRessource((*it)->getType()) + energyReachable ;
						}
						currentAgentWorldModel->setEnergyCounterOfOneRessource((*it)->getType(),energyAdded );
						
						currentAgentWorldModel->setDeltaEnergy(currentAgentWorldModel->getDeltaEnergy() + energyReachable);

					}
				}
			}
			
			
			
			// * update agent energy consumption -- if inactive, "revive" the agent (ie. it ran out of energy)
			
			// decrease the energyLevel and deltaEnergyLevel
			if ( currentAgentWorldModel->getEnergyLevel() > 0.0 && currentAgentWorldModel->getActiveStatus() == true ) 
			{
				currentAgentWorldModel->setEnergyLevel(currentAgentWorldModel->getEnergyLevel()-1); 
				
				/***
				 * Allopatric test
				 * Deprecated
				 **/
				bool allopatric = false;
				if(allopatric){
					if(currentAgentWorldModel->_xReal > 490 && currentAgentWorldModel->_xReal < 510){
						int mountainCost=0;
						
						mountainCost = 10000;//pow((1-(pow((currentAgentWorldModel->getEnergyLevel()-500),4)/pow(500,4))),1000)*40000;// pow((500-currentAgentWorldModel->getEnergyLevel())/100,100);
						// 					currentAgentWorldModel->resetActiveGenome();
						
						currentAgentWorldModel->_genomesList.clear();
						currentAgentWorldModel->setWaitForGenome(true);
						currentAgentWorldModel->setActiveStatus(false);
// 						currentAgentWorldModel->setRobotLED_status(false);
						currentAgentWorldModel->setLifeTime(0);
						if(currentAgentWorldModel->_xReal < 500) currentAgentWorldModel->_xReal=currentAgentWorldModel->_xReal - (rand() % 300);
						else 
							currentAgentWorldModel->_xReal=currentAgentWorldModel->_xReal+ (rand() % 300);
						// 					currentAgentWorldModel->setEnergyLevel(currentAgentWorldModel->getEnergyLevel() - mountainCost);				
							currentAgentWorldModel->_yReal=rand() % 200 + 10;
					}
				}
				/***
				 * -------------
				 ***/
			}
			currentAgentWorldModel->setDeltaEnergy(currentAgentWorldModel->getDeltaEnergy()-1); 
			
			
			// "revive" agent with empty genomes if ran out of energy.
			
			if  ( currentAgentWorldModel->getEnergyLevel()  <= 0  && currentAgentWorldModel->getActiveStatus() == true)
			{
				currentAgentWorldModel->resetEnergyCounter();
				currentAgentWorldModel->setMaturity(1);
				
				if (currentAgentWorldModel->_agentId == gAgentIndexFocus && gVerbose) // debug
				{
					std::cout << "agent #" << gAgentIndexFocus << " is revived (energy was 0)." << std::endl;
				}
				
				
				
				currentAgentWorldModel->resetActiveGenome();//inutile?
				
				currentAgentWorldModel->setEnergyLevel(MedeaSpSharedData::gEnergyRevive); 
				currentAgentWorldModel->setEnergyCounterOfOneRessource(currentAgentWorldModel->getEnergyCounter().size()-1,MedeaSpSharedData::gEnergyRevive);
				//---The robot is Dead (ie not listening for a genome)
				currentAgentWorldModel->setActiveStatus(false);
				currentAgentWorldModel->setWaitForGenome(false);
				currentAgentWorldModel->_genomesList.clear();
				currentAgentWorldModel->_genomesList.empty(); 
				
				
			}
		}
	}	
}
コード例 #4
0
// * 
// * update energy level for each agents (ONLY active agents) (only in experimental setups featuring energy items)
// *
void MedeaAltruismReplayPartialEvoWorldObserver::updateAllAgentsEnergyLevel()
{	
	
	for ( int i = 0 ; i != gAgentCounter ; i++ ) // for each agent
	{
		MedeaAltruismReplayPartialEvoAgentWorldModel *currentAgentWorldModel = dynamic_cast<MedeaAltruismReplayPartialEvoAgentWorldModel*>(gWorld->getAgent(i)->getWorldModel());
		
		// * check energy level. Becomes inactive if zero.
		
		if ( currentAgentWorldModel->getEnergyLevel() <= 0 )
		{
			currentAgentWorldModel->setDeltaEnergy(0);
			currentAgentWorldModel->setActiveStatus(false);
			currentAgentWorldModel->setWaitingAfterLifeSynchronization(true);
		}

		// * if active, check if agent harvests energy. (experimental setup dependant)
		
		if ( currentAgentWorldModel->getActiveStatus() == true )
		{
			// * update agent energy (if needed) - agent should be on an active energy point location to get energy
		
			Point2d posRobot(currentAgentWorldModel->_xReal,currentAgentWorldModel->_yReal);
			if ( gEnergyMode && currentAgentWorldModel->getActiveStatus())
			{
				for(std::vector<EnergyPoint>::iterator it = gEnergyPoints.begin(); it != gEnergyPoints.end(); it++)
				{
					if( (getEuclidianDistance (posRobot,it->getPosition()) < gEnergyPointRadius) && (it->getActiveStatus()))
					{
						float loadingEnergy = currentAgentWorldModel->getEnergyHarvestingRate() * gEnergyPointValue;
						//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;
	
						gLogFile << gWorld->getIterations() << " : " << currentAgentWorldModel->_agentId
							<< " get " << loadingEnergy  << " Before " << currentAgentWorldModel->getEnergyLevel() <<std::endl;

						// update energy level
						currentAgentWorldModel->setEnergyLevel(currentAgentWorldModel->getEnergyLevel() + loadingEnergy);
						currentAgentWorldModel->setDeltaEnergy(currentAgentWorldModel->getDeltaEnergy() + loadingEnergy);
						currentAgentWorldModel->increaseTotalEnergyHarvested(loadingEnergy);
	
						//saturate
						if ( currentAgentWorldModel->getEnergyLevel() > MedeaAltruismSharedData::gEnergyMax ) // assume: need MedeaAltruismSharedData::gEvaluationTime to live full life
							currentAgentWorldModel->setEnergyLevel(MedeaAltruismSharedData::gEnergyMax);
	
	
						it->setRespawnLag((loadingEnergy/gEnergyPointValue)*MedeaAltruismSharedData::gHighestBoundRespawn);
						it->setActiveStatus(false);
					}
				}
			}
		}
		
		
		// * update agent energy consumption -- if inactive, "revive" the agent (ie. it ran out of energy)
		
		// decrease the energyLevel and deltaEnergyLevel

		if (currentAgentWorldModel->getActiveStatus() == true )
		{
		
			if ( currentAgentWorldModel->getEnergyLevel() > 0.0 ) 
			{
				currentAgentWorldModel->setEnergyLevel(currentAgentWorldModel->getEnergyLevel()-1); 
			}
			currentAgentWorldModel->setDeltaEnergy(currentAgentWorldModel->getDeltaEnergy()-1); 
		}


		// "revive" agent with empty genomes if ran out of energy.
		
		if  ( currentAgentWorldModel->getEnergyLevel()  <= 0.0 )
		{
			gLogFile << gWorld->getIterations() << " : " << currentAgentWorldModel->_agentId << " Restart" << std::endl;
			// reformulate (check python script compatibility before): gLogFile << "Info(" << gWorld->getIterations() << ") : robot " << _wm->_agentId << " was revived (human intervention)" << std::endl;

			if (currentAgentWorldModel->_agentId == gAgentIndexFocus && gVerbose) // debug
			{
				std::cout << "agent #" << gAgentIndexFocus << " is revived (energy was 0)." << std::endl;
			}
			
			currentAgentWorldModel->resetActiveGenome();
		
			currentAgentWorldModel->setEnergyLevel(MedeaAltruismSharedData::gEnergyRevive); // !n : too few?

			currentAgentWorldModel->setActiveStatus(false); // true: restart, false: no-restart
			currentAgentWorldModel->setWaitingAfterLifeSynchronization(true);
		
			currentAgentWorldModel->_genomesList.empty();
		}
	}	
}
コード例 #5
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 << "]";
			}
				
			
		}
	}


	
}
void ChangeDetectionController::createOrganism(double &left, double &right, int desired_size, double speed) {
	ChangeDetectionAgentWorldModel* worldModel = dynamic_cast<ChangeDetectionAgentWorldModel*> (_wm);
	RobotAgentPtr agent = gWorld->getAgent(worldModel->_agentId);

    // You are only eager to connect when your current organism is not large enough according to your standards.
    if (agent->isPartOfOrganism()){
        Organism *o = agent->getOrganism();
        
        if (o->size() < desired_size){
            agent->setConnectToOthers(Agent::POSITIVE);
        }else{
            agent->setConnectToOthers(Agent::NEUTRAL);
        }
    }else{
        agent->setConnectToOthers(Agent::POSITIVE);        
    }
    
	if (agent->getConnectToOthers() == Agent::NEGATIVE) {
		avoidObstacles(left, right, speed);
		return;
	}

	Point2d posRobot(worldModel->getPosition().x, worldModel->getPosition().y);

//	double closestDistance = getMaximumDistance();
	bool found = false;
	Point2d closestPoint;
	RobotAgentPtr closest;

	vector<RobotAgentPtr> close = agent->getNearRobots();

	// find robots that we can connect to
	vector<RobotAgentPtr>::iterator it;
	for (it = close.begin(); it != close.end(); it++) {
		if ((*it)->getConnectToOthers() == Agent::POSITIVE) {
			//Point2d closeRobot((*it)->getWorldModel()->_xReal, (*it)->getWorldModel()->_yReal);
			//double distance = getEuclidianDistance(posRobot, closeRobot);
			//if (distance < closestDistance) {
				//found = true;
				//closestDistance = distance;
				//closestPoint = closeRobot;
				//closest = (*it);
			//}
		}
	}

	// No robots that want to connect are close
	if (!found) {
		avoidObstacles(left, right, speed);
	} else {
		// steer towards the closest robot that wants to connect
		double angle = (atan2(closestPoint.y - posRobot.y, closestPoint.x - posRobot.x) / M_PI) * 180.0;
		double diffAngle = angle - _wm->_agentAbsoluteOrientation;
		if (diffAngle < -180.0) {
			diffAngle += 360.0;
		}
		if (diffAngle > 180.0) {
			diffAngle -= 360.0;
		}

		followAngle(diffAngle, left, right);
		left *= speed;
		right *= speed;
	}
}