Beispiel #1
0
        public int Write(WriteAdapter adapter)
        {
            // First, call the wrapped sensor's write method. Make sure to use our own adapter, not the passed one.
            var wrappedShape = m_WrappedSensor.GetObservationShape();

            m_LocalAdapter.SetTarget(m_StackedObservations[m_CurrentIndex], wrappedShape, 0);
            m_WrappedSensor.Write(m_LocalAdapter);

            // Now write the saved observations (oldest first)
            var numWritten = 0;

            for (var i = 0; i < m_NumStackedObservations; i++)
            {
                var obsIndex = (m_CurrentIndex + 1 + i) % m_NumStackedObservations;
                adapter.AddRange(m_StackedObservations[obsIndex], numWritten);
                numWritten += m_UnstackedObservationSize;
            }

            return(numWritten);
        }
Beispiel #2
0
        public void TestFloat2DSensorWrite()
        {
            var sensor = new Float2DSensor(3, 4, "floatsensor");

            for (var h = 0; h < 4; h++)
            {
                for (var w = 0; w < 3; w++)
                {
                    sensor.floatData[h, w] = 3 * h + w;
                }
            }

            var output = new float[12];
            var writer = new WriteAdapter();

            writer.SetTarget(output, sensor.GetObservationShape(), 0);
            sensor.Write(writer);
            for (var i = 0; i < 9; i++)
            {
                Assert.AreEqual(i, output[i]);
            }
        }
        public void TestRayZeroLength()
        {
            // Place the cube touching the origin
            var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);

            cube.transform.position = new Vector3(0, 0, .5f);
            cube.tag = k_CubeTag;

            Physics.SyncTransforms();

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

            perception.raysPerDirection = 0;
            perception.rayLength        = 0.0f;
            perception.sphereCastRadius = .5f;
            perception.detectableTags   = new List <string>();
            perception.detectableTags.Add(k_CubeTag);

            {
                // Set the layer mask to either the default, or one that ignores the close cube's layer

                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);

                // hit fraction is arbitrary but should be finite in [0,1]
                Assert.GreaterOrEqual(outputBuffer[2], 0.0f);
                Assert.LessOrEqual(outputBuffer[2], 1.0f);
            }
        }
Beispiel #4
0
        public void Generate(TensorProxy tensorProxy, int batchSize, IEnumerable <AgentInfoSensorsPair> infos)
        {
            TensorUtils.ResizeTensor(tensorProxy, batchSize, m_Allocator);
            var agentIndex = 0;

            foreach (var infoSensorPair in infos)
            {
                var sensor = infoSensorPair.sensors[m_SensorIndex];
                if (infoSensorPair.agentInfo.done)
                {
                    // If the agent is done, we might have a stale reference to the sensors
                    // e.g. a dependent object might have been disposed.
                    // To avoid this, just fill observation with zeroes instead of calling sensor.Write.
                    TensorUtils.FillTensorBatch(tensorProxy, agentIndex, 0.0f);
                }
                else
                {
                    m_WriteAdapter.SetTarget(tensorProxy, agentIndex, 0);
                    sensor.Write(m_WriteAdapter);
                }
                agentIndex++;
            }
        }
Beispiel #5
0
        public void Generate(TensorProxy tensorProxy, int batchSize, IEnumerable <AgentInfoSensorsPair> infos)
        {
            TensorUtils.ResizeTensor(tensorProxy, batchSize, m_Allocator);
            var vecObsSizeT = tensorProxy.shape[tensorProxy.shape.Length - 1];
            var agentIndex  = 0;

            foreach (var info in infos)
            {
                if (info.agentInfo.done)
                {
                    // If the agent is done, we might have a stale reference to the sensors
                    // e.g. a dependent object might have been disposed.
                    // To avoid this, just fill observation with zeroes instead of calling sensor.Write.
                    TensorUtils.FillTensorBatch(tensorProxy, agentIndex, 0.0f);
                }
                else
                {
                    var tensorOffset = 0;
                    // Write each sensor consecutively to the tensor
                    foreach (var sensorIndex in m_SensorIndices)
                    {
                        var sensor = info.sensors[sensorIndex];
                        m_WriteAdapter.SetTarget(tensorProxy, agentIndex, tensorOffset);
                        var numWritten = sensor.Write(m_WriteAdapter);
                        tensorOffset += numWritten;
                    }
                    Debug.AssertFormat(
                        tensorOffset == vecObsSizeT,
                        "mismatch between vector observation size ({0}) and number of observations written ({1})",
                        vecObsSizeT, tensorOffset
                        );
                }

                agentIndex++;
            }
        }
        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)
                                );
                }
            }
        }