diff --git a/Project/Assets/ML-Agents/Examples/CarCatching/Prefabs/CarAgentGridCollab.prefab b/Project/Assets/ML-Agents/Examples/CarCatching/Prefabs/CarAgentGridCollab.prefab index 638306bd..dd029ba8 100644 --- a/Project/Assets/ML-Agents/Examples/CarCatching/Prefabs/CarAgentGridCollab.prefab +++ b/Project/Assets/ML-Agents/Examples/CarCatching/Prefabs/CarAgentGridCollab.prefab @@ -329,7 +329,7 @@ GameObject: - component: {fileID: 5601152702967375707} - component: {fileID: 3822330893343168228} - component: {fileID: 5628194071647130095} - m_Layer: 0 + m_Layer: 2 m_Name: CarAgentGridCollab m_TagString: blueAgent m_Icon: {fileID: 0} diff --git a/Project/Assets/ML-Agents/Examples/CarCatching/Prefabs/CarCatchingArea.prefab b/Project/Assets/ML-Agents/Examples/CarCatching/Prefabs/CarCatchingArea.prefab index 74fede53..520eed63 100644 --- a/Project/Assets/ML-Agents/Examples/CarCatching/Prefabs/CarCatchingArea.prefab +++ b/Project/Assets/ML-Agents/Examples/CarCatching/Prefabs/CarCatchingArea.prefab @@ -59,28 +59,24 @@ MonoBehaviour: StartingPos: {x: 0, y: 0, z: 0} StartingRot: {x: 0, y: 0, z: 0, w: 0} StartingScale: {x: 0, y: 0, z: 0} - GoalPosition: {x: 0, y: 0, z: 0} DecisionRequester: {fileID: 0} NavMeshAgent: {fileID: 0} - Agent: {fileID: 7246486209573452180} StartingPos: {x: 0, y: 0, z: 0} StartingRot: {x: 0, y: 0, z: 0, w: 0} StartingScale: {x: 0, y: 0, z: 0} - GoalPosition: {x: 0, y: 0, z: 0} DecisionRequester: {fileID: 0} NavMeshAgent: {fileID: 0} - Agent: {fileID: 3964309580746521657} StartingPos: {x: 0, y: 0, z: 0} StartingRot: {x: 0, y: 0, z: 0, w: 0} StartingScale: {x: 0, y: 0, z: 0} - GoalPosition: {x: 0, y: 0, z: 0} DecisionRequester: {fileID: 0} NavMeshAgent: {fileID: 0} - Agent: {fileID: 4005891969102443327} StartingPos: {x: 0, y: 0, z: 0} StartingRot: {x: 0, y: 0, z: 0, w: 0} StartingScale: {x: 0, y: 0, z: 0} - GoalPosition: {x: 0, y: 0, z: 0} DecisionRequester: {fileID: 0} NavMeshAgent: {fileID: 0} UseRandomAgentRotation: 1 @@ -96,7 +92,7 @@ PrefabInstance: m_Modifications: - target: {fileID: 9194218059880268, guid: 8797a13bf18c2ab48bc8b884e5d4b04d, type: 3} propertyPath: m_VoxelSize - value: 12.5 + value: 7.6666665 objectReference: {fileID: 0} - target: {fileID: 431764501063180419, guid: 8797a13bf18c2ab48bc8b884e5d4b04d, type: 3} diff --git a/Project/Assets/ML-Agents/Examples/CarCatching/Scripts/CarAgent.cs b/Project/Assets/ML-Agents/Examples/CarCatching/Scripts/CarAgent.cs index 719bf466..da5cbf8d 100644 --- a/Project/Assets/ML-Agents/Examples/CarCatching/Scripts/CarAgent.cs +++ b/Project/Assets/ML-Agents/Examples/CarCatching/Scripts/CarAgent.cs @@ -1,4 +1,5 @@ -using UnityEngine; +using Unity.Mathematics; +using UnityEngine; using Unity.MLAgents; using Unity.MLAgents.Actuators; using Unity.MLAgents.Sensors; @@ -107,10 +108,13 @@ public void MoveAgent(ActionSegment act) public override void OnActionReceived(ActionBuffers actionBuffers) { var rawAction = new Vector2(actionBuffers.ContinuousActions[0], actionBuffers.ContinuousActions[1]); + var clipAction = new Vector2(Mathf.Clamp(rawAction[0], -1f, 1f), Mathf.Clamp(rawAction[1], 0f, 1f)); Debug.Log(this.transform.parent.gameObject.name + ", " + this.name + " onActionReceived: " + rawAction + " " + transform.position); - var reverselyNormalizedPos2d = ReverselyNormalizePos2d(rawAction); + + // var reverselyNormalizedPos2d = ReverselyNormalizePos2dCartesian(rawAction); + var reverselyNormalizedPos2d = ReverselyNormalizePos2dPolar(clipAction); // Add the reversely normalized action and the car's global position (because setDestination accept a global target position) var navigationGoal = transform.position + @@ -124,12 +128,44 @@ public override void OnActionReceived(ActionBuffers actionBuffers) // MoveAgent(actionBuffers.DiscreteActions); } - public Vector2 ReverselyNormalizePos2d(Vector2 pos) + // This method reversely normalized pos output by neural network using Cartesian coordinate system. The car itself acts as origin. + // So the legal decision range is a square whose side length is decisionRangeRadius. + public Vector2 ReverselyNormalizePos2dCartesian(Vector2 pos) { Vector2 ans = new Vector2(pos.x * decisionRangeRadius, pos.y * decisionRangeRadius); return ans; } + // This method reversely normalized pos output by neural network using Polar coordinate system. The car itself acts as origin. + // The legal decision range is a circle never hits any obstacles. + public Vector2 ReverselyNormalizePos2dPolar(Vector2 pos) + { + //pos.x is normalized angle, pos.y is normalized radius + var normalizedAngle = pos.x; + var normalizedRadius = pos.y; + + // non-normalized angle + var angle = normalizedAngle * math.PI; + float radius = decisionRangeRadius; + Vector3 dir = new Vector3(math.cos(angle), 0, math.sin(angle)); + + // Physics.DefaultRaycastLayers means all layers will be considered during casting except Ignore Raycast layer. + RaycastHit hit; + if (Physics.Raycast(transform.position, dir, out hit, decisionRangeRadius, Physics.DefaultRaycastLayers)) + { + radius = hit.distance; + } + // non-normalized radius + radius = normalizedRadius * radius; + + Debug.Log(this.transform.parent.gameObject.name + + ", " + this.name + " onActionReceived: polar angle " + angle + "polar radius " + radius); + Vector2 ans = new Vector2(radius * math.cos(angle), radius * math.sin(angle)); + Debug.Log(this.transform.parent.gameObject.name + + ", " + this.name + " onActionReceived: polar target " + ans); + return ans; + } + public override void Heuristic(in ActionBuffers actionsOut) { @@ -159,5 +195,10 @@ public void FixedUpdate() { Debug.Log(this.transform.parent.gameObject.name + ", " + this.name + " FixedUpdate: " + carCatchingEnvController.ResetTimer + " " + transform.position); + + // Debug.Log( this.transform.parent.gameObject.name + + // ", " + this.name + " StepCount: " + StepCount); + // Debug.Log( this.transform.parent.gameObject.name + + // ", " + this.name + " CompleteEpisodes: " + CompletedEpisodes); } } diff --git a/Project/Assets/ML-Agents/Examples/CarCatching/Scripts/CarCatchingEnvController.cs b/Project/Assets/ML-Agents/Examples/CarCatching/Scripts/CarCatchingEnvController.cs index ac166b1f..d6a3a5f2 100644 --- a/Project/Assets/ML-Agents/Examples/CarCatching/Scripts/CarCatchingEnvController.cs +++ b/Project/Assets/ML-Agents/Examples/CarCatching/Scripts/CarCatchingEnvController.cs @@ -21,7 +21,6 @@ public class CarInfo // StartingScale is used for collision detection between cars and walls during initialization [HideInInspector] public Vector3 StartingScale; - [HideInInspector] public Vector3 GoalPosition; [HideInInspector] public DecisionRequester DecisionRequester; [HideInInspector] public NavMeshAgent NavMeshAgent; } @@ -77,13 +76,12 @@ void Start() item.StartingPos = itemTrans.position; item.StartingRot = itemTrans.rotation; item.StartingScale = itemTrans.localScale; - item.GoalPosition = itemTrans.position; item.DecisionRequester = item.Agent.GetComponent(); item.NavMeshAgent = item.Agent.GetComponent(); } for (; RunningNum < AgentsList.Count && AgentsList[RunningNum].Agent.isRunning; ++RunningNum) ; - + // Academy.Instance.OnEnvironmentReset += ResetScene; ResetScene(); } @@ -113,7 +111,7 @@ public Vector3 GetRandomSpawnPos(Quaternion rot) var agentHalfExtents = AgentsList[0].StartingScale * 0.5f; while (foundNewSpawnLocation == false) { - //Global Position = ground position + x,z local position + y + //Global Position = ground position + x,z local position + y randomSpawnPos = ground.transform.position + GetRandomPos() + new Vector3(0f, localY, 0f); Debug.Log( this.name + " GetRandomSpawnPos: " + randomSpawnPos); if (Physics.CheckBox(randomSpawnPos, agentHalfExtents, rot) == false)