// 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;
        }
    }
Example #2
0
        //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);
        }
Example #3
0
        //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);
        }