// Update the neural network assigned to this genome with sensor input. void Update() { car.isAlive = isAlive; if (!isAlive) { return; } List <float> inputs = car.GetSensorReadings(); /* * Two outputs for left and right thrust. */ List <float> outputs = phenotype.Update(inputs, UpdateType.Active); if (outputs.Count != 2) { Debug.LogError("Error in neural network, output count should be two."); return; } car.leftThrust = Mathf.Clamp01(outputs[0]); car.rightThrust = Mathf.Clamp01(outputs[1]); if (runOnlyMode && Time.time - lastImprovementTime > 15.0f && car.trackMgr.avgSpeed <= 0.33f) { isAlive = false; } fitness = car.trackMgr.progressDistance * car.trackMgr.avgSpeed; if (fitness < 0) { fitness = 0; } // Only kill car if it crashes when doing runOnlyMode if (runOnlyMode) { return; } // NOTICE: kill of the car after one lap so speed is evolved. if (car.progressValue >= 1.0f) { isAlive = false; return; } float compensation = 1.0f; if (car.trackMgr.progressDistance >= 10) { compensation = 2.0f; } // TODO: clean up this mess if (fitness > bestFitness + _params.ImprovementEpsilon / _params.ImprovementTimeScale) { if (fitness > bestFitness + _params.ImprovementEpsilon) { bestFitness = fitness; lastImprovementTime = Time.time; } else if (Time.time - lastImprovementTime > (compensation * _params.MaxTimeWithoutImprovement * _params.ImprovementTimeScale)) { isAlive = false; } } else if (Time.time - lastImprovementTime > _params.MaxTimeWithoutImprovement) { isAlive = false; } }
//updates the ANN with information from the sweepers enviroment public bool Update(List <Vector3> mines) { //this will store all the inputs for the NN List <double> inputs = new List <double>(); //get List to closest mine Vector3 vClosestMine = GetClosestMine(mines); //normalise it vClosestMine.Normalize(); #if false // get the angle to the closest mine Vector3 DeltaToMine = vClosestMine - m_vPosition; Vector2D DeltaToMine2D = new Vector2D(DeltaToMine.x, DeltaToMine.y); Vector2D LookAt2D = new Vector2D(m_vLookAt.x, m_vLookAt.y); double DeltaAngle = LookAt2D.GetDeltaAngle(DeltaToMine2D); inputs.Add(DeltaAngle); inputs.Add(DeltaAngle); inputs.Add(DeltaAngle); inputs.Add(DeltaAngle); #else //add in List to closest mine inputs.Add(vClosestMine.X); inputs.Add(vClosestMine.Y); //add in sweepers look at List inputs.Add(m_vLookAt.X); inputs.Add(m_vLookAt.Y); #endif //update the brain and get feedback List <double> output = m_ItsBrain.Update(inputs); //make sure there were no errors in calculating the //output if (output.Count < m_ItsBrain.NumOutputs) { 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 RotForce = System.Math.Min(System.Math.Max(RotForce, -m_dMaxTurnRate), m_dMaxTurnRate); m_dRotation += RotForce; m_dSpeed = (m_lTrack + m_rTrack); //update Look At m_vLookAt.X = (double)-System.Math.Sin(m_dRotation); m_vLookAt.Y = (double)System.Math.Cos(m_dRotation); //update position m_vPosition += (m_vLookAt * m_dSpeed); //wrap around window limits if (m_vPosition.X > m_WindowWidth) { m_vPosition.X = 0; } if (m_vPosition.X < 0) { m_vPosition.X = m_WindowWidth; } if (m_vPosition.Y > m_WindowHeight) { m_vPosition.Y = 0; } if (m_vPosition.Y < 0) { m_vPosition.Y = m_WindowHeight; } return(true); }
//updates the ANN with information from the sweepers enviroment public bool Update(List <IVector <T> > mines) { //this will store all the inputs for the NN List <T> inputs = new List <T>(); //get List to closest mine IVector <T> vClosestMine = GetClosestMine(mines); //normalise it vClosestMine = vClosestMine.Normalize(); #if false // get the angle to the closest mine Vector3D DeltaToMine = vClosestMine - m_vPosition; Vector2D DeltaToMine2D = new Vector2D(DeltaToMine.x, DeltaToMine.y); Vector2D LookAt2D = new Vector2D(m_vLookAt.x, m_vLookAt.y); double DeltaAngle = LookAt2D.GetDeltaAngle(DeltaToMine2D); inputs.Add(DeltaAngle); inputs.Add(DeltaAngle); inputs.Add(DeltaAngle); inputs.Add(DeltaAngle); #else //add in List to closest mine inputs.Add(vClosestMine[0]); inputs.Add(vClosestMine[1]); //add in sweepers look at List inputs.Add(m_vLookAt[0]); inputs.Add(m_vLookAt[1]); #endif //update the brain and get feedback ///watch the performance here List <double> output = m_ItsBrain.Update(inputs.Select(o => o.ToDouble()).ToList()); //make sure there were no errors in calculating the //output if (output.Count < m_ItsBrain.NumOutputs) { 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 RotForce = System.Math.Min(System.Math.Max(RotForce, -m_dMaxTurnRate), m_dMaxTurnRate); m_dRotation += RotForce; m_dSpeed = (m_lTrack + m_rTrack); //update Look At m_vLookAt[0] = M.New <T>((double)-System.Math.Sin(m_dRotation)); m_vLookAt[1] = M.New <T>((double)System.Math.Cos(m_dRotation)); //update position m_vPosition.Add(m_vLookAt.Multiply(m_dSpeed)); //wrap around window limits if (m_vPosition[0].GreaterThan(m_WindowWidth)) { m_vPosition[0] = M.Zero <T>(); } if (m_vPosition[0].LessThan(0)) { m_vPosition[0] = M.New <T>(m_WindowWidth); } if (m_vPosition[1].GreaterThan(m_WindowHeight)) { m_vPosition[1] = M.Zero <T>(); } if (m_vPosition[1].LessThan(0)) { m_vPosition[1] = M.New <T>(m_WindowHeight); } return(true); }