コード例 #1
0
ファイル: CMinesweeper.cpp プロジェクト: kevroy314/NNTest
//-------------------------------Update()--------------------------------
//
//	First we take sensor readings and feed these into the sweepers brain.
//
//	The inputs are:
//
//	A vector to the closest mine (x, y)
//	The sweepers 'look at' vector (x, y)
//
//	We receive two outputs from the brain.. lTrack & rTrack.
//	So given a force for each track we calculate the resultant rotation
//	and acceleration and apply to current velocity vector.
//
//-----------------------------------------------------------------------
bool CMinesweeper::Update(vector<SVector2D> &mines)
{

    //this will store all the inputs for the NN
    vector<double> inputs;

    //get vector to closest mine
    SVector2D vClosestMine = GetClosestMine(mines);

    //normalise it
    Vec2DNormalize(vClosestMine);

    //add in vector to closest mine
    inputs.push_back(vClosestMine.x);
    inputs.push_back(vClosestMine.y);

    //add in sweepers look at vector
    inputs.push_back(m_vLookAt.x);
    inputs.push_back(m_vLookAt.y);


    //update the brain and get feedback
    vector<double> output = m_ItsBrain.Update(inputs);

    //make sure there were no errors in calculating the
    //output
    if (output.size() < CParams::iNumOutputs)
    {
        return false;
    }

    //assign the outputs to the sweepers left & right tracks
    m_lTrack = output[0];
    m_rTrack = output[1];

    //calculate steering forces
    double RotForce = m_lTrack - m_rTrack;

    //clamp rotation
    Clamp(RotForce, -CParams::dMaxTurnRate, CParams::dMaxTurnRate);

    m_dRotation += RotForce;

    m_dSpeed = (m_lTrack + m_rTrack);

    //update Look At
    m_vLookAt.x = -sin(m_dRotation);
    m_vLookAt.y = cos(m_dRotation);

    //update position
    m_vPosition += (m_vLookAt * m_dSpeed);

    //wrap around window limits
    if (m_vPosition.x > CParams::WindowWidth) m_vPosition.x = 0;
    if (m_vPosition.x < 0) m_vPosition.x = CParams::WindowWidth;
    if (m_vPosition.y > CParams::WindowHeight) m_vPosition.y = 0;
    if (m_vPosition.y < 0) m_vPosition.y = CParams::WindowHeight;

    return true;
}
コード例 #2
0
ファイル: CMinesweeper.cpp プロジェクト: Supy/ml
//-------------------------------Update()--------------------------------
//
//	First we take sensor readings. These are then fed into the learning algorithm
//
//	The inputs are:
//	
//	A vector to the closest mine (x, y)
//	The sweepers 'look at' vector (x, y)
//	So given a force we calculate the resultant rotation 
//	and acceleration. This is then applied to current velocity vector.
//
//-----------------------------------------------------------------------
bool CMinesweeper::Update(vector<CCollisionObject> &objects, vector<CMinesweeper> &tanks, CMlp &mlp)
{
	
	//get vector to closest mine
	SVector2D vClosestMine = GetClosestMine(objects);

	GetClosestSuperMine(objects);

	//normalise it
	Vec2DNormalize(vClosestMine);
	double angleToMine = Vec2DAngle(m_vLookAt, vClosestMine);
	double steering = 0.5;
	if(abs(angleToMine) > 0.5){
		if(angleToMine <= 0)
			steering = 0.0;
		else
			steering = 1.0;
	}


	minesLeft = minesRight = false;

	// We want more than the closest mine. We want all mines within a certain radius to make a better decision
	// on which direction to turn.
	vector<int> nearbyObjects = GetNearbySupermines(objects, CParams::dMineScale + 9);
	Vec2DNormalize(m_vLookAt);

	// Shift the point we measure angles from to the back of the sweeper
	// in order to reduce the area where the sweeper doesn't see stuff in front of it.
	SVector2D fakePosition = m_vPosition - (m_vLookAt*100);
	for(int i=0; i < nearbyObjects.size(); i++){

		if (objects[nearbyObjects[i]].getType() == CCollisionObject::ObjectType::SuperMine)
		{			
			SVector2D direction =   objects[nearbyObjects[i]].getPosition() - fakePosition;
			double angle = Vec2DAngle(m_vLookAt, direction) * 180 / CParams::dPi;

			// Which quadrant does the mine fall into
			if(angle >= -20.0 && angle < 0.0)
				minesLeft = true;
			else if(angle <= 20.0 && angle >= 0.0)
				minesRight = true;
		}
	}


	// Don't collide with other tanks either
	vector<int> nearbySweepers = GetNearbySweepers(tanks, CParams::iSweeperScale + 10);
	for(int i=0; i < nearbySweepers.size(); i++){		
		SVector2D direction =   tanks[nearbySweepers[i]].Position() - fakePosition;
		double angle = Vec2DAngle(m_vLookAt, direction) * 180 / CParams::dPi;

		// Which quadrant does the mine fall into
		if(angle >= -20.0 && angle < 0.0)
			minesLeft = true;
		else if(angle <= 20.0 && angle >= 0.0)
			minesRight = true;
	}



	// Set the inputs to the MLP of where the mines are located.
	mlp.SetNodeInput(0, minesLeft);
	mlp.SetNodeInput(1, minesRight);

	mlp.CalculateOutput();

	// Our MLP outputs steering directions in the range 0.1-0.9. First we standardize it to 0-1.0.
	double output = (mlp.GetOutput(0) - 0.1) / 0.8;
		
	if (output <= 0.499 || output >= 0.501) steering = output;

	// Next we need to use this output in the form -0.3-0.3.
	double convertedRotation = (steering * CParams::dMaxTurnRate * 2.0) - CParams::dMaxTurnRate;
	
	//TODO: calculate the steering forces here, it is set to 0 for now...
	double RotForce = convertedRotation;
	
	//clamp rotation
	Clamp(RotForce, -CParams::dMaxTurnRate, CParams::dMaxTurnRate);

	m_dRotation += RotForce;

	// Grab our calculated speed.
	m_dSpeed = (((mlp.GetOutput(1) - 0.1) / 0.8) * CParams::dMaxSpeed);	

	//update Look At 
	m_vLookAt.x = -sin(m_dRotation);
	m_vLookAt.y = cos(m_dRotation);

	//update position
	m_vPosition += (m_vLookAt * m_dSpeed);

	
	//wrap around window limits
	if (m_vPosition.x > CParams::WindowWidth) m_vPosition.x = 0;
	if (m_vPosition.x < 0) m_vPosition.x = CParams::WindowWidth;
	if (m_vPosition.y > CParams::WindowHeight) m_vPosition.y = 0;
	if (m_vPosition.y < 0) m_vPosition.y = CParams::WindowHeight;

	return true;
}