implementation of drecon in unity 2022 lts
forked from:
https://github.com/joanllobera/marathon-envs
				
			
			
		
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							594 lines
						
					
					
						
							18 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							594 lines
						
					
					
						
							18 KiB
						
					
					
				| using System.Collections; | |
| using System.Collections.Generic; | |
| using UnityEngine; | |
| using Unity.MLAgents; | |
| using Unity.MLAgents.Actuators; | |
| using Unity.MLAgents.Sensors; | |
| using System.Linq; | |
| using static BodyHelper002; | |
| using System; | |
| using ManyWorlds; | |
| 
 | |
| public class BodyManager002 : MonoBehaviour, IOnSensorCollision | |
| { | |
|     // Options / Configurables global properties | |
| 	public Transform CameraTarget; | |
| 	public float FixedDeltaTime = 0.005f; | |
| 	public bool ShowMonitor = false; | |
| 	public bool DebugDisableMotor; | |
| 	public bool DebugShowWithOffset; | |
| 
 | |
| 
 | |
|     // Observations / Read only global properties | |
| 	public List<Muscle002> Muscles; | |
| 	public List<BodyPart002> BodyParts; | |
| 	public List<float> SensorIsInTouch; | |
| 	public List<float> Observations; | |
| 	public int ObservationNormalizedErrors; | |
| 	public int MaxObservationNormalizedErrors; | |
| 	public List<GameObject> Sensors; | |
| 	public float FrameReward; | |
| 	public float AverageReward; | |
| 
 | |
| 
 | |
|     // private properties | |
| 	Vector3 startPosition; | |
| 
 | |
| 	Dictionary<GameObject, Vector3> transformsPosition; | |
| 	Dictionary<GameObject, Quaternion> transformsRotation; | |
| 
 | |
| 	Agent _agent; | |
| 	SpawnableEnv _spawnableEnv; | |
| 	TerrainGenerator _terrainGenerator; | |
| 	DecisionRequester _decisionRequester; | |
| 
 | |
| 	static int _startCount; | |
| 
 | |
|     float[] lastVectorAction; | |
| 	float[] vectorDifference; | |
| 	List <Vector3> mphBuffer; | |
|  | |
| 	[Tooltip("Max distance travelled across all episodes")] | |
| 	/**< \brief Max distance travelled across all episodes*/ | |
| 	public float MaxDistanceTraveled; | |
|  | |
| 	[Tooltip("Distance travelled this episode")] | |
| 	/**< \brief Distance travelled this episode*/ | |
| 	public float DistanceTraveled; | |
| 
 | |
| 	List<SphereCollider> sensorColliders; | |
| 	static int _spawnCount; | |
| 
 | |
| 	// static ScoreHistogramData _scoreHistogramData; | |
|  | |
| 
 | |
| 	// void FixedUpdate() | |
| 	// { | |
| 	// 	foreach (var muscle in Muscles) | |
| 	// 	{ | |
| 	// 	// 	var i = Muscles.IndexOf(muscle); | |
| 	// 	// 	muscle.UpdateObservations(); | |
| 	// 	// 	if (!DebugShowWithOffset && !DebugDisableMotor) | |
| 	// 	// 		muscle.UpdateMotor(); | |
| 	// 	// 	if (!muscle.Rigidbody.useGravity) | |
| 	// 	// 		continue; // skip sub joints | |
| 	// 	// } | |
| 	// } | |
|  | |
| 	public BodyConfig BodyConfig; | |
| 
 | |
| 	// Start is called before the first frame update | |
| 	void Start() | |
|     { | |
|     } | |
| 
 | |
|     // Update is called once per frame | |
|     void Update() | |
|     { | |
|     } | |
| 
 | |
|     public void OnInitializeAgent() | |
|     { | |
| 		_spawnableEnv = GetComponentInParent<SpawnableEnv>(); | |
| 		_terrainGenerator = GetComponentInParent<TerrainGenerator>(); | |
| 		SetupBody(); | |
| 		DistanceTraveled = float.MinValue; | |
| 	} | |
| 
 | |
| 	public void OnAgentReset() | |
| 	{ | |
| 		if (DistanceTraveled != float.MinValue) | |
| 		{ | |
| 			var scorer = FindObjectOfType<Scorer>(); | |
| 			scorer?.ReportScore(DistanceTraveled, "Distance Traveled"); | |
| 		} | |
| 		HandleModelReset(); | |
| 		Sensors = _agent.GetComponentsInChildren<SensorBehavior>() | |
| 			.Select(x=>x.gameObject) | |
| 			.ToList(); | |
| 		sensorColliders = Sensors | |
| 			.Select(x=>x.GetComponent<SphereCollider>()) | |
| 			.ToList(); | |
| 		SensorIsInTouch = Enumerable.Range(0,Sensors.Count).Select(x=>0f).ToList(); | |
| 		// HACK first spawned agent should grab the camera | |
| 		var smoothFollow = GameObject.FindObjectOfType<SmoothFollow>(); | |
| 		if (smoothFollow != null && smoothFollow.target == null) { | |
| 			if (_spawnCount == 0) // HACK follow nth agent | |
| 			{ | |
| 				smoothFollow.target = CameraTarget; | |
| 				ShowMonitor = true;    | |
| 			} | |
| 			else | |
| 				_spawnCount++;              | |
| 		} | |
| 		lastVectorAction = null; | |
| 		vectorDifference = null;		 | |
| 		mphBuffer = new List<Vector3>(); | |
| 	} | |
| 
 | |
| 	public void OnAgentAction(float[] vectorAction) | |
| 	{ | |
| 		if (lastVectorAction == null){ | |
| 			lastVectorAction = vectorAction.Select(x=>0f).ToArray(); | |
| 			vectorDifference = vectorAction.Select(x=>0f).ToArray(); | |
| 		} | |
| 		int i = 0; | |
| 		foreach (var muscle in Muscles) | |
| 		{ | |
| 			// if(muscle.Parent == null) | |
| 			// 	continue; | |
| 			if (muscle.ConfigurableJoint.angularXMotion != ConfigurableJointMotion.Locked){ | |
| 				vectorDifference[i] = Mathf.Abs(vectorAction[i]-lastVectorAction[i]); | |
| 				muscle.TargetNormalizedRotationX = vectorAction[i++]; | |
| 			} | |
| 			if (muscle.ConfigurableJoint.angularYMotion != ConfigurableJointMotion.Locked){ | |
| 				vectorDifference[i] = Mathf.Abs(vectorAction[i]-lastVectorAction[i]); | |
| 				muscle.TargetNormalizedRotationY = vectorAction[i++]; | |
| 			} | |
| 			if (muscle.ConfigurableJoint.angularZMotion != ConfigurableJointMotion.Locked){ | |
| 				vectorDifference[i] = Mathf.Abs(vectorAction[i]-lastVectorAction[i]); | |
| 				muscle.TargetNormalizedRotationZ = vectorAction[i++]; | |
| 			} | |
| 			if (!DebugDisableMotor) | |
| 				muscle.UpdateMotor(); | |
| 		} | |
| 
 | |
|         if (ShowMonitor) | |
|         { | |
|             // var hist = new[] {velocity, uprightBonus, heightPenality, effort}.ToList(); | |
|             // Monitor.Log("rewardHist", hist.ToArray(), displayType: Monitor.DisplayType.Independent); | |
|         } | |
| 	} | |
| 
 | |
|     public BodyPart002 GetFirstBodyPart(BodyPartGroup bodyPartGroup) | |
|     { | |
|         var bodyPart = BodyParts.FirstOrDefault(x=>x.Group == bodyPartGroup); | |
|         return bodyPart; | |
|     } | |
|     public List<BodyPart002> GetBodyParts() | |
|     { | |
|         return BodyParts; | |
|     } | |
|     public List<BodyPart002> GetBodyParts(BodyPartGroup bodyPartGroup) | |
|     { | |
|         return BodyParts.Where(x=>x.Group == bodyPartGroup).ToList(); | |
|     } | |
| 
 | |
|     public float GetActionDifference() | |
|     { | |
| 		float actionDifference = 1f - vectorDifference.Average(); | |
| 		actionDifference = Mathf.Clamp(actionDifference, 0, 1); | |
| 		actionDifference = Mathf.Pow(actionDifference,2); | |
|         return actionDifference; | |
|     } | |
| 
 | |
|     void SetupBody() | |
|     { | |
|         _agent = GetComponent<Agent>(); | |
| 		_decisionRequester = GetComponent<DecisionRequester>(); | |
| 		Time.fixedDeltaTime = FixedDeltaTime; | |
| 
 | |
| 		BodyParts = new List<BodyPart002> (); | |
| 		BodyPart002 root = null; | |
| 		foreach (var t in GetComponentsInChildren<Transform>()) | |
| 		{ | |
| 			if (BodyConfig.GetBodyPartGroup(t.name) == BodyHelper002.BodyPartGroup.None) | |
| 				continue; | |
| 			 | |
| 			var bodyPart = new BodyPart002{ | |
| 				Rigidbody = t.GetComponent<Rigidbody>(), | |
| 				Transform = t, | |
| 				Name = t.name, | |
| 				Group = BodyConfig.GetBodyPartGroup(t.name),  | |
| 			}; | |
| 			if (bodyPart.Group == BodyConfig.GetRootBodyPart()) | |
| 				root = bodyPart; | |
| 			bodyPart.Root = root; | |
| 			bodyPart.Init(); | |
| 			BodyParts.Add(bodyPart); | |
| 		} | |
| 		var partCount = BodyParts.Count; | |
| 
 | |
| 		Muscles = new List<Muscle002> (); | |
| 		var muscles = GetComponentsInChildren<ConfigurableJoint>(); | |
| 		ConfigurableJoint rootConfigurableJoint = null; | |
| 		var ragDoll = GetComponent<RagDoll002>(); | |
| 		foreach (var m in muscles) | |
| 		{ | |
| 			var maximumForce = ragDoll.MusclePowers.First(x=>x.Muscle == m.name).PowerVector; | |
| 			maximumForce *= ragDoll.MotorScale; | |
| 			var muscle = new Muscle002{ | |
| 				Rigidbody = m.GetComponent<Rigidbody>(), | |
| 				Transform = m.GetComponent<Transform>(), | |
| 				ConfigurableJoint = m, | |
| 				Name = m.name, | |
| 				Group = BodyConfig.GetMuscleGroup(m.name), | |
| 				MaximumForce = maximumForce | |
| 			}; | |
| 			if (muscle.Group == BodyConfig.GetRootMuscle()) | |
| 				rootConfigurableJoint = muscle.ConfigurableJoint; | |
| 			muscle.RootConfigurableJoint = rootConfigurableJoint; | |
| 			muscle.Init(); | |
| 
 | |
| 			Muscles.Add(muscle);			 | |
| 		} | |
| 		_startCount++;         | |
|     } | |
| 
 | |
| 
 | |
| 
 | |
| 	void HandleModelReset() | |
| 	{ | |
| 		Transform[] allChildren = _agent.GetComponentsInChildren<Transform>(); | |
| 		if (transformsPosition != null) | |
| 		{ | |
| 			foreach (var child in allChildren) | |
| 			{ | |
| 				child.position = transformsPosition[child.gameObject]; | |
| 				child.rotation = transformsRotation[child.gameObject]; | |
| 				var childRb = child.GetComponent<Rigidbody>(); | |
| 				if (childRb != null) | |
| 				{ | |
| 					childRb.angularVelocity = Vector3.zero; | |
| 					childRb.velocity = Vector3.zero; | |
| 				} | |
| 			} | |
| 
 | |
| 		} | |
| 		else | |
| 		{ | |
| 			startPosition = _agent.transform.position; | |
| 			transformsPosition = new Dictionary<GameObject, Vector3>(); | |
| 			transformsRotation = new Dictionary<GameObject, Quaternion>(); | |
| 			foreach (Transform child in allChildren) | |
| 			{ | |
| 				transformsPosition[child.gameObject] = child.position; | |
| 				transformsRotation[child.gameObject] = child.rotation; | |
| 			} | |
| 		} | |
| 	} | |
| 
 | |
| 	public float GetHeightNormalizedReward(float maxHeight) | |
| 	{ | |
| 		var height = GetHeight(); | |
| 		var heightPenality = maxHeight - height; | |
| 		heightPenality = Mathf.Clamp(heightPenality, 0f, maxHeight); | |
| 		var reward = 1f - heightPenality; | |
| 		reward = Mathf.Clamp(reward, 0f, 1f); | |
| 		return reward; | |
| 	} | |
| 	internal float GetHeight() | |
| 	{ | |
| 		var feetYpos = BodyParts | |
| 			.Where(x => x.Group == BodyPartGroup.Foot) | |
| 			.Select(x => x.Transform.position.y) | |
| 			.OrderBy(x => x) | |
| 			.ToList(); | |
| 		float lowestFoot = 0f; | |
| 		if (feetYpos != null && feetYpos.Count != 0) | |
| 			lowestFoot = feetYpos[0]; | |
| 		var height = GetFirstBodyPart(BodyPartGroup.Head).Transform.position.y - lowestFoot; | |
| 		return height; | |
| 	} | |
| 	public float GetDirectionNormalizedReward(BodyPartGroup bodyPartGroup, Vector3 direction) | |
| 	{ | |
| 		BodyPart002 bodyPart = GetFirstBodyPart(bodyPartGroup); | |
| 		float maxBonus = 1f; | |
| 		var toFocalAngle = bodyPart.ToFocalRoation * bodyPart.Transform.right; | |
| 		var angle = Vector3.Angle(toFocalAngle, direction); | |
| 		var qpos2 = (angle % 180) / 180; | |
| 		var bonus = maxBonus * (2 - (Mathf.Abs(qpos2) * 2) - 1); | |
| 		return bonus; | |
| 	} | |
| 
 | |
| 	public float GetUprightNormalizedReward(BodyPartGroup bodyPartGroup) | |
| 	{ | |
| 		BodyPart002 bodyPart = GetFirstBodyPart(bodyPartGroup); | |
| 		float maxBonus = 1f; | |
| 		var toFocalAngle = bodyPart.ToFocalRoation * -bodyPart.Transform.forward; | |
| 		var angleFromUp = Vector3.Angle(toFocalAngle, Vector3.up); | |
| 		var qpos2 = (angleFromUp % 180) / 180; | |
| 		var uprightBonus = maxBonus * (2 - (Mathf.Abs(qpos2) * 2) - 1); | |
| 		return uprightBonus; | |
| 	} | |
| 	public float GetEffortNormalized(string[] ignorJoints = null) | |
| 	{ | |
| 		double effort = 0; | |
| 		double jointEffort = 0; | |
| 		double joints = 0; | |
| 		foreach (var muscle in Muscles) | |
| 		{ | |
| 			if(muscle.Parent == null) | |
| 				continue; | |
| 			var name = muscle.Name; | |
| 			if (ignorJoints != null && ignorJoints.Contains(name)) | |
| 				continue; | |
| 			if (muscle.ConfigurableJoint.angularXMotion != ConfigurableJointMotion.Locked) { | |
| 				jointEffort = Mathf.Pow(Mathf.Abs(muscle.TargetNormalizedRotationX),2); | |
| 				effort += jointEffort; | |
| 				joints++; | |
| 			} | |
| 			if (muscle.ConfigurableJoint.angularYMotion != ConfigurableJointMotion.Locked) { | |
| 				jointEffort = Mathf.Pow(Mathf.Abs(muscle.TargetNormalizedRotationY),2); | |
| 				effort += jointEffort; | |
| 				joints++; | |
| 			} | |
| 			if (muscle.ConfigurableJoint.angularZMotion != ConfigurableJointMotion.Locked) { | |
| 				jointEffort = Mathf.Pow(Mathf.Abs(muscle.TargetNormalizedRotationZ),2); | |
| 				effort += jointEffort; | |
| 				joints++; | |
| 			} | |
| 		} | |
| 
 | |
| 		return (float) (effort / joints); | |
| 	} | |
| 	public void OnSensorCollisionEnter(Collider sensorCollider, GameObject other) { | |
| 		// if (string.Compare(other.name, "Terrain", true) !=0) | |
| 		if (other.GetComponent<Terrain>() == null) | |
| 			return; | |
| 		var sensor = Sensors | |
| 			.FirstOrDefault(x=>x == sensorCollider.gameObject); | |
| 		if (sensor != null) { | |
| 			var idx = Sensors.IndexOf(sensor); | |
| 			SensorIsInTouch[idx] = 1f; | |
| 		} | |
| 	} | |
| 	public void OnSensorCollisionExit(Collider sensorCollider, GameObject other) | |
| 	{ | |
| 		// if (string.Compare(other.gameObject.name, "Terrain", true) !=0) | |
| 		if (other.GetComponent<Terrain>() == null) | |
| 			return; | |
| 		var sensor = Sensors | |
| 			.FirstOrDefault(x=>x == sensorCollider.gameObject); | |
| 		if (sensor != null) { | |
| 			var idx = Sensors.IndexOf(sensor); | |
| 			SensorIsInTouch[idx] = 0f; | |
| 		} | |
| 	}   | |
| 	public Vector3 GetLocalCenterOfMass() | |
|     { | |
|         var centerOfMass = GetCenterOfMass(); | |
| 		centerOfMass -= transform.position; | |
|         return centerOfMass; | |
|     } | |
| 	public Vector3 GetCenterOfMass() | |
| 	{ | |
| 		var centerOfMass = Vector3.zero; | |
| 		float totalMass = 0f; | |
| 		var bodies = BodyParts | |
| 			.Select(x=>x.Rigidbody) | |
| 			.Where(x=>x!=null) | |
| 			.ToList(); | |
| 		foreach (Rigidbody rb in bodies) | |
| 		{ | |
| 			centerOfMass += rb.worldCenterOfMass * rb.mass; | |
| 			totalMass += rb.mass; | |
| 		} | |
| 		centerOfMass /= totalMass; | |
| 		return centerOfMass; | |
| 	} | |
| 
 | |
|     public Vector3 GetNormalizedVelocity() | |
|     { | |
|         var pelvis = GetFirstBodyPart(BodyConfig.GetRootBodyPart());  | |
|         Vector3 metersPerSecond = pelvis.Rigidbody.velocity; | |
|         var n = GetNormalizedVelocity(metersPerSecond); | |
|         return n; | |
|     } | |
| 
 | |
|     public Vector3 GetNormalizedPosition() | |
|     { | |
| 		// var position = GetCenterOfMass(); | |
|         var pelvis = GetFirstBodyPart(BodyConfig.GetRootBodyPart());  | |
| 		var position = pelvis.Transform.position; | |
| 		var normalizedPosition = GetNormalizedPosition(position - startPosition); | |
|         return normalizedPosition; | |
|     } | |
|     public void SetDebugFrameReward(float reward) | |
| 	{ | |
| 		FrameReward = reward; | |
| 		var stepCount = _agent.StepCount > 0 ? _agent.StepCount : 1; | |
| 		if (_decisionRequester?.DecisionPeriod > 1) | |
| 			stepCount /= _decisionRequester.DecisionPeriod; | |
| 		AverageReward = _agent.GetCumulativeReward() / (float) stepCount;		 | |
| 	} | |
| 
 | |
| 
 | |
|     public List<float> GetSensorIsInTouch() | |
|     { | |
|         return SensorIsInTouch; | |
|     } | |
|     // public List<float> GetBodyPartsObservations() | |
|     // { | |
|     //     List<float> vectorObservation = new List<float>(); | |
| 	// 	foreach (var bodyPart in BodyParts) | |
| 	// 	{ | |
| 	// 		bodyPart.UpdateObservations(); | |
| 	// 		// _agent.sensor.AddObservation(bodyPart.ObsRotation); | |
|     //         vectorObservation.Add(bodyPart.ObsRotation.x); | |
|     //         vectorObservation.Add(bodyPart.ObsRotation.y); | |
|     //         vectorObservation.Add(bodyPart.ObsRotation.z); | |
|     //         vectorObservation.Add(bodyPart.ObsRotation.w); | |
|  | |
| 	// 		// _agent.sensor.AddObservation(bodyPart.ObsRotationVelocity); | |
|     //         vectorObservation.Add(bodyPart.ObsRotationVelocity.x); | |
|     //         vectorObservation.Add(bodyPart.ObsRotationVelocity.y); | |
|     //         vectorObservation.Add(bodyPart.ObsRotationVelocity.z); | |
|  | |
| 	// 		// _agent.sensor.AddObservation(GetNormalizedVelocity(bodyPart.ObsVelocity)); | |
|     //         var normalizedVelocity = GetNormalizedVelocity(bodyPart.ObsVelocity); | |
|     //         vectorObservation.Add(normalizedVelocity.x); | |
|     //         vectorObservation.Add(normalizedVelocity.y); | |
|     //         vectorObservation.Add(normalizedVelocity.z); | |
| 	// 	} | |
|     //     return vectorObservation; | |
|     // } | |
|     public List<float> GetMusclesObservations() | |
|     { | |
|         List<float> vectorObservation = new List<float>(); | |
| 		foreach (var muscle in Muscles) | |
| 		{ | |
| 			muscle.UpdateObservations(); | |
| 			if (muscle.ConfigurableJoint.angularXMotion != ConfigurableJointMotion.Locked) | |
| 				vectorObservation.Add(muscle.TargetNormalizedRotationX); | |
| 			if (muscle.ConfigurableJoint.angularYMotion != ConfigurableJointMotion.Locked) | |
| 				vectorObservation.Add(muscle.TargetNormalizedRotationY); | |
| 			if (muscle.ConfigurableJoint.angularZMotion != ConfigurableJointMotion.Locked) | |
| 				vectorObservation.Add(muscle.TargetNormalizedRotationZ); | |
|         }         | |
|         return vectorObservation; | |
|     } | |
| 	[Obsolete("use GetSensorObservations()")] | |
|     public List<float> GetSensorYPositions() | |
|     { | |
| 		var sensorYpositions = Sensors | |
| 			.Select(x=> this.GetNormalizedPosition(x.transform.position - startPosition)) | |
| 			.Select(x=>x.y) | |
| 			.ToList(); | |
|         return sensorYpositions; | |
|     } | |
| 	[Obsolete("use GetSensorObservations()")] | |
| 	public List<float> GetSensorZPositions() | |
|     { | |
| 		var sensorYpositions = Sensors | |
| 			.Select(x=> this.GetNormalizedPosition(x.transform.position - startPosition)) | |
| 			.Select(x=>x.z) | |
| 			.ToList(); | |
|         return sensorYpositions; | |
|     } | |
| 
 | |
| 	public List<float> GetSensorObservations() | |
| 	{ | |
| 		var localSensorsPos = new Vector3[Sensors.Count]; | |
| 		var globalSensorsPos = new Vector3[Sensors.Count]; | |
| 		for (int i = 0; i < Sensors.Count; i++) { | |
| 			globalSensorsPos[i] = sensorColliders[i].transform.TransformPoint(sensorColliders[i].center); | |
| 			localSensorsPos[i] = globalSensorsPos[i] - startPosition; | |
| 		} | |
| 
 | |
| 		// get heights based on global senor position | |
| 		var sensorsPos = Sensors | |
| 			.Select(x=>x.transform.position).ToList(); | |
| 		var senorHeights = _terrainGenerator != null | |
| 			? _terrainGenerator.GetDistances2d(globalSensorsPos) | |
| 			: Enumerable.Range(0, globalSensorsPos.Length).Select(x=>0f).ToList(); | |
| 		for (int i = 0; i < Sensors.Count; i++) { | |
| 			senorHeights[i] -= sensorColliders[i].radius; | |
| 			if (senorHeights[i] >= 1f) | |
| 				senorHeights[i] = 1f; | |
| 		} | |
| 			 | |
| 		// get z positions based on local positions | |
| 		var bounds = _spawnableEnv.bounds; | |
| 		var normalizedZ = localSensorsPos | |
| 			.Select(x=>x.z / (bounds.extents.z)) | |
| 			.ToList(); | |
| 		var observations = senorHeights | |
| 			.Concat(normalizedZ) | |
| 			.ToList(); | |
| 		return observations; | |
| 	} | |
| 
 | |
|     // public void OnCollectObservationsHandleDebug(AgentInfo info) | |
|     // { | |
| 	// 	if (Observations?.Count != info.vectorObservation.Count) | |
| 	// 		Observations = Enumerable.Range(0, info.vectorObservation.Count).Select(x => 0f).ToList(); | |
| 	// 	ObservationNormalizedErrors = 0; | |
| 	// 	for (int i = 0; i < Observations.Count; i++) | |
| 	// 	{ | |
| 	// 		Observations[i] = info.vectorObservation[i]; | |
| 	// 		var x = Mathf.Abs(Observations[i]); | |
| 	// 		var e = Mathf.Epsilon; | |
| 	// 		bool is1 = Mathf.Approximately(x, 1f); | |
| 	// 		if ((x > 1f + e) && !is1) | |
| 	// 			ObservationNormalizedErrors++; | |
| 	// 	} | |
| 	// 	if (ObservationNormalizedErrors > MaxObservationNormalizedErrors) | |
| 	// 		MaxObservationNormalizedErrors = ObservationNormalizedErrors;   | |
|  | |
|     //     var pelvis = GetFirstBodyPart(BodyPartGroup.Hips); | |
| 	// 	DistanceTraveled = pelvis.Transform.position.x; | |
| 	// 	MaxDistanceTraveled = Mathf.Max(MaxDistanceTraveled, DistanceTraveled); | |
|     //     Vector3 metersPerSecond = pelvis.Rigidbody.velocity; | |
| 	// 	Vector3 mph = metersPerSecond * 2.236936f; | |
| 	// 	mphBuffer.Add(mph); | |
| 	// 	if (mphBuffer.Count > 100) | |
| 	// 		mphBuffer.RemoveAt(0); | |
| 	// 	var aveMph = new Vector3( | |
| 	// 		mphBuffer.Select(x=>x.x).Average(), | |
| 	// 		mphBuffer.Select(x=>x.y).Average(), | |
| 	// 		mphBuffer.Select(x=>x.z).Average() | |
| 	// 	); | |
| 	// 	if (ShowMonitor) | |
| 	// 	{ | |
| 	// 		Monitor.Log("MaxDistance", MaxDistanceTraveled.ToString()); | |
| 	// 		Monitor.Log("NormalizedPos", GetNormalizedPosition().ToString()); | |
| 	// 		Monitor.Log("MPH: ", (aveMph).ToString()); | |
| 	// 	}             | |
|     // }   | |
|  | |
| 	float NextGaussian(float mu = 0, float sigma = 1) | |
| 	{ | |
| 		var u1 = UnityEngine.Random.value; | |
| 		var u2 = UnityEngine.Random.value; | |
| 
 | |
| 		var rand_std_normal = Mathf.Sqrt(-2.0f * Mathf.Log(u1)) * | |
| 							Mathf.Sin(2.0f * Mathf.PI * u2); | |
| 
 | |
| 		var rand_normal = mu + sigma * rand_std_normal; | |
| 
 | |
| 		return rand_normal; | |
| 	} | |
| 	public Vector3 GetNormalizedVelocity(Vector3 metersPerSecond) | |
| 	{ | |
| 		var maxMetersPerSecond = _spawnableEnv.bounds.size | |
| 			/ _agent.MaxStep | |
| 			/ Time.fixedDeltaTime; | |
| 		var maxXZ = Mathf.Max(maxMetersPerSecond.x, maxMetersPerSecond.z); | |
| 		maxMetersPerSecond.x = maxXZ; | |
| 		maxMetersPerSecond.z = maxXZ; | |
| 		maxMetersPerSecond.y = 53; // override with | |
| 		float x = metersPerSecond.x / maxMetersPerSecond.x; | |
| 		float y = metersPerSecond.y / maxMetersPerSecond.y; | |
| 		float z = metersPerSecond.z / maxMetersPerSecond.z; | |
| 		// clamp result | |
| 		x = Mathf.Clamp(x, -1f, 1f); | |
| 		y = Mathf.Clamp(y, -1f, 1f); | |
| 		z = Mathf.Clamp(z, -1f, 1f); | |
| 		Vector3 normalizedVelocity = new Vector3(x,y,z); | |
| 		return normalizedVelocity; | |
| 	} | |
| 	public Vector3 GetNormalizedPosition(Vector3 pos) | |
| 	{ | |
| 		var maxPos = _spawnableEnv.bounds.size; | |
| 		float x = pos.x / maxPos.x; | |
| 		float y = pos.y / maxPos.y; | |
| 		float z = pos.z / maxPos.z; | |
| 		// clamp result | |
| 		x = Mathf.Clamp(x, -1f, 1f); | |
| 		y = Mathf.Clamp(y, -1f, 1f); | |
| 		z = Mathf.Clamp(z, -1f, 1f); | |
| 		Vector3 normalizedPos = new Vector3(x,y,z); | |
| 		return normalizedPos; | |
| 	} | |
| }
 | |
| 
 |