//TODO: sometimes the velocity is not reseted.. for some reason public void ResetCarPosition(GameObject gameObject) { Rigidbody rigidbody = gameObject.GetComponent <Rigidbody>(); NeuralChildObject _stats = GetStats(gameObject); _stats.AverageSpeed = 0; _stats.DriveDistance = 0; _stats.DriveTime = Time.time; if (childRespawnAtParent) { gameObject.transform.position = startPosition; _stats.LastPosition = startPosition; } else { gameObject.transform.position = _stats.LastPosition; } _stats.Speed = 0f; _stats.Streets.Clear(); _stats.ResultHistory.Clear(); _stats.SenoreHistory.Clear(); SetStats(gameObject, _stats); rigidbody.velocity = Vector3.zero; rigidbody.angularVelocity = new Vector3(0, 0, 0); gameObject.transform.rotation = startRotation; SetColor(gameObject, Color.white); }
/// <summary> /// Sets stats for the gameObject /// </summary> /// <param name="gameObject"></param> /// <param name="neuralChildObject"></param> void SetStats(GameObject gameObject, NeuralChildObject neuralChildObject) { NeuralChild childScript = gameObject.GetComponent <NeuralChild>(); if (childScript != null) { childScript.stats = neuralChildObject; } else { stats = neuralChildObject; } }
void ReadPoints(NeuralChildObject _stats) { float score = 0; switch (fitnessMeasure) { case FitnessMeasure.distance: score = _stats.DriveDistance; break; case FitnessMeasure.distanceByTime: score = _stats.DriveTime; break; case FitnessMeasure.distance2byTime: score = _stats.DriveTime + _stats.DriveDistance; break; case FitnessMeasure.speed: score = _stats.AverageSpeed; break; case FitnessMeasure.streetParts: score = _stats.Streets.Count; break; case FitnessMeasure.points: score = _stats.Points.Count; break; } points[_stats.Id] = score; if (bestScore < score) { saveBestNetwork = true; bestScore = score; bestNetwork = networks[_stats.Id]; bestStats = _stats; SetColor(gameObjectsChilds[_stats.Id], Color.green); if (newNetworkVersion) { List <NeuralNetwork.NetworkModels.DataSet> dataSets = new List <NeuralNetwork.NetworkModels.DataSet>(); for (int i = 0; i < _stats.ResultHistory.Count; i++) { dataSets.Add(new NeuralNetwork.NetworkModels.DataSet(_stats.SenoreHistory[i], _stats.ResultHistory[i])); } newNetworks.Train(dataSets, 0.5); } } }
/// <summary> /// Get stats from the gameObject /// </summary> /// <param name="gameObject"></param> /// <returns></returns> NeuralChildObject GetStats(GameObject gameObject) { NeuralChild childScript = gameObject.GetComponent <NeuralChild>(); NeuralChildObject _stats = new NeuralChildObject(); if (childScript != null) { _stats = childScript.stats; } else { _stats = stats; } return(_stats); }
void Start() { stats = new NeuralChildObject(); stats.LastPosition = transform.position; }
public void GameOver(GameObject gameObject, Collision col = null, bool timeOver = false) { try { NeuralChildObject _stats = GetStats(gameObject); if (col == null && !timeOver) { return; } try { if (col.collider.gameObject.tag == "Point") { if (!_stats.Points.Contains(col.collider.gameObject)) { _stats.Points.Add(col.collider.gameObject); } return; } if (col.collider.gameObject.tag == "Street") { if (!_stats.Streets.Contains(col.collider.gameObject)) { _stats.Streets.Add(col.collider.gameObject); } return; } if (col.gameObject.tag == "Car") { return; } } catch (Exception) { } if (ignoreCollide) { return; } bool reproduce = false; if ((_stats.Dead == false) || timeOver) { ReadPoints(_stats); try { _stats.ResultHistory.Remove(_stats.ResultHistory[_stats.ResultHistory.Count - 1]); _stats.SenoreHistory.Remove(_stats.SenoreHistory[_stats.SenoreHistory.Count - 1]); } catch (Exception) { } if (spawnChild && child != null) { deadChilds++; if (!timeOver && newNetworkVersion) { while (newNetworks.Compute(sensors) == results) { newNetworks.BackPropagate(results); newNetworks.BackPropagate(results); } } _stats.Dead = true; SetStats(gameObject, _stats); if (deadChilds >= childs + 1) { if (timeOver) { print("[" + transform.root.gameObject.name + "][ResetReason] TimeOver"); //get stats of living childs foreach (GameObject childgo in gameObjectsChilds) { if (childgo != null) { _stats = GetStats(childgo); ReadPoints(_stats); } } } else { print("[" + transform.root.gameObject.name + "][ResetReason] All childs dead"); } reproduce = true; } } else { if (id > population) { reproduce = true; } else { id++; print("[" + transform.root.gameObject.name + "][ResetReason] Car dead"); ResetCarPosition(gameObject); } } } else { _stats.Dead = true; SetStats(gameObject, _stats); return; } //now we reproduce if (reproduce) { double maxValue = points[0]; int maxIndex = 0; List <Network> cache = new List <Network>(); //looking for the two best networks in the generation for (int i = 1; i < population; i++) { if (points[i] > maxValue) { maxIndex = i; maxValue = points[i]; } } if (newNetworkVersion) { for (int i = 0; i < _stats.ResultHistory.Count; i++) { newNetworks.ForwardPropagate(_stats.SenoreHistory[i]); } for (int i = 0; i < population; i++) { points[i] = 0; } } else { if (points[maxIndex] > bestDistance) { bestDistance = (float)points[maxIndex]; } lastBest = networks[maxIndex]; if (bestNetwork == null) { bestNetwork = networks[0]; } cache.Add(lastBest); if (maxValue != 0) { lastBest = networks[maxIndex]; cache.Add(lastBest); } cache.Add(new Network(parameters)); UpdateNetwork(networkUpdateParameter); } } } catch (Exception e) { print(e.StackTrace); } return; }
/// <summary> /// Points and Movement. /// </summary> /// <param name="gameObject"></param> /// <param name="id"></param> public void UpdateCar(GameObject gameObject) { Rigidbody rigidbody = gameObject.GetComponent <Rigidbody>(); rigidbody.velocity = Vector3.zero; rigidbody.angularVelocity = new Vector3(0, 0, 0); Sensores(gameObject); mutationUpdate(); //Update stats //Used to create points NeuralChildObject _stats = GetStats(gameObject); time = Time.time - _stats.DriveTime; if (timeLimit != 0) { if (time > timeLimit) { GameOver(gameObject, null, true); } } if (_stats.AverageSpeed == 0) { _stats.AverageSpeed = rigidbody.velocity.magnitude; } else { _stats.AverageSpeed = (_stats.AverageSpeed + rigidbody.velocity.magnitude) / 2; } //End Update stats if (newNetworkVersion) { try { results = newNetworks.Compute(sensors); } catch (Exception) { newNetworks = new NeuralNetwork.NetworkModels.Network(parameters[0], new int[] { 8, 8, 8 }, 4, 2, 1); } } else { try { results = networks[_stats.Id].process(sensors); } catch (Exception) { networks[_stats.Id] = new Network(parameters); results = networks[_stats.Id].process(sensors); } } frontForce = (float)results[0]; backForce = (float)results[1]; leftForce = (float)results[2]; leftForce += (float)results[3]; rightForce = (float)results[4]; rightForce += (float)results[5]; if (frontForce >= maxSpeed) { frontForce = maxSpeed; } if (backForce >= maxSpeed) { backForce = maxSpeed; } _stats.Speed += (frontForce / 14); _stats.Speed -= (backForce / 8) / (_stats.Speed * 16); speed = _stats.Speed; if (_stats.Speed <= -maxSpeed) { _stats.Speed = -maxSpeed; } else if (_stats.Speed >= maxSpeed) { _stats.Speed = maxSpeed; } _stats.DriveDistance = Vector3.Distance(gameObject.transform.position, startPosition); _stats.LastPosition = gameObject.transform.position; gameObject.transform.Rotate(0, (leftForce - rightForce) * 2, 0); gameObject.transform.Translate(0, 0, _stats.Speed); //gameObject.transform.position = Vector3.Lerp(gameObject.transform.position, new Vector3(0,0, _stats.speed), 0.5f * Time.deltaTime); _stats.SenoreHistory.Add(sensors); _stats.ResultHistory.Add(results); SetStats(gameObject, _stats); if (ignoreCollide) { ignoreCollide = false; } }
public void Sensores(GameObject gameObject = null) { if (gameObject == null) { gameObject = this.gameObject; } NeuralChildObject _stats = GetStats(gameObject); Rigidbody rigidbody = gameObject.GetComponent <Rigidbody>(); RaycastHit hit; Vector3 sensorStartPos = gameObject.transform.position + (gameObject.transform.TransformDirection(Vector3.forward) * frontSensorPosition); sensorStartPos.y = senoreHight; sensors[0] = rigidbody.velocity.magnitude; int layerMask = ~(1 << LayerMask.NameToLayer("Car")); //front center if (Physics.Raycast(sensorStartPos, gameObject.transform.forward, out hit, sensoreLength, layerMask)) { sensors[1] = hit.distance; Debug.DrawRay(sensorStartPos, gameObject.transform.forward * hit.distance, Color.yellow); } else { sensors[1] = sensoreLength * 4; Debug.DrawRay(sensorStartPos, gameObject.transform.TransformDirection(Vector3.forward) * sensoreLength, Color.white); } //left if (Physics.Raycast(sensorStartPos, Quaternion.AngleAxis(-frontSesnorAngle, gameObject.transform.up) * gameObject.transform.forward, out hit, sensoreLength, layerMask)) { sensors[2] = hit.distance; Debug.DrawRay(sensorStartPos, (Quaternion.AngleAxis(-frontSesnorAngle, gameObject.transform.up) * gameObject.transform.forward) * hit.distance, Color.yellow); } else { sensors[2] = sensoreLength; Debug.DrawRay(sensorStartPos, (Quaternion.AngleAxis(-frontSesnorAngle, gameObject.transform.up) * gameObject.transform.forward) * sensoreLength); } //left 2 if (Physics.Raycast(sensorStartPos, Quaternion.AngleAxis(-(frontSesnorAngle / 2), gameObject.transform.up) * gameObject.transform.forward, out hit, sensoreLength, layerMask)) { sensors[3] = hit.distance; Debug.DrawRay(sensorStartPos, (Quaternion.AngleAxis(-(frontSesnorAngle / 2), gameObject.transform.up) * gameObject.transform.forward) * hit.distance, Color.yellow); } else { sensors[3] = sensoreLength; Debug.DrawRay(sensorStartPos, (Quaternion.AngleAxis(-(frontSesnorAngle / 2), gameObject.transform.up) * gameObject.transform.forward) * sensoreLength); } //left 3 if (Physics.Raycast(sensorStartPos, Quaternion.AngleAxis(-(frontSesnorAngle * 1.5f), gameObject.transform.up) * gameObject.transform.forward, out hit, sensoreLength, layerMask)) { sensors[8] = hit.distance; Debug.DrawRay(sensorStartPos, (Quaternion.AngleAxis(-(frontSesnorAngle * 1.5f), gameObject.transform.up) * gameObject.transform.forward) * hit.distance, Color.yellow); } else { sensors[8] = sensoreLength; Debug.DrawRay(sensorStartPos, (Quaternion.AngleAxis(-(frontSesnorAngle * 1.5f), gameObject.transform.up) * gameObject.transform.forward) * sensoreLength); } //right if (Physics.Raycast(sensorStartPos, Quaternion.AngleAxis(frontSesnorAngle, gameObject.transform.up) * gameObject.transform.forward, out hit, sensoreLength, layerMask)) { sensors[4] = hit.distance; Debug.DrawRay(sensorStartPos, (Quaternion.AngleAxis(frontSesnorAngle, gameObject.transform.up) * gameObject.transform.forward) * hit.distance, Color.yellow); } else { sensors[4] = sensoreLength; Debug.DrawRay(sensorStartPos, (Quaternion.AngleAxis(frontSesnorAngle, gameObject.transform.up) * gameObject.transform.forward) * sensoreLength); } //right 2 if (Physics.Raycast(sensorStartPos, Quaternion.AngleAxis((frontSesnorAngle / 2), gameObject.transform.up) * gameObject.transform.forward, out hit, sensoreLength, layerMask)) { sensors[5] = hit.distance; Debug.DrawRay(sensorStartPos, (Quaternion.AngleAxis((frontSesnorAngle / 2), gameObject.transform.up) * gameObject.transform.forward) * hit.distance, Color.yellow); } else { sensors[5] = sensoreLength; Debug.DrawRay(sensorStartPos, (Quaternion.AngleAxis((frontSesnorAngle / 2), gameObject.transform.up) * gameObject.transform.forward) * sensoreLength); } //right 2 if (Physics.Raycast(sensorStartPos, Quaternion.AngleAxis((frontSesnorAngle * 1.5f), gameObject.transform.up) * gameObject.transform.forward, out hit, sensoreLength, layerMask)) { sensors[9] = hit.distance; Debug.DrawRay(sensorStartPos, (Quaternion.AngleAxis((frontSesnorAngle * 1.5f), gameObject.transform.up) * gameObject.transform.forward) * hit.distance, Color.yellow); } else { sensors[9] = sensoreLength; Debug.DrawRay(sensorStartPos, (Quaternion.AngleAxis((frontSesnorAngle * 1.5f), gameObject.transform.up) * gameObject.transform.forward) * sensoreLength); } //backward sensorStartPos = sensorStartPos - ((gameObject.transform.TransformDirection(Vector3.forward) * frontSensorPosition) * 2); if (Physics.Raycast(sensorStartPos, gameObject.transform.forward * -1, out hit, (sensoreLength / 2), layerMask)) { sensors[6] = hit.distance; Debug.DrawRay(sensorStartPos, gameObject.transform.forward * -1 * hit.distance, Color.yellow); } else { sensors[6] = sensoreLength / 2; Debug.DrawRay(sensorStartPos, gameObject.transform.TransformDirection(Vector3.forward * -1) * (sensoreLength / 2), Color.white); } sensors[7] = _stats.Speed; }
// Use this for initialization void Start() { childFolder = new GameObject(); childFolder.name = "[" + transform.root.gameObject.name + "] Childs"; stats = new NeuralChildObject(); InvokeRepeating("mutationUpdate", 1, 1); startPosition = transform.position; startRotation = transform.rotation; stats.LastPosition = startPosition; ignoreCollide = ignoreFirstCollide; Debug.Log("[" + transform.root.gameObject.name + "] Generation " + generation); results = new double[4]; points = new double[population]; sensors = new double[10]; networks = new Network[population]; newNetworks = new NeuralNetwork.NetworkModels.Network(parameters[0], new int[] { 8, 8, 8 }, 4, 2, 1); gameObjectsChilds = new GameObject[population]; gameObjectsChilds[0] = this.gameObject; NeuralWeights loadedWeightsValues = null; if (LoadLastNerual) { string m_Path = Application.dataPath + "/" + transform.root.gameObject.name + ".xml"; print(m_Path); loadedWeightsValues = Load(m_Path); if (loadedWeightsValues != null) { bestScore = loadedWeightsValues.bestScore; generation = loadedWeightsValues.Generation; print("[" + transform.root.gameObject.name + "] LoadedWeights"); } } if (newNetworkVersion) { if (loadedWeightsValues != null) { newNetworks.HiddenLayers = loadedWeightsValues.HiddenLayers; newNetworks.InputLayer = loadedWeightsValues.InputLayer; newNetworks.OutputLayer = loadedWeightsValues.OutputLayer; } for (int i = 1; i < population; i++) { //Spawn childs if wanted and can if (spawnChild && child != null) { SpawnChild(); } } } else { networks[0] = new Network(parameters); for (int i = 1; i < population; i++) { //Spawn childs if wanted and can if (spawnChild && child != null) { SpawnChild(); } if (loadedWeightsValues == null) { networks[i] = new Network(parameters); } else { networks[i] = new Network(parameters); networks[i].setWeights(loadedWeightsValues.weights); networks[i] = new Network(this, networks[i]); } } } }