public void TestRaycasts()
        {
            SetupScene();
            var obj        = new GameObject("agent");
            var perception = obj.AddComponent <RayPerceptionSensorComponent3D>();

            perception.RaysPerDirection = 1;
            perception.MaxRayDegrees    = 45;
            perception.RayLength        = 20;
            perception.DetectableTags   = new List <string>();
            perception.DetectableTags.Add(k_CubeTag);
            perception.DetectableTags.Add(k_SphereTag);

            var radii = new[] { 0f, .5f };

            foreach (var castRadius in radii)
            {
                perception.SphereCastRadius = castRadius;
                var sensor = perception.CreateSensor();

                var expectedObs = (2 * perception.RaysPerDirection + 1) * (perception.DetectableTags.Count + 2);
                Assert.AreEqual(sensor.GetObservationShape()[0], expectedObs);
                var outputBuffer = new float[expectedObs];

                WriteAdapter writer = new WriteAdapter();
                writer.SetTarget(outputBuffer, sensor.GetObservationShape(), 0);

                var numWritten = sensor.Write(writer);
                Assert.AreEqual(numWritten, expectedObs);

                // Expected hits:
                // ray 0 should hit the cube at roughly halfway
                // ray 1 should hit a sphere but no tag
                // ray 2 should hit a sphere with the k_SphereTag tag
                // The hit fraction should be the same for rays 1 and
                //
                Assert.AreEqual(1.0f, outputBuffer[0]); // hit cube
                Assert.AreEqual(0.0f, outputBuffer[1]); // missed sphere
                Assert.AreEqual(0.0f, outputBuffer[2]); // missed unknown tag

                // Hit is at z=9.0 in world space, ray length is 20
                Assert.That(
                    outputBuffer[3], Is.EqualTo((9.5f - castRadius) / perception.RayLength).Within(.0005f)
                    );

                // Spheres are at 5,0,5 and 5,0,-5, so 5*sqrt(2) units from origin
                // Minus 1.0 for the sphere radius to get the length of the hit.
                var expectedHitLengthWorldSpace = 5.0f * Mathf.Sqrt(2.0f) - 0.5f - castRadius;
                Assert.AreEqual(0.0f, outputBuffer[4]); // missed cube
                Assert.AreEqual(0.0f, outputBuffer[5]); // missed sphere
                Assert.AreEqual(0.0f, outputBuffer[6]); // hit unknown tag -> all 0
                Assert.That(
                    outputBuffer[7], Is.EqualTo(expectedHitLengthWorldSpace / perception.RayLength).Within(.0005f)
                    );

                Assert.AreEqual(0.0f, outputBuffer[8]);  // missed cube
                Assert.AreEqual(1.0f, outputBuffer[9]);  // hit sphere
                Assert.AreEqual(0.0f, outputBuffer[10]); // missed unknown tag
                Assert.That(
                    outputBuffer[11], Is.EqualTo(expectedHitLengthWorldSpace / perception.RayLength).Within(.0005f)
                    );
            }
        }
        public void TestRayFilter()
        {
            var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);

            cube.transform.position = new Vector3(0, 0, 10);
            cube.tag  = k_CubeTag;
            cube.name = "cubeFar";

            var cubeFiltered = GameObject.CreatePrimitive(PrimitiveType.Cube);

            cubeFiltered.transform.position = new Vector3(0, 0, 5);
            cubeFiltered.tag   = k_CubeTag;
            cubeFiltered.name  = "cubeNear";
            cubeFiltered.layer = 7;

            Physics.SyncTransforms();

            var obj        = new GameObject("agent");
            var perception = obj.AddComponent <RayPerceptionSensorComponent3D>();

            perception.RaysPerDirection = 0;
            perception.RayLength        = 20;
            perception.DetectableTags   = new List <string>();

            var filterCubeLayers = new[] { false, true };

            foreach (var filterCubeLayer in filterCubeLayers)
            {
                // Set the layer mask to either the default, or one that ignores the close cube's layer
                var layerMask = Physics.DefaultRaycastLayers;
                if (filterCubeLayer)
                {
                    layerMask &= ~(1 << cubeFiltered.layer);
                }
                perception.RayLayerMask = layerMask;

                var sensor      = perception.CreateSensor();
                var expectedObs = (2 * perception.RaysPerDirection + 1) * (perception.DetectableTags.Count + 2);
                Assert.AreEqual(sensor.GetObservationShape()[0], expectedObs);
                var outputBuffer = new float[expectedObs];

                WriteAdapter writer = new WriteAdapter();
                writer.SetTarget(outputBuffer, sensor.GetObservationShape(), 0);

                var numWritten = sensor.Write(writer);
                Assert.AreEqual(numWritten, expectedObs);

                if (filterCubeLayer)
                {
                    // Hit the far cube because close was filtered.
                    Assert.That(outputBuffer[outputBuffer.Length - 1],
                                Is.EqualTo((9.5f - perception.SphereCastRadius) / perception.RayLength).Within(.0005f)
                                );
                }
                else
                {
                    // Hit the close cube because not filtered.
                    Assert.That(outputBuffer[outputBuffer.Length - 1],
                                Is.EqualTo((4.5f - perception.SphereCastRadius) / perception.RayLength).Within(.0005f)
                                );
                }
            }
        }
Exemplo n.º 3
0
 public int Write(WriteAdapter adapter)
 {
     numWriteCalls++;
     // No-op
     return(0);
 }
Exemplo n.º 4
0
 public int Write(WriteAdapter adapter)
 {
     // No-op
     return(0);
 }
Exemplo n.º 5
0
 public int Write(WriteAdapter adapter)
 {
     return(this.ObservationSize());
 }