浏览代码

Refactor RayPerception and add RayPerception2D (#1793)

* Fix typos

* Use abstract class for rayperception

* Created RayPerception2D. (#1721)

* Incorporate RayPerception2D

* Fix typo

* Make abstract class

* Add tests
/develop-generalizationTraining-TrainerController
GitHub 6 年前
当前提交
be0d2709
共有 9 个文件被更改,包括 239 次插入86 次删除
  1. 6
      UnitySDK/Assets/ML-Agents/Examples/BananaCollectors/Scripts/BananaAgent.cs
  2. 100
      UnitySDK/Assets/ML-Agents/Examples/SharedAssets/Scripts/RayPerception.cs
  3. 2
      UnitySDK/Assets/ML-Agents/Examples/SharedAssets/Scripts/RayPerception.cs.meta
  4. 37
      UnitySDK/Assets/ML-Agents/Editor/Tests/RayPerceptionTests.cs
  5. 3
      UnitySDK/Assets/ML-Agents/Editor/Tests/RayPerceptionTests.cs.meta
  6. 75
      UnitySDK/Assets/ML-Agents/Examples/SharedAssets/Scripts/RayPerception2D.cs
  7. 11
      UnitySDK/Assets/ML-Agents/Examples/SharedAssets/Scripts/RayPerception2D.cs.meta
  8. 80
      UnitySDK/Assets/ML-Agents/Examples/SharedAssets/Scripts/RayPerception3D.cs
  9. 11
      UnitySDK/Assets/ML-Agents/Examples/SharedAssets/Scripts/RayPerception3D.cs.meta

6
UnitySDK/Assets/ML-Agents/Examples/BananaCollectors/Scripts/BananaAgent.cs


public Material frozenMaterial;
public GameObject myLaser;
public bool contribute;
private RayPerception rayPer;
private RayPerception3D rayPer;
public bool useVectorObs;
public override void InitializeAgent()

Monitor.verticalOffset = 1f;
myArea = area.GetComponent<BananaArea>();
rayPer = GetComponent<RayPerception>();
rayPer = GetComponent<RayPerception3D>();
myAcademy = FindObjectOfType<BananaAcademy>();
}

if (shoot)
{
myLaser.transform.localScale = new Vector3(1f, 1f, 1f);
Vector3 position = transform.TransformDirection(RayPerception.PolarToCartesian(25f, 90f));
Vector3 position = transform.TransformDirection(RayPerception3D.PolarToCartesian(25f, 90f));
Debug.DrawRay(transform.position, position, Color.red, 0f, true);
RaycastHit hit;
if (Physics.SphereCast(transform.position, 2f, position, out hit, 25f))

100
UnitySDK/Assets/ML-Agents/Examples/SharedAssets/Scripts/RayPerception.cs


using System.Collections.Generic;
using System.Collections;
using System.Collections.Generic;
namespace MLAgents
{
/// <summary>
/// Ray perception component. Attach this to agents to enable "local perception"
/// via the use of ray casts directed outward from the agent.
/// </summary>
public class RayPerception : MonoBehaviour
{
List<float> perceptionBuffer = new List<float>();
Vector3 endPosition;
RaycastHit hit;
/// <summary>
/// Creates perception vector to be used as part of an observation of an agent.
/// </summary>
/// <returns>The partial vector observation corresponding to the set of rays</returns>
/// <param name="rayDistance">Radius of rays</param>
/// <param name="rayAngles">Anlges of rays (starting from (1,0) on unit circle).</param>
/// <param name="detectableObjects">List of tags which correspond to object types agent can see</param>
/// <param name="startOffset">Starting heigh offset of ray from center of agent.</param>
/// <param name="endOffset">Ending height offset of ray from center of agent.</param>
public List<float> Perceive(float rayDistance,
float[] rayAngles, string[] detectableObjects,
float startOffset, float endOffset)
{
perceptionBuffer.Clear();
// For each ray sublist stores categorial information on detected object
// along with object distance.
foreach (float angle in rayAngles)
{
endPosition = transform.TransformDirection(
PolarToCartesian(rayDistance, angle));
endPosition.y = endOffset;
if (Application.isEditor)
{
Debug.DrawRay(transform.position + new Vector3(0f, startOffset, 0f),
endPosition, Color.black, 0.01f, true);
}
float[] subList = new float[detectableObjects.Length + 2];
if (Physics.SphereCast(transform.position +
new Vector3(0f, startOffset, 0f), 0.5f,
endPosition, out hit, rayDistance))
{
for (int i = 0; i < detectableObjects.Length; i++)
{
if (hit.collider.gameObject.CompareTag(detectableObjects[i]))
{
subList[i] = 1;
subList[detectableObjects.Length + 1] = hit.distance / rayDistance;
break;
}
}
}
else
{
subList[detectableObjects.Length] = 1f;
}
public abstract class RayPerception : MonoBehaviour {
perceptionBuffer.AddRange(subList);
}
return perceptionBuffer;
}
protected List<float> perceptionBuffer = new List<float>();
/// <summary>
/// Converts polar coordinate to cartesian coordinate.
/// </summary>
public static Vector3 PolarToCartesian(float radius, float angle)
{
float x = radius * Mathf.Cos(DegreeToRadian(angle));
float z = radius * Mathf.Sin(DegreeToRadian(angle));
return new Vector3(x, 0f, z);
}
public virtual List<float> Perceive(float rayDistance,
float[] rayAngles, string[] detectableObjects,
float startOffset, float endOffset)
{
return perceptionBuffer;
}
/// <summary>
/// Converts degrees to radians.
/// </summary>
public static float DegreeToRadian(float degree)
{
return degree * Mathf.PI / 180f;
}
}
/// <summary>
/// Converts degrees to radians.
/// </summary>
public static float DegreeToRadian(float degree)
{
return degree * Mathf.PI / 180f;
}
}

2
UnitySDK/Assets/ML-Agents/Examples/SharedAssets/Scripts/RayPerception.cs.meta


fileFormatVersion: 2
guid: bb172294dbbcc408286b156a2c4b553c
guid: a14e2e238ae844231bc2c88e17bae5a5
MonoImporter:
externalObjects: {}
serializedVersion: 2

37
UnitySDK/Assets/ML-Agents/Editor/Tests/RayPerceptionTests.cs


using UnityEngine;
using NUnit.Framework;
namespace MLAgents.Tests
{
public class RayPerceptionTests : MonoBehaviour
{
[Test]
public void TestPerception3D()
{
var angles = new[] {0f, 90f, 180f};
var tags = new[] {"test", "test_1"};
var go = new GameObject("MyGameObject");
RayPerception3D rayPer3D = go.AddComponent<RayPerception3D>();
var result = rayPer3D.Perceive(1f, angles ,
tags, 0f, 0f);
Debug.Log(result.Count);
Assert.IsTrue(result.Count == angles.Length * (tags.Length + 2));
}
[Test]
public void TestPerception2D()
{
var angles = new[] {0f, 90f, 180f};
var tags = new[] {"test", "test_1"};
var go = new GameObject("MyGameObject");
RayPerception2D rayPer2D = go.AddComponent<RayPerception2D>();
var result = rayPer2D.Perceive(1f, angles,
tags);
Debug.Log(result.Count);
Assert.IsTrue(result.Count == angles.Length * (tags.Length + 2));
}
}
}

3
UnitySDK/Assets/ML-Agents/Editor/Tests/RayPerceptionTests.cs.meta


fileFormatVersion: 2
guid: 29010426d01b4569830a85795f4f345b
timeCreated: 1552498773

75
UnitySDK/Assets/ML-Agents/Examples/SharedAssets/Scripts/RayPerception2D.cs


using System.Collections.Generic;
using UnityEngine;
namespace MLAgents
{
/// <summary>
/// Ray 2D perception component. Attach this to agents to enable "local perception"
/// via the use of ray casts directed outward from the agent.
/// </summary>
public class RayPerception2D : RayPerception
{
Vector2 endPosition;
RaycastHit2D hit;
/// <summary>
/// Creates perception vector to be used as part of an observation of an agent.
/// </summary>
/// <returns>The partial vector observation corresponding to the set of rays</returns>
/// <param name="rayDistance">Radius of rays</param>
/// <param name="rayAngles">Angles of rays (starting from (1,0) on unit circle).</param>
/// <param name="detectableObjects">List of tags which correspond to object types agent can see</param>
public List<float> Perceive(float rayDistance,
float[] rayAngles, string[] detectableObjects)
{
perceptionBuffer.Clear();
// For each ray sublist stores categorical information on detected object
// along with object distance.
foreach (float angle in rayAngles)
{
endPosition = transform.TransformDirection(
PolarToCartesian(rayDistance, angle));
if (Application.isEditor)
{
Debug.DrawRay(transform.position,
endPosition, Color.black, 0.01f, true);
}
float[] subList = new float[detectableObjects.Length + 2];
hit = Physics2D.CircleCast(transform.position, 0.5f, endPosition, rayDistance);
if (hit)
{
for (int i = 0; i < detectableObjects.Length; i++)
{
if (hit.collider.gameObject.CompareTag(detectableObjects[i]))
{
subList[i] = 1;
subList[detectableObjects.Length + 1] = hit.distance / rayDistance;
break;
}
}
}
else
{
subList[detectableObjects.Length] = 1f;
}
perceptionBuffer.AddRange(subList);
}
return perceptionBuffer;
}
/// <summary>
/// Converts polar coordinate to cartesian coordinate.
/// </summary>
public static Vector2 PolarToCartesian(float radius, float angle)
{
float x = radius * Mathf.Cos(DegreeToRadian(angle));
float y = radius * Mathf.Sin(DegreeToRadian(angle));
return new Vector2(x, y);
}
}
}

11
UnitySDK/Assets/ML-Agents/Examples/SharedAssets/Scripts/RayPerception2D.cs.meta


fileFormatVersion: 2
guid: 59a9c4378bb2a40c49eb7a248c52fbf5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

80
UnitySDK/Assets/ML-Agents/Examples/SharedAssets/Scripts/RayPerception3D.cs


using System.Collections.Generic;
using UnityEngine;
namespace MLAgents
{
/// <summary>
/// Ray perception component. Attach this to agents to enable "local perception"
/// via the use of ray casts directed outward from the agent.
/// </summary>
public class RayPerception3D : RayPerception
{
Vector3 endPosition;
RaycastHit hit;
/// <summary>
/// Creates perception vector to be used as part of an observation of an agent.
/// </summary>
/// <returns>The partial vector observation corresponding to the set of rays</returns>
/// <param name="rayDistance">Radius of rays</param>
/// <param name="rayAngles">Angles of rays (starting from (1,0) on unit circle).</param>
/// <param name="detectableObjects">List of tags which correspond to object types agent can see</param>
/// <param name="startOffset">Starting height offset of ray from center of agent.</param>
/// <param name="endOffset">Ending height offset of ray from center of agent.</param>
public override List<float> Perceive(float rayDistance,
float[] rayAngles, string[] detectableObjects,
float startOffset, float endOffset)
{
perceptionBuffer.Clear();
// For each ray sublist stores categorical information on detected object
// along with object distance.
foreach (float angle in rayAngles)
{
endPosition = transform.TransformDirection(
PolarToCartesian(rayDistance, angle));
endPosition.y = endOffset;
if (Application.isEditor)
{
Debug.DrawRay(transform.position + new Vector3(0f, startOffset, 0f),
endPosition, Color.black, 0.01f, true);
}
float[] subList = new float[detectableObjects.Length + 2];
if (Physics.SphereCast(transform.position +
new Vector3(0f, startOffset, 0f), 0.5f,
endPosition, out hit, rayDistance))
{
for (int i = 0; i < detectableObjects.Length; i++)
{
if (hit.collider.gameObject.CompareTag(detectableObjects[i]))
{
subList[i] = 1;
subList[detectableObjects.Length + 1] = hit.distance / rayDistance;
break;
}
}
}
else
{
subList[detectableObjects.Length] = 1f;
}
perceptionBuffer.AddRange(subList);
}
return perceptionBuffer;
}
/// <summary>
/// Converts polar coordinate to cartesian coordinate.
/// </summary>
public static Vector3 PolarToCartesian(float radius, float angle)
{
float x = radius * Mathf.Cos(DegreeToRadian(angle));
float z = radius * Mathf.Sin(DegreeToRadian(angle));
return new Vector3(x, 0f, z);
}
}
}

11
UnitySDK/Assets/ML-Agents/Examples/SharedAssets/Scripts/RayPerception3D.cs.meta


fileFormatVersion: 2
guid: bb172294dbbcc408286b156a2c4b553c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存